45 KiB
LLM Protocol Decisions
Append-only log of decisions about the AI AGENT CORE PROTOCOL and related LLM tooling (skills, instruction files, shared conventions) across the 8 known .github/copilot-instructions.md files.
Current protocol state (quick reference)
Active as of 2026-04-24. For the full evolution history, see the dated table near the bottom of this file. Read this summary first to orient yourself before diving into the dated entries.
Session start flow:
- Primary files: agent reads
copilot-instructions.md+ 3 SKILL.md files (docs-discovery,docs-check,protocol-audit). First response's[LOADED_DOCS: ...]shows 4 files. - Inherit files: agent reads this inherit
copilot-instructions.md+ AyCode.Core's canonicalcopilot-instructions.md(for the numbered rules) + 3 SKILL.md files. First response's[LOADED_DOCS: ...]shows 5 files. - Why pre-load: workspace skills are NOT in Claude Code's native skill-registry; pre-loading ensures implicit triggers fire reliably.
AI AGENT CORE PROTOCOL (present verbatim in each primary .github/copilot-instructions.md):
- MANDATORY OUTPUT PREFIX — every response starts with
[LOADED_DOCS: N files (+K this turn: <short names>)]. Short-name rule: basename by default;TOPIC/README.mdfor topic-folder READMEs (to disambiguate the manyREADME.mdfiles); extend upward for cross-project collisions. Never emit a bareREADME.mdin the prefix. - HARD-GATE: DOCS BEFORE CODE — no
code_search/ sourceget_fileuntil relevant.mddocs are loaded. Includes CROSS-REPO HARD-GATE (applies to every repo entered viaown-dep-repos) and PER-QUESTION DOC-FIRST (check for unloaded.mdbefore grepping code). - STRICT NO-RE-READ POLICY — a doc is "in context" only if actually read via tool call in THIS conversation (session summaries / memory entries do NOT count — lossy compression).
- CONTEXT RECOVERY — auto-detection triggers: session starts with a summary, mid-session compaction, or inability to quote exact content → reset
[LOADED_DOCS: NONE]and re-read per Rule #2. - EXPLICIT CONSENT FOR MODIFICATIONS — no rewriting, creating, or deleting any file (code, docs, config, memory, or otherwise) without explicit user approval.
Docs layout — Option C "folder + topic-prefixed companions":
- Paired topics live in
TOPIC/folders:TOPIC/README.md(main, canonical) +TOPIC/TOPIC_ISSUES.md+TOPIC/TOPIC_TODO.md+ optionalTOPIC/TOPIC_<subname>.md. - Single-file reference docs (
ARCHITECTURE.md,CONVENTIONS.md,GLOSSARY.md,DTOS.md, etc.) remain flat at thedocs/root. - Each
docs/root has aREADME.mdindex listing the topics. - Project-specific variants of framework topics (e.g., the server-side logger in
AyCode.Core.Server, the Nop bridge inMango.Nop.Services) get their ownTOPIC/README.mdunder the variant project'sdocs/. .csprojfiles use recursive glob:<None Include="docs\**\*.md" />so Pattern B nesting auto-shows in Visual Studio Solution Explorer without manual entries.
Instruction files — 8 total:
- 5 primary files contain the full numbered AI AGENT CORE PROTOCOL:
AyCode.Core,AyCode.Blazor,Libraries,FruitBank(Mango/Source),FruitBankHybridApp. - 3 inherit files reference AyCode.Core's protocol via blockquote (no duplicated numbered rules):
Mango.Nop.Core(sub-project framework),Nop.Plugin.Misc.AIPlugin(plugin source),Mango.FruitBank(nopCommerce deployment host). - Each non-Core file has
## Shared Agent Skills+## Protocol Historysections.
Issue / TODO / Decision ID format (globally unique):
- Format:
{TOPIC}-{TYPE}-{N}(e.g.,LOG-I-5,SIG-T-3,BIN-B-1,XCUT-I-1,LLMP-DEC-4) - Topic codes:
LOG(logger),SIG(SignalR),SBP(SignalR binary protocol),BIN(binary serializer),TOON(Toon serializer),GRID(MGGRID),XCUT(cross-cutting),LLMP(LLM-protocol meta — usesDECtype only). - Type codes:
I= issue,T= TODO,B= bug,C= critical (severity override),DEC= decision (LLMP-only). - Counter scope: per (topic, type) pair.
LOG-I-1andLOG-T-1independent. - Append-only: IDs never change once assigned. Full registry + rules:
AyCode.Core/.github/skills/docs-check/references/TOPIC_CODES.md.
Agent skills — all three at AyCode.Core/.github/skills/:
docs-discovery— extracts topic tokens from user requests, globs**/docs/TOPIC/**/*.md(+ companion patterns), loads the paired main+ISSUES+TODO set before source-code search. Updates LOADED_DOCS via Rule #1 format.protocol-auditv2.2 — readsreferences/REPOS.mdand audits all 8 instruction files: Common invariants C1-C4 for all (C4 =## Session Setuppresence, added in LLMP-DEC-33); Primary-only (P1-P10) for the 5 primary; Inherit-only (I1-I3) for the 3 inherit; Cross-cutting (X1, X3) for primary, (X1, X2) for non-Core primary, (X1, X2) for inherit. Reports PASS/FAIL per invariant-file cell, with patch suggestions. Does NOT auto-apply patches.docs-checkv1.0 — end-of-code-modifying-response skill: evaluates loaded.mdfor drift vs code, missing topic coverage, csproj-glob registration gaps, and new issue/TODO candidates. Emits the[DOCUMENTATION CHECK]section (or[DOCUMENTATION CHECK] None.single-line). Read-only on loaded docs; all patches as proposals per Rule #5.
Docs-sync enforcement ([DOCUMENTATION CHECK] at end of code-modifying responses):
- Keep all .md in sync — if code and loaded docs disagree, notify and ask (do NOT silently edit).
- Identify missing documentation — if a frequently-used pattern isn't documented in main topic docs, propose an entry.
- Topic-based separation — split logically distinct topics into separate
.mdfiles; keep concise and LLM-oriented. - File registration (scope: outside existing glob only) — if a new
.mdfalls outside the nearest.csproj's recursive globs (docs\**\*.md,**\README.md), surface the needed glob patch. Common case (doc underdocs/, folder-README) is zero-cost via csproj globs set up cluster-wide. - Issue / TODO surfacing — surface concrete, non-duplicate, actionable
_ISSUES.md/_TODO.mdcandidates as draft entries (priority P1-P3, rationale, code ref — NO ID, user assigns at apply-time). Prerequisites (ALL must hold): companion is inLOADED_DOCS; high-confidence (quotable evidence); concrete; not duplicate. Max 3 items per response. Also: surfaceStatus: FIXEDsuggestions when a listed issue is fixed in the current response. - Empty-state output — if
[DOCUMENTATION CHECK]has nothing to report:[DOCUMENTATION CHECK] None.single line, no padding.
Decision Log governance (this file):
- Append-only. Never rewrite or delete entries. Reversals and refinements get new entries that reference the superseded one by ID (e.g., "LLMP-DEC-26 superseded by LLMP-DEC-27").
- Entries have
LLMP-DEC-NIDs (topic=LLMP, type=DEC — see TOPIC_CODES.md). Sequential, append-only, never renumber. Reference entries by ID for unambiguous citation from code comments, other.mdfiles, or cross-repo. - Archive annually once the log reaches ~50 entries (split to
LLM_PROTOCOL_DECISIONS_<year>.md). IDs stay unique across archives. Affectedcolumn uses the scope codes defined below.- User consent required for every new entry.
Purpose
Quick lookup for why a rule is the way it is, to avoid:
- Re-debating decisions that were already discussed and resolved
- Silently "optimizing away" a rule whose edge-case purpose is no longer obvious
- Losing context between sessions / across team members
Scope
Tracked here:
.github/copilot-instructions.mdrule additions / removals / rewordingsCLAUDE.mdchanges- New, modified, or removed agent skills (
docs-discovery,protocol-audit, etc.) - Protocol-level structural shifts (doc layout, file location conventions)
NOT tracked here:
- Code refactors or feature work — use commit messages / PR descriptions
- Code-architecture decisions — see
docs/ARCHITECTURE.mdat the relevant layer - Trivial fixes (typos, path corrections without rule-semantic change)
Writing rules
- Append-only. If a decision is reversed or superseded, add a NEW entry that points to the old one. Do not rewrite history — the evolution itself is informative.
- One row per decision. Keep the rationale concise; the purpose is scan-ability, not prose.
Affectedcolumn uses the scope codes defined below — always be explicit about which files were touched.- Explicit consent required for additions (per Rule #5 of the active
copilot-instructions.md). The LLM proposes the entry; the user reviews and approves before the write. - Reference this log before proposing a protocol change — if the change was already discussed, the existing entry may save a debate.
Scope codes (for the Affected column)
| Code | Meaning |
|---|---|
5× primary |
All 5 primary copilot-instructions.md (AyCode.Core, AyCode.Blazor, Libraries, FruitBank, FruitBankHybridApp) |
4× non-Core primary |
The 4 primary files except AyCode.Core |
3× inherit |
The 3 inherit files (Mango.Nop.Core, Nop.Plugin.Misc.AIPlugin, Mango.FruitBank) |
all 8 |
All 8 files: 5 primary + 3 inherit |
<repo>/... |
A single specific file path |
<skill-name>/... |
Skill directory under .github/skills/ |
The "primary" vs "inherit" distinction is defined in protocol-audit/references/REPOS.md.
2026
| ID | Date | Decision | Rationale | Affected |
|---|---|---|---|---|
| LLMP-DEC-1 | 2026-04-20 | Added CROSS-REPO HARD-GATE to Rule #2 | Docs-before-code was applied only to the own repo, not external deps | 5× primary |
| LLMP-DEC-2 | 2026-04-20 | Added PER-QUESTION DOC-FIRST to Rule #2 | LLM skipped checking for relevant .md before jumping to code search |
5× primary |
| LLMP-DEC-3 | 2026-04-21 | Expanded Rule #5 scope: "code/files" → "any file..." | Memory / config / docs edits also need consent; old wording too narrow | 5× primary |
| LLMP-DEC-4 | 2026-04-22 | Added Auto-detection triggers to Rule #4 | "realize" was subjective; post-compaction reset to [LOADED_DOCS: NONE] didn't fire reliably |
5× primary |
| LLMP-DEC-5 | 2026-04-22 | Added "in context" definition to Rule #3 | Summary content was mistaken for actually-loaded docs (lossy compression) | 5× primary |
| LLMP-DEC-6 | 2026-04-22 | Unified AyCode.Blazor Rule #3 with the other 4 repos | Was custom "CRITICAL TOOL EXECUTION FIREWALL" variant; normalized | AyCode.Blazor/copilot-instructions.md |
| LLMP-DEC-7 | 2026-04-22 | "strictly maintain rule X" → "rule 3" | Per-repo numbers varied (15/18/19/20/21); unified reference | 5× primary |
| LLMP-DEC-8 | 2026-04-22 | Created protocol-audit skill at repo-level |
Cross-repo consistency check; .github/skills/ chosen over personal paths (DRY) |
protocol-audit/SKILL.md + protocol-audit/references/REPOS.md |
| LLMP-DEC-9 | 2026-04-22 | Added ## Shared Agent Skills section (protocol-audit) |
Discoverability of AyCode.Core-hosted skills from dependent repos | 4× non-Core primary |
| LLMP-DEC-10 | 2026-04-23 | Created docs-discovery skill (parallel session) |
Paired-doc (main + _ISSUES + _TODO) auto-loading before code search |
docs-discovery/SKILL.md + AyCode.Core/copilot-instructions.md |
| LLMP-DEC-11 | 2026-04-23 | Extended ## Shared Agent Skills with docs-discovery (parallel session) |
Both skills now listed in each dependent repo | 4× non-Core primary + Mango.Nop.Core/copilot-instructions.md |
| LLMP-DEC-12 | 2026-04-24 | LOADED_DOCS prefix: full list → count+delta format | Long lists became visual noise at scale; delta preserves self-commitment | 5× primary + docs-discovery/SKILL.md |
| LLMP-DEC-13 | 2026-04-24 | Created this Decision Log | Institutional memory for protocol evolution; avoid re-debating resolved choices | AyCode.Core/.github/LLM_PROTOCOL_DECISIONS.md |
| LLMP-DEC-14 | 2026-04-24 | Added ## Protocol History section |
Cross-repo discoverability of the Decision Log | 4× non-Core primary + Mango.Nop.Core/copilot-instructions.md |
| LLMP-DEC-15 | 2026-04-24 | Filled empty Nop.Plugin.Misc.AIPlugin instruction file | Previously 0 bytes; now minimal inherit-pattern referencing AyCode.Core + both skills + log | Nop.Plugin.Misc.AIPlugin/copilot-instructions.md |
| LLMP-DEC-16 | 2026-04-24 | Filled empty Mango\FruitBank instruction file | Previously 0 bytes; now minimal inherit-pattern with ⚠️ "purpose TBD" notice | Mango/FruitBank/copilot-instructions.md |
| LLMP-DEC-17 | 2026-04-24 | Expanded REPOS.md: 5 repos → 8 (primary + inherit) | Audit scope was incomplete; sub-project & plugin files were missed | protocol-audit/references/REPOS.md |
| LLMP-DEC-18 | 2026-04-24 | Fixed Mango.Nop.Core @repo path (7 .. → 6 ..) |
Previous path resolved to H:\Aycode\... (non-existent). Corrected relative depth from repo root |
Mango.Nop.Core/copilot-instructions.md |
| LLMP-DEC-19 | 2026-04-24 | Resolved Mango.FruitBank purpose (nopCommerce host) | Confirmed: directory is a nopCommerce deployment for FruitBank company, hosting Nop.Plugin.Misc.AIPlugin. Layer 4 (host), not TBD. Updated content accordingly. | Mango/FruitBank/copilot-instructions.md |
| LLMP-DEC-20 | 2026-04-24 | protocol-audit v1.0 → v2.0: primary/inherit invariant split |
SKILL.md now applies Common + Primary invariants to rows 1-5, Common + Inherit + Cross-cutting to rows 6-8. New invariants: P3 (Rule #1 count+delta format), X1 (Shared Agent Skills), X2 (Protocol History). | protocol-audit/SKILL.md + protocol-audit/references/REPOS.md (issues cleared) |
| LLMP-DEC-21 | 2026-04-24 | Docs layout: paired topics migrated to TOPIC/README.md + TOPIC/TOPIC_*.md pattern (Option C) |
Single docs/ folder with flat TOPIC_*.md files was noisy at scale; folder grouping reinforces the "folder navigation rule" and gives each topic a canonical README.md entry point. Option C (README.md main + topic-prefixed companions) chosen over pure Pattern B for (a) glob-pattern compatibility with old **/TOPIC*.md, (b) unique LOADED_DOCS basenames for companion files, (c) GitHub README auto-render preserved. Single-file topics (ARCHITECTURE, GLOSSARY, CONVENTIONS, DTOS, etc.) kept flat. |
13 docs/ folders across 5 repos (AyCode.Core, AyCode.Blazor, Libraries, FruitBankHybridApp, Nop.Plugin.Misc.AIPlugin); ~35 file renames/moves; 13 new README.md index files; 4 csproj files converted from explicit file-lists to recursive glob (docs\**\*.md); docs-discovery/SKILL.md Step 2 glob patterns updated to match Pattern B layout |
| LLMP-DEC-22 | 2026-04-24 | Rule #1 LOADED_DOCS format: "basenames only" → "shortest unique short names" | After the Pattern B docs migration, many README.md files share the same basename across different topic folders (e.g., LOGGING/README.md, BINARY/README.md, SIGNALR/README.md). A bare README.md in the LOADED_DOCS prefix is ambiguous and breaks the self-commitment / no-re-read mechanism. New rule: basename by default (already unique for topic-prefixed companions and flat single-file topics); TOPIC/README.md for topic-folder READMEs; further disambiguation upward for cross-project collisions. |
5× primary + docs-discovery/SKILL.md Step 4 |
| LLMP-DEC-23 | 2026-04-24 | Full cross-reference cleanup after Pattern B migration (batch sed + targeted fixes) | After the docs migration, ~45 .md files contained outdated paths (flat TOPIC_*.md refs that are now TOPIC/TOPIC_*.md; renamed mains LOGGING_SERVER.md→LOGGING/README.md etc.; pre-existing depth bugs like AyCode.Core/docs/LOGGING.md that were always wrong depth; cross-folder sibling refs inside SIGNALR_BINARY_PROTOCOL/ pointing to SIGNALR/ topics by basename). Three-pass cleanup: (1) batch sed on 44 files for docs/TOPIC*.md → Pattern B paths; (2) second sed pass for pre-existing AyCode.Core/docs/{LOGGING,BINARY,SIGNALR}/ → AyCode.Core/{AyCode.Core,AyCode.Services}/docs/... depth correction (with placeholder guard to avoid double-substitution); (3) targeted Edits for cross-folder sibling refs and project-level README doc-listing tables. Final grep: zero old-style references remain. |
~45 .md files across all 5 repos; AyCode.Core/copilot-instructions.md rule 8 + 19; AyCode.Blazor rule 14; FruitBankHybridApp rules 15+20; 7 project-level README.md "doc listing" tables; 9 MGGRID sibling refs; 5 cross-folder SIGNALR↔SIGNALR_BINARY_PROTOCOL refs |
| LLMP-DEC-24 | 2026-04-24 | Phantom-reference fixes: docs/ARCHITECTURE.md from .github/ + BINARY/README.md serializer-overview target |
(1) AyCode.Core/.github/copilot-instructions.md:96 had docs/ARCHITECTURE.md#framework-vs-consumer-boundary which resolved to .github/docs/ARCHITECTURE.md (non-existent) relative to the file's own location. Fixed to ../docs/ARCHITECTURE.md#framework-vs-consumer-boundary so the path resolves to the existing repo-root docs/ARCHITECTURE.md. (2) AyCode.Core/AyCode.Core/docs/BINARY/README.md:22 pointed to docs/ARCHITECTURE.md for "Serialization overview (Toon vs AcBinary vs AcJson)". The new TOON/README.md (created by a parallel session) uses the more canonical ../../Serializers/README.md — the serializer-framework-level README that genuinely compares all three formats. Aligned BINARY/README.md to the same target for consistency. |
AyCode.Core/.github/copilot-instructions.md + AyCode.Core/AyCode.Core/docs/BINARY/README.md |
| LLMP-DEC-25 | 2026-04-24 | Added "Current protocol state (quick reference)" section to the top of the Decision Log | The log grows monotonically (append-only); readers landing on it shouldn't have to scan every dated entry to learn the currently-active protocol. The new top-of-file summary captures Rules #1-5, docs layout convention, instruction-file inventory (5 primary + 3 inherit), agent skills, and Decision Log governance. Dated entries remain the source of truth for why each decision was made; the summary is the what at a glance. Archival plan noted: yearly split at ~50 entries. | AyCode.Core/.github/LLM_PROTOCOL_DECISIONS.md |
| LLMP-DEC-26 | 2026-04-24 | Extended docs-sync rule with two sub-rules: File registration + Issue / TODO surfacing (initial version; superseded by 2026-04-24 revision below) |
(1) File registration — every new .md must be visible in Visual Studio Solution Explorer, which requires a <None Include=".." /> entry (or matching recursive glob) in the nearest .csproj. (2) Issue / TODO surfacing — surface concrete bugs/TODO candidates in [DOCUMENTATION CHECK] when not already in loaded _ISSUES.md / _TODO.md. Initial calibration: "concrete + non-duplicate + actionable — silence beats noise". This version was revised after two external LLM critiques — see the next entry. |
5× primary (docs-sync rule: AyCode.Core #18, AyCode.Blazor #13, Libraries #16, FruitBank #14, FruitBankHybridApp #14) |
| LLMP-DEC-27 | 2026-04-24 | Revision of the two new sub-rules after two-session LLM review + proactive csproj glob expansion | Two external LLM critiques identified gaps in the initial sub-rule text. Applied revisions: (A) File registration scope-limit — check only if the new file falls OUTSIDE an existing recursive glob (zero-cost skip for the common docs/-path case). (B) Issue / TODO surfacing guardrails — added 4 explicit prerequisites (companion must be in LOADED_DOCS for reliable duplicate check; high confidence with quotable evidence; concrete observation; not duplicate). Added volume cap max 3 per response. Removed ID assignment from draft entries (user assigns at apply-time to avoid parallel-session collisions). Added status-update-on-fix clause (fixing an issue listed in loaded _ISSUES.md → surface Status: FIXED suggestion). (C) ENFORCEMENT empty-state guard — if nothing to report: [DOCUMENTATION CHECK] None. single line (no prose padding). (D) Proactive csproj glob expansion — added <None Include="**\README.md" Exclude="$(DefaultItemExcludes);docs\**" /> to 9 csproj files already having docs/** glob; added the same pattern (without docs/** exclusion) to 5 csproj files lacking any md glob. Together these cover folder-level README.md files in code directories (Loggers, Serializers, SignalRs, DbContexts, LogItems, etc.), making them visible in VS Solution Explorer without per-file rule trigger. The rule sub-rule A now mostly fires only for truly unusual locations. Cross-reference added between sub-rule B and the existing "Identify missing documentation" clause (different targets: main docs vs companions). |
5× primary instruction files (docs-sync rule revision); 14 csproj files (glob expansion): 9 with docs/** + **/README.md, 5 with only **/README.md |
| LLMP-DEC-28 | 2026-04-24 | Created docs-check skill; docs-sync rule → short pointer |
Observation: both Claude Code and Copilot interpret and follow skills more reliably than numbered rules (explicit activation, step-by-step SKILL.md, description-matching forces deliberate thought). The docs-sync rule had grown into a multi-step procedure (drift detection, missing docs, topic separation, file registration, issue/TODO surfacing with 4 prereqs + volume cap + status-update-on-fix, empty-state handling) — exactly the shape of a skill, not a rule. Created AyCode.Core/.github/skills/docs-check/SKILL.md (v1.0) encapsulating the full procedure in 7 steps + edge cases + negative examples. Rule #18 (and equivalents) shortened in each primary file to a single pointer: "at the end of EVERY code-modifying response, invoke the docs-check skill ...". Removed ~40 lines of duplicated procedure per primary file (×5 = ~200 lines of redundant text across the workspace). Skill is read-only on loaded docs (no new Read/Grep during invocation); all patches surface as proposals (Rule #5). |
1 new skill: docs-check/SKILL.md; 5 primary copilot-instructions.md (docs-sync rule shortened); 7 non-Core files (## Shared Agent Skills section extended with the docs-check bullet: 4 primary non-Core + 3 inherit) |
| LLMP-DEC-29 | 2026-04-24 | protocol-audit v2.0 → v2.1 |
(a) X1 invariant extended to expect all three skills in ## Shared Agent Skills (was two: docs-discovery + protocol-audit; now adds docs-check). (b) New X3 invariant: the docs-sync rule in each primary file points to the docs-check skill (checks for backtick-wrapped `docs-check` and the skill path). (c) Applicability matrix extended: X3 applies to all 5 primary files, N/A for the 3 inherit files (they don't have the numbered docs-sync rule). |
protocol-audit/SKILL.md |
| LLMP-DEC-30 | 2026-04-24 | Introduced globally-unique issue/TODO/decision ID system + batch-migrated existing entries | Three reasons: (a) make IDs like ISSUE-01 unambiguous outside their containing file (DB natural-key ready, code-comment friendly, cross-repo clear); (b) remove collision risk across parallel LLM sessions (per-topic+type counter is a smaller concurrency domain than global counter); (c) standardize the inconsistent mix of existing prefixes (PROTO-, DISPATCH-, DS-, CONN-, XCUT-, DESER-, SER-, SGEN-, BWO-, and per-file ISSUE-NN/TODO-NN). Format: {TOPIC}-{TYPE}-{N} — topic code from registry, type = I(ssue) / T(ODO) / B(ug) / C(ritical severity override) / DEC (LLMP-only), N is per-topic-per-type counter starting at 1 (no zero-padding). Topic codes: LOG, SIG, SBP, BIN, TOON, GRID (avoids MG-prefix-collision with Mg* class naming), XCUT, LLMP. Sub-categories (PROTO, DISPATCH, CONN, etc.) move from ID to body header tag (## SIG-I-1 [PROTO]: ...). Registry maintained in docs-check/references/TOPIC_CODES.md. Migration: ~50 existing entries renumbered across 10 files (LOGGING, SIGNALR, SBP, BINARY, TOON topic folders) + cross-references updated workspace-wide; found and mapped the previously-uncatalogued BWO-4 entry → BIN-I-15. |
docs-check/references/TOPIC_CODES.md (new); docs-check/SKILL.md (Step 5 draft entry format + topic registry reference); 10 topic doc files (IDs renumbered); cross-ref updates across ~20 .md files in the workspace |
| LLMP-DEC-31 | 2026-04-24 | Consolidated XCUT cross-cutting entries into dedicated docs/XCUT/ folder |
Before: cross-cutting entries (currently just XCUT-I-1: JSON-in-Binary request parameters) were duplicated — canonical body in BINARY_ISSUES.md, short cross-ref in SIGNALR_ISSUES.md. This pattern breaks down as more XCUT entries arrive (every added cross-cutting topic needs duplicate maintenance, and the concept of "which side is canonical" is arbitrary). Now: canonical home is AyCode.Core/AyCode.Core/docs/XCUT/ (topic-folder at project level, consistent with LOGGING/, BINARY/, TOON/ placement). Contains README.md (explaining XCUT concept + convention), XCUT_ISSUES.md (canonical entries), XCUT_TODO.md (template + future entries). Each affected topic's file keeps a short cross-ref pointing to the canonical entry; body size per topic drops to ~2 lines. Migrated XCUT-I-1 — full body now lives in XCUT_ISSUES.md, with cross-refs from BINARY_ISSUES.md and SIGNALR_ISSUES.md. Also updated: BINARY_TODO.md#bin-t-1 Related-link now points to canonical; AyCode.Core/docs/CONVENTIONS.md JSON-in-Binary section references canonical. |
New folder AyCode.Core/AyCode.Core/docs/XCUT/ (3 files); updated BINARY_ISSUES.md, SIGNALR_ISSUES.md (XCUT sections); BINARY_TODO.md, AyCode.Core/docs/CONVENTIONS.md (related-link updates); AyCode.Core/AyCode.Core/docs/README.md (topic list extended) |
| LLMP-DEC-32 | 2026-04-24 | SKILL.md generalization + workspace-meta-tooling exception documented | Two related concerns raised: (1) SKILL.md files had hardcoded specific repo/project names (e.g., "5 AyCode/Mango repos (AyCode.Core, AyCode.Blazor, Libraries, FruitBank, FruitBankHybridApp)" in protocol-audit's description; "AyCode.Core/AyCode.Core/docs/XCUT/" in docs-check's Step 5). Skills should describe BEHAVIOR; specific data lives in references/ files. (2) The .github/skills/ registry files (REPOS.md, TOPIC_CODES.md) list higher-layer products (Layer 3 consumers like FruitBank) — a literal Framework-First Design Principle violation if interpreted strictly. Decisions: (a) Skills stay universal (one copy under AyCode.Core/.github/skills/, referenced by all other repos via Shared Agent Skills section) — per-layer skill duplication rejected as maintenance-hostile. (b) SKILL.md files generalized to read from references/ registries instead of hardcoding names. (c) The .github/ folder is explicitly exempted from Framework-First: it is workspace-configuration, not framework code. Rule added to AyCode.Core/copilot-instructions.md's Framework-First Design Principle section. Scope notes added to REPOS.md and TOPIC_CODES.md at their tops. Future escape hatch: if a skill becomes truly layer-specific (e.g., fruit-measurement-audit for FruitBank-only concerns), it goes in that layer's .github/skills/, not in AyCode.Core's. |
protocol-audit/SKILL.md (description + invariant X3 + applicability note generalized); docs-check/SKILL.md (Step 5 XCUT path reference generalized); docs-discovery/SKILL.md (consumer-specific class-name example swapped for a placeholder); AyCode.Core/.github/copilot-instructions.md (Framework-First section + "Exception for workspace meta-tooling" paragraph); protocol-audit/references/REPOS.md (scope note header); docs-check/references/TOPIC_CODES.md (scope note header) |
| LLMP-DEC-33 | 2026-04-24 | protocol-audit v2.1 → v2.2 — added C4 invariant for Session Setup section presence |
New common invariant C4 enforces ## Session Setup section presence across all 8 files, with references to the three skill SKILL.md files (and for inherit files, also the canonical host's copilot-instructions.md). Ensures the new Session Setup rule is mechanically verifiable. Applicability matrix updated: C-invariant range extended from C1-C3 to C1-C4. |
protocol-audit/SKILL.md (version bump; new C4 invariant; applicability matrix update) |
| LLMP-DEC-34 | 2026-04-24 | Token-economics principle made explicit — amortization over multi-turn sessions is the central design principle | Observation: a validation session exposed an LLM reasoning bias — when asked whether the protocol's upfront cost was worth it, the agent's first answer categorized protocol-audit/SKILL.md (~6K tokens) as "wasteful for this specific turn" because the turn didn't invoke it. A single user reminder ("the session just started") was enough for the LLM to self-correct and reframe the cost as amortizing over the full session lifetime. Issue: the Session Setup rule's rationale said "one-time cost per session" but did NOT explicitly name the single-turn optimization trap. LLMs default to per-turn local optimization and can mis-judge pre-loaded content as wasteful, especially in early session turns or quick one-off queries. Fix: extended the ## Session Setup "Why mandatory" paragraph in all 8 copilot-instructions.md files (5 primary + 3 inherit) with an explicit **Amortization — critical, do NOT re-evaluate per-turn** note. The note states: (a) cost is measured over the ENTIRE session; (b) the first domain question alone recoups it; (c) the alternative (repeated source-code searches per turn) costs 10-20K tokens per turn with lower quality; (d) the design depends on cross-turn amortization + Rule #3 (no-re-read) + Rule #4 (context recovery as only exception); (e) this is the central token-economics principle of the entire stack. Proactively inoculates future sessions against the single-turn-optimization bias that was observed. |
5× primary + 3× inherit copilot-instructions.md (Session Setup "Why mandatory" paragraph extended with Amortization sub-paragraph) |
| LLMP-DEC-35 | 2026-04-24 | Added mandatory Session Setup — pre-load 3 SKILL.md files at session start | Problem: Claude Code does NOT populate workspace skills into its system-reminder / native skill-registry. Previous design relied on instruction-driven invocation (rule pointer → LLM reads SKILL.md on first trigger). This is fragile: the agent might not recognize implicit triggers (e.g., "this is a domain question → load docs-discovery"), might forget to load the SKILL.md, or might delay loading until after a code-search has already started. A test session confirmed the risk: an LLM answered a rule-listing question without loading any skill, then retroactively loaded them only when asked directly — the first domain question would have missed the docs-discovery trigger. Solution: Added ## Session Setup section to all 8 copilot-instructions.md files (primary and inherit). Rule mandates pre-loading of all three SKILL.md files (docs-discovery, docs-check, protocol-audit) at session start, immediately after reading the main copilot-instructions.md. For inherit files, AyCode.Core's copilot-instructions.md is also in the mandatory load set (because inherit files do not duplicate Rules #1-5 — the canonical host has them). Expected [LOADED_DOCS: ...] prefix on first response: 4 files for primary, 5 for inherit. Cost: ~10-13K tokens one-time per session; Rule #3 (no-re-read) prevents repeated reads. Reliability gain: implicit triggers fire reliably for the entire session. The ## Shared Agent Skills section intros (in 7 non-Core files) were also updated to cross-reference the Session Setup mandate. |
5× primary + 3× inherit copilot-instructions.md (added ## Session Setup section); 4× non-Core primary + 3× inherit = 7× non-Core (Shared Agent Skills intro updated to cross-reference Session Setup) |
| LLMP-DEC-36 | 2026-04-24 | Migrated Toon docs to TOON/README.md + TOON_*.md (Option C) |
Last AyCode.Core domain still on flat layout. Absorbed the orphan ToonExtendedInfo.txt at repo root; added paired TOON_ISSUES.md / TOON_TODO.md per convention. Verified format spec against actual code (MetaWriter, DataSection, TypeDefinitions, Descriptions), not just the legacy marketing-style txt — surfaced richer reality (placeholder system, enum backing-field detection, navigation metadata, type relation constants) absent from the old txt. Serialize-only status recorded as TOON_TODO.md#toon-t-6. |
AyCode.Core/docs/TOON/ (8 new files) + AyCode.Core/docs/README.md (topic list) + AyCode.Core/Serializers/Toons/README.md (stub pointer) + ToonExtendedInfo.txt (removed) |
| LLMP-DEC-37 | 2026-04-24 | docs-discovery SKILL.md hardening: literal-path tilalom + false-empty guardrail (cross-session validation feedback) |
Incident: a parallel Copilot session executed docs-discovery for a logger-review query but substituted a literal AyCode.Core/docs/LOGGING/... path for the spec'd **/docs/{TOKEN}/**/*.md glob. The literal path missed AyCode.Core's project-level docs layout (<RepoRoot>/<Project>/docs/LOGGING/), yielded 0 matches, and Copilot concluded "docs are empty" → fell through to code-only review, skipping the loaded paired-docs set (8 known issues, 11 prioritized TODOs). Fix scope: minimal — 2 sentences appended to existing steps, NOT new rules. (a) Step 2 end: explicit prohibition on substituting literal <repo>/docs/... for the recursive **/docs/... glob, with one-line rationale that ** matches both repo-root and project-level layouts in a single pass. (b) Step 3 end: false-empty guardrail — if glob returns 0 matches OR all matches are 0-byte, re-validate the glob (typo? literal substituted?) and retry once with the same token under a corrected **/docs/... pattern (NEVER an ad-hoc path guess) before falling through to code-search. Rejected alternatives: an early Copilot draft proposed 5 new numbered rules + 5 new SKILL steps (incl. a Step 0 "load every README.md" pass). Evaluation: most were redundant with existing rules (vs. hard-gate, paired-docs Step 5, Rule #1 prefix), one was based on **-semantics misunderstanding (proposed "two-pass" globs where the second pattern is a strict subset of the first), one was actively harmful to token economy (Step 0). Net: ~80% reduction in proposed protocol surface, same bug-class coverage. |
docs-discovery/SKILL.md (Step 2 end + Step 3 end) |
| LLMP-DEC-38 | 2026-04-24 | Retroactively assigned LLMP-DEC-N IDs to existing Decision Log entries |
When the globally-unique ID system was introduced (LLMP-DEC-30) with the LLMP topic code for LLM-protocol meta-decisions using DEC type, the existing ~37 Decision Log entries remained keyed by date alone. This meant the design intention (entries have unambiguous string IDs for cross-referencing) wasn't realized for historical entries. Fix: added an ID column as the leftmost in the 2026 table, and populated LLMP-DEC-1 through LLMP-DEC-37 in chronological order (retroactive assignment, this entry is LLMP-DEC-38 as the first ID-aware addition). Entries now referenceable by ID from code comments, other .md files, PR descriptions, or future DB migration. The LLMP-DEC-N format is append-only (IDs never renumber); superseded decisions get new entries that reference old ones by ID (e.g., "LLMP-DEC-26 superseded by LLMP-DEC-27"). |
AyCode.Core/.github/LLM_PROTOCOL_DECISIONS.md (ID column + 37 retroactive IDs) |
| LLMP-DEC-39 | 2026-04-24 | docs-discovery SKILL.md Step 2 restructuring — recursive **/ wildcard requirement moved to prominent CRITICAL section at TOP (second iteration; LLMP-DEC-37 proved insufficient) |
Incident: a second Copilot session exhibited the same literal-path bug that LLMP-DEC-37 was supposed to prevent — it synthesized AyCode.Core/docs/LOGGING/README.md (a path that doesn't exist; the real docs are at AyCode.Core/AyCode.Core/docs/LOGGING/, one level deeper at project-level) instead of using the recursive **/docs/LOGGING/**/*.md glob. LLMP-DEC-37 had appended a warning to the END of Step 2, which was not prominent enough — Copilot read Step 2, formed its own mental model of "usual docs paths", and never reached the trailing caution. Fix: moved the warning to the TOP of Step 2 as a ### ⚠️ CRITICAL subsection. Content expanded: (a) explicit depth-level enumeration (repo-root <Repo>/docs/TOPIC/, project-level <Repo>/<Project>/docs/TOPIC/, nested), (b) concrete failure-mode walkthrough showing the specific "know the repo → synthesize shallow path → 0 matches → false-empty conclusion" pattern that fires for Pattern B layouts, (c) correct-vs-wrong form side-by-side examples, (d) absolute rule: NEVER drop the leading **/ even when the repo is known. The old trailing warning was consolidated to a back-reference to the new top section to keep Step 2 from splitting the message. User rejected intermediate proposals (byte-count verification, flat **/docs/TOPIC.md defensive pattern) as "drótozás" (hardcoding) — fix stays structural, no glob pattern additions. |
docs-discovery/SKILL.md (Step 2 restructuring; supersedes LLMP-DEC-37's Step-2-end placement) |
| LLMP-DEC-40 | 2026-04-24 | Rule #1 clarification: removed false "globally unique by basename" claim for copilot-instructions.md |
Observation: a parallel Claude Code self-audit session noticed a literal contradiction in Rule #1. The short-name rule line 18 said copilot-instructions.md is "globally unique by basename" — true for a typical session (1 active repo = 1 loaded copilot-instructions.md) but FALSE for protocol-audit sessions, which load all 8 copilot-instructions.md files simultaneously. The claim conflicts with the cross-project-disambiguation rule one line above (line 17) whenever the audit use-case fires. The LLM correctly identified the ambiguity and proposed a patch. Fix: replaced the parenthetical "globally unique by basename" with an explicit acknowledgment of the protocol-audit collision case + pointer to the already-existing cross-project-disambiguation rule above. New wording uses concrete disambiguation examples (AyCode.Core/copilot-instructions.md, FruitBankHybridApp/copilot-instructions.md). The .github/ prefix tiltás is retained — now justified as "implicit location" rather than "already unique". Deferred (explicit YAGNI): proposed new protocol-audit C5 invariant (semantic validation: Rule #1 basename-uniqueness claims must match the actual file-set in REPOS.md). Rejected for now — one known instance isn't enough to justify invariant surface / false-positive risk; revisit if a second similar contradiction appears. |
5× primary copilot-instructions.md (Rule #1 line 18 patched) |
| LLMP-DEC-41 | 2026-04-24 | Created adr-author skill — 4th workspace skill, extends Session Setup pre-load from 3 to 4 |
Gap identified: the existing skill-stack (docs-discovery, docs-check, protocol-audit) covers documentation retrieval, code↔docs drift detection, and cross-repo file-structural audit — but has no artifact-producing workflow for pre-code architectural decisions (greenfield repo planning, feature design, tech-stack choices, library selection, migration planning). The {TOPIC}_TODO.md format is an implementation queue (known scope, code ref expected, P1-P3 priority); it cannot naturally hold decision rationale, weighed alternatives, or trade-off tables. Without a dedicated artifact, design rationale tends to disappear into chat history or get flattened into TODO entries that lose the "why". Solution: adr-author skill encoding the canonical Michael Nygard ADR workflow as a structured interview (Step 1 routing → Step 2 context → Step 3 alternatives → Step 4 trade-offs → Step 5 decision → Step 6 consequences → Step 7 draft + write → Step 8 cross-refs). Tool-neutral like the other three skills. Routing logic: two decision-log paradigms supported — per-repo docs/adr/NNNN-<slug>.md Nygard-style files (product/code/domain decisions) VS workspace-level LLMP_PROTOCOL_DECISIONS.md table rows with ID LLMP-DEC-N (protocol-meta decisions). Invocation model (new): explicit user request OR LLM-suggest-back — LLM flags when conversation exhibits 2+ ADR-heuristics (multiple alternatives weighed, irreversible, cross-cutting, 6-18mo re-openable); user must confirm before invocation. Never auto-invoke. Session Setup pre-load 3 → 4 skill: consistent with existing protocol-audit (on-demand) pattern — the skill's content must be in context for trigger recognition. Handoff: docs-check can flag ADR-worthy observations at end-of-response; docs-discovery owns "how does X work" questions, adr-author owns "let's design X" questions. User rationale for broader scope than greenfield-only: user correctly pointed out ADR-worthy decisions arise in mature code too (refactors, library additions, migration paths), not just new-repo planning — the original Nygard definition supports this scope. |
new: AyCode.Core/.github/skills/adr-author/SKILL.md + AyCode.Core/.github/skills/adr-author/references/ADR_TEMPLATE.md; 5× primary copilot-instructions.md (Session Setup: three→four; prefix count 4→5); 3× inherit copilot-instructions.md (Session Setup: three→four; prefix count 5→6); 4× non-Core primary + 3× inherit copilot-instructions.md (Shared Agent Skills intro "All three"→"All four"; new adr-author bullet added after docs-check bullet) |
| LLMP-DEC-42 | 2026-04-25 | adr-author SKILL.md: added "Multi-project repo case" placement guidance to Step 1 (cross-cutting vs project-scoped) |
Incident: a Claude Code session executing adr-author for a bearer token design produced an excellent ADR draft but left the docs/adr/ location ambiguous — the draft path said docs/adr/0001-... without resolving whether that meant <repo>/docs/adr/ (repo root, cross-cutting placement) or <repo>/<project>/docs/adr/ (project-scoped). The decision in question affected 2+ projects (AyCode.Services client + AyCode.Services.Server), so the placement question was real, not academic. The original SKILL.md Step 1 used <active-repo>/docs/adr/... placeholder which silently assumed single-project repos; multi-project layouts (which exist in this and likely other repos) had no explicit guidance. Fix: added a "Multi-project repo case" sub-section to Step 1 with three rules: (1) existing convention wins (Glob first; never fragment by creating a parallel folder); (2) no existing folder → match scope to placement (cross-cutting → highest common ancestor, typically repo root; project-scoped → that project's docs/); (3) ambiguous scope → ask the user explicitly before proceeding. Step 7's path reference updated to <adr-folder> resolved in Step 1, removing the misleading <active-repo>/docs/adr/ literal. Generic, not hardcoded: no specific repo names or project paths in the rules — they apply to any multi-project repo. |
adr-author/SKILL.md (Step 1 + Step 7 updates) |
Known follow-ups
(No open follow-ups. All items from previous audits resolved — see dated entries above for fix history.)
Notes
- Dates before 2026-04-24 are retroactive reconstructions from session history; intra-day ordering is approximate.
- For precise attribution of individual file changes, consult the git history of the affected files.
- This log is a summary artifact — it records the decision and its rationale, not the full diff.