DOJ-3712: Update IDT CLAUDE.md with toolkit contract + overlay protocol + symbolic refs (2/2)#20
Conversation
Single-file addition (CLAUDE.md, ~520 lines) covering:
- What This Toolkit Is — multi-tenant generic plugin pitch + Base+Overlay
framing (DOJ-3706); separates Layer 1 (cmi5/xAPI invariants), Layer 2
(pedagogy generic), Layer 3 (consumer voice — never in IDT base).
- Skill overlays — discovery + invocation + tier defaults +
Layer 1 invariant validator; §5.4 findings-shaped procedure for
audit/review commands; ${CLAUDE_PLUGIN_ROOT} defensive note (DOJ-3775
§6.1) for direct-CLI invocation; canonical consumer references
(dojo-academy academy-philosophy + content-standards) per DOJ-3710.
- Symbolic references — [course:<slug>] / [module:.../...] convention
per DOJ-3713; resolver contract; DojoOS rendering example with
path-aware routing forward-compat (DOJ-3714); explicit anti-patterns
(no hardcoded URLs, no relative .md paths, no unknown type prefixes).
- Repo composability — three-expectation contract for consumer repos
(declare dependency, provide content layout, optionally ship overlays);
catalogue of representative consumer types.
- CI workflow — DOJ-3774 lint pipeline (3 standalone scripts at
scripts/ci/, ~7s typical run); rationale for standalone-vs-heredoc;
security note (read-only permissions, pinned action SHAs, no
github.event.* in shell).
- Conventions for agents — Linear-not-GitHub, branch/PR/squash rules,
Greptile 5/5 with no skip-the-review, CI gating, Spanish accents,
multi-tenant discipline test, forbidden words/patterns.
- Linear issue map — DOJ-3705 → DOJ-3712 chain plus DOJ-3713/3714/3774/
3775 cross-references.
- Related repos — dojo-academy (canonical consumer), dojo-os (renderer
+ symbolic-ref resolver owner), srd-framework / business-model-toolkit
/ ux-research-toolkit (sibling plugins).
Companion to dojo-academy/CLAUDE.md updated in parallel (separate PR).
Verified locally:
- python3 scripts/ci/check_json_schemas.py — 3 schemas valid
- python3 scripts/ci/check_frontmatter.py — 64 valid, 2 skipped
- python3 scripts/ci/check_agent_references.py — 19 agents indexed,
all references resolve
Created by Claude Code on behalf of @andres
|
@greptile review |
Greptile SummaryThis PR adds a new
Path to 5/5 Confidence
Confidence Score: 3/5Documentation-only change with no runtime code, but two agent-facing instructions are internally inconsistent and could cause agents to enforce an unratified spec or merge before confirming a passing review score. The Greptile gate rule and the DOJ-3713 Proposed/MUST mismatch are both actionable instructions that would produce wrong agent behavior if followed literally — merging without score confirmation, and enforcing a spec still under proposal. These govern how future work gets executed and reviewed, not merely style. CLAUDE.md — specifically the Symbolic references section (lines 170–176), the Greptile conventions block (lines 367–370), and the resolver contract table (lines 200–214).
|
| Filename | Overview |
|---|---|
| CLAUDE.md | New 518-line agent guidance file covering overlay protocol, symbolic references, CI, and conventions — contains an imperative/status mismatch on DOJ-3713 (MUST vs Proposed) and a self-contradictory Greptile gate instruction that could lead agents to merge before confirming 5/5. |
Sequence Diagram
sequenceDiagram
participant Agent as Claude Agent
participant Runtime as IDT Runtime
participant Plugin as consumer plugin.json
participant Overlay as Overlay Skills
participant Validator as L1 Invariant Validator
Agent->>Runtime: Run authoring command (e.g. /idt:write-text-class)
Runtime->>Plugin: Walk cwd/.claude-plugin/plugin.json
alt plugin.json missing
Plugin-->>Runtime: Zero overlays (voice-neutral path)
else plugin.json malformed
Plugin-->>Runtime: Visible warning + zero overlays
else overlays found
Plugin-->>Runtime: Candidate SKILL.md list
end
Runtime->>Runtime: Filter by overlay_target, sort by overlay_priority asc
Runtime->>Validator: Pre-loop snapshot of L1 fields
loop Each overlay (priority ascending)
Runtime->>Overlay: Run overlay with prior output
Overlay-->>Runtime: Mutated draft
Runtime->>Validator: Compare snapshot vs post-overlay L1 fields
alt L1 field mutated
Validator-->>Runtime: ABORT - name offending SKILL.md
else clean
Validator-->>Runtime: OK
end
end
Runtime->>Validator: Final post-loop snapshot check
Runtime-->>Agent: Final output (L1+L2 base + applied voice overlays)
Prompt To Fix All With AI
Fix the following 5 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 5
CLAUDE.md:170-176
**Imperative "MUST" on a Proposed spec**
The "Symbolic references" section instructs authoring commands that they "MUST emit symbolic refs in cross-link positions", yet the Linear issue map (line 454) marks DOJ-3713 as **Proposed** (`openspec/changes/2026-05-symbolic-references/`). An agent reading this file will attempt to enforce a spec that hasn't been finalized — and may reject or rewrite content using perfectly valid hardcoded URLs while the openspec is still being iterated on. Either the status in the issue map should be updated to "Shipped" (if the openspec is authoritative and stable) or the MUST should be softened to "SHOULD" with a note that the convention is still under proposal.
### Issue 2 of 5
CLAUDE.md:367-372
**Greptile gate instruction is self-contradictory**
Lines 368–370 state: "Greptile must hit **5/5 functional** before merge. Address every finding, push fixes, then merge — no waiting for re-review cycles after fixes are pushed." An agent following this literally will address findings from the first review and then merge immediately without waiting for a second Greptile pass to confirm the score reached 5/5. This directly undercuts the 5/5 gate the sentence just established. If the intent is "one review cycle is enough — fix and merge", the 5/5 requirement should be dropped or clarified as "first-pass 5/5." If the intent is truly 5/5 before merge, remove the "no waiting for re-review" clause.
### Issue 3 of 5
CLAUDE.md:200-214
**`lesson:` prefix ambiguity in the resolver contract**
The type prefix table documents two distinct slug-path shapes under the same `lesson:` prefix: `<courseSlug>/<moduleSlug>/<classSlug>` for regular lessons and `<courseSlug>/docs/<chapterSlug>/<lessonSlug>` for workbook lessons. The resolver contract (`parseSymbolicRef` / `resolveSymbolicRef`) section does not specify how implementations should disambiguate — whether by counting path segments, detecting a `docs` sentinel, or another mechanism. Without this clarification, two independent resolver implementations could disagree on how to parse `lesson:vibe-coding-blueprint/docs/ch-01-mindset/lesson-01-vibe-coder`, breaking forward compatibility. The disambiguation rule should be spelled out in the resolver contract or in `openspec/changes/2026-05-symbolic-references/design.md`.
### Issue 4 of 5
CLAUDE.md:443-444
**DOJ-3829 referenced but absent from the issue map**
The DOJ-3709 row mentions "PR-B: 6 generic skills via DOJ-3829" but DOJ-3829 has no entry in the issue map table. Anyone (or any agent) using this map to trace the migration history will hit a dead end. Add a row for DOJ-3829 or inline a brief description so the cross-reference is self-contained.
### Issue 5 of 5
CLAUDE.md:356-357
**Branch naming convention hardcoded to a specific contributor**
The branch format `andres/<issue-id-lowercase>-<short-description>` embeds a real username. This CLAUDE.md documents norms for **agents** working in the repo (opening line), and any contributor or agent acting on behalf of a different user would produce incorrectly-named branches. If this is intentionally single-contributor, a comment noting that would prevent confusion; if the repo is expected to accept other contributors in the future, this should use a placeholder like `<username>/<issue-id-lowercase>-<short-description>`.
Reviews (1): Last reviewed commit: "DOJ-3712: Add CLAUDE.md documenting tool..." | Re-trigger Greptile
|
|
||
| ### `${CLAUDE_PLUGIN_ROOT}` defensive note (DOJ-3775, §6.1) | ||
|
|
||
| Skills and commands resolve sibling files via Claude Code's plugin | ||
| substitution token `${CLAUDE_PLUGIN_ROOT}` (e.g. | ||
| `${CLAUDE_PLUGIN_ROOT}/assets/runtime/overlay-protocol.md`, | ||
| `${CLAUDE_PLUGIN_ROOT}/agents/<agent>.md`). |
There was a problem hiding this comment.
Imperative "MUST" on a Proposed spec
The "Symbolic references" section instructs authoring commands that they "MUST emit symbolic refs in cross-link positions", yet the Linear issue map (line 454) marks DOJ-3713 as Proposed (openspec/changes/2026-05-symbolic-references/). An agent reading this file will attempt to enforce a spec that hasn't been finalized — and may reject or rewrite content using perfectly valid hardcoded URLs while the openspec is still being iterated on. Either the status in the issue map should be updated to "Shipped" (if the openspec is authoritative and stable) or the MUST should be softened to "SHOULD" with a note that the convention is still under proposal.
Prompt To Fix With AI
This is a comment left during a code review.
Path: CLAUDE.md
Line: 170-176
Comment:
**Imperative "MUST" on a Proposed spec**
The "Symbolic references" section instructs authoring commands that they "MUST emit symbolic refs in cross-link positions", yet the Linear issue map (line 454) marks DOJ-3713 as **Proposed** (`openspec/changes/2026-05-symbolic-references/`). An agent reading this file will attempt to enforce a spec that hasn't been finalized — and may reject or rewrite content using perfectly valid hardcoded URLs while the openspec is still being iterated on. Either the status in the issue map should be updated to "Shipped" (if the openspec is authoritative and stable) or the MUST should be softened to "SHOULD" with a note that the convention is still under proposal.
How can I resolve this? If you propose a fix, please make it concise.| |---|---|---| | ||
| | 1 | `scripts/ci/check_json_schemas.py` | Every `assets/schemas/*.json` parses as valid JSON. | | ||
| | 2 | `scripts/ci/check_frontmatter.py` | Every `commands/*.md`, `skills/*/SKILL.md`, `agents/*.md` either has no frontmatter (skipped — e.g. translation pipeline support docs) or has a parseable mapping with a non-empty `description` field. | | ||
| | 3 | `scripts/ci/check_agent_references.py` | Every `${CLAUDE_PLUGIN_ROOT}/agents/<name>.md` reference inside skills / commands resolves to a file that ships in `agents/`. Bare `agents/<name>.md` references are intentionally ignored — those are consumer-relative (e.g. `commands/_translation-pipeline.md` documents `agents/translator.md` shipped by the consumer, not by IDT). | | ||
|
|
||
| Typical run time: ~7 seconds. Designed as a **pre-Greptile gate** — catches |
There was a problem hiding this comment.
Greptile gate instruction is self-contradictory
Lines 368–370 state: "Greptile must hit 5/5 functional before merge. Address every finding, push fixes, then merge — no waiting for re-review cycles after fixes are pushed." An agent following this literally will address findings from the first review and then merge immediately without waiting for a second Greptile pass to confirm the score reached 5/5. This directly undercuts the 5/5 gate the sentence just established. If the intent is "one review cycle is enough — fix and merge", the 5/5 requirement should be dropped or clarified as "first-pass 5/5." If the intent is truly 5/5 before merge, remove the "no waiting for re-review" clause.
Prompt To Fix With AI
This is a comment left during a code review.
Path: CLAUDE.md
Line: 367-372
Comment:
**Greptile gate instruction is self-contradictory**
Lines 368–370 state: "Greptile must hit **5/5 functional** before merge. Address every finding, push fixes, then merge — no waiting for re-review cycles after fixes are pushed." An agent following this literally will address findings from the first review and then merge immediately without waiting for a second Greptile pass to confirm the score reached 5/5. This directly undercuts the 5/5 gate the sentence just established. If the intent is "one review cycle is enough — fix and merge", the 5/5 requirement should be dropped or clarified as "first-pass 5/5." If the intent is truly 5/5 before merge, remove the "no waiting for re-review" clause.
How can I resolve this? If you propose a fix, please make it concise.| `dojo-academy` (the Dojo Coding content monorepo) is the first consumer to | ||
| adopt the overlay protocol (DOJ-3710). It ships two overlay skills: | ||
|
|
||
| - `skills/content-standards/SKILL.md` — structural overlay, priority `50`. | ||
| Applies the `CONTEXT → CONCEPT → BUILD → SHIP → REFLECT` formula and the | ||
| "text classes carry the course" load-bearing rule on top of the L1+L2 base | ||
| draft. | ||
| - `skills/academy-philosophy/SKILL.md` — voice overlay, priority `100`. | ||
| Applies "Builder-First, AI-Native" voice, named frameworks like | ||
| Multi-Quading, and momentum-ending paragraphs. | ||
|
|
||
| Reading those two files is the fastest way to internalize what an overlay | ||
| looks like in practice. Their `overlay_target` arrays list the IDT commands | ||
| they apply to (`new-course`, `course-audit`, `slides-preview`, and the | ||
| DOJ-3708 / DOJ-3709 migrated `write-*` commands). |
There was a problem hiding this comment.
lesson: prefix ambiguity in the resolver contract
The type prefix table documents two distinct slug-path shapes under the same lesson: prefix: <courseSlug>/<moduleSlug>/<classSlug> for regular lessons and <courseSlug>/docs/<chapterSlug>/<lessonSlug> for workbook lessons. The resolver contract (parseSymbolicRef / resolveSymbolicRef) section does not specify how implementations should disambiguate — whether by counting path segments, detecting a docs sentinel, or another mechanism. Without this clarification, two independent resolver implementations could disagree on how to parse lesson:vibe-coding-blueprint/docs/ch-01-mindset/lesson-01-vibe-coder, breaking forward compatibility. The disambiguation rule should be spelled out in the resolver contract or in openspec/changes/2026-05-symbolic-references/design.md.
Prompt To Fix With AI
This is a comment left during a code review.
Path: CLAUDE.md
Line: 200-214
Comment:
**`lesson:` prefix ambiguity in the resolver contract**
The type prefix table documents two distinct slug-path shapes under the same `lesson:` prefix: `<courseSlug>/<moduleSlug>/<classSlug>` for regular lessons and `<courseSlug>/docs/<chapterSlug>/<lessonSlug>` for workbook lessons. The resolver contract (`parseSymbolicRef` / `resolveSymbolicRef`) section does not specify how implementations should disambiguate — whether by counting path segments, detecting a `docs` sentinel, or another mechanism. Without this clarification, two independent resolver implementations could disagree on how to parse `lesson:vibe-coding-blueprint/docs/ch-01-mindset/lesson-01-vibe-coder`, breaking forward compatibility. The disambiguation rule should be spelled out in the resolver contract or in `openspec/changes/2026-05-symbolic-references/design.md`.
How can I resolve this? If you propose a fix, please make it concise.| `python3 scripts/ci/check_agent_references.py`, | ||
| `python3 scripts/ci/check_json_schemas.py`. |
There was a problem hiding this comment.
DOJ-3829 referenced but absent from the issue map
The DOJ-3709 row mentions "PR-B: 6 generic skills via DOJ-3829" but DOJ-3829 has no entry in the issue map table. Anyone (or any agent) using this map to trace the migration history will hit a dead end. Add a row for DOJ-3829 or inline a brief description so the cross-reference is self-contained.
Prompt To Fix With AI
This is a comment left during a code review.
Path: CLAUDE.md
Line: 443-444
Comment:
**DOJ-3829 referenced but absent from the issue map**
The DOJ-3709 row mentions "PR-B: 6 generic skills via DOJ-3829" but DOJ-3829 has no entry in the issue map table. Anyone (or any agent) using this map to trace the migration history will hit a dead end. Add a row for DOJ-3829 or inline a brief description so the cross-reference is self-contained.
How can I resolve this? If you propose a fix, please make it concise.| --- | ||
|
|
There was a problem hiding this comment.
Branch naming convention hardcoded to a specific contributor
The branch format andres/<issue-id-lowercase>-<short-description> embeds a real username. This CLAUDE.md documents norms for agents working in the repo (opening line), and any contributor or agent acting on behalf of a different user would produce incorrectly-named branches. If this is intentionally single-contributor, a comment noting that would prevent confusion; if the repo is expected to accept other contributors in the future, this should use a placeholder like <username>/<issue-id-lowercase>-<short-description>.
Prompt To Fix With AI
This is a comment left during a code review.
Path: CLAUDE.md
Line: 356-357
Comment:
**Branch naming convention hardcoded to a specific contributor**
The branch format `andres/<issue-id-lowercase>-<short-description>` embeds a real username. This CLAUDE.md documents norms for **agents** working in the repo (opening line), and any contributor or agent acting on behalf of a different user would produce incorrectly-named branches. If this is intentionally single-contributor, a comment noting that would prevent confusion; if the repo is expected to accept other contributors in the future, this should use a placeholder like `<username>/<issue-id-lowercase>-<short-description>`.
How can I resolve this? If you propose a fix, please make it concise.Fixes 5 findings from initial Greptile pass (3/5 → expected 5/5): 1. Symbolic refs section (DOJ-3713 Proposed/MUST mismatch): MUST → SHOULD, added explicit advisory note. Agents prefer symbolic refs in new content but MUST NOT rewrite hardcoded URLs while DOJ-3713 is under proposal. Convention upgrades to MUST once DOJ-3713 ships. 2. Greptile gate self-contradiction: clarified the policy as "5/5 functional on first review pass" with non-blocking re-score (per feedback_dont_wait_for_greptile_rereviews.md). Removed the apparent conflict between "5/5 before merge" and "no waiting for re-review". 3. lesson: prefix disambiguation: added explicit rule that segment 2 of the slug-path being the literal token `docs` distinguishes workbook lessons from standard module-nested lessons. Two examples included; resolvers MUST implement consistently. 4. Linear issue map: added DOJ-3829 as its own row (was previously only inline-referenced from the DOJ-3709 row). 5. Branch naming: parameterized `andres/...` to `<username>/...` with a note that the literal `andres/` prefix in linear-setup.json reflects the current primary contributor and should be updated by future contributors. Re-verified locally: - python3 scripts/ci/check_json_schemas.py — 3 schemas valid - python3 scripts/ci/check_frontmatter.py — 64 valid, 2 skipped - python3 scripts/ci/check_agent_references.py — 19 agents, all references resolve Created by Claude Code on behalf of @andres
Summary
CLAUDE.md(518 lines added)Sections added
${CLAUDE_PLUGIN_ROOT}defensive note for direct-CLI invocation (DOJ-3775 §6.1); canonical consumer references (dojo-academyacademy-philosophy+content-standards) per DOJ-3710.[course:<slug>]/[module:.../...]convention (DOJ-3713); resolver contract; DojoOS rendering example with path-aware routing forward-compat (DOJ-3714); explicit anti-patterns (no hardcoded URLs, no relative.mdpaths, no unknown type prefixes).scripts/ci/, ~7s typical run); rationale for standalone-vs-heredoc; security note (read-only permissions, pinned action SHAs, nogithub.event.*in shell).Verification
python3 scripts/ci/check_json_schemas.py— 3 schemas validpython3 scripts/ci/check_frontmatter.py— 64 valid, 2 skipped (translation pipeline support docs)python3 scripts/ci/check_agent_references.py— 19 agents indexed, all${CLAUDE_PLUGIN_ROOT}/agents/...references resolveCLAUDE.mdadded at repo rootCloses DOJ-3712
Created by Claude Code on behalf of @andres