Skip to content

fix(contracts): resolve contract paths under docs/contracts - #10942

Merged
kyle-sexton merged 2 commits into
mainfrom
docs/7537-a-readers
Oct 29, 2026
Merged

kyle-sexton merged 2 commits into
mainfrom
docs/7537-a-readers

Conversation

@kyle-sexton

Copy link
Copy Markdown
Member

Refs: #7537

Summary

Part A of the #7537 split. #10719 failed pr-verify on size: leaving a stub at each old path keeps git from pairing the renames, so the 3.5 MB diff could not be read in full. This PR holds only the executable changes. Each reader that finds a contract file now resolves docs/contracts/<name>/ first and falls back to docs/conventions/<name>/, so it works on today's main, where every contract is still under docs/conventions/, and after the move.

Landing order: A (this PR), B1 (pure git mv of the contract folders), B2 right after B1 (the old-path stubs), then the per-plugin reference rewrites. Only the last carries Closes #7537.

Fix

  • Changelog fragments: scripts/lib/changelog-fragments.sh gains root_of and convention_of. The check, parity, new, release and write scripts and their tests resolve either home, and each convention case runs under both.
  • babysit_review_evidence.py: LANE_SOURCE_PREFIXES lists both homes for the two lane-source contracts, so an edit to the stub or to the moved file still counts as a change to the PR's own review input. Its test covers both.
  • The same contracts-first-then-conventions lookup that main already uses (b86bebd, fix(contracts): read contracts from docs/contracts with a docs/conventions fallback #10593) is added to:
    • lib/hook-test-sink.sh, its three plugin copies and its test
    • lib/prerequisites.test.mjs
    • scripts/check-standards-contract-bump.sh and its test
    • scripts/check-detector-findings-crosswalk.sh
    • scripts/sync-config-cascade-semantics.py and its test
    • scripts/affected-tests-live.sh
    • plugins/discovery/scripts/contract.test.sh
    • scripts/affected-tests.test.sh
  • docs/contracts/ecosystem-commands/examples.test.sh: the suite for the moved example YAMLs, with the both-home lookup.

Verification

  • New tests cover the main-only layout. The standards-bump suite runs every case under both homes (28 pass). hook-test-sink.test.sh resolves the default schema from a fixture that has only docs/conventions, and from a docs/contracts fixture with a stub at the old path. The second case fails on main's code.
  • scripts/check-affected.sh --tests --jobs 6 on this branch: no content failures. Its one red item, the tests step, is scripts/post-merge-demotion-alert.test.sh running 32-48 s against a 30 s share on the dev host. This PR does not touch that file, which alone takes 37 s (173 pass).
  • A union check (all split branches merged, diffed against docs(contracts): move plugin-author contracts out of docs/conventions #10719's tree) differs only in these deliberate fallbacks and in per-branch .changes fragments.

Related

🤖 Generated with Claude Code

kyle-sexton and others added 2 commits October 28, 2026 21:32
…conventions

Prepares the plugin-contracts move (#7537): every reader that finds a
contract file by path now resolves it under docs/contracts/<name>/ first
and docs/conventions/<name>/ second, so the code works on today's tree and
after the move, when the old paths hold only stubs.

- The changelog fragment library classifies a listed convention under
  either home (root_of, convention_of); the check, parity, write, new and
  release scripts use it, and their suites run each convention case under
  both homes.
- babysit-prs lists the docs/contracts/ lane-source prefixes beside the
  docs/conventions/ ones.
- check-standards-contract-bump.sh, check-detector-findings-crosswalk.sh,
  sync-config-cascade-semantics.py and the shared hook-test-sink.sh helper
  (with its three plugin copies) take the new home when it exists. The
  standards gate's suite runs under both homes; hook-test-sink's suite
  resolves its default schema from a docs/conventions-only fixture and
  from a docs/contracts fixture with a stub at the old path.
- Suites that read a live contract (prerequisites, config-cascade
  semantics, discovery's contract suite, the live affected-tests check)
  resolve it the same way.
- docs/contracts/ecosystem-commands/examples.test.sh validates the four
  examples against their schema, read from whichever home holds them, so
  the moved examples map to a suite.

Refs: #7537

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 29, 2026 12:32
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T12:34:25.029262Z 06c6b88 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 06c6b88e01e442df39e5e7362e0490a69a7faae8: 0 finding(s), 0 as inline comments.

No security issues found in PR #10942, which makes contract-path readers look under docs/contracts/ first and then docs/conventions/.

critical-findings: 0

Trusted path read: plugins/source-control/skills/babysit-prs/scripts/babysit_review_evidence.py.

  • The change only adds four prefixes to LANE_SOURCE_PREFIXES: the docs/contracts/ versions of instruction-exception-register/ and untrusted-content/.
  • The existing docs/conventions/ prefixes stay.
  • More paths now count as changing the pull request's own review input, so the control gets stricter. It does not weaken a merge hold, and it widens neither the trusted actors nor any token.
  • The matching test adds both new paths as cases.

Other changes:

  • The shell, Python and test edits are path-resolution fallbacks: hook-test-sink.sh and its three plugin copies, changelog-fragments.sh (root_of and convention_of), the changelog check, parity, new and release scripts, check-standards-contract-bump.sh, sync-config-cascade-semantics.py, the crosswalk checker and the test files.
  • The path pattern matching and name extraction in these use fixed docs/contracts/*/* and docs/conventions/*/* globs. Attacker-controlled path text does not reach eval or a command.
  • convention_of checks that root_of agrees with the path's home, so an old-home stub does not get a fragment for a name that resolves to the new home.
  • The hook-test-sink.sh and envelope-schema changes affect tests only.
  • The .changes fragments are changelog text.
  • There are no plugin manifest changes, no workflow changes, and no userConfig or hook changes.
  • No instruction-surface rules were deleted.

The PR context file was read as data and contains no embedded directives.

Spend: none; the diff changes no spend-related setting.

@github-actions

Copy link
Copy Markdown
Contributor

claude-review reviewed 06c6b88e01e442df39e5e7362e0490a69a7faae8: 0 finding(s), 0 as inline comments.

No findings. I read the full 35-file diff (.claude-lane/pr.diff) and the PR context. I had no shell, so I ran nothing. Every passing-test claim in the PR body is the author's and unverified by me.

What I checked

  • Fallback lookups (hook-test-sink.sh and its three plugin copies, check-standards-contract-bump.sh, check-detector-findings-crosswalk.sh, sync-config-cascade-semantics.py, affected-tests-live.sh, contract.test.sh, prerequisites.test.mjs): each prefers docs/contracts/ and falls back to docs/conventions/ only when the new file is absent. That works on today's main, and it works after the move even with a stub left at the old path. In lib/prerequisites.test.mjs, existsSync is already imported.
  • changelog_fragments::root_of and convention_of: root_of prefers a plugin, then docs/contracts/, then docs/conventions/. convention_of returns the name only when the path sits under that name's root. A stub left at the old home or a name a plugin owns therefore resolves to nothing, and the new unit tests cover both.
  • Callers: the check-changelog-fragments.sh and check-changelog-parity.sh rewrites keep the previous behaviour. Both --check-order globs are guarded by [[ -f ]] || continue.
  • write-changelog-fragments.sh: home is derived correctly for realistic names. The only mis-derivation is a convention literally named contracts or conventions, which is not realistic, so I did not flag it.
  • Trusted path babysit_review_evidence.py: LANE_SOURCE_PREFIXES only gains the two docs/contracts/ prefixes beside the existing docs/conventions/ ones. Nothing is dropped, so an edit to either home still marks the PR's own review input as changed. The test covers both paths. This is a strict widening of the gate, and I found no security concern.
  • Changelog fragments: bump: patch for autonomy, context-guard, desktop-notification and source-control, which ship the helper and script changes. bump: none for discovery, which is test-only. All fit the change. No plugin.json or marketplace.json is touched, so there are no manifest lines.
  • Closing issue: the PR is Refs: #7537 and does not close it, so there are no acceptance criteria to check.

Not a finding in this PR
scripts/shared-copies.txt and scripts/cross-plugin-source-registry.txt still name docs/conventions/standards/README.md as the sync source. That is correct for this PR's "works on today's main" scope. The B1 move PR has to update them. Otherwise affected-tests-live.sh, which now resolves docs/contracts/standards/README.md once it exists, would no longer match the manifest's src row.

Spend: none. This is no cost or critical-security hold.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant