Skip to content

build(contract): machine-readable decisions contract + zero-token plan-time surface#6154

Merged
shipyard-local[bot] merged 4 commits into
mainfrom
feature/decisions-contract
Jul 19, 2026
Merged

build(contract): machine-readable decisions contract + zero-token plan-time surface#6154
shipyard-local[bot] merged 4 commits into
mainfrom
feature/decisions-contract

Conversation

@shipyard-local

@shipyard-local shipyard-local Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Agents keep re-proposing settled build-system/CI/release config — the merge
queue was floated three times, bump-at-merge proposed and retracted twice,
auto-rebase and --adopt-head repeatedly suggested against scar tissue. Each
re-proposal burns a planning cycle and risks re-installing a fixed bug.

Ship the settled decisions as data plus a plan-time read surface so the next
agent sees them before touching fleet/CI config:

  • .agents/contract.toml: schema-versioned, layered (generic default layer any
    Shipyard+tartci+self-hosted repo inherits, plus a pulp overlay for warm-dir
    ODR, the Debug macOS lane, the CMakeLists VERSION-line collision, no paid
    runners). Public-safe: issue numbers, env-var names, and file paths only — no
    emails, chat topology, or private host names. Each guard is constrained to the
    declared fleet/CI config surface so the read surface can never fire on a
    non-config path.
  • tools/scripts/decisions_contract.py: the one agent-neutral checker both Claude
    and Codex call. validate (exit 0/2), surface (advisory, exit 0, prints only
    the rows a changed fleet/CI path triggers), list. Noninteractive, --json,
    stable exit codes, no Shipyard/gh/network.
  • hooks/scripts/decisions-contract-{hint,pointer}.sh: agent-neutral hook scripts
    resolving the repo root via git rev-parse (not CLAUDE_PLUGIN_ROOT), wired for
    Claude (hooks/hooks.json PostToolUse) and Codex (.codex/hooks.json
    SessionStart + PostToolUse). Defense-in-depth only — advisory, never blocking
    (Codex PreToolUse cannot hard-block); the boundary is the CLI validate gate +
    CI required checks. Clean no-op for external contributors: a change touching no
    guarded config path, or a checkout without the contract file, prints nothing
    and exits 0.
  • AGENTS.md + CLAUDE.md name .agents/contract.toml and the checker directly, so
    Codex (which reads AGENTS.md, not "read CLAUDE.md") gets the pointer too.
  • test/cmake/quality_tests.cmake: decisions-contract-validate (asserts the
    shipped file is always schema-valid) and decisions-contract-selftest.

test_decisions_contract.py asserts the file parses + is schema-valid, the
surface returns the expected rows for guarded paths and is a silent no-op for
non-fleet paths, a malformed contract fails validate with exit 2, the hint hook
is a clean no-op without a fleet path and surfaces via both TOOL_INPUT and stdin,
and both AGENTS.md and CLAUDE.md carry the pointer.


Summary by cubic

Adds a machine-readable decisions contract and an agent-neutral plan-time surface to stop re-proposals of settled build/CI/release config. Ships a single CLI, advisory hooks for Claude and Codex, CI tests, and clear doc pointers.

  • New Features
    • Layered .agents/contract.toml with guards limited to fleet/CI paths; content is public-safe.
    • tools/scripts/decisions_contract.py with validate/surface/list, --json, stable exits, no network; used by agents and CI.
    • Advisory hooks: decisions-contract-pointer.sh (SessionStart via .codex/hooks.json) and decisions-contract-hint.sh (PostToolUse via hooks/hooks.json and .codex/hooks.json). Resolve repo root via git; no-op if irrelevant.
    • CI/tests: decisions-contract-validate and decisions-contract-selftest (schema validity, surface no-op on non-fleet paths, hook behavior, docs pointers).
    • Docs: AGENTS.md and CLAUDE.md link to the contract and checker; source_tree_pollution_check allowlists .codex.

Written for commit 09bbdae. Summary will update on new commits.

Review in cubic


🔎 Provenance

Agent claude
Machine m3
Workspace SL
Tab Set up fleet project with Orchestrate in new workspace
Directory /Volumes/Workshop/Code/pulp-worktrees/bw-decisions-contract
Session e135c3c1-8355-4030-aa59-05f60adaf16c

Resume

claude --resume e135c3c1-8355-4030-aa59-05f60adaf16c

Jump to this tab

cmux surface focus E9FDEFE9-7FA3-491F-AB18-66AA81E3C2B5

Relaunch (any agent)

cmux surface resume get --surface E9FDEFE9-7FA3-491F-AB18-66AA81E3C2B5

Restore URLhttps://claude.ai/code/session_018qWM833UhHu4DFu5fXcFnF

stamped 2026-07-16 17:55 UTC

danielraffel and others added 2 commits July 16, 2026 09:30
…n-time surface

Agents keep re-proposing settled build-system/CI/release config — the merge
queue was floated three times, bump-at-merge proposed and retracted twice,
auto-rebase and --adopt-head repeatedly suggested against scar tissue. Each
re-proposal burns a planning cycle and risks re-installing a fixed bug.

Ship the settled decisions as data plus a plan-time read surface so the next
agent sees them before touching fleet/CI config:

- .agents/contract.toml: schema-versioned, layered (generic `default` layer any
  Shipyard+tartci+self-hosted repo inherits, plus a `pulp` overlay for warm-dir
  ODR, the Debug macOS lane, the CMakeLists VERSION-line collision, no paid
  runners). Public-safe: issue numbers, env-var names, and file paths only — no
  emails, chat topology, or private host names. Each guard is constrained to the
  declared fleet/CI config surface so the read surface can never fire on a
  non-config path.
- tools/scripts/decisions_contract.py: the one agent-neutral checker both Claude
  and Codex call. validate (exit 0/2), surface (advisory, exit 0, prints only
  the rows a changed fleet/CI path triggers), list. Noninteractive, --json,
  stable exit codes, no Shipyard/gh/network.
- hooks/scripts/decisions-contract-{hint,pointer}.sh: agent-neutral hook scripts
  resolving the repo root via `git rev-parse` (not CLAUDE_PLUGIN_ROOT), wired for
  Claude (hooks/hooks.json PostToolUse) and Codex (.codex/hooks.json
  SessionStart + PostToolUse). Defense-in-depth only — advisory, never blocking
  (Codex PreToolUse cannot hard-block); the boundary is the CLI validate gate +
  CI required checks. Clean no-op for external contributors: a change touching no
  guarded config path, or a checkout without the contract file, prints nothing
  and exits 0.
- AGENTS.md + CLAUDE.md name .agents/contract.toml and the checker directly, so
  Codex (which reads AGENTS.md, not "read CLAUDE.md") gets the pointer too.
- test/cmake/quality_tests.cmake: decisions-contract-validate (asserts the
  shipped file is always schema-valid) and decisions-contract-selftest.

test_decisions_contract.py asserts the file parses + is schema-valid, the
surface returns the expected rows for guarded paths and is a silent no-op for
non-fleet paths, a malformed contract fails validate with exit 2, the hint hook
is a clean no-op without a fleet path and surfaces via both TOOL_INPUT and stdin,
and both AGENTS.md and CLAUDE.md carry the pointer.
@github-actions

Copy link
Copy Markdown

Diff coverage (required)

Diff coverage threshold: 75% (required).
This percentage applies only to the coverage surfaces currently represented on Codecov; see docs/guides/coverage.md for the current perimeter.

diff-cover report

Diff: origin/main...HEAD, staged and unstaged changes

No lines with coverage information in this diff.

See coverage.md for the current represented surface, how to interpret this number, and the full Phase 1 → Phase 3 roadmap.

Per-tier diff coverage (#566 Phase 2)

Tier Target Diff coverage Touched lines Result
audio-critical 80% — (no touched lines) 0
user-facing 70% — (no touched lines) 0
infrastructure 50% — (no touched lines) 0

All touched tiers meet their per-tier floors.

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

# Conflicts:
#	.claude-plugin/marketplace.json
#	.claude-plugin/plugin.json
#	test/cmake/quality_tests.cmake
@shipyard-local
shipyard-local Bot added this pull request to the merge queue Jul 19, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 19, 2026
@shipyard-local
shipyard-local Bot added this pull request to the merge queue Jul 19, 2026
Merged via the queue into main with commit 14865e2 Jul 19, 2026
24 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant