# Repo Prefixes — format spec for repo-level namespace in topic IDs

Specification of the `<PREFIX>` component in the workspace's 4-component ID format. **Each repo declares its own prefix in its own `copilot-instructions.md` `@repo` block** — there is no central prefix listing here, in line with the Framework-First Design Principle (a framework `.md` does not enumerate consumer repos).

This file lives in `AyCode.Core/.github/` because the **format spec** is workspace-meta (used by every repo). It does NOT list non-framework prefixes.

## Full ID format

```
<PREFIX>-<TOPIC>-<TYPE>-<RAND>
```

| Component | Source | Description |
|---|---|---|
| `<PREFIX>` | Each repo's own `copilot-instructions.md` `@repo` block (`prefix = "..."` field) | Repo-level namespace |
| `<TOPIC>` | `docs-check/references/TOPIC_CODES.md` | Topic code (e.g., `LOG`, `BIN`, `SIG`) |
| `<TYPE>` | `docs-check/references/TOPIC_CODES.md` | Entry type (`I` = issue, `T` = TODO, `B` = bug, `C` = critical severity override) |
| `<RAND>` | Generated at creation | 4-character random alphanumeric suffix from `[A-Z0-9]` |

**Format rules**: all uppercase, hyphen-separated, no underscores, no spaces. Hash anchors in markdown cross-refs use lowercase: `accore-log-i-k7m2`.

**Examples** (using this repo's own prefix only — see Framework-First note above):
```
ACCORE-LOG-I-K7M2          # AyCode.Core's logger issue, random suffix K7M2
ACCORE-BIN-T-W9F1          # AyCode.Core's BINARY TODO, random suffix W9F1
ACCORE-XCUT-I-X8Q1         # AyCode.Core's cross-cutting issue
LLMP-DEC-50                # workspace-meta Decision (no prefix — see "LLMP exception" below)
```

## Why per-repo prefixes

Without prefixes, IDs like `LOG-I-5` are not globally unique across repos. Two peers may independently create logger-related issues with colliding IDs. More importantly: **framework docs cannot reference consumer-side issues** per the Framework-First Design Principle (a lower-layer framework cannot depend on a higher-layer consumer). Per-repo prefixes provide:

1. **Globally unique IDs** — `ACCORE-LOG-I-K7M2` ≠ `<other-prefix>-LOG-I-K7M2`, even when topic, type, and random suffix all match.
2. **Layer enforcement is visible** — a framework doc body referencing a higher-layer-prefixed ID becomes an immediate red flag in review (the prefix mismatch reveals the dependency-direction violation).
3. **Cross-repo search via wildcard** — `*-LOG-I-*` glob/regex finds all logger issues workspace-wide, with no central registry needed; the LLM filters by prefix after retrieval.
4. **Distributed parallel work** — combined with the random `<RAND>` suffix, multiple developers can create entries in parallel branches without ID-collision at merge time.

## ACCORE — this repo's own prefix

This repo (`AyCode.Core`) uses prefix **`ACCORE`** (declared in this repo's own `copilot-instructions.md` `@repo` block, `prefix = "ACCORE"` field).

## Per-repo prefix declaration convention

Every repo participating in the workspace declares its own prefix in its `.github/copilot-instructions.md` `@repo` block:

```
@repo {
  name = "<RepoName>"
  prefix = "<PREFIX>"        # ← prefix declared here
  type = "framework" | "product" | "consumer" | ...
  layer = 0..N
  own-dep-repos = [...]
}
```

To discover a peer's prefix at agent runtime: read that peer's `copilot-instructions.md` (already loaded if the peer is in `own-dep-repos`). For peers NOT in `own-dep-repos` (i.e., higher-layer consumers from a framework's perspective): cross-repo wildcard search (next section) avoids needing to know the prefix in advance.

## Cross-repo ID search (no central registry needed)

When searching for entries across the workspace (e.g., "all logger issues" — across framework AND any consumer repos), agents use the prefix-wildcard glob:

```
*-LOG-I-*       # all logger issues, any prefix
*-BIN-T-*       # all BINARY TODOs, any prefix
*-SIG-*         # all SIGNALR entries (issues + TODOs + bugs)
```

The wildcard pattern is workspace-discovery-agnostic — no central prefix list required. Result enumeration finds all matches; the LLM filters by prefix per the user's intent. The `docs-discovery` skill includes the cross-repo wildcard convention in its discovery flow.

## Random suffix spec

The `<RAND>` suffix is **4 characters from `[A-Z0-9]`** (36⁴ ≈ 1.7 million combinations per topic-type-prefix triple).

**Generation rules**:

1. Each new entry receives a fresh random suffix at creation time.
2. Before finalizing: the agent globs existing entries (active topic file + all year-month bucket archive files for that topic) and verifies the suffix is not yet used.
3. If collision detected (extremely rare — birthday-paradox 50% probability at ~1300 entries per topic-type-prefix triple): regenerate the suffix.
4. The suffix is **append-only** once assigned — never renumbered, never recycled, never reassigned to a different entry.

**At archive time** (`docs-archive` skill): performs collision-check before moving entries to year-month bucket archive files. If collision detected with an existing archive entry: skill aborts, signals the user, awaits manual resolution — no silent corruption.

## LLMP exception

`LLMP-DEC-N` Decision Log entries **do NOT receive a repo prefix**. They are workspace-meta — there is exactly one `LLM_PROTOCOL_DECISIONS.md` file (in AyCode.Core), and decisions are workspace-wide, not repo-specific. Bare format: `LLMP-DEC-1`, `LLMP-DEC-2`, ...

Sequential numbering for LLMP-DEC entries is **preserved** (legacy from before this registry existed; no random suffix). This is acceptable because the single Decision Log file enforces serialization — no parallel branches create concurrent LLMP-DEC entries that would collide.

If a future scenario emerges where workspace-meta decisions span multiple Decision Logs (unlikely), this exception will be revisited.

## Cross-references

- **Topic codes registry**: `docs-check/references/TOPIC_CODES.md` — the `<TOPIC>` component
- **Decision Log**: `LLM_PROTOCOL_DECISIONS.md` — registry of `LLMP-DEC-N` entries (workspace-meta, no prefix)
- **Per-repo prefix declarations**: each repo's own `.github/copilot-instructions.md` `@repo` block

## Picking a prefix for a new repo

When a new repo joins the workspace, it picks its own prefix (no central approval needed):

1. Choose a prefix (4-12 chars, uppercase, alphanumeric, no hyphens / underscores).
2. Verify it does NOT collide with `Ac*` / `Mg*` C# class-name prefixes (prefix must be ≥ 4 chars to avoid 2-char visual collision in mixed code/markdown content).
3. Verify it is visually distinct from prefixes of repos this new repo will reference or interoperate with (workspace-discovery-time check, not centrally enforced).
4. Declare the prefix in the new repo's `.github/copilot-instructions.md` `@repo` block (`prefix = "<PREFIX>"` field).
5. (Optional) Add an `LLMP-DEC-N` entry recording the new repo's join + prefix choice, if the new repo's existence is workspace-meta-significant.
