# Topic Codes — registry for globally-unique issue/TODO/decision IDs > **Scope note — workspace meta-tooling:** This registry is **workspace-configuration, not framework code**. It lists topics across any layer (framework, shared libraries, consumer products) because LLM agents operate across the full workspace and need one unified topic list. This is an intentional exception to the Framework-First Design Principle — see `AyCode.Core/.github/copilot-instructions.md` → Framework-First Design Principle → Exception for workspace meta-tooling. If AyCode.Core is extracted as a standalone framework, this registry is replaced with the new workspace's topic set (typically only LOG, BIN, TOON, XCUT, LLMP — the framework-layer topics). Canonical registry of topic codes used in issue, TODO, bug, critical, and decision entry IDs across the workspace. ID format: `{TOPIC}-{TYPE}-{N}`. ## Why this registry exists To make IDs like `LOG-I-5`, `SIG-B-2`, `XCUT-I-1` **globally unique strings** — unambiguous when referenced from code comments, cross-file, commit messages, or a future DB migration. ## Topic codes | Code | Topic | Scope | Docs location (primary) | |---------|-----------------------------|-----------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------| | `LOG` | LOGGING | Logger system: levels, writers, config-reading vs DI factory | `AyCode.Core/AyCode.Core/docs/LOGGING/` (+ variants in `AyCode.Core.Server`, `AyCode.Services`, `Mango.Nop.Services`) | | `AUTH` | AUTH | User authentication: bearer tokens, JWT, login flow, hub authorization | `AyCode.Core/docs/AUTH/` | | `SIG` | SIGNALR | SignalR transport: tags, client base, dispatch, session | `AyCode.Core/AyCode.Services/docs/SIGNALR/` (+ variant in `AyCode.Services.Server`) | | `SBP` | SIGNALR_BINARY_PROTOCOL | Binary wire protocol over SignalR: framing, chunking, argument read | `AyCode.Core/AyCode.Services/docs/SIGNALR_BINARY_PROTOCOL/` | | `BIN` | BINARY | AcBinary serializer: features, format, writers, source generator | `AyCode.Core/AyCode.Core/docs/BINARY/` | | `TOON` | TOON | Toon serializer: LLM-optimized format with @meta/@types/@data sections | `AyCode.Core/AyCode.Core/docs/TOON/` | | `GRID` | MGGRID (grid component) | MGGRID component family: layout, CRUD, columns, toolbar, rendering | `AyCode.Blazor/AyCode.Blazor.Components/docs/MGGRID/` | | `XCUT` | cross-cutting | Issues / TODOs that span ≥2 topics — one canonical home, referenced from others | `AyCode.Core/AyCode.Core/docs/XCUT/` *(canonical; entry can be cross-ref'd from each affected topic file)* | | `LLMP` | LLM-protocol meta | LLM protocol decisions (Decision Log entries only — uses `LLMP-DEC-N` form) | `AyCode.Core/.github/LLM_PROTOCOL_DECISIONS.md` | ## Type codes | Code | Type | Used in file | Notes | |-------|----------------|----------------------------------------------|----------------------------------------------------------------------------------------------------| | `I` | Issue | `{TOPIC}_ISSUES.md` | Concrete concern: spec inconsistency, broken contract, observable edge case | | `T` | TODO | `{TOPIC}_TODO.md` | Forward-looking planned work: refactor, missing feature, optimization | | `B` | Bug | `{TOPIC}_ISSUES.md` (alongside `I` entries) | Confirmed broken behaviour, reproducible, needs a code fix | | `C` | Critical | `{TOPIC}_ISSUES.md` or `{TOPIC}_TODO.md` | **Severity override** — emergency priority, supersedes `I`/`B`/`T` category; body explains type | | `DEC` | Decision | `LLM_PROTOCOL_DECISIONS.md` | **LLMP-only.** Append-only protocol decision entries. | ### Distinctions - **I vs B**: Both tracked together in `_ISSUES.md`. Use `B` only when the behaviour is confirmed broken with a reproducer. `I` covers concerns, inconsistencies, doc drift, edge cases without an active bug. - **C (Critical)**: A severity flag, not a category. `LOG-C-1` means "logger critical item 1" — body must state whether it's an underlying bug / issue / todo. Prefer `C` over `I`/`B`/`T` when severity is emergency. Do NOT double-classify (no `LOG-IB-1` or similar). - **DEC**: LLMP exception — long form because "LLMP-D-1" is unreadable. Decision Log entries only. ## ID format rules 1. **Format**: `{TOPIC}-{TYPE}-{N}` — all uppercase, hyphen-separated. 2. **Sequential number**: starts at 1, no zero-padding (`LOG-I-1`, `LOG-I-10`, `LOG-I-123`). 3. **Counter scope**: per (topic, type) pair. `LOG-I-*` and `LOG-T-*` have independent counters. `LOG-B-*` has its own counter (separate from `LOG-I-*`). 4. **Append-only**: once assigned, IDs never change. If an entry is reversed or superseded, add a NEW entry that references the prior one — do not renumber. 5. **Hash anchor** (markdown cross-file refs): lowercase with hyphens preserved (`LOGGING_ISSUES.md#log-i-5` — GitHub auto-converts). 6. **No sub-category in ID**: legacy prefixes like `PROTO-`, `DISPATCH-`, `CONN-`, `DS-` are NOT allowed at ID level. Capture sub-category in the entry body header: `## SIG-I-4 [PROTO]: ...`. ## Registry maintenance To add a new topic code: 1. Propose the code (2-5 uppercase chars), short and mnemonic. 2. Check it doesn't collide with C# class-name prefixes (`Ac*` = AyCode.Core, `Mg*` = Mango-specific) — the code should be visually distinct from those prefixes. 3. Add a row to this registry. 4. Create the topic folder: `docs/{TOPIC_FOLDER_NAME}/` with `README.md`, optional `{TOPIC_FOLDER_NAME}_ISSUES.md`, `{TOPIC_FOLDER_NAME}_TODO.md`. 5. Add a Decision Log entry (`LLMP-DEC-N`) recording the new topic. ## Collision avoidance with class-name prefixes C# code conventions in this workspace: - `Ac*` — AyCode.Core framework types (e.g., `AcLoggerBase`, `AcBinarySerializer`) - `Mg*` — Mango company types (e.g., `MgGrid`, `MgDbTableBase`, `MgEntityBase`) Topic codes intentionally avoid these 2-char prefixes to prevent visual confusion in mixed content (e.g., `MgGrid.cs → GRID-I-1`, not `MG-I-1`). ## Examples ``` LOG-I-5 # logger issue 5 LOG-T-3 # logger TODO 3 LOG-B-1 # logger bug 1 (confirmed broken) LOG-C-1 # logger CRITICAL — body: underlying bug / issue / todo SIG-I-4 # SignalR issue 4 (body may note: [PROTO] sub-category) SBP-T-2 # SignalR Binary Protocol TODO 2 BIN-B-1 # Binary serializer bug 1 TOON-I-3 # Toon issue 3 GRID-T-7 # MgGrid TODO 7 XCUT-I-1 # cross-cutting issue 1 (affects ≥2 topics) LLMP-DEC-4 # LLM-protocol decision 4 (Decision Log entry) ``` ## Cross-references to other files - **Reference format** (cross-file in markdown): `LOGGING_ISSUES.md#log-i-5` (filename + hash anchor). Bare ID (`LOG-I-5`) may be used when context is unambiguous (within the same topic). - **Code comments**: `// See LOG-I-5` — bare ID acceptable since it's globally unique. - **DB natural key** (future migration): `(topic, type, seq)` tuple; or the full string `LOG-I-5` as a single column. ## Status field conventions Every entry in `_ISSUES.md`, `_TODO.md`, and `LLM_PROTOCOL_DECISIONS.md` SHOULD carry an explicit `Status` field. **3 allowed values**: | Status | Meaning | Archive eligible? | |---|---|---| | `Open` | Active / unresolved (default for new entries); also used for documented-current-behaviour entries that must remain visible | No | | `InProgress` | Partial work in flight; some scope addressed but more remains | No | | `Closed` | Done — bug fixed, decision made (won't fix / superseded by another entry / accepted), TODO completed. The body of the entry explains *what happened* (date, ref, rationale). | Yes | ### Defaults - New entries default to `Status: Open`. - For documented current-behaviour entries (accepted limitations / "by design" / "this is how it works"), use `Status: Open` with an optional body callout: `> **Note:** This entry documents accepted current behaviour — not scheduled for change.` These never archive (Open status). ### Update workflow When status changes, update the `Status` line in-place. **This is the ONE exception to append-only** — the Status field is mutable; entry body / ID / Description remain immutable. When marking `Closed`: 1. **Format the Status line as** `Status: Closed (YYYY-MM-DD)` — the inline date is what `docs-archive` uses to determine the destination year-bucket. 2. **Add a `### Resolution` sub-section** documenting the closure. **Strongly recommended** — without it, future readers (and the `docs-archive` skill on lookup) have no context for "what changed, why, where". Suggested fields: - **What:** one-line summary of the change. - **Where:** code reference (file/class/commit hash) or doc reference (ADR / PR). - **Why:** the rationale (fix / "won't fix because X" / "superseded by LOG-I-Y" / "accepted as-is"). - Optional: scope, date if different from Status line, related entries. The body carries the **nuance**; the Status field only signals archive-eligibility. ### Lifecycle: archive `Closed` entries are eligible for rotation into year-bucketed archive files (`_.md`) via the `docs-archive` skill. Year derived from a date in the entry body. Archive operation is user-invoked — closed entries don't disappear automatically. See `AyCode.Core/.github/skills/docs-archive/SKILL.md`. ## Change history See the Decision Log (`../../../LLM_PROTOCOL_DECISIONS.md`) for the introduction of this registry and future topic-code additions.