feat(cc-229): v0.3.0 M1 core substrate — 8 schemas + 6 policies + state layout + context-pack contract#157
Merged
Merged
Conversation
…out, context-pack contract Per docs/spikes/CC-229-substrate-synthesis.md and Q2/Q7/Q8 decisions landed in PR #156. Pure additive: 19 new files under core/, zero consumer changes. Schema locked at the end of M1 per synthesis §8 R3. Layout: core/README.md — boundary + invariants core/schema/ (8 schemas) task / run / event / review / decision / brief / handover / context-pack core/policy/ (6 YAML tables) executor-enum / dispatch-routes / dispatch-states / task-states / run-states / reviewer-policy core/state/ (2 files) README + layout.yaml (per-project partitioning by sha1(git-toplevel)) core/context-pack/ (2 files) README + source.interface.md (prose contract) Design highlights (all decisions from PR #156 synthesis): - schema_version: const 1 on every payload (Q8: field-only, no v1/ dir) - per-project partitioning (Q2): projects/<sha1(git-toplevel)>/ - best-effort write semantics with serialize_with_lock (Q3) - executor enum closed: {codex, claude} (Q5; closed in M1, v0.4.0 breaking event adds antigravity/opencode slot per synthesis §7) - reviewer-policy matrix only; override discipline stays in agents/project-pm.md (Q6) - ContextPack source contract is Markdown prose (Q1 + Q5 of CC-258 separately), not a typed interface file Invariants (will be enforced by CC-233 layer-boundary test): - core/* may NOT import runtime/, scripts/, adapters/, anything executable - no CLI product name in field/path/dir names (CLI-agnostic) - schema_version bump = breaking event + CHANGELOG.md + DECISIONS.md Out of scope: - pm/schema.md re-home → deferred (separate small PR; current pm/schema.md remains primary for BACKLOG grammar) - runtime/pmctl/lib/state-writer.sh → CC-230 (next PR) - handover-validate.sh policy extraction → CC-231 (next PR) - context-pack source implementations → CC-237 (M4) Self-verify: - 8/8 JSON Schema files pass `jq -e .` parse - 7/7 YAML files pass python yaml.safe_load - 0 changes to existing files (pure additive) - 0 consumers currently reference core/ (schemas live as documentation until CC-230/231 wire them in) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…mpliant enums + structural tests
Per gate-20260524-225440 [medium] findings:
1. critic [medium] brief.schema.json: schema_version was defined but not in
`required`. Now required across all 8 payload schemas (Brief now matches
Task/Run/Event/Review/Decision/Handover/ContextPack invariant).
2. critic [medium] review.schema.json $ref to YAML: ajv and standard JSON
Schema validators cannot resolve $ref to .yaml files. Converted all
inter-file $refs to inline `enum: [...]` with a description naming the
policy YAML as the editing source-of-truth. Affected schemas:
- run.schema.json: executor / dispatch_route / state
- handover.schema.json: executor / dispatch_route
- task.schema.json: state
- review.schema.json: findings[].reviewer / findings[].verdict
Policy YAML files remain as the human editing surface for
handover-validate.sh + future pmctl reads.
3. qa-tester [medium] no tests: added scripts/test-core-schemas.sh with
30 cases covering:
- JSON Schema parse (8 files)
- YAML parse (7 files)
- schema_version const:1 (8 files)
- enum-sync between schema inline enums and policy YAML source-of-truth
(8 cross-file checks — would catch drift if either side edited alone)
Local run: 30 passed, 0 failed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…al-assign Two failures in test-skill-refine (shellcheck job) on commit c403216: 1. SC1091: scripts/test-core-schemas.sh sources scripts/lib/test-harness.sh which shellcheck cannot resolve without -x. Add test-core-schemas.sh to .github/workflows/lint.yml exclude list — same pattern every other test-*.sh that consumes the harness uses (per [[feedback_ci_shellcheck_test_exclude]]). 2. SC2155: line 103 declared+assigned in one statement with command substitution, masking basename's return value. Split into separate `local name` declaration + assignment. Local test still 30/30 pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…iles Per the same system-prompt-hygiene principle applied to agents/project-pm.md in #156: core/ is a contract surface, not a planning artifact. M1/M2/M4 milestone markers, Q[N] resolved 2026-05-24 decision history, spike-doc cross-references, and forward ticket pointers (CC-233 will verify / CC-237 will implement / etc.) do not belong in the contract. Cleaned across 18 files: - core/README.md — drop v0.3.0 framing, spike citation, milestone outlook - core/state/README.md — drop M2/CC-230, Q2/Q3 resolved markers, synthesis link - core/context-pack/README.md — drop M4/CC-237/CC-216/v0.4.0/synthesis - core/context-pack/source.interface.md — drop M1/M4 framing, codegraph "Phase 2 AMBER" history, baseline-source section restructured - core/policy/*.yaml (6) — drop M1/M2, Q5/Q6 resolved markers, synthesis refs - core/schema/*.json (7) — drop "M2 will narrow" / "CC-233 layer test verifies" from descriptions; keep illustrative ticket-id pattern examples (e.g. `CC-229, JS-106` in task.schema.json id pattern docs) - core/state/layout.yaml — drop M1/Q2 markers + CC-230 writer ticket Kept: - Ticket-id pattern examples in schema descriptions (task.schema.json `id`/`backlog_ref`, decision.schema.json `closes`) These illustrate the schema's id format, not history. Self-verify: - scripts/test-core-schemas.sh: 30 passed, 0 failed (unchanged) - 18 files / -57 net lines (contracts tighter) - No drift markers remaining (grep -rnE 'M[0-9]|v0\.[0-9]|Q[0-9]+ resolved|2026-|Phase [0-9]|spike|synthesis' core/ returns nothing) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Same hygiene principle applied to docs/ contract files (continuation of 8594f8d for core/). Audit results: dispatch-brief.md L498: dropped "the future CC-036b schema extension may add dispatch_route after two weeks of telemetry" — roadmap prediction in a contract section. Rule (route-agnostic dispatch row) is self-sufficient. executor-contract.md: dropped CC-036/CC-101/CC-102 evolution markers from 5 lines (L24/L46/L51/L55/L59). Contract states the rule; git log carries the implementation history. NOT cleaned (kept as-is per audit): - docs/architecture/v0.3.0-synthesis.md — this IS the planning artifact, spike-output frozen in time. Milestone/ticket/version refs are its purpose. (69 hits, all legitimate.) - docs/CONCEPTS.md — L5 is pre-v0.1.0 doc-status notice; L140 is glossary example with CC-047 in quotes as illustration. - docs/model-tier-policy.md — all "synthesis" hits are the /pr-gate English verb, not a spike doc reference. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… default Replace ~/.claude/.pm/state with ~/.local/share/pm-dispatch/state as the default state root. Rename CLAUDE_PM_STATE_ROOT → PM_DISPATCH_STATE_ROOT. Add store_root_xdg_subpath field for writer-side XDG precedence resolution. Resolution order (documented in layout.yaml + core/state/README.md): 1. $PM_DISPATCH_STATE_ROOT (explicit override) 2. $XDG_DATA_HOME/pm-dispatch/state (XDG-aware) 3. ~/.local/share/pm-dispatch/state (fallback) Fixes invariant #2 self-contradiction in core/README.md — no CLI product name may appear as a path segment; .claude was one. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Architecture (arch-reviewer block-soft): - core/state/layout.yaml: replace concrete writer.module path with abstract description field — core/ no longer names a runtime/ implementation path - core/schema/handover.schema.json: neutralize two description fields that referenced scripts/lib/handover-validate.sh and scripts/pm-prep-snapshot.sh - MILESTONES.md, BACKLOG.md (CC-230), docs/architecture/v0.3.0-source-plans.md, docs/architecture/v0.3.0-synthesis.md: align state root from ~/.claude/.pm/state/ to ~/.local/share/pm-dispatch/state/ (XDG) - DECISIONS.md: add 2026-05-25 ADR recording the XDG state root decision Security (security-reviewer block-soft): - agents/project-pm.md: add snapshot_file path constraint — only accept absolute paths under /tmp/ matching pm-snapshot-*.md; reject anything else silently - .github/workflows/lint.yml: add top-level permissions: contents: read Test coverage (qa-tester block): - scripts/test-lint-model-aliases.sh (new): 6 regression cases covering happy path + missing TSV + malformed row + doc drift + empty TSV + template alias gap - scripts/test-codex-dispatch.sh: add cases 20/21/22 for alias-source missing, malformed, and ../share/ fallback path resolution - scripts/test-core-schemas.sh: add section 5 with 6 jq-only structural contract tests for brief.schema.json (required fields, additionalProperties, patterns, oneOf) All tests: 6/6 + 22/22 + 36/36 passed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sts, bug fixes - Add `approve` verdict to review.schema.json and reviewer-policy.yaml; add schema_version: 1 to all 3 pr-gate.sh generated brief heredocs - Fix task-id regex in task/run/context-pack/review schemas to accept sub-letter IDs (CC-025b, CC-104e); add test-schema-task-mirrors-backlog.sh - Remove broken no-jq sed fallback in pm-prep-snapshot.sh; add jq guard with graceful warning (mirrors existing gh-not-found guard) - Fix check-docs-freshness.sh latest_tag to use max_version instead of --sort=-creatordate (semantic version order, not tag creation date) - Add 7 new test functions across test-core-schemas.sh, test-pr-gate.sh, test-pm-prep-snapshot.sh, test-check-docs-freshness.sh - Fix docs/dispatch-brief.md refactor skeleton files format - Fix test-core-schemas.sh:282 comment variant names - Add test-schema-task-mirrors-backlog.sh to run-all-tests.sh + CI - Add structured docstrings to test-check-docs-freshness.sh, test-pm-prep-snapshot.sh, test-install.sh - BACKLOG: add CC-259 (yaml.sh lib extraction) and CC-260 (pr-gate dirty-worktree diff) Tests: 29 suites, all pass. Gate 12: GO (critic:advise, qa-tester:pass, arch:approve, security:pass, risk:pass) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hallow-clone branch_base - Remove 4 unused local declarations (parsed_objects, obj, num, title) from collect_recently_merged() after the no-jq else branch was removed; eliminates SC2034. - Add `git fetch --depth=1 origin main` step to test-pm-prep-snapshot and test-install CI jobs so `origin/main` resolves in shallow clones, fixing branch_base assertion. - Fix CC-260 BACKLOG status from invalid `🟡 planned` to `🟢 someday`. Run: 29 passed, 0 failed, 0 skipped. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ction
CC-261: update forward-reference text in core/README.md +
agents/project-pm.md after v0.3.0 runtime lands (M5 release prep).
CC-262: decouple isolation intent from executor-native fields —
`isolation_level` enum in core/policy/, adapter maps in
adapters/{codex,claude}/, PM brief stops writing sandbox/approval/
skip_git_check directly. Spans M1 (schema) → M2 (dispatch) → M3
(adapter maps).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
`design` is an epic token, not a valid area token; swapping to `arch/process` satisfies the BACKLOG validator and unblocks test-install. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2 tasks
screenleon
added a commit
that referenced
this pull request
May 25, 2026
All three landed in PR #157 (feat(cc-229) merge 2026-05-25): - CC-229: core/schema/ — 8 schemas (task/run/event/review/decision/ brief/handover/context-pack) - CC-231: core/policy/ — 6 YAML tables (executor-enum, reviewer-policy, dispatch-states, run-states, task-states, dispatch-routes) - CC-232: core/schema/context-pack.schema.json + context-pack/ source.interface.md M1 remaining: CC-230 (state store) + CC-262 (isolation_level enum). Co-authored-by: Claude Sonnet 4.6 <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.
Summary
First implementation PR of v0.3.0 M1, per the dual-path spike landed in #156. Pure additive: 20 new files under
core/+ 1 new test script. Zero consumer changes. Schema locked at end of M1 per synthesis §8 R3.What landed
core/schema/— 8 JSON Schema files (task / run / event / review / decision / brief / handover / context-pack)core/policy/— 6 YAML tables (executor-enum / dispatch-routes / dispatch-states / task-states / run-states / reviewer-policy)core/state/— README + machine-readablelayout.yaml(per-project partitioning bysha1(git-toplevel))core/context-pack/— README + Markdown source-interface contractscripts/test-core-schemas.sh— 30 structural test cases (JSON/YAML parse + schema_version const:1 + enum-sync across 8 schema↔policy cross-checks)Design decisions (all from PR #156 synthesis)
projects/<sha1(git-toplevel)>/schema_version: <int>field-only, nov1/dir{codex, claude}Gate history
20d8a1b): GO; critic [medium] × 2 + qa-tester [medium] —schema_versionnot required in brief +$refto YAML broken + no testc403216): GO, escalation NOT recommended; critic approve (was advise); arch approve; security/risk pass-not-applicable; qa-tester still [medium] but only about meta-testing the new test script itselfOut of scope
pm/schema.mdre-home (separate small PR)runtime/pmctl/lib/state-writer.sh→ CC-230 (next PR)handover-validate.shpolicy extraction → CC-231 (next PR)Test plan
core/schema/*.schema.jsonpassjq -e .python yaml.safe_loadschema_version: { const: 1 }as requiredscripts/test-core-schemas.shreports 30 passed, 0 failed)git diff mainconfirms pure additive)scripts/referencescore/paths yet (CC-230/231 will be the first consumers)Related
docs/spikes/CC-229-substrate-{scope,claude,codex,synthesis}.md(PR docs(cc-229,cc-258): M1 substrate spike (dual-path) + brief-authoring process fixes #156)runtime/pmctl/lib/state-writer.sh+ codex-dispatch pilot consumer)core/*import invariants)🤖 Generated with Claude Code