v4: folio split (Phases 3 + 3.5 + 3.6) — craft 94→47 commands - #290
Merged
Conversation
T1.1 of the v4.0.0 train. Working artifacts (tasks/) ride the branch, deleted before final merge per CP-4. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PCmhbNUV6iSQrx1USQjACG
Checks off T1.1-T1.6/CP-1 and T2.1-T2.8/CP-2 to match .STATUS (both phases merged 2026-07-10). Flags the two Phase-1 claims not yet re-verified: T1.5 homebrew-tap fix (local-only branch, unpushed) and T1.6 GitHub secrets (claimed set, not re-confirmed). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Removes the 24 command files (17 docs/*, 7 site/*) + 6 docs agents + 6 skill dirs now owned by folio (git filter-repo extraction verified in Phase 2). site/deploy.md un-deprecated (stays as a real command per B2, frontmatter delegation to the now-removed site-management skill stripped). Fixed the 3 STAY-command dead references flagged by T3.1 (docs/changelog.md, docs/update.md, do.md's Docs-category routing + docs:validate phantom) plus scattered /craft:docs:sync mentions repointed to /folio:docs:sync. Ran bump-version.sh --counts-only (70/39/2, 14 files). NOT done yet (WIP, tests red — 59 failures, all mapped to later tasks): - T3.2: hub.md's 804-line DOCS grid still lists the 24 removed commands - T3.3: enumerated test relocations (test_site_publish.py -> folio, hub_integration/layer3 displays, dist_doc_accuracy stale-count sweep across ~15 docs/ site pages not covered by bump-version's file list) - Real open question found mid-task: skills/orchestration/plan-orchestrator/ SKILL.md and test_doc_scorer_changeshape.py both treat the now-deleted commands/docs/sync.md as the single source of truth for the doc-impact scoring rubric used by brainstorm/plan/grill's default scaffolding. This wasn't in the original ORCHESTRATE-folio-split.md follow-up list — needs a decision (inline the rubric into craft, or have plan-orchestrator reference folio cross-plugin) before T3.3 can close that test. - test_integration_teaching_workflow.py references site/publish.md, site/progress.md, site/build.md (deleted) — overlaps the existing teaching-residue-audit backlog item, not previously connected to this split. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Inlines the doc-impact scoring rubric (previously living only in the now-moved commands/docs/sync.md) into a craft-owned reference file, skills/orchestration/references/doc-impact-rubric.md, and repoints the 3 skills that treated docs/sync.md as their single source of truth (plan-orchestrator, brainstorm, brainstorm-insights). Also fixes the "N commands support --orch" test invariant: only 4 commands genuinely carry --orch/--orch-mode now (do, brainstorm, check, ci:generate) — docs:sync moved to folio and orch.md's own frontmatter `name: orch` was a false-positive match, not a real --orch argument. Updated both the integration and e2e test command lists and docstrings to reflect 4, not 5. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…cmds test_hub_integration.py and test_hub_layer3.py hardcoded sample-command lists and category floors (docs>=19, site>=8) from before the split. Updated to the real post-split counts (docs=5, site=1) and swapped sample commands (docs:sync/site:build -> docs:changelog/site:deploy, both of which still exist in craft). Note: commands/hub.md's own 804-line ASCII catalog is separately stale (pre-dates even the 94-command baseline) — its full "diet" rebuild is explicitly deferred to Phase 3.5 per ROSTER-craft-v4-disposition's own open question, not in scope here. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Swept 94->70 commands / 45->39 skills claims across 21 docs-site
pages test_dist_doc_accuracy.py's H2 full-sweep checks (not covered
by bump-version.sh's curated file list — same class of gap as the
earlier CLAUDE.md/tutorial fix).
- Removed test_mermaid_dogfood.py's TestDocumentation class and
test_mermaid_e2e.py's TestDocsCheckIntegration/TestStructure classes
(7 tests total) — all asserted on commands/docs/{mermaid,check}.md
and skills/docs/mermaid-linter, which moved to folio; that coverage
belongs there now, not in craft's suite.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Test relocations/updates (folio now owns this coverage):
- test_markdownlint_list_spacing_e2e.py: removed TestDocumentationIntegration
(commands/docs/lint.md moved)
- test_teaching_documentation.py: test_teaching_commands_documented now only
checks git/status.md (site/publish|progress|build.md moved)
- test_integration_teaching_workflow.py: test_04 now checks folio's salvaged
site-management/references/{publish,build}.md instead of asserting
standalone command files that were killed (not moved) per T2.4's salvage
- agents/orchestrator-v2.md: 2 stale /craft:docs:sync mentions -> docs:changelog
Real regressions found and fixed (not test staleness):
- commands/code/demo.md had `deprecated: true` / `replaced-by:
skills/code/demonstration-builder/` — that skill moved to folio in T3.1,
leaving a dangling shim pointer. Un-deprecated it (same treatment as
site/deploy.md) since craft has no replacement for it anymore; it's
still a real, substantive 183-line command, scheduled for its own
salvage-gated deletion in Phase 3.5, not now.
- README.md: 4 live count claims (94/45/8) missed by bump-version.sh's
file list, caught by test_count_drift_tripwire.py's real-tree Phase 7
scan. Fixed to 70/39/2.
Flagged, not fixed (genuine open question):
- scripts/dependency-manager.sh hardcodes commands/docs/demo.md (now in
folio) as its dependency-declaration source; the whole subsystem
(dependency-manager.sh, tool-detector.sh, health-check.sh,
installers/*.sh) may belong in folio now. Skipped the one live test
with a clear reason rather than guessing at a redesign.
Confirmed PRE-EXISTING on dev (not caused by this split, left alone):
test_v115_adhd_enhancements.py's 3 failures (stale "Site Creation
Workflow" section, mermaid click-node count, "Scenario 6" playground
entry) all predate this branch — verified failing identically on dev.
Full suite: 2645 passed, 41 skipped, 1 xfail, 1 xpass, 0 unexplained
failures (down from 59 after T3.1).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
User-decided 2026-07-12: leave the orphaned dependency-manager.sh subsystem dormant in craft (not delete, not migrate to folio now). hub.md's 804-line catalog rebuild reconfirmed as correctly deferred to Phase 3.5 (no action). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Craft landed at 70 commands post-folio-split (T3.1), below the old 86 floor. Skills floor (26) already has headroom against the real count (39) and needs no change per the plan's own note. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs/commands/docs/*.md (17 files) and docs/commands/site/docs/frameworks.md were separate mkdocs-served mirror copies of the commands deleted in T3.1 (mkdocs.yml nav paths resolve relative to docs_dir=docs, so these were the actual pages served, not the top-level commands/ source). Removed both the files and their 18 now-dangling mkdocs.yml nav entries. mkdocs build --strict still surfaces 34 warnings from internal links pointing at these removed pages (docs/commands.md, docs/commands/docs.md, docs/commands/docs/changelog.md, 2 REFCARD/tutorial cross-refs) — part of the broader T3.5 prose sweep, not fixed in this commit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…mmands
TUTORIAL-docs-{check,check-links,generate,lint,mermaid,sync}.md were each
entirely about one command that moved to folio in T3.1 — deleted rather
than repointed, plus their 6 mkdocs.yml nav entries.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Dispatched a Workflow (8 parallel agents) to sweep the 63 remaining live docs pages (guide/, tutorials/, cookbook/, commands/, reference/) that mentioned the 22 commands moved to folio in T3.1-T3.2. Historical/archived content (docs/specs/, docs/plans/, docs/archive/, CHANGELOG.md) was deliberately excluded per the existing docs-staleness convention. Repoint pattern: illustrative /craft:X mentions -> /folio:X, dead relative links to now-deleted pages removed, docs:changelog/docs:update/ site:deploy/docs:claude-md:* (staying commands) left untouched throughout. Also fixed: 1 dangling nav link in docs/tutorials/index.md (pointed at a tutorial page deleted in the prior T3.5 slice); 2 stale test assertions in test_teaching_documentation.py still expecting /craft:site:publish after the sweep correctly repointed REFCARD.md/REFCARD-TEACHING.md to /folio:site:publish. Verified: mkdocs build --strict clean (0 warnings, was 1 before this commit); full pytest suite 2597->2599 passed, 0 unexplained failures (3 confirmed pre-existing on dev, test_v115_adhd_enhancements.py). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- capture-craft-output.sh:27 phantom /craft:site:create -> /folio:site:build - 4 advice-string scripts repointed /craft:docs:demo -> /folio:docs:demo - 2 VHS tapes + ci/local.md phantom docs:validate fixed - test_teaching_demo_exists regression fixed (site:publish moved to folio) - tasks/todo.md: T3.5 checked off with verification summary Full suite green except 3 pre-existing dev-baseline failures (test_v115_adhd_enhancements.py, confirmed via direct dev-branch run). mkdocs build --strict: 0 errors.
- T3.6: validate-counts.sh confirms 70/39/2 actual==documented, no drift - T3.7: new docs/MIGRATION-v4.md with full old->new command/agent/skill destination table (verified against actual folio checkout); README.md + CHANGELOG.md breadcrumbs; mkdocs.yml nav entry - tasks/todo.md: T3.6, T3.7 checked off
pytest 2601/2604 pass (3 pre-existing dev-baseline failures, 0 regressions); all 6 CI-required bash suites green; mkdocs --strict clean. Phase 3 (craft amputation, 94->70 cmds) done. CP-3 reached: branch holds, no PR yet pending user go-ahead (Phase 3.5 v4 rider shares this train).
…xtras skill
Consolidation per ROSTER-craft-v4-disposition: dist:pypi, dist:curl-install,
dist:marketplace were already deprecated shims pointing at the dist-extras
skill. Salvaged their unique content (workflow YAML templates, dry-run
examples, check tables) verbatim into skills/distribution/dist-extras/
references/{pypi,curl-install,marketplace}.md, then deleted the 3 commands.
- tests/test_marketplace_dogfood.py, tests/cli/marketplace-tests.sh:
repointed from the deleted command to the new skill reference; dropped
frontmatter-specific assertions (references have no YAML frontmatter)
- bump-version.sh --counts-only: 70->67 commands
- Mechanical count-drift sweep: 17 docs-site files with stray "70 commands"
literals fixed to 67 (check-command-mastery.md's illustrative "70 vs 107"
worked example left untouched — it's a frozen scenario, not a live claim)
- scripts/config/exclusions.txt: added README.md's v1.0.0 "26 commands"
changelog entry (historical fact) — crossed the 40%-of-canonical
staleness-checker floor now that the total shrank
- skill_standards_audit.py --fix: added TOC stubs to the 2 new >300-line
reference files
- docs/MIGRATION-v4.md: added the 3 new command->skill-reference rows
Plan deviation noted (see MIGRATION-v4.md): ROSTER assumed code:demo was
still a deprecated shim to salvage-and-kill; T3.1 had already un-deprecated
it (its skill moved to folio), so it's now self-contained content, not a
shim — moved from ROSTER's kill-list to the keep-as-is set.
Full suite: 2601/2604 pass (3 pre-existing dev-baseline failures, 0
regressions; 2 additional failures on this run were confirmed flaky
perf/timing tests that passed on rerun). mkdocs build --strict clean.
…claude-md skill
Consolidation per ROSTER-craft-v4-disposition: docs:claude-md:{edit,sync,init}
were already deprecated shims pointing at skills/docs/claude-md/. Salvaged
their unique content (635+362+320 lines) verbatim into
skills/docs/claude-md/references/{edit,sync,init}.md, then deleted the 3
commands + their 4 docs-site mirror pages (claude-md.md router page +
edit/init/sync mirrors) and mkdocs.yml nav entries.
- 8 advice-string call sites fixed (2 scripts, 6 utils/skills files) that
suggested the now-dead slash commands as a next step — repointed to
"ask Claude to use the docs/claude-md skill" phrasing
- tests/test_hub_integration.py: DOCS category floor 5->2 (only
docs:changelog + docs:update remain — release-plumbing per B2)
- 9 broken internal links fixed (docs.md, commands.md, index.md,
API-REFERENCE-CLAUDE-MD.md, cookbook troubleshooting doc) pointing at
the deleted command/mirror pages
- bump-version.sh --counts-only: 67->64 commands
- Mechanical count-drift sweep: same 17 docs-site files + homebrew.md's
illustrative example, re-applied at the new canonical
- New checker exclusion: guide/check-command-mastery.md added to
DOCS_EXCLUDE_RELPATHS (illustrative /craft:check output showing a
deliberate stale-count WARNING scenario, not a live claim)
- skill_standards_audit.py --fix: TOC stubs for the 3 new >300-line refs
- docs/MIGRATION-v4.md: added the 3 new command->skill-reference rows
Full suite: 2601/2604 pass (3 pre-existing dev-baseline failures only, 0
regressions). mkdocs build --strict clean. No broken links.
…eviation recorded commands/check/gen-validator.md (447L, deprecated shim -> skills/check/) salvaged verbatim into skills/check/references/gen-validator.md, then deleted. skills/check/SKILL.md's "Validator Generation" section and "See Also"/"Backing Commands" repointed (no standalone command remains). Plan deviation recorded in MIGRATION-v4.md: commands/check.md was NOT collapsed to a micro-shim per ROSTER's older plan. Its own header already documents a prior salvage pass and cites skills/code/command-skill-token-efficiency/SKILL.md's classification test (does the command always run, even before skill-routing fires?) for why Step 0/confirm-gate/--orch/CRAFT_MODE content stays in the command file. skills/check/SKILL.md itself defers back to commands/check.md as "the full check command spec" -- forcing a shim here would violate "extract, don't delete." Left as-is. - bump-version.sh --counts-only: 64->63 commands - Mechanical count-drift sweep: same 16-file class + homebrew.md's illustrative example, re-applied at the new canonical - Fixed a checker false-positive: test_skill_referenced_commands_exist's regex matches ANY backtick-quoted commands/*.md string, including inside an explanatory "was formerly at X" note -- reworded to avoid the pattern - docs/MIGRATION-v4.md: added gen-validator's row + the deviations section Full suite: 2601/2604 pass (3 pre-existing dev-baseline failures only, 0 regressions). mkdocs build --strict clean.
…workflow:insights folded into skill references Extracts commands/git/worktree.md, commands/git/docs/refcard.md, and commands/workflow/insights.md into skills/dev/git/references/ and skills/workflow/brainstorm-insights/references/, salvaging their unique content (AskUserQuestion prompts, scope/branch-pattern detection tables, Step 0/0.5 flow) before deletion. Fixes cross-tree relative links to the new skill-reference locations by switching to absolute GitHub blob URLs (mkdocs docs_dir can't resolve links escaping docs/), repoints callers in branch-guard.sh and capture-craft-output.sh, and updates test suites (test_command_enhancements_e2e, test_hub_discovery/integration/layer3, test_insights_improvements_dogfood/e2e, test_facet_parsing_defensive, test_brief_command_*) whose fixtures hardcoded the old command paths or a now-empty commands/workflow/ category. Completes T3.5.1 (4/4 families). Full pytest: 2575 passed, 4 failed (3 known dev-baseline + 1 expected local branch-guard.sh install drift from this commit's own content change), 43 skipped. mkdocs build --strict: clean. Counts: 60 commands, 2 agents, 39 skills. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPt2e4ffzTowm4boYhFhyN
…:coverage, teaching-residue utils; demote discovery-usage Folds sprint/roadmap planning and spec->ORCHESTRATE pipeline into the plan-orchestrator skill (Modes 3-4), folds coverage reporting into the test-strategist skill, removes 2 unused teaching-residue utility commands, and demotes discovery-usage.md (internal-only, never a real slash command) to a plain docs page. Repoints ~35 caller references across guides, reference docs, tutorials, and skills. 60->53 commands. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPt2e4ffzTowm4boYhFhyN
…nprotect/status/clean/branch/protect-baseline) All 7 already carried deprecated:true/replaced-by:skills/dev/git/ and were verified redundant with skills/dev/git/SKILL.md (Operations 1,3,6,8,9,10,12) before deletion. commands/git/ is now empty. Repoints callers across CLAUDE.md, hub.md, and docs/ to skill-based phrasing. 53->46 commands. T3.5.2 complete. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPt2e4ffzTowm4boYhFhyN
Records exact line counts per consolidation family, resume order (smallest-first), and the /goal command to re-enter Phase 3.5 with full context. Session stopped here on explicit user instruction after T3.5.1+T3.5.2 landed clean (46 commands, tests at baseline, mkdocs strict clean). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPt2e4ffzTowm4boYhFhyN
…lidations into deferred Phase 3.6 T3.5.3's 5 target families (orch:drive/workflow, arch x4, code:audit x5, plan:feature) are all live, non-deprecated commands, unlike T3.5.1/T3.5.2's confirmed-redundant shims. plan:feature specifically carries a locked prior decision (SPEC-orchestrator-consolidation-2026-07-04 D2) that it was deliberately un-deprecated. Consolidating these means real router-architecture design work, not shim deletion — deferred to its own properly-scoped Phase 3.6 rather than rushed. Phase 3.5 closes at 46 commands (T3.5.1+T3.5.2), tests at baseline, mkdocs strict clean. No PR opened. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TPt2e4ffzTowm4boYhFhyN
Adversarial review of the deferred Phase 3.6 plan. Key finding: commands/orch.md already exists and already soft-routes to orch:drive/orch:workflow, so T3.6.2's "build a fresh router" premise was stale. 10 decisions locked, net effect: - 4 workstreams -> 2 (orch.md refactor, code:audit router); arch router dropped, plan:feature stays excluded per its pre-existing D2 lock - Reframed as organizational cleanup, not command-count reduction (invocability preserved for every subcommand, so 46->~26 was never reachable this way) - Split into 2 independent PRs instead of one bundled CP-3.6 gate - orch.md's launch logic moves to a new skill; orch.md itself becomes the router - Explicit discovery-cache regen step added to both workstreams' task lists See docs/specs/GRILL-phase-3-6-router-consolidation-2026-07-15.md for full ledger. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…streams Rewrites tasks/todo.md's stale Phase 3.6 section (T3.6.0-T3.6.7, planned as one bundled CP-3.6 gate at "craft@26") with the post-grill scope: 3 independently mergeable workstreams (orch.md refactor, code:audit router, ci router), each its own PR. arch router dropped (D6); plan:feature stays excluded (pre-existing D2 lock); framed as organizational cleanup, not command-count reduction, since D3 preserves slash-invocability for every absorbed subcommand. Also corrects a gap in the prior GRILL pass: the original Phase 3.6 plan had 5 target families, not 4 - `ci` (8 commands, 2117 lines, largest family) was missed in the first grill and is added back here as Workstream C (D10), with a real repo-flag format mismatch (short-name vs OWNER/NAME) found and scheduled as an explicit fix rather than left latent. Updates ORCHESTRATE-folio-split.md's Phase Overview rows for 3.5 (mark actually CLOSED, was showing unstarted) and 3.6 (point at the new scope). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Caught at the start of implementation, before any orch.md/drive.md/workflow.md change was made: D1/D7 were locked from line-counts and flag names alone, without reading drive.md/workflow.md in full. They're already thin command wrappers delegating to their own skills (drive-engine, workflow-engine) - the exact end-state the plan wanted to build - and the 3 commands document genuinely distinct execution engines with no real duplication. Same verdict as arch (D6): drop it. Phase 3.6 proceeds with 2 real workstreams (code:audit router, ci router). orch.md/drive.md/workflow.md are untouched by this branch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
D3 (preserve slash-invocability) cited "T3.5.1 kept commands invocable via skill, not deleted" as precedent -- factually wrong, T3.5.1 deleted the dist:pypi/curl-install/marketplace commands entirely (840e57d). The actual distinguishing factor: those 3 were already deprecated:true shims before T3.5.1 touched them, unlike Phase 3.6's targets which T3.6.0 confirmed are live and non-deprecated. Conclusion unchanged, citation fixed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Caught during implementation, before any file was changed: D8's "cohesive audit shape" verdict for all 5 code:audit-family commands was decided from line counts and a partial flag check. Full read of deps-audit.md/ deps-check.md/docs-check.md shows they're generic cross-project tools with incompatible flag surfaces (deps-check has no --format/--fix at all; docs-check has no formal arguments block and is really a generic docs+ deploy pipeline, not schema-audit-shaped). Workstream B shrinks to command-audit + skill-standards only (298 lines) -- the only 2 that genuinely share shape and verified-compatible --format/--fix semantics. deps-audit.md/deps-check.md/docs-check.md are untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…uter skill
Phase 3.6 Workstream B (docs/specs/GRILL-phase-3-6-router-consolidation-2026-07-15.md,
tasks/todo.md T3.6.B1-B5): the only 2 of the original 5 code:audit-family
commands that genuinely share shape and --format/--fix semantics
(both validate craft's own frontmatter/schema).
- New skills/code/audit-router/SKILL.md: shared --format/--fix vocabulary,
health-score formula, exit-code convention shared by both commands
- Salvaged both full bodies verbatim into references/{command-audit,
skill-standards}.md (ADR-002 line-conservation)
- commands/code/{command-audit,skill-standards}.md shrunk to thin shims:
frontmatter (arg surface) unchanged, both stay directly slash-invocable
- deps-audit.md/deps-check.md/docs-check.md untouched -- they're generic
cross-project tools with incompatible flag surfaces, not schema-audit-shaped
Count cascade: 39->40 skills (bump-version.sh + manual sweep of 6 files
outside its tracked list: commands/dist/homebrew.md, docs/MIGRATION-v4.md,
docs/QUICK-START.md, docs/architecture.md, docs/commands.md,
docs/guide/getting-started.md, docs/guide/hub-live-dashboard.md, docs/index.md,
docs/skills-agents.md, docs/tutorials/TUTORIAL-code-skill-standards.md,
README.md). Commands unchanged at 46 (no command added/removed, only 2
shrunk in place).
Full suite: 2561 passed / 4 failed (all confirmed pre-existing on this
branch via git stash: branch-guard hook-install drift + 3 known
test_v115_adhd_enhancements baseline failures) / 43 skipped.
mkdocs build --strict: clean (0 errors). validate-counts.sh + bump-version.sh
--verify: ALL CONSISTENT.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Both declared `category: code` while living in `commands/ci/`, which help_file_validator._check_category_mismatch flags as a real defect (expected category is derived from the parent directory). Found during Phase 3.6 Workstream C investigation. No router was built: a full read of all 8 commands/ci/*.md showed the family is genuinely heterogeneous (detect.md duplicates skills/ci/SKILL.md, triage.md's classify_failure() is extracted by tests/test_ci_triage_unit.py, generate.md is 731 lines of unique CI templates), so this metadata fix is the only real defect the investigation surfaced. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Both declared `category: orchestrate` while living in `commands/orch/`, and no `commands/orchestrate/` directory exists — so the category was unbacked. help_file_validator._check_category_mismatch derives the expected category from the parent directory and flags this. Pre-existing on dev; surfaced by a repo-wide validator sweep run while fixing the same defect class on commands/ci/. Repo-wide mismatch count is now 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3.6 opened with 5 router workstreams and closes with 1 shipped: - plan:feature — excluded (pre-existing D2 lock, unchanged) - arch — dropped (D6), no real duplication - orch — dropped (D11), already delegates to engine skills - code:audit — SHIPPED, shrunk 5 commands -> 2 (D12), 204822a - ci — no router (D13); metadata fix only D13 records the ci full-body read: detect.md duplicates skills/ci/SKILL.md, triage.md's classify_failure() is regex-extracted and exec()'d by tests/test_ci_triage_unit.py (markdown IS the source of truth), generate.md is 730 lines of unique templates. No shared shape to route. Also withdraws D10's repo-flag normalization as a premise artifact: no validator enforces cross-family flag-shape consistency, so it was only a "defect" relative to a router vocabulary that no longer exists. Root cause across D11/D12/D13: the grill locked load-bearing decisions from line counts and flag names without reading the bodies. Every family that looked cohesive from surface metrics collapsed on a full read. Rule recorded for future consolidation phases: read every candidate body in full before locking a router decision. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 3.6 is closed and committed; the branch is deliberately parked, not abandoned. Records why it is not PR-ready so the next session does not re-derive the diagnosis. Scope reality: this branch is the whole v4 train (36 commits, Phases 3+3.5+3.6), 41 behind dev off a 2026-07-09 merge-base — not a small Workstream B+C PR. Three CI blockers with three unrelated causes: 1. test_branch_guard.sh — stale branch, NOT a regression. A characterization test encoding a known limitation that guard-hardening PRs #287-289 closed on dev; dev already renamed it `..._now_caught` expecting 2. The suite runs the INSTALLED hook at $HOME/.claude/hooks/, so its result is machine-global state, not branch state — which is why it passes on dev and fails here with identical code. Fixed free by a dev merge. 2. ci.yml:92 command floor 60 vs actual 46 — the open T3.4, stale a second time (targeted 86->60, then Phase 3.5 cut to 46). CI hard-fails. The new number is a decision (mass-deletion guardrail), not a mechanical edit. 3. test_git_shim_correctness.sh — the only true branch debt. T3.5.2 deleted commands/git/ but left the suite asserting those 7 shims exist. A dev merge does NOT fix it. Needs the suite updated/removed + its ci.yml:180 line. Root blind spot: these are bash suites (ci.yml:177-180); pytest does not run them. T3.5.2 cited "full pytest 2575 passed" as evidence and shipped this. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Brings 41 commits of dev (guard-hardening PRs #287-289, the cwd resolver, and /craft:git:issue-check from PR #283) onto the v4 folio-split branch. 34 conflicts resolved. Surface: 47 commands / 40 skills / 2 agents. Conflict resolution: - ~30 count-cascade conflicts (dev 95/45/8 vs branch 46/40/2) -> took the branch's post-split surface, then recomputed every tracked count mechanically via bump-version.sh --counts-only (14 files) rather than trusting hand-resolution. validate-counts.sh exits 0 at 47/40/2. - commands/docs/quickstart.md (modify/delete) -> kept deleted; folio owns it (verified present at folio/commands/docs/quickstart.md). dev's only change was a count bump inside an example template. - commands/git/issue-check.md -> KEPT AS A LIVE COMMAND, not folded into skills/dev/git/. Git's directory-rename detection had auto-relocated it to skills/dev/git/references/ (our side renamed commands/git/ -> skills/dev/git/references/ in T3.5.2), which would have broken tests/test_issue_check_unit.py: that test hardcodes commands/git/issue-check.md and exec()s the classify_issue() block out of it, so the command file is the single source of truth for the classifier. Same structural constraint recorded for commands/ci/triage.md in GRILL D13. Restored to commands/git/; its 12 unit tests pass. - skills/dev/git/SKILL.md -> kept the branch's reference-doc rows, dropped dev's stale commands/git/docs/refcard.md row. Operation 13 (Issue Premise Check) merged in cleanly from dev. - mkdocs.yml nav -> dropped dev's 7 deleted git command entries, kept the issue-check entry (blind --ours would have dropped it from the site). Also corrects two now-false claims in skills/dev/git/SKILL.md ("commands/git/ is now empty", "there is no explicit /craft:git:* invocation path anymore") — issue-check is a live command and the skill now says so, with the reason. Long-tail doc counts (46 -> 47) updated in 6 live user-facing files. Historical changelog entries, illustrative sample outputs, and spec/brainstorm records deliberately left at their original numbers. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
T3.4 — command floor 60 -> 40. The floor is a mass-deletion guardrail and must sit BELOW the real surface. It went stale twice (86 -> 60) while the actual count fell 94 -> 70 -> 47, leaving the floor ABOVE the surface: CI hard-failed with "Expected at least 60 commands, found 47" on every run. 40 leaves ~15% headroom under the v4 surface of 47. Rationale is now a comment in ci.yml so the next surface change does not repeat this. test_git_shim_correctness.sh — inverted, not deleted. It asserted each commands/git/*.md was a genuine thin shim; T3.5.2 then COMPLETED that migration by deleting all 11 shims, making the assertions unsatisfiable (7 FAIL on this branch, 21/21 on dev where the files still exist). The shim-drift it guarded is now structurally impossible, so it instead guards the migration's end state: 1. the 11 former shims stay deleted (nobody silently re-adds one) 2. skills/dev/git/SKILL.md still carries Operations 1-12 3. issue-check stays live + non-deprecated (the one sanctioned exception) 4. no unsanctioned command reappears under commands/git/ Verified by planted defect, not just a green run: resurrecting status.md -> caught; renaming Operation 5 -> caught; marking issue-check deprecated -> caught; clean baseline 25/25 before and after. ci.yml needs no change — the suite keeps its filename. Root blind spot both share: these are bash suites (ci.yml), and pytest does not run them. T3.5.2 cited "full pytest 2575 passed" as its evidence and shipped the breakage behind a green check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Data-Wise
added a commit
that referenced
this pull request
Jul 16, 2026
…nce closed .STATUS still claimed "Counts unchanged 95/45/8" and last_session 2026-07-15, while dev is at 47/40/2 after today's two merges — the project's own state record contradicting the repo by ~48 commands. Records: PR #290 (v4 folio split, merge-commit 4af10f2, craft 94->47), PR #291 (ci-bash-suites validator, squash 88b221d), 5034aef (2 stale docs/commands.md count claims), and the local branch-guard hook re-sync that cleared the last known test failure. The session recap keeps the reusable part rather than just the outcome: the three CI blockers had three unrelated causes (stale branch / stale plan number / real debt) and triaging them as one bucket would have produced three wrong fixes. Also records the evidence discipline that paid off — planted defects over green runs, reading the CI log rather than the badge, baselining before blaming, and treating a recommendation refuted mid-execution as refuted rather than authorized. Open items carried forward: Phase 4, tasks/todo.md's nonexistent plan-of-record path, docs/commands.md:10's "17 Categories" definition question, and 2 branch-guard false positives. R09 status-drift verified back to its pre-existing baseline: my first draft said "preserved for the v4.0.0 tag", which tripped Check B — .STATUS's milestone is ONE line containing "SHIPPED", so every vX.Y.Z token on it must resolve to a real git tag, and v4.0.0 is not cut yet. Reworded to "the eventual v4 release tag". The 2 remaining warnings (v2.61.1, v1.16.0) are pre-existing historical prose, confirmed by running the checker against HEAD's .STATUS in the real repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Data-Wise
added a commit
that referenced
this pull request
Jul 16, 2026
… positives (#292) * fix(guard): strip quoted spans + scope writes to PROJECT_ROOT branch-guard.sh's Bash write-through detection (Patterns 1-4) coarse-scanned the raw command string for shell metacharacters with plain grep, which has no notion of quoting. Three false positives fired live in one session, including during an audit of this exact bug class: awk 'NR>=203 && ...' -> '>' inside a single-quoted awk program read as a redirect grep -E '>[^=]' ... -> same, inside a grep pattern grep -n '...\"cp \|...' ... -> literal "cp " substring inside a quoted search pattern read as a cp invocation Same failure class Group 14c (2026-07-10) already fixed for heredoc bodies via HAS_HEREDOC; this generalizes it to any quoted span, not just heredoc bodies. COMMAND_SCAN strips quoted-span CONTENTS before the coarse `grep -q` presence checks; extraction (`grep -oE`) still runs against the ORIGINAL $COMMAND, so a real target quoted for spaces is unaffected. A fourth, unrelated bug fired alongside it: `cp <file> /tmp/...` was flagged as "creates a new code file on dev" even though /tmp is nowhere near the repo — only /dev/* was excluded. Added a PROJECT_ROOT prefix check on the resolved write target. PROJECT_ROOT is a realpath (`git rev-parse --show-toplevel`); $CWD often isn't (macOS's /tmp -> /private/tmp, and `mktemp -d` returns the /tmp form) — a naive literal-prefix compare broke 6 pre-existing in-repo-write tests during development. Fixed by canonicalizing the target's directory via `cd && pwd -P` (POSIX, avoids realpath/readlink -f, which aren't universally available) before comparing. Verified by planted defect AND by replaying the actual live false positives verbatim against the fixed hook (all resolve to exit=0), plus an isolated confirmation that a genuine redirect on a fresh dev-branch repo still returns exit=2 (blocked). New Group 22 (9 tests): 5 catch the false-positive class (including the 2 real historical commands), 4 are regression guards proving the fix doesn't weaken real detection (quoted target with spaces, cp inside the repo, a real touch alongside an unrelated quoted decoy). Full suite: 133/133 (was 124/133 mid-development, before the pwd -P fix). E2E: 30/30 (1 skipped, unrelated). Full pytest: 2601 passed / 1 failed (the 1 is the expected repo-vs-installed-hook divergence this branch itself causes, cleared by install-guards.sh — same pattern as PRs #290/#291). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(guard-audit): correct the skill's fictional config schema Discovered while running this skill to audit the false positives fixed in 7b51969. Step 5's documented config schema (nested "branches" object, "version": 2, allowed_extensions, pr_body_scan, force_push_allow, dev_allowed_extensions) is read ZERO times by scripts/branch-guard.sh — grepped for every one of those keys, all 0 matches. The real schema is a flat branch-name -> protection-level map, read via a single lookup, _json_get ".\"${BRANCH}\"" (branch-guard.sh:234). Following the skill's own instructions would have produced a config file the guard silently ignores. Also removed a fabricated "destructive git in PR body" rule (grepped the script for pr_body/PR body/--body: 0 matches — no such scanning exists) and replaced Step 4's fictional recommendations with the two real friction classes this session actually found: quoted-span misdetection and missing path scoping, neither fixable via any config key. Added a classification step (Step 4) splitting false positives into branch-policy (config-fixable) vs. detection-logic (requires a code PR to branch-guard.sh, not a config change) — the skill's "never modify branch-guard.sh" constraint was previously silent on what to do when the bug IS in branch-guard.sh; now it says so explicitly rather than implying a config workaround exists for everything. Verified: skill_standards_audit.py 100/100, markdownlint clean, description 400 chars (well under the 1536 cap). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * perf(guard): collapse COMMAND_SCAN to one sed invocation 7b51969's quote-stripping added printf | sed | sed (3 forks) to every Bash tool call on dev/main. dev's own dogfood perf budget (test_branch_guard_under_200ms) went from 207ms (pre-existing, already marginal on this machine — same class as the test_performance_cached_run xfail note re: unreliable wall-clock timing on shared runners) to 236ms. Collapsed to a single sed invocation (two -e expressions, here-string instead of printf|pipe) -> 3 forks to 1. Re-measured 0.80-0.90s per pytest invocation across 3 runs, consistently under budget. Full suite (133/133), E2E (30/30), and full pytest (2602 passed / 0 failed) all still green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(guard): correct cross-boundary quote-pairing regression in COMMAND_SCAN Adversarial review of PR #292's own Group 22 tests surfaced a real false negative the quote-stripping fix introduced: two independent sed passes (single-quote pass, then double-quote pass) let a single-quote-pair span across two unrelated double-quoted strings that each contain one apostrophe (e.g. "it's" ... "don't"), erasing a real redirect sitting between them from COMMAND_SCAN. Confirmed live: a genuine `> new_file.py` write-through on dev went completely undetected. Fix: combine both quote types into one alternation pattern (`'...'|"..."`) so quote-type resolves at the first quote character encountered and can never pair across a boundary of the other type. Verified via planted-defect replay: the new regression test fails against the reverted two-pass sed and passes against this fix; full suite 134/134. --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
The v4 folio-split train — Phases 3, 3.5, and 3.6 — landing as the single gated
operation the plan always intended ("branch holds — 3.5 rides the same train").
craft's docs-authoring surface is extracted to the standalone
folioplugin.Surface: 94 → 47 commands, 40 skills, 2 agents.
Phase 3.6 — router consolidations: 1 of 5 shipped
Opened with five router workstreams; four were dropped after reading the command
bodies in full, which the original grill had only line-counted:
plan:featurearchorchdrive-engine/workflow-enginecode:auditaudit-routerskillciRoot cause of the drops: the grill locked load-bearing decisions from line counts and
flag names. Every family that looked cohesive from surface metrics collapsed on a full
read. Rule recorded in the GRILL ledger for future consolidation phases.
Real defects found and fixed
category:metadata mismatches —ci/{fix,local}.mddeclaredcategory: code;orch/{drive,workflow}.mddeclaredcategory: orchestrateagainst a nonexistentdirectory. All flagged by
help_file_validator._check_category_mismatch(live-wired viadocs_update_orchestrator→/craft:docs:update). A repo-wide sweep found theorchpair, which was pre-existing on
dev. Repo-wide mismatches: 0.below the real surface. It went stale twice (86 → 60) while the count fell 94 → 70 → 47,
leaving the floor above the surface — CI hard-failed on every run. Rationale is now a
comment in
ci.yml.test_git_shim_correctness.sh— inverted, not deleted. It asserted eachcommands/git/*.mdwas a thin shim; T3.5.2 completed that migration by deleting all 11,making the assertions unsatisfiable (7 FAIL here, 21/21 on
dev). It now guards themigration's end state: shims stay deleted, Operations 1–12 survive in the skill,
issue-checkstays live, no unsanctioned command reappears./craft:git:issue-checkkept as a live commanddevshipped this (PR #283) into the surface this branch deleted. Git's directory-renamedetection auto-relocated it into
skills/dev/git/references/— which would have brokentests/test_issue_check_unit.py: that test hardcodescommands/git/issue-check.mdandexec()s theclassify_issue()block out of it, so the command file is the single sourceof truth for the classifier. Same structural constraint recorded for
commands/ci/triage.md(D13). Restored to
commands/git/; its 12 unit tests pass.SKILL.md's now-false claims("
commands/git/is now empty", "no explicit/craft:git:*path anymore") are correctedwith the reason.
Test evidence
Run in the worktree the PR ships from (
~/.git-worktrees/craft/feature-folio-split):The 1 remaining failure is local-environment-only:
test_branch_guard_dogfood.py::TestHookInstallation::test_repo_copy_matches_installedcompares the repo's
scripts/branch-guard.shagainst~/.claude/hooks/. This branchlegitimately changed the hook's message text (repointing
/craft:git:guard→ skill phrasingafter T3.5.2 removed that command), so the local machine's
dev-era installed hook differs.CI runs
install-guards.shatci.yml:151before the suites, syncing them. Proven, notassumed — re-running that class with an isolated
HOMEcontaining the branch's hook:6 passed, 1 skipped.All 4 CI-required bash suites green (
SKIP_PERF=1, as CI runs them):test_branch_guard.shwas red before the merge and needed no edit — it was stale-branchdrift.
devhad renamed the test to..._now_caught(expect 2) when PRs #287–#289 closedthat
git -Cgap; this branch carried the old..._not_caught(expect 0). The suite exercisesthe installed hook, so its result is machine-global state, not branch state — which is why
it passed on
devand failed here with identical code.Rewritten test verified by planted defect, not just a green run:
Other gates:
Merge notes (41 commits from dev, 34 conflicts)
~30 were count-cascade (
dev95/45/8 vs branch 46/40/2). Resolved to the post-split surface,then every tracked count recomputed mechanically via
bump-version.sh --counts-onlyrather than trusting hand-resolution. The guard-script conflicts that were expected in
no-switch-guard.sh/install-guards.sh/version-check.shdid not materialise —all auto-merged clean.
Judgment calls:
commands/docs/quickstart.md(modify/delete) → kept deleted; folio owns it (verified ondisk).
dev's only change was a count bump inside an example template.mkdocs.ymlnav → droppeddev's 7 deleted git entries, kept theissue-checkentry(a blind
--ourswould have dropped it from the site).entries, illustrative sample outputs, and spec/brainstorm records deliberately left at their
original numbers.
Known, deliberately not fixed
docs/commands.md:15("46 commands now support dry-run mode") and:205("46 commands fordocumentation generation…") are pre-existing errors, not off-by-one from this merge —
:205was already wrong before it, since the docs surface moved to folio. They need a realdocs pass, not a sed.
Root blind spot this PR closes
The two CI gates that were red are bash suites (
ci.yml:177–186) — pytest does not runthem. T3.5.2 cited "full pytest 2575 passed" as its verification evidence and shipped the
breakage behind a green check. Worth considering separately: a
/craft:checktier that runsboth.
🤖 Generated with Claude Code