t1k:doctor
| Field | Value |
|---|---|
| Module | t1k-base |
| Version | 3.6.6 |
| Effort | medium |
| Tools | — |
Keywords: broken, check, diagnose, health, integrity, registry, validate
How to invoke
Section titled “How to invoke”/t1k:doctor[fix]TheOneKit Doctor — Registry Validation
Section titled “TheOneKit Doctor — Registry Validation”Validates that all registry fragments, skills, and manifest are consistent and coherent.
/t1k:doctor # Read-only validation report/t1k:doctor fix # Attempt to fix detected issues/t1k:doctor --ci # CI mode: run all checks, exit code 1 on any fail, GitHub annotationsLive Registry State (fetch on demand — do NOT inline in body)
Section titled “Live Registry State (fetch on demand — do NOT inline in body)”When running checks, fetch live registry state via tool calls AFTER the skill body is loaded — NEVER embed inline shell-substitution tokens (the !-prefix-then-backtick syntax) here (cache-busts the cached prefix on every fragment edit; doctor runs constantly during dev). Use:
Readeach.claude/t1k-routing-*.jsonmatching glob → routing fragmentsReadeach.claude/t1k-activation-*.jsonmatching glob → activation fragmentsRead .claude/metadata.json→ kit + module metadataGlob .claude/agents/*.mdthenReadeach → agent filesGlob .claude/skills/*/SKILL.mdthenReadeach → skill files
If a glob returns no matches, treat as “no entries” — do not echo error.
Check Groups
Section titled “Check Groups”Run all checks in sequence. Full check list: references/checks.md
-
Core checks (#1–6): Role coverage, skill existence, cross-layer hardcoding, manifest, registry version, config completeness
-
Module checks (#7–17): File ownership, dependency integrity, activation match, agent presence, routing overlays, stale files, origin frontmatter
-
Manifest checks (#21): Per-module manifest integrity, orphaned flat files
-
SSOT checks (#22–27): schemaVersion, version presence, no stale modules/, context requiredPaths, activation format, v3 installedModules
-
No-override checks (#28–29): Filename collision detection, agent prefix correctness. The universal
t1k-prefix rule (skills + agents, SSOTskills/t1k-skill-creator/references/architecture-rules.md§ 0 +skills/t1k-agent-creator/references/architecture-rules.md§ 0) is the authoritative invariant; release-action gatesvalidate-skill-prefix.cjs,validate-agent-prefix.cjs,validate-new-name-conformance.cjsenforce at PR time. -
Frontmatter quality (#18–20): Agent maxTurns, skill effort, agent model appropriateness
-
Cross-platform (#30): Hook files free of shell-only patterns (2>/dev/null, /dev/stdin, execSync shell strings)
-
MCP health (#31): Required MCPs connected, recommended MCPs present. Runs
.claude/hooks/doctor-check-31-mcp-connectivity.cjs. A missing/misconfigured REQUIRED MCP is FAIL level (exit 1); a missing RECOMMENDED MCP is WARN; when theclaudeCLI itself cannot be queried the whole check reports UNKNOWN rather than a false PASS or FAIL. Seereferences/checks.md#31. Full tiered-requirement spec (required/recommended/optional definitions, per-layer MCP tables):references/mcp-requirements.md. -
Sync-back health (#32): Recent sync-back PRs are healthy (no CONFLICTING state, no phantom-file diffs)
-
Kits membership SSOT (#33):
Object.keys(metadata.kits) === unique(installedModules[*].kit)— runsscripts/check-kits-membership.cjsto catch drift between the derived kit membership and the sourceinstalledModules. WARN level on mismatch. -
Orphaned agents (#34): Agent files under
.claude/agents/whoseorigin:frontmatter points to a kit no longer ininstalledModules[*].kit(ormetadata.kitson older schemas) — leftovers from pre-manifest installs. Runsscripts/check-orphaned-agents.cjs. WARN level; fix:t1k uninstall --kit <name> --include-orphans(v3.5+) or manual rm. -
CLAUDE.md bloat (#35): Project
CLAUDE.mdexceeds 5k token budget (char/4 heuristic). Runsscripts/check-claude-md-bloat.cjs. WARN level; fix: move details todocs/+ deduplicate with auto-loadedrules/*.md. -
Rule duplication (#36): Same rule filename present in both
~/.claude/rules/and project.claude/rules/(double-loaded, wastes context). Enhanced with byte-hash content dedup — also detects identical content under different filenames. Runsscripts/check-rule-duplication.cjs. INFO level; fix: keep each rule in one scope only. -
Context budget (#37): Sums token estimates for all
.claude/rules/*.md+ projectCLAUDE.md. Warns when total exceeds 12 000 tokens; fails (exit 1) when total exceeds 15 000. Complements the release-time gatevalidate-context-window-budget.cjs. Runsscripts/check-context-budget.cjs. WARN/FAIL level; fix: move verbose content todocs/, trim rule files. -
Always-loaded union (#59): The only check that measures what a SESSION actually loads — the UNION of
rules/*.md+CLAUDE.mdacross BOTH scopes (~/.claude/and the project.claude/), for the installed set read frommetadata.installedModules. Every other budget check measures one population and so cannot see this: the release gatevalidate-context-window-budget.cjscaps ONE KIT, #37 sums the PROJECT scope only, #38 caps ONE FILE. On a real machine (2026-08-20) the global scope alone was ~42 800 tokens (171% of the union budget) while #37 reported PASS, because a consumer’s project.claude/rules/is near-empty and that is all #37 can see (modules/t1k-verification/rules/green-that-proves-nothing.md, “measures the wrong population”). Reports per-scope split, per-kit attribution, and the top offending FILES ranked descending — a bare total is not actionable. Also flags rules double-loaded across scopes (billed twice; see #36) and rules owned by modules not in the installed set (see #12). Runsscripts/check-always-loaded-union.cjs. WARN only, always exit 0 — a consumer already over budget must not have their session broken by the check that tells them so; promoting to FAIL is gated on the fleet median falling under budget (ratchet comment dated in the script). UNKNOWN — never a reassuring zero — when no install metadata resolves in either scope. Budget override:T1K_UNION_BUDGET_TOKENS(default 25 000). Fix: attack the top offender first; split it or move detail todocs/. -
Oversized rules (#38): Per-file check — any
.claude/rules/*.mdexceeding 5 000 tokens (char/4 heuristic) gets a WARN. Oversized rule files inflate the always-loaded context budget and signal content that belongs indocs/. Runsscripts/check-oversized-rules.cjs. WARN level; fix: split the rule or move implementation details todocs/. -
Modules registry sync (#39):
.claude/t1k-modules.jsonmodulesfield must match the projection of every.claude/modules/*/module.json(description, required, dependencies, skills, activationFragment). Catches drift between the per-module SSOT and the rollup before push. Runsscripts/check-modules-registry-sync.cjs. SKIPs on non-modular kits. WARN level; fix: push the change and let CI regenerate viatheonekit-release-action/scripts/generate-modules-registry.cjs, or run that script locally from the kit root. The release-action gatevalidate-modules-registry-sync.cjsis the Error-level enforcer. -
Module detect coverage (#41): Every non-core module in
.claude/modules/(excluding the frozent1k-base/t1k-extended/t1k-maintainerset and anyrequired: truekit-base module) must carry an activedetect:block, or explicitly opt out viadetect._optOut: true. Adetect._disabled: truestub is reported as “needs activation”. Runsscripts/check-module-detect-coverage.cjs. Severity is data-driven: WARN before the ratchet date in.claude/t1k-modules.json.ratchetDates.module-detect-coverage, ERROR (exit 1) after it;T1K_BYPASS_DETECT_RATCHET=1forces WARN regardless. SKIPs when.claude/modules/is absent. Fix:/t1k:modules create <module-name>per missing module. -
Statusline wiring (#42): Validates the T1K statusline is wired end-to-end: (a)
hooks/statusline.cjsexists under resolved.claude/, (b)metadata.json.installedFiles[]lists it withownership=kitANDmoduleName=t1k-base, (c)settings.json.statusLine.commandcontains bothhook-runner.cjsandstatuslinetokens, (d)hooks/hook-runner.cjsexists. Catches release/install regressions that leave the statusline silently unrendered. Runs.claude/hooks/doctor-check-42-statusline-wiring.cjs. Skips on kit source repos wheremetadata.json.installedFiles[]is absent (invariant is consumer-only). FAIL level; fix:t1k updateto reclaim ownership and remerge settings. -
No inlined universal rules (#44): SKILL.md files must not inline the 3 boilerplate blocks that auto-load from
.claude/rules/(skill-security, AI-Driven Design, fork-hygiene 5-line). Runsscripts/check-no-inline-universal-rules.cjs. FAIL level; fix: remove the inlined block and reference the canonical rule/reference file. Seereferences/checks.md#44. -
Auto-pipelines GitHub MCP prereq (#46): When
features.autoIssueSubmissionorfeatures.autoLessonSyncis ON, correlates that with the GitHub MCP’s presence — a missing/unauthenticatedgithubMCP means the sync-back/issue-filing sub-agent has no way to submit, and entries queue silently with no signal to the user. Also surfaces pending-queue counts (pending-skill-updates.jsonl,pending-issue-submissions.jsonl). Runsscripts/check-auto-pipelines-prereq.cjs. WARN level (advisory; exits 0 always); SKIPs (reportsstatus: "skip") when both flags are OFF or theclaudeCLI cannot be queried to probe MCP state. Fix:claude mcp add github. -
Activation skill resolution (#47): Every skill ref in every
t1k-activation-*.jsonsessionBaseline[]andmappings[].skills[]array must resolve to a real skill directory — accepting BOTH bare-slug form (nakama-rpc) and the full-prefixed form (t1k-nakama-rpc). Wraps the release-action gatevalidate-activation-skill-resolution.cjs. WARN level locally (advisory; the release-action gate is the strict enforcer at PR time). Fix: rename the ref to either form the prefixer’sbuildSelfHealMap()accepts (canonical dir, kit-stripped, module-stripped, kit+module-stripped, ort1k--stripped). Seereferences/checks.md#47. -
Global install core-only (#48):
$HOME/.claude/metadata.jsonshould contain ONLYcoreunder.kits. Engine-specific kits (unity, designer, cocos, react-native, web, nakama) belong PER-PROJECT in the project’s.claude/, not globally. Mixing engine kits globally causes activation bleed (irrelevant skills auto-load), stale-install drift, and orphaned files. Runsscripts/check-global-core-only.cjs. WARN level; fix:t1k uninstall --global --kit <name>for each non-core kit listed. -
Multimodal setup (#49): When
t1k-extendedis installed ANDskills/t1k-extended-multimodal/SKILL.mdis present: validates GEMINI_API_KEY (WARN), MINIMAX_API_KEY (WARN, optional), python3 ≥ 3.10 (FAIL), andgithub:The1Studio/human-mcp#v2.15.1resolvability (WARN — freshness signal vianpm view; install hint points to fork). Runshooks/doctor-check-49-multimodal-setup.cjs. FAIL level for missing python3; WARN for missing API keys / MCP. -
Stale-backup folders inside auto-scanned dirs (#50): Detects quarantine subdirectories (
.stale-backup-*,.zombies-*,.backup-*,.archive-*,.old,.deprecated,.trash) sitting INSIDE Claude Code’s auto-scanned folders (agents/,skills/,rules/,hooks/,commands/). Dot-prefix does NOT hide them — the/agentsUI and skill discovery walk into them and surface their contents as live registrations (zombie entries). Scans BOTH global~/.claude/and project.claude/. Runsscripts/check-stale-backup-folders.cjs. WARN level; fix: move the quarantine folder OUTSIDE the auto-scanned dir (mv ~/.claude/agents/.stale-backup-* ~/.claude/.stale-backup-*) orrm -rfafter verification. Seedocs/naming-convention.md§ Violation handling for the canonical guidance. -
Agent budget calibration (#51): Scans
.claude/agents/*.mdfor budget-checkpoint +maxTurnscalibration perskills/t1k-team/references/agent-completion-discipline.md. Flags: (a) a FLAT-token checkpoint in the body (a literal like150K/150,000/200Knot tied to the agent’smodel:window — should be window-relative, ~75%@200K / ~55%@1M); (b) a tool-heavy agent (hasBashand/orTask/Agentintools:, i.e. can mutate/orchestrate) with NO budget checkpoint in the body at all; (c) under-sizedmaxTurnsfor the task class (tool-heavy agent atmaxTurns < 50— multi-PR/refactor/MCP-validation work hits the turn cap before tokens, #528:t1k-kit-developer45→90). Runsscripts/check-agent-budget-calibration.cjs. WARN level; fix: make the checkpoint window-relative and sizemaxTurnsto the task per the rule. -
Hook registration drift (#52): Compares installed enforcement hook scripts with their required event + matcher registrations in
settings.json. Reports hook files that arrived through an update but remain inert on older consumers. Runs.claude/hooks/doctor-check-52-hook-registration-drift.cjs. FAIL level; fix: update with a current CLI so it can reconcile the missing registrations. -
Agent routing reachability (#53): Every agent
.mdunder.claude/agents/must be reachable by the data-driven routing index (hooks/lib/agent-routing-index.cjs) thatgeneric-agent-detectorconsults — an agent contributing zero keywords can never be suggested, so its task shape silently falls through togeneral-purpose. Also flags agents that are absent from everyt1k-routing-*.jsonrolesmap AND declare noroles:frontmatter at all (roles: noneis a legitimate explicit opt-out; saying nothing is drift). Runsscripts/check-agent-routing-reachability.cjs. WARN level; fix: add an<example>block with auser:prompt (andContext:line) to the agent description, or state the roles intent explicitly. Resolves #659. -
Agent MCP tool-grant drift (#54): Reconciles
mcp__<server>__<tool>grants in every agent’stools:frontmatter against theservedToolsmanifest declared for that server int1k-config-*.json. A stale grant reads as a capability the agent has, so the resulting weaker verdict gets mis-attributed to an MCP-server bug rather than to our own allowlist. Runsscripts/check-agent-mcp-tool-grants.cjs. WARN level; a server with no declared manifest is reported unverified, never as a violation (a false “this tool doesn’t exist” is the failure mode this check exists to prevent). Pass--include-ungrantedfor the informational served-but-ungranted direction. Resolves #651. -
Kit file drift (#55): Compares project-local
.claude/against the global install and reports three states: modules BEHIND the global version, kit executables MISSING locally, and executables DIVERGED AHEAD (same module version, different content). Project-local shadows global perrules/prefer-local-over-global-edits.md, so a stale local copy can hold a shipped fix inert indefinitely with no signal. Runs.claude/hooks/doctor-check-55-kit-file-drift.cjs. Offline — compares the two installs on disk, never the network. FAIL level; fix:t1k modules update, or/t1k:sync-backFIRST when content diverged ahead, since update overwrites those edits (#367). -
Dead permission rules (#56): Flags
permissions.{allow,deny,ask}entries whose tool name Claude Code’s file-permission matcher never consults —Write(path),MultiEdit(path),NotebookEdit(path)(useEdit(path)) andGlob(path)(useRead(path)). Such a rule passes the settings schema and grants/denies nothing while reading like a live rule; Claude Code’s own warning appears once, at startup, only for the file it loaded. Scanssettings.json+settings.local.jsonin both scopes (--project-onlyto skip global). Runsscripts/check-dead-permission-rules.cjs. WARN level; the dead-form table isreferences/permission-rule-forms.json(transcribed from the shipped rule validator) so a new form is a data edit, never a code edit. Resolves #763. -
Global bootstrap state (#57): Reports what the silent global-bootstrap did on this machine, read back from its sentinel
<realHome>/.t1k/global-bootstrap.json. The bootstrap installscore+model-routerinto~/.claude/from SessionStart with no prompt and no output on success, so this check plus the[t1k:global-bootstrap]frame are the ONLY way to observe it. States: PASS (global install present / bootstrapped), SKIP (never triggered, opted out, or an attempt in flight), WARN (failed below the cap, or an unreadable sentinel), FAIL (stopped permanently after 3 REAL failures — lock contention never counts). Runs.claude/hooks/doctor-check-57-global-bootstrap.cjs. Offline — reads the sentinel on disk, never the network. Fix on FAIL:t1k init --global --yes --kit core --preset full, then check~/.claude/.kit-update.log. Seedocs/global-bootstrap.md. -
Kit install scope (#58): Reports kits installed in BOTH scopes at once. A kit belongs to exactly one —
coreglobal, engine/domain kits per-project (rules/kit-install-scope.md). Only the project copy is ever served, so the shadowed global copy still updates and still reads healthy int1k --versionwhile no session loads it; updating the wrong one is silent. Consumes the per-scope inventoryhooks/telemetry-utils.cjsalready computes (kitScope === 'both') rather than adding a second reader. Runs.claude/hooks/doctor-check-58-kit-install-scope.cjs. Offline. SKIPs on kit source trees (nokits/scope/installedAtin metadata) and on global-only sessions; INFO when the project declaresinheritsFrom→ global (deliberate layering). WARN level otherwise; fix:t1k uninstall --local --kit coreort1k uninstall --global --kit <engine-kit>. Complements #48 (no non-core kit globally) and #55 (whether two coexisting copies agree). -
Markdown link integrity (#60): Relative markdown links inside
.claude/whose target exists in neither the on-disk layout nor the FLATTENED namespace a consumer holds (flatten-module-files.cjscollapsesmodules/<m>/skills/<s>/to.claude/skills/<s>/and does not rewrite link paths, so depth is counted from the INSTALLED location). Links that escape.claude/under both readings, and links into a namespace the install never received (modules/,plans/), are skipped — a consumer cannot fix missing content. Runs.claude/hooks/doctor-check-60-markdown-link-integrity.cjs. Offline. FAIL level; WARN on a kit source tree when the target may belong to a co-installed kit. Fix: recount the../for the installed location (skills/<s>/SKILL.md→ 2; itsreferences/→ 3;agents/<a>.md→ 1). Seet1k-skill-creator/references/architecture-rules.md§ L.1. -
Skill reference citations (#61): A SKILL.md naming its own
references/<file>must ship that file. Covers the NON-link citation forms #60 cannot see (code span, table cell, prose). Cross-skill citations carrying more path in front ofreferences/are deliberately not resolved against the citing skill —t1k-architecture/references/fork-hygiene.mdis cited 26 times from elsewhere. Fenced blocks are ignored. Runs.claude/hooks/doctor-check-61-skill-reference-citations.cjs. Offline. FAIL level; fix: write the reference or delete the citation — the failure is silent otherwise (the model opens nothing and continues). -
Orphan reference files (#62):
references/**.mdthat nothing anywhere under.claude/cites. The corpus is the WHOLE tree — every markdown, JSON, and script file minus the candidate — because a per-skill check reports shared references as orphaned and tells users to delete live content. Matching is deliberately generous (full path,references/suffix, or basename), so it under-reports rather than over-reports. Runs.claude/hooks/doctor-check-62-orphan-reference-files.cjs. Offline. WARN only, never FAIL — the remedy is deletion; confirm by hand before acting. -
Unused local modules — engine mismatch (#63): A locally installed kit whose own
context.requiredPathsare absent from the project (e.g. unity with noAssets//ProjectSettings/). Data-driven — no declaration means no finding. Runs.claude/hooks/doctor-check-63-unused-local-modules.cjs. Offline, diagnostic-only. Emits Contract A[t1k:doctor:scope-finding …]per finding;confidence=highrequires opt-in viascopeEnforcement.autoRemoveKits, so a default install never auto-removes. Seereferences/checks.md#63. -
Uninstall integrity (#64): A stale interrupted-uninstall journal (FAIL, idempotent re-run remedy — an in-flight uninstall reports INFO instead) and unacknowledged auto-removal ledger entries (WARN, with a situation-correct recovery command — never
t1k recover restore). Report-only, never mutates. Runs.claude/hooks/doctor-check-64-uninstall-integrity.cjs. Seereferences/checks.md#64. -
Install-ledger drift (#65): Content under
.claude/the install ledger does not account for — a kit-shipped file absent frommetadata.kits[].files[](unupdatable AND unprunable), amodules/<name>/the owning kit no longer ships (positive evidence from the regeneratedt1k-modules.json), or an_origin.kitnaming a kit installed in neither scope (ownership resolution then points at the wrong repo). Single-scope, so it runs on a global-only install where #55 skips. Report-only and read-only — every frame isaction=report confidence=low, and the remedy for an untracked file is to TRACK it, not delete it.status=unknownis distinct fromstatus=ok. Runs.claude/hooks/doctor-check-65-install-ledger-drift.cjs. Resolves core#1085. Seereferences/checks.md#65. -
DOTS project fitness (#66): Unused theonekit-unity
dots-*modules (dots-core, dots-ai, dots-combat, dots-inventory, dots-nav, dots-rendering, dots-testing) — installed but no DOTS/ECS evidence anywhere in the project (nocom.unity.entitiesin anyPackages/manifest.json, nounity-dots-library/com.the1studio.dots-*package directory, no.csfile declaringIComponentData/ISystem/SystemBase). Kit-specific but hosted in core (gate #22 forbids non-core kits from shipping hooks); dormant unless theonekit-unity is installed — the dormancy gate is kit-identity, never DOTS-code-presence, since the WARN branch fires precisely when DOTS code is absent. Report-only — printst1k modules remove <name>per unused module, never emits Contract A’s[t1k:doctor:scope-finding ...]frame (module-family granularity, not the kit-granularity auto-remove pipeline). Fails open (SKIP, never a false-absent WARN) on an unreadable directory or an exceeded walk budget. Runs.claude/hooks/doctor-check-66-dots-project-fitness.cjs. Seereferences/checks.md#66. -
Session-memory graph integrity (#67): Session memory IS a graph and was never validated as one — memory files are nodes (identity = frontmatter
name:, class =metadata.type),[[wikilinks]]are edges,MEMORY.mdis the index deciding what is reachable at session load. Pins node identity toslugify(basename): the only convention under which a link author can name a target without opening it, and what existing links already assumed. Distinguishes a broken edge (FAIL, repairable) from a link to an unwritten memory (WARN — the memory spec permits it as an intent marker; conflating the two trains readers to ignore the check). Supports typed edges[[relation::target]]over a closed set (supersedes, supports, contradicts, derived_from, mentions). Runsscripts/check-memory-graph.cjs. WARN level, exit 0 unless--strict; SKIPs when the project has no memory dir. Fix:node scripts/check-memory-graph.cjs <root> --fix(dry-run) then--apply. Never invents an edge target, writes an index row, or deletes. Test:tests/check-memory-graph.test.cjs— 19 assertions pinning FAILURE states. -
Inheritance integrity (#68): When
metadata.jsoncontainsinheritsFrom, validates the parent.claude/path is well-formed: exists, is a directory, ends in.claude, contains a valid T1Kmetadata.json, is not a self-reference, and forms no cycle (≤5 hops). Runsscripts/check-inherits-from.cjs. ERROR level (the field is opt-in — if set, it must be valid); SKIPs wheninheritsFromis absent frommetadata.json(no-op for existing installs) ormetadata.jsonitself is missing. Fix: remove theinheritsFromfield or re-create/correct the parent.claude/. Test:.claude/hooks/__tests__/check-inherits-from.test.cjs(scenarios T5–T11). Seereferences/checks.md#68. -
Rule citation graph (#69): The always-loaded rule corpus modelled as a GRAPH — each rule a node, each
rule-name.mdit cites an edge. Four existing checks measure rule WEIGHT (#36, #38, #59, plus the release budget gate) and none can see rule STRUCTURE. Reports structural hubs (most-cited rules, where removing one breaks many readers), citations that resolve to nothing (FAIL), and citations to a rule that exists on disk but this install does not load (WARN — correct on an install with the owning kit, a dead pointer here). Uncited rules are reported at INFO as a SIGNAL for #59’s budget conversation, never as a delete list — a rule can be load-bearing and cited by nobody. Node population is not re-derived: it reuses #59’s exportedcollectScope(), the SSOT for what a session actually loads. Runsscripts/check-rule-graph.cjs. Exit 0 unless--strict. Test:tests/check-rule-graph.test.cjs— 17 assertions, four of which pin FALSE-POSITIVE suppression (SKILL.md/CLAUDE.mdambiguous basenames,phase-N.mdplaceholders, skill-reference citations). -
Phantom kits (#71): Iterates
metadata.kitsentries and warns on any wherefilesisundefinedor an empty array. Phantom entries are written whent1k initis interrupted (SIGINT, network failure) before file extraction — they causeproject-detector.cjsto misidentify the project framework andt1k updateto spawn init loops that always fail (Issue #38). Runsscripts/check-phantom-kits.cjs. Skips when~/.t1k/locks/kit-install.lock.lock/is held (install in progress) to avoid false-positives on transient empty states. WARN level; fix:jq 'del(.kits.<name>)' .claude/metadata.json > /tmp/m.json && mv /tmp/m.json .claude/metadata.jsonthent1k init --kit <name> --yes. Snapshot test:tests/check-phantom-kits.test.cjswith fixturetests/phantom-fixture.json. -
Plaintext reference mentions (#74): Closes the gap #60/#61 both PASS through — a plain-text
references/<name>.mdmention in an HTML comment, other prose, or a.cjs/.mjsstring literal, where neither markdown-link syntax (#60) nor own-skillSKILL.mdcitation resolution (#61) applies. Two forms: qualifiedskills/<s>/references/<f>resolved in the FLATTENED namespace like #60 (optionallymodules/<m>/-prefixed); barereferences/<f>scoped to a skill’s ownreferences/*.mdandscripts/*.cjs/*.mjs(neverSKILL.md— that’s #61’s job), resolved against the citing skill’s ownreferences/first, tolerating cross-skill shorthand when the basename exists under ANY skill’sreferences/. Fenced code in.mdis stripped first, same as #60/#61. Runs.claude/hooks/doctor-check-74-plaintext-reference-mentions.cjs. Offline. WARN-first ratchet (Core Requirement #13): reports WARN, exit 0, never FAIL yet — RATCHET TO FAIL on/after 2026-09-08 once a broader consumer sample confirms zero new false positives. Fix: write the file, or repoint the mention — a mention emitted by a.cjs/.mjsscript ships into every consumer’s generated output. Seereferences/checks.md#74. -
StatusLine outdated form (#75):
t1k modules updatenever upgrades an EXISTINGstatusLine.command(core#1396) — onlybackfillStatusLine, scoped to an ABSENT key, ever writes it, so an install whoset1k initpredates core#702’s resolver-form hardening (2026-08-13) is frozen on the pre-hardening literal form forever with zero signal (t1k --versionreports “up to date” throughout). The literal form silently drops statusline segments under Claude Code 2.1.150+‘sHOME=$CLAUDE_PROJECT_DIRoverride. Complements #42 (wired vs. not) by checking the wired command’s SHAPE, using the samehooks/lib/hook-command-form.cjsidentity SSOT check #52 uses. Runs.claude/hooks/doctor-check-75-statusline-outdated-form.cjs. Offline. FAIL level on a literal-form command; SKIP when no kit-ownedstatusLine.commandis present at all (that’s #42’s job). Fix:t1k initto re-merge settings untiltheonekit-cli#501ships. Seereferences/checks.md#75. -
Unreachable kit fragment (#76):
t1k-activation-core.jsonis 793 lines, actively maintained, and read at runtime — yet inert on every consumer, becauset1k modules updaterefreshest1k-activation-<module>.jsononly when<module>names an INSTALLED MODULE, andcoreis a kit name, never a module name (core#1385). Structural check, not a staleness heuristic — flags anyactivationfragment this repo ships (_origin.repositorymatch), unclaimed by a module, whose filename suffix matches no directory under.claude/modules/, meaning no future update can ever reach it regardless of current content. Scoped toactivationonly —routing/configfragments share the same unclaimed shape but refresh through a different, working mechanism (core#1385’s own explicit false-positive warning). Runs.claude/hooks/doctor-check-76-unreachable-kit-fragment.cjs. Offline. WARN-first ratchet (Core Requirement #13): reports WARN, exit 0 — RATCHET TO FAIL on/after 2026-09-10. Not auto-fixable — relocating the content is a maintainer design decision. Seereferences/checks.md#76. -
Scope remediation: the background agent
features.contextBloatGuarddispatches on a duplication-over-threshold session — reads checks #55/#58/#63 findings, refuses far more than it acts, and when it does remove a kit, backs up, verifies, and records before reporting. Never wired intofixmode. Full behavior spec:references/scope-remediation.md.
See references/frontmatter-recommendations.md for recommended values and output format.
CI Mode (--ci flag)
Section titled “CI Mode (--ci flag)”When invoked as /t1k:doctor --ci, the doctor runs in non-interactive CI mode:
- Runs all checks from the standard check list plus the Tier 2 eval registry checks
- Emits GitHub Actions workflow annotations (
::error file=...::format) for each failure - Writes a machine-readable summary to
.claude/telemetry/doctor-ci-{date}.json - Exits with code 1 if ANY check fails (suitable as a blocking CI gate)
- Exits with code 0 only if all checks pass
- Completes in < 60s on
theonekit-core
CI Check Sequence
Section titled “CI Check Sequence”- SKILL.md frontmatter completeness — every
SKILL.mdmust have:name,description,version,effort,origin,repository,module,protected - Agent frontmatter validity — every
.claude/agents/*.mdmust have:name,description,model,maxTurns,origin,repository - Hook .cjs syntax — runs
node --checkon every.claude/hooks/*.cjs - t1k-config-*.json schema — validates
registryVersion,kitName,priority(number) present in every config fragment - t1k-manifest.json validity — per installed module,
.t1k-manifest.jsonmust exist and list only real files - Cross-ref integrity — vendors the Phase 1 script from
theonekit-release-action/scripts/check-skill-cross-refs.cjs - Tier 2A routing check — delegates to
scripts/eval/tier2/routing-check.cjs - Tier 2B activation check — delegates to
scripts/eval/tier2/activation-check.cjs
See references/ci-mode.md for full spec and GitHub Actions workflow snippet.
Auto-Healing (fix mode)
Section titled “Auto-Healing (fix mode)”Only deterministic fixes: regenerate .t1k-manifest.json, detect orphaned/stale files, report what needs manual attention. Full details: references/fix-mode.md
Output Format
Section titled “Output Format”## Doctor Report — {date}### Checks- Role coverage: [PASS | FAIL — missing agent for role X]- Skill existence: [PASS | FAIL — missing skill: Y]...### Issues Found- [issue description + file + line]### Recommended Fixes- [action]Gotchas
Section titled “Gotchas”- Origin metadata is CI/CD-managed, committed to git — Do NOT modify
origin,repository,module,protectedmanually. CI manages them. Check #16 validates consistency. - Module skills are flattened in release ZIPs —
modules/{name}/skills/flattened to.claude/skills/during release. Themodule:frontmatter preserves the original assignment. - Activation fragments use bare-slug refs by convention — entries in
sessionBaseline[]andmappings[].skills[]oft1k-activation-*.jsontypically appear as bare slugs (nakama-rpc) rather than full-prefixed dir names (t1k-nakama-rpc). The prefixer’sauto-prefix-skills.cjs::buildSelfHealMap()self-heals legacy refs to canonical form at release time, but the SSOT in the fragment files stays bare. The release-action validatorvalidate-activation-skill-resolution.cjs(and check #47) accepts BOTH forms, so authors can use either. New refs should match an existing accepted variant — anything else fails the gate at PR time.
Registry validation and manifest repair only.