14 KiB
Topic Codes — registry for AyCode.Core's own topics (ACCORE)
Per the Framework-First Design Principle, this Layer 0 registry lists only the framework's own (ACCORE) topics. Each higher-layer repo hosts its own TOPIC_CODES.md for repo-specific topics — see ## Per-repo extension convention below. A consumer's topic-search at runtime walks own-dep-repos to gather both its own and all inherited (lower-layer) topic registries.
Full ID format: <PREFIX>-<TOPIC>-<TYPE>-<RAND> — see AyCode.Core/.github/REPO_PREFIXES.md for the <PREFIX> and <RAND> components. The <TOPIC> and <TYPE> components are defined in this file (for the framework) and in each higher-layer repo's own equivalent (for consumer-side topics).
Why this registry exists
To make IDs like ACCORE-LOG-I-K7M2, ACCORE-SIG-B-3R9P, ACCORE-XCUT-I-A4B7 unambiguous within the framework. The <TOPIC> component (registered here for ACCORE) combines with <PREFIX> (per REPO_PREFIXES.md) and <RAND> (4-character random alphanumeric suffix) to form the full ID.
Framework's own (ACCORE) topic codes
| Code | Topic | Scope | Docs location |
|---|---|---|---|
LOG |
LOGGING | Logger system: levels, writers, config-reading vs DI factory | AyCode.Core/AyCode.Core/docs/LOGGING/ (+ variants in AyCode.Core.Server, AyCode.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/ |
XCUT |
cross-cutting | Issues / TODOs spanning ≥2 ACCORE topics — one canonical home, referenced from each affected topic | AyCode.Core/AyCode.Core/docs/XCUT/ |
META |
meta-tooling | Issues/TODOs about the workspace meta-tooling itself: skills, registries, .github/ conventions, ADR/Decision Log governance, protocol-stack edge cases. Distinct from code-domain topics (LOG, BIN, etc.). |
AyCode.Core/.github/META_ISSUES.md + AyCode.Core/.github/META_TODO.md |
LLMP |
LLM-protocol meta | LLM protocol decisions (Decision Log entries only — uses LLMP-DEC-N form, no prefix) |
AyCode.Core/.github/LLM_PROTOCOL_DECISIONS.md |
Type codes (universal across all repos)
| 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. UseBonly when the behaviour is confirmed broken with a reproducer.Icovers concerns, inconsistencies, doc drift, edge cases without an active bug. - C (Critical): A severity flag, not a category.
ACCORE-LOG-C-K7M2means "AyCode.Core's logger critical item with random suffix K7M2" — body must state whether it's an underlying bug / issue / todo. PreferCoverI/B/Twhen severity is emergency. Do NOT double-classify (noACCORE-LOG-IB-K7M2or similar). - DEC: LLMP exception — long form because "LLMP-D-1" is unreadable. Decision Log entries only.
Per-repo extension convention
Each higher-layer repo MAY host its own TOPIC_CODES.md for repo-specific topics. Recommended location:
<repo>/.github/TOPIC_CODES.md
This per-repo file lists ONLY that repo's own topic codes. Lower-layer (inherited) topics are reachable through the dependency tree — at runtime, the docs-check skill walks own-dep-repos from the invocation point to gather both this repo's own topics AND all inherited topics from deps.
Topic codes need NOT be globally unique across repos — the <PREFIX> component disambiguates. Two repos may legitimately use the same topic code for repo-local concepts (e.g., one framework's DAL ≠ another framework's DAL).
If a higher-layer repo has no repo-specific topics, the file is omitted (default = the repo uses only inherited topics from its deps).
The framework (this file) does NOT enumerate higher-layer topics — that would violate Framework-First. To find all topics workspace-wide, agents walk the dep tree from a top-layer consumer (which transitively sees everything).
ID format rules
- Format:
<PREFIX>-<TOPIC>-<TYPE>-<RAND>— all uppercase, hyphen-separated. The<PREFIX>component identifies the owning repo perAyCode.Core/.github/REPO_PREFIXES.md(and per each repo's own@repo.prefixfield). LLMP exception:LLMP-DEC-Nentries (workspace-meta Decision Log) skip the prefix and use sequentialNinstead of<RAND>— single-file serialization avoids parallel-branch collision. - Random suffix:
<RAND>is a 4-character alphanumeric suffix from[A-Z0-9](~1.7M combinations per<PREFIX>-<TOPIC>-<TYPE>triple). Generated at entry creation; the agent globs existing entries (active topic file + all year-bucketed archive files) and verifies uniqueness; regenerate on rare collision. - 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, do not re-randomize.
- Hash anchor (markdown cross-file refs): lowercase with hyphens preserved (
LOGGING_ISSUES.md#accore-log-i-k7m2— GitHub auto-converts). Always use the full prefixed form; bare hash anchors without prefix are ambiguous across repos. - No sub-category in ID: legacy sub-prefixes like
PROTO-,DISPATCH-,CONN-,DS-are NOT allowed at ID level. Capture sub-category in the entry body header:## ACCORE-SIG-I-K7M2 [PROTO]: ....
Registry maintenance — adding a new ACCORE topic
To add a new topic code for AyCode.Core specifically:
- Propose the code (2-5 uppercase chars), short and mnemonic, scoped to ACCORE's domain (framework concerns only).
- Check it doesn't collide with C# class-name prefixes (
Ac*/Mg*) — the topic code should be visually distinct in mixed code/markdown content. - Check it doesn't collide with existing ACCORE topic codes in the table above.
- Add a row to the "Framework's own (ACCORE) topic codes" table.
- Create the topic folder:
AyCode.Core/<project>/docs/{TOPIC_FOLDER_NAME}/withREADME.md, optional{TOPIC_FOLDER_NAME}_ISSUES.md,{TOPIC_FOLDER_NAME}_TODO.md. - Add a Decision Log entry (
LLMP-DEC-N, in the workspace-levelLLM_PROTOCOL_DECISIONS.md) recording the new framework topic.
For higher-layer repos: each consumer registers its own topics in its own TOPIC_CODES.md per the per-repo extension convention. No framework-level approval is needed — the consumer is sovereign over its own domain.
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 (Ac, Mg) to prevent visual confusion in mixed content. Topic codes are 2-5 chars and SHOULD NOT start with Ac or Mg. (Example principle: a hypothetical 2-char MG topic code would visually collide with Mg* class names; choose a more distinctive ≥3-char code.)
Examples (ACCORE only)
ACCORE-LOG-I-K7M2 # framework's logger issue (random suffix K7M2)
ACCORE-LOG-T-3R9P # framework's logger TODO
ACCORE-LOG-B-A4B7 # framework's logger bug (confirmed broken)
ACCORE-LOG-C-X9Q4 # framework's logger CRITICAL — body: underlying bug / issue / todo
ACCORE-SIG-I-M2K8 # framework's SignalR issue (body may note: [PROTO] sub-category)
ACCORE-SBP-T-7N3F # framework's SignalR Binary Protocol TODO
ACCORE-BIN-B-P5W2 # framework's Binary serializer bug
ACCORE-TOON-I-D8R6 # framework's Toon issue
ACCORE-XCUT-I-F4G1 # framework's cross-cutting issue (affects ≥2 ACCORE topics)
LLMP-DEC-50 # workspace-meta Decision Log entry (no prefix — bare exception)
The <RAND> suffixes shown above are illustrative. Real entries generate fresh random suffixes at creation time per REPO_PREFIXES.md's "Random suffix spec".
Cross-references to other files
- Reference format (cross-file in markdown):
LOGGING_ISSUES.md#accore-log-i-k7m2(filename + lowercase hash anchor with full 4-component ID). Always use the full prefixed form — bare hash anchors without prefix are ambiguous across repos. - Code comments:
// See ACCORE-LOG-I-K7M2— full prefixed form, since the ID is globally unique only with prefix. - DB natural key (future migration):
(prefix, topic, type, suffix)tuple; or the full stringACCORE-LOG-I-K7M2as a single column. - Workspace registries:
AyCode.Core/.github/REPO_PREFIXES.md(framework prefix spec); this file (ACCORE topics + format spec); each higher-layer repo's own.github/TOPIC_CODES.md(consumer-side topics);AyCode.Core/.github/LLM_PROTOCOL_DECISIONS.md(LLMP-DEC entries, workspace-meta history).
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: Openwith 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:
- Format the Status line as
Status: Closed (YYYY-MM-DD)— the inline date is whatdocs-archiveuses to determine the destination year-bucket. - Add a
### Resolutionsub-section documenting the closure. Strongly recommended — without it, future readers (and thedocs-archiveskill 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 ACCORE-LOG-I-XXXX" / "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 (<file>_<year>.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.