AyCode.Core/.github/skills/docs-check/references/TOPIC_CODES.md

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/
SIGDS SIGNALR_DATASOURCE Client-server DataSource on SignalR transport: change tracking, rollback, sync state, load lifecycle, IList wrapper AyCode.Core/AyCode.Services.Server/docs/SIGNALR_DATASOURCE/
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. 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. ACCORE-LOG-C-K7M2 means "AyCode.Core's logger critical item with random suffix K7M2" — 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 ACCORE-LOG-IB-K7M2 or 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

  1. Format: <PREFIX>-<TOPIC>-<TYPE>-<RAND> — all uppercase, hyphen-separated. The <PREFIX> component identifies the owning repo per AyCode.Core/.github/REPO_PREFIXES.md (and per each repo's own @repo.prefix field). LLMP exception: LLMP-DEC-N entries (workspace-meta Decision Log) skip the prefix and use sequential N instead of <RAND> — single-file serialization avoids parallel-branch collision.
  2. 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.
  3. 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.
  4. 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.
  5. 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:

  1. Propose the code (2-6 uppercase chars), short and mnemonic, scoped to ACCORE's domain (framework concerns only).
  2. Check it doesn't collide with C# class-name prefixes (Ac* / Mg*) — the topic code should be visually distinct in mixed code/markdown content.
  3. Check it doesn't collide with existing ACCORE topic codes in the table above.
  4. Add a row to the "Framework's own (ACCORE) topic codes" table.
  5. Create the topic folder: AyCode.Core/<project>/docs/{TOPIC_FOLDER_NAME}/ with README.md, optional {TOPIC_FOLDER_NAME}_ISSUES.md, {TOPIC_FOLDER_NAME}_TODO.md.
  6. Add a Decision Log entry (LLMP-DEC-N, in the workspace-level LLM_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-6 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 string ACCORE-LOG-I-K7M2 as 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: 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 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.