Skip to content

Blind both layer-verdict lanes for the 2026-09-23 re-record - #141

Merged
seathatflowsinourveins merged 5 commits into
mainfrom
claude/blind-codex-lane-20260923
Sep 23, 2026
Merged

seathatflowsinourveins merged 5 commits into
mainfrom
claude/blind-codex-lane-20260923

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Owner

Summary

This PR prepares the 2026-09-23 cross-family re-record, where both lanes must judge on the retained evidence alone. The 20260922 Codex lane events show why: one layer's child ran 3 native web searches and 1 MCP tool call, and read a file outside the repository.

Codex lane (tools/sota-convergence/codex_lane.py)

Denied by configuration. Every codex exec now runs with --ignore-user-config -c features.hooks=false -c features.plugin_hooks=false -c web_search="disabled". Measured with codex-cli 0.155.1:

  • MCP servers (RUST_LOG=info, run from the agent-lab checkout): a default run initialized seven MCP servers (ai-memory, SocratiCode, jCodeMunch, Serena, context-mode, plugin-runtime and OpenAI Developers MCP). With these flags only plugin-runtime and OpenAI Developers MCP initialized, and native auth still worked.
  • Web search: without the web_search pin, a probe child ran a web search. With it, the child reported no web search tool.
  • Rejected alternative: per-server mcp_servers.<name>.enabled=false overrides failed with "invalid transport".

Git history. The run is refused when --repo or any parent has .git, since git walks up. --allow-git-history exists for use outside a blind wave.

Blind audit. A report-only codex/blind-audit.json covers every child. It counts web searches and MCP calls, and flags commands that do any of the following:

  • name absolute paths outside the repository and packets;
  • use ~ or $HOME paths;
  • climb out with .. or name a bare /;
  • run git, ai-memory, agentsview, mcporter, qmd, socraticode, jcodemunch, serena, sqlite3, curl or wget.

Stated as limits (not denied by configuration):

  • shell reads under --sandbox read-only;
  • $CODEX_HOME/AGENTS.md, which a probe child still quoted.

Rule 1 of lane-prompt.md now forbids memory stores, code indexes, MCP tools, web search, git history and other checkouts. It stays five rules, because lane_packets.py embeds them in the packets.

Blind checkout (blind_checkout.py --export DIR)

--export copies the stripped tree without .git or BLIND-MANIFEST.json. The worktree's .git recovers every stripped value with git show, and the old git archive advice would export the committed tree before stripping. The README now hands the lanes the export.

Claude lane (vendored from agent-lab #36, aacd937)

  • Refuters and re-checks now run as semantic-evidence-reviewer (Read, Glob, Grep). Previously they ran as evidence-reviewer, whose ai-memory, SocratiCode, jCodeMunch and Serena tools can return the incumbent verdicts.
  • Every prompt adds a blind rule.
  • The vendored bytes are 0d66c9a1. SHA256SUMS, vendored-lanes.json and two lane-provenance.json entries are updated. The Codex entry is appended for the new codex_lane.py and lane-prompt.md hashes.
  • The Claude lane has no path audit in these tools. The re-record's coordinator audits its agent transcripts.

Review

An independent Opus evidence review ran three rounds:

  1. fix_required: 2 major, 4 minor.
  2. fix_required: 1 major (the audit missed ~, $HOME, .. and sqlite3 paths), 2 minor.
  3. accept, with 2 minors. The bare / minor is fixed here. ~ false positives such as HEAD~1 are accepted as noise in a report-only audit.

Checks (local, this head after rebase on 9e643b1)

  • The lane tests (test_verdict_lane_vendoring, test_codex_lane, test_blind_checkout, test_lane_packets, test_record_verdicts, test_claude_lane and test_layer_verdicts): 253 tests OK.
  • The new tests fail on the previous code.
  • validate.py, evidence_manifest.py --check, landscape.py, build_verdicts.py --check, validate_convergence.py --all-recorded and the workflow SHA256SUMS: all pass.
  • Full python3 -m unittest at d10a41ad: 3233 tests. The only failures are the 32 stop_blocks_entry tests in test_adaptive_paper_*, which read the live host paper STOP hold. They pass with HOME set to a temp dir, and the paper lane is fixing their isolation.
  • Guarded gitleaks on origin/main..HEAD: no leaks.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…r it

The layer-verdict lane now runs its refuters as the Read/Glob/Grep-only
semantic-evidence-reviewer and adds a blind rule to every prompt
(agent-lab #36). The vendored bytes, SHA256SUMS, vendored-lanes.json and
two lane-provenance entries name the new hash 0d66c9a1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…audit

- codex_lane.py pins native web search off (web_search="disabled"; an
  unpinned probe child ran a web search), refuses a --repo with .git unless
  --allow-git-history, and writes a report-only codex/blind-audit.json of
  web searches, MCP calls and commands reaching outside the repository and
  packets or running git/memory/index CLIs. The comment and README name
  what configuration denies and what still rests on the prompt.
- blind_checkout.py --export copies the stripped tree without .git or
  BLIND-MANIFEST.json for the lanes; the README drops the git archive
  advice, which would export the unstripped committed tree.
- lane-prompt.md keeps five rules (lane_packets.py embeds them); the blind
  boundary is a sentence in rule 1.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…repos under any .git

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@seathatflowsinourveins
seathatflowsinourveins enabled auto-merge (squash) September 23, 2026 18:48
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 23, 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-09-23T19:02:34.200606Z 2123f8e PR opened
ℹ️ 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.

@seathatflowsinourveins
seathatflowsinourveins merged commit 2013d27 into main Sep 23, 2026
21 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/blind-codex-lane-20260923 branch September 23, 2026 18:51

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2123f8e096

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

stripped value, and the manifest is the operator's audit trail. Lanes are given this copy."""
if export.exists():
raise SystemExit(f"--export {export} already exists")
shutil.copytree(dest, export, symlinks=True, ignore=shutil.ignore_patterns(".git", "BLIND-MANIFEST.json"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove verdict-bearing instructions from the blind export

The export copies AGENTS.md and CLAUDE.md unchanged, so a Codex child started with -C <export> automatically receives repository instructions that disclose the incumbent choices before it reads the stripped packet—for example, the root instructions explicitly name NautilusTrader as the selected destination. This defeats the new blind lane for affected US-equities layers even though .git and the manifest are absent; sanitize or replace the project instruction files in the exported tree.

AGENTS.md reference: AGENTS.md:L70-L80

Useful? React with 👍 / 👎.

const refute = async (p, subject, round) => {
const got = await parallel(LENSES.map((lens) => () =>
agent(lensPrompt(p, subject, lens), { label: (round === 'revision' ? 'refute:recheck:' : 'refute:') + `${lens}:${p.catalog}/${p.layer_id}`, phase: round === 'revision' ? 'Re-check' : 'Refute', agentType: 'evidence-reviewer', model: 'opus', effort: 'high', schema: VOTE }).catch(() => null)))
agent(lensPrompt(p, subject, lens), { label: (round === 'revision' ? 'refute:recheck:' : 'refute:') + `${lens}:${p.catalog}/${p.layer_id}`, phase: round === 'revision' ? 'Re-check' : 'Refute', agentType: 'semantic-evidence-reviewer', model: 'opus', effort: 'high', schema: VOTE }).catch(() => null)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update the workflow routing contract for the refuter role

Changing the refuters to semantic-evidence-reviewer leaves the portable workflow contract stale: examples/claude-native/workflows/test-envelope.mjs:365 still requires every refute: call to use evidence-reviewer. Running node examples/claude-native/workflows/test-envelope.mjs now exits 1 with FAIL contract: workflows/layer-verdict-lane.js routes each stage to its reviewed agent, model and effort, so the native workflow validation cannot pass until that routing expectation and its associated checksums are updated.

Useful? React with 👍 / 👎.

Comment on lines +459 to +465
git_dirs = [str(path) for path in (repo, *repo.parents) if (path / ".git").exists()]
if git_dirs and not args.allow_git_history:
# git walks up from a subdirectory, so an export inside any repository still reaches history.
print(f"codex_lane: {git_dirs[0]} has .git, whose history a child can read from {repo}; run the lane on a "
"blind_checkout.py --export copy placed outside every repository, or pass --allow-git-history "
"outside a blind wave", file=sys.stderr)
return 2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep the documented checkout workflow executable

When the lane is run from a normal checkout, this new guard returns 2 before either a model invocation or --dry-run. The repository's maintained recipe at recipes/sota-convergence-practice.md:81 and all three examples at tools/sota-convergence/README.md:1179-1184 still invoke --repo . without creating an export or passing --allow-git-history, so following the documented workflow now fails immediately. Update those entry points to create/use the blind export, or explicitly opt the non-blind recipe into history.

Useful? React with 👍 / 👎.

Comment on lines +1148 to +1149
-c model_reasoning_effort=<effort> \
--ignore-user-config -c features.hooks=false -c features.plugin_hooks=false <filled prompt>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include the web-search override in the documented command

This block is introduced as the command the runner executes, but it omits the new -c web_search="disabled" argument from ISOLATION_ARGS. Anyone reproducing or debugging the invocation from this command runs with native web search available, contradicting the blind-run invariant described immediately below and potentially contaminating the verdict.

Useful? React with 👍 / 👎.

Comment on lines +510 to +511
cmd = build_command(repo, strict_schema_path.resolve(), tmp_out, args.effort, prompt_text, args.model,
ISOLATION_ARGS)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Invalidate cached returns when lane provenance changes

These new isolation arguments and the prompt edit change the runner-owned provenance hashes, but existing_output_is_valid() still skips any matching lane/catalog/layer/packet return without checking its provenance. Reusing a work directory from the previous lane therefore skips every old Codex result, after which record_verdicts.py rejects those results because their hashes do not match the current runner; subsequent runs keep skipping the same rejected files, so the re-record cannot recover without manual deletion. Include the current runner/prompt hashes in the resumable-skip check.

AGENTS.md reference: AGENTS.md:L17-L20

Useful? React with 👍 / 👎.

Comment on lines +282 to +285
reasons = [f"path outside the repository and packets: {path}"
for path in ABSOLUTE_PATH.findall(command)
if not path.startswith(SYSTEM_PREFIXES)
and not any(path == root or path.startswith(root.rstrip("/") + "/") for root in allowed_roots)]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Audit data paths under system executable prefixes

Exempting every path beginning with /usr/ or /bin/ suppresses more than the shell executable: a command such as /bin/cat /usr/local/share/prior-verdict.json produces no flag at all, even though the data file is outside both allowed roots. This contradicts the report's stated absolute-path coverage and can hide reads from another checkout or retained artifact installed under /usr/local; exempt only recognized executable tokens rather than every argument under these directory prefixes.

Useful? React with 👍 / 👎.

const refute = async (p, subject, round) => {
const got = await parallel(LENSES.map((lens) => () =>
agent(lensPrompt(p, subject, lens), { label: (round === 'revision' ? 'refute:recheck:' : 'refute:') + `${lens}:${p.catalog}/${p.layer_id}`, phase: round === 'revision' ? 'Re-check' : 'Refute', agentType: 'evidence-reviewer', model: 'opus', effort: 'high', schema: VOTE }).catch(() => null)))
agent(lensPrompt(p, subject, lens), { label: (round === 'revision' ? 'refute:recheck:' : 'refute:') + `${lens}:${p.catalog}/${p.layer_id}`, phase: round === 'revision' ? 'Re-check' : 'Refute', agentType: 'semantic-evidence-reviewer', model: 'opus', effort: 'high', schema: VOTE }).catch(() => null)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use a candidate-neutral role for the blind Claude refuters

The newly selected semantic-evidence-reviewer is not a neutral Read/Glob/Grep-only context: its project definition at examples/claude-native/agents/semantic-evidence-reviewer.md:7-13 preloads the typesafe-ai skill and explicitly tells the child to read the user's installed copy when needed. TypeSafe is itself a candidate—and a current winner—in the foundation/instructions-skills layer, so all four refutation/re-check children for that packet receive one candidate's skill outside the retained packet while the competing skills do not. The BLIND prompt cannot remove preloaded role context; use a skill-free read-only role for this lane.

Useful? React with 👍 / 👎.

seathatflowsinourveins added a commit that referenced this pull request Oct 10, 2026
The owner decided on 2026-10-10 (about 17:15Z, relayed by the command center)
that Claude review no longer runs inside GitHub: AI reviews run on the local
host and GitHub enforces the gates. The API refused every request that carried
claude-code-action's attribution (CLAUDE_CODE_ENTRYPOINT=claude-code-github-action,
base-action/src/parse-sdk-options.ts:284 at 2dca132f) on all five Console keys,
while the same keys work from the CLI and the Agent SDK (the command center's
correction #141, measured).

Removed: claude-pr-review.yml, claude-pr-toolkit-review.yml, harness-audit.yml
and their three test modules, their zizmor-coverage entries and their
local-pages inventory paths. test_claude_federation_diagnostics keeps its
retained-snapshot and decision-claim tests. A new
InGitHubClaudeReviewRetiredTests keeps the three files absent and no workflow
running the Claude action or naming an Anthropic key.

New record docs/decisions/2026-10-10-retire-in-github-claude-review.md (cause,
what remains, revisit triggers, inverse); supersession notes in the four
claude-actions/federation records and the decision-record index;
docs/github-automation.md's current practice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 10, 2026
The owner decided on 2026-10-10 (about 17:15Z, relayed by the command center)
that Claude review no longer runs inside GitHub: AI reviews run on the local
host and GitHub enforces the gates. The API refused every request that carried
claude-code-action's attribution (CLAUDE_CODE_ENTRYPOINT=claude-code-github-action,
base-action/src/parse-sdk-options.ts:284 at 2dca132f) on all five Console keys,
while the same keys work from the CLI and the Agent SDK (the command center's
correction #141, measured).

Removed: claude-pr-review.yml, claude-pr-toolkit-review.yml, harness-audit.yml
and their three test modules, their zizmor-coverage entries and their
local-pages inventory paths. test_claude_federation_diagnostics keeps its
retained-snapshot and decision-claim tests. A new
InGitHubClaudeReviewRetiredTests keeps the three files absent and no workflow
running the Claude action or naming an Anthropic key.

New record docs/decisions/2026-10-10-retire-in-github-claude-review.md (cause,
what remains, revisit triggers, inverse); supersession notes in the four
claude-actions/federation records and the decision-record index;
docs/github-automation.md's current practice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 10, 2026
The owner decided on 2026-10-10 (about 17:15Z, relayed by the command center)
that Claude review no longer runs inside GitHub: AI reviews run on the local
host and GitHub enforces the gates. The API refused every request that carried
claude-code-action's attribution (CLAUDE_CODE_ENTRYPOINT=claude-code-github-action,
base-action/src/parse-sdk-options.ts:284 at 2dca132f) on all five Console keys,
while the same keys work from the CLI and the Agent SDK (the command center's
correction #141, measured).

Removed: claude-pr-review.yml, claude-pr-toolkit-review.yml, harness-audit.yml
and their three test modules, their zizmor-coverage entries and their
local-pages inventory paths. test_claude_federation_diagnostics keeps its
retained-snapshot and decision-claim tests. A new
InGitHubClaudeReviewRetiredTests keeps the three files absent and no workflow
running the Claude action or naming an Anthropic key.

New record docs/decisions/2026-10-10-retire-in-github-claude-review.md (cause,
what remains, revisit triggers, inverse); supersession notes in the four
claude-actions/federation records and the decision-record index;
docs/github-automation.md's current practice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
The owner decided on 2026-10-10 (about 17:15Z, relayed by the command center)
that Claude review no longer runs inside GitHub: AI reviews run on the local
host and GitHub enforces the gates. The API refused every request that carried
claude-code-action's attribution (CLAUDE_CODE_ENTRYPOINT=claude-code-github-action,
base-action/src/parse-sdk-options.ts:284 at 2dca132f) on all five Console keys,
while the same keys work from the CLI and the Agent SDK (the command center's
correction #141, measured).

Removed: claude-pr-review.yml, claude-pr-toolkit-review.yml, harness-audit.yml
and their three test modules, their zizmor-coverage entries and their
local-pages inventory paths. test_claude_federation_diagnostics keeps its
retained-snapshot and decision-claim tests. A new
InGitHubClaudeReviewRetiredTests keeps the three files absent and no workflow
running the Claude action or naming an Anthropic key.

New record docs/decisions/2026-10-10-retire-in-github-claude-review.md (cause,
what remains, revisit triggers, inverse); supersession notes in the four
claude-actions/federation records and the decision-record index;
docs/github-automation.md's current practice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
The owner decided on 2026-10-10 (about 17:15Z, relayed by the command center)
that Claude review no longer runs inside GitHub: AI reviews run on the local
host and GitHub enforces the gates. The API refused every request that carried
claude-code-action's attribution (CLAUDE_CODE_ENTRYPOINT=claude-code-github-action,
base-action/src/parse-sdk-options.ts:284 at 2dca132f) on all five Console keys,
while the same keys work from the CLI and the Agent SDK (the command center's
correction #141, measured).

Removed: claude-pr-review.yml, claude-pr-toolkit-review.yml, harness-audit.yml
and their three test modules, their zizmor-coverage entries and their
local-pages inventory paths. test_claude_federation_diagnostics keeps its
retained-snapshot and decision-claim tests. A new
InGitHubClaudeReviewRetiredTests keeps the three files absent and no workflow
running the Claude action or naming an Anthropic key.

New record docs/decisions/2026-10-10-retire-in-github-claude-review.md (cause,
what remains, revisit triggers, inverse); supersession notes in the four
claude-actions/federation records and the decision-record index;
docs/github-automation.md's current practice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
* Retire Claude review inside GitHub; AI reviews run locally

The owner decided on 2026-10-10 (about 17:15Z, relayed by the command center)
that Claude review no longer runs inside GitHub: AI reviews run on the local
host and GitHub enforces the gates. The API refused every request that carried
claude-code-action's attribution (CLAUDE_CODE_ENTRYPOINT=claude-code-github-action,
base-action/src/parse-sdk-options.ts:284 at 2dca132f) on all five Console keys,
while the same keys work from the CLI and the Agent SDK (the command center's
correction #141, measured).

Removed: claude-pr-review.yml, claude-pr-toolkit-review.yml, harness-audit.yml
and their three test modules, their zizmor-coverage entries and their
local-pages inventory paths. test_claude_federation_diagnostics keeps its
retained-snapshot and decision-claim tests. A new
InGitHubClaudeReviewRetiredTests keeps the three files absent and no workflow
running the Claude action or naming an Anthropic key.

New record docs/decisions/2026-10-10-retire-in-github-claude-review.md (cause,
what remains, revisit triggers, inverse); supersession notes in the four
claude-actions/federation records and the decision-record index;
docs/github-automation.md's current practice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Pin the repository grant count at 90 after the retirement

The three removed workflows were in the local-pages repository grants. At the
landing base, main f38116f (93 grants), the test's own derivation
(grants.inventory_paths over git ls-files) gives 90 for this branch, equal to
the policy's repository grants, and the test pins 90. At the earlier bases
eb31d23 and 9d4c00c the same derivation gave 90 and 89.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Take up the command center's notes on the retirement

- .github/actions-permissions.json drops anthropics/claude-code-action@* and
  oven-sh/setup-bun@*: no workflow uses them; a new test keeps every allowed
  pattern in use, and the record's inverse puts them back.
- docs/github-automation.md: the allow-list text, no "harness description",
  no "still awaits hosted acceptance" clause.
- The retirement test catches the claude-review environment in its plain,
  name: and quoted forms, and reads *.yaml as well.
- Record nits: #953 marked open, the check is named sota-sources, and the
  federation-diagnostics note says the three workflows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Cite #968's real merge commit in the inverse

The record's inverse named a SHA that does not exist; #968's merge commit is
9d4c00c (git rev-parse 9d4c00c). The
federation note now says the history of those workflows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Read each job's environment in the retirement guard

The GPT read at 48e4bd3 found three valid YAML forms of the claude-review
environment that the regex guard let through: a flow mapping, a quoted name
key, and a comment after the key. The guard now reads each job's environment
as a scalar or a mapping's name (job_environments), cross-checked against
PyYAML when it is installed; all three forms are regressions, each caught here
and missed at e46f68e, and actionlint accepts each fixture.

The record names the claude-native-practice skill rows as a dated follow-up
for cc-native-practice (the command center's ruling at 20:19Z).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Word the skill-row follow-up without the pinned-copy premise

The command center's correction #146: no personal copy of claude-native-practice
is installed on this host; sessions load the checkout's project skill. The
follow-up is now stated neutrally: the skill rows for the retired route are
updated in a cc-native-practice pull request, then re-pinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* State what the environment reading covers, and what PyYAML covers

The docstring claimed comments in general; the text reading handles a comment
after the key, not a comment line before name: at the job's indentation or a
multi-line flow mapping. The PyYAML comparison covers those, and CI runs it
(validate run 38084944806, passed, not skipped). The command center's micro at
08a76ab.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Cite the environment forms' sources, and test the inverse pin against git

The GPT read at 13d1eb7 asked, under the correction rule, for:
- the upstream sources of the environment reading: GitHub's workflow syntax
  for jobs.<job_id>.environment (a name, or an object with name and url) and
  YAML 1.2.2's block and flow mappings, quoted keys and comments, cited with
  page digests in the record and next to the regression cases;
- a regression for the corrected inverse pin: RetirementInversePinTests reads
  the pin from the record and checks it is #968's merge commit holding the
  three workflows. It fails on the former SHA (no such commit) and is skipped,
  with the reason, only outside a worktree or in a shallow clone (CI clones
  with fetch-depth 0).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…ew (#1001)

* Retire the skill's Claude-in-GitHub rows and point them to local review

The claude-native-practice skill still selected the route that
docs/decisions/2026-10-10-retire-in-github-claude-review.md retired:
the github-action row (anthropics/claude-code-action at a pin) and the
Actions part of pr-review-pre-cue.

- slots.json, slots.md and the layer pages: `retired` joins the status
  vocabulary; github-action becomes retired with a dated block (record,
  correction #141, scope, the three workflows, the former default, route,
  alternatives, evidence and notes as a snapshot, the revisit triggers);
  pr-review-pre-cue becomes default (scoped) and lists the routes
  available now (local Claude reads, GPT reads, Codex's GitHub review,
  the required verdict-review-gate) apart from the open #953 worker.
- The scope is the owner's repositories (the command center's ruling of
  2026-10-10), not "this repository": a hermetic A/B showed a session in
  another repository concluding that the action was still fine there.
  The same ruling retires the managed Claude Code Review GitHub App.
- Stale texts the independent pre-read and the stricter check found: the
  release-tracking note (Dependabot as the action's tracker), the
  scheduled-tasks route (GitHub Actions schedules only for jobs that run
  no model) and its source mapping, the usage-cost-monitoring note
  (Actions under WIF), and the pre-cue source mapping (in Actions through
  #909). The pre-cue route no longer lists a read the record does not name.
- tests/test_native_practice_retired_routes.py: no current row selects a
  retired route; a retired route is named elsewhere only in a sentence or
  list item that says it is retired; every line of slots.json, slots.md,
  the layer pages and cross-client.md is read (duplicates kept, the source
  mappings of live slots included); only the dated snapshots are exempt.
  Positive controls are the rows as they stood; the mutation table is in
  the pull request description.
- The slot manifest of #923 is relabeled against the new slots.json
  bytes, so the exact-difference check of the provenance test runs again
  instead of skipping.
- docs/decisions/2026-10-09-claude-code-native-practice.md: a dated
  pointer to the retirement, as #981 did for the older records.

Source read for this change: anthropics/claude-code-action at
2dca132ff0e0c4094ce6048b422c6915a071210b, base-action/src/
parse-sdk-options.ts:283-284 (CLAUDE_CODE_ENTRYPOINT is set to
claude-code-github-action).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Close the holes in the retirement guard and qualify the one-default rule for retired slots

Answers the Codex review in GitHub of #1001 at ba6ab3a (four P2s) and the co-op's GPT first read at the same head (three P2s, the first three below); each was reproduced before the change.
- Sentence units split at a full stop or a semicolon whatever follows, and at a line break: "This route was retired; the current default is claude-code-action." was one unit that said retired.
- The generic phrases "in Actions", "through Actions" and "under WIF" count as the retired route only with Claude context, judged per leaf string; the named workflows, "through #909" and the managed app count
  everywhere. The routes the decision retains (every bullet of its "What remains" section, a catalog job in GitHub Actions, a non-model gate under WIF) are accepted.
- The skill's entry point SKILL.md is scanned, and a test requires every file of the skill folder to be read by a check.
- The one-default rule names the retired exception in slots.json, in the slots.md copy and in step 3 of SKILL.md (a retired row has none and says what replaced the route).
- The ruled default text is pinned exactly (the read's measured boundary: the date changed on all three surfaces passed), and a check compares every row's Overturn when across slots.json, the index and the
  layer pages (one step wider than the review of #1005, where an edit left the index cell behind).
Each finding fails its own test when its fix is undone alone, and 43 single-edit mutations are caught; the old guard accepts the four bad scenarios of the read and rejects its two legitimate ones.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Bind the manifest label to the shipped slots file and close the remaining holes of the retirement guard

Answers the CC's Claude first read of #1001 at 6e97620 (two P2s, six P3s) and Codex's second review in GitHub of the same head (two P2 threads); each was reproduced before the change.
- P2-1: the slot manifest was labeled against the slots.json of ba6ab3a, so the exact-difference check of the provenance test skipped at the head (OK, skipped=1). The label is the sha256 of the shipped file again,
  the check no longer skips, and a new test fails when a change to slots.json does not carry its label (the CC's ruling: a silent skip is this defect's class, so it fails loud).
- P2-2: a live source mapping (skills-library, primary_sources[5]) still ran `claude -p` "in a GitHub workflow ... plus a nightly cron"; the guard had no such form. It is reworded to say the run is retired,
  and "in a GitHub workflow" (also from, via, through, using, as) counts as the retired route when the sentence is about Claude.
- P3-1: the Claude Code GitHub Action, /install-github-app and an @claude mention are the retired route under other names (claude-code-security-review stays out: a documented rejection).
- P3-4: the Former default exemption of a layer page applies to a retired slot only.
- P3-5: a retired slot's own source mapping is read, and now says retired.
- P3-2: "e.g." and "i.e." no longer end a sentence, and wrapped lines of prose are one paragraph (the slots.md prose and SKILL.md were judged line by line).
- P3-6: the manifest prose lists the fields beyond the exported ones that differ from the snapshot.
- P3-7: the entry point directs ("a retired row has no default, so follow the replacement it names"), and the step-3 pin no longer fails with an IndexError on a renumbering.
Each correction fails its own test when it is undone alone, and the mutation table is extended.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Judge retired-route prose one physical line at a time and close the guard's other gaps

Answers the command center's Claude micro of #1001 at ef3f3e7 (P2-1, P3-1 to P3-5) and Codex's four threads of the same head (:43, :63, :122, :211). Each case was reproduced before the change:
compare-guards-ef3f3e7b-vs-third-commit.txt runs 19 scenarios through the guard of ef3f3e7 and this one; the old guard is wrong on 13 (it accepts a retired route that is reintroduced), this one on none.
- P2-1 (correction #160): joining wrapped lines into one paragraph let "Retired 2026-10-10" followed by a line that says the current default is claude-code-action pass on four prose surfaces (SKILL.md, slots.md,
  cross-client.md, layer-page preambles), the scenario Codex raised at ba6ab3a line 41. Prose is judged one physical line at a time again, a line break ends a unit, and the message of every line-judged surface
  states the rule (RULE; the legend of slots.md states it too and a test pins the two to each other).
- P3-1 and Codex :43: three more names of the same route, all in the vendor's own text: the page's title "Claude Code GitHub Actions" and its "installs the Claude GitHub App"
  (code.claude.com/docs/en/github-actions.md, capture sha256 87b99aef, lines 5, 9, 33, 63-64), the mirror claude-code-base-action (anthropics/claude-code-action@2dca132ff0e0:
  .github/scripts/check_workflow_hardening.py:18, .github/workflows/sync-base-action.yml:1 and 43, CLAUDE.md:20) and the carrier named first ("Use the GitHub Action for Claude reviews", generic
  like "in Actions": it counts when the field or unit is about Claude). The families "in Actions" and "through Actions" take on, with, inside and via.
- Codex :122 and the command center's P3-3 and P3-5: a unit that negates the retirement outright ("not retired", "never retired", "no longer retired", "isn't retired", "unretired") no longer counts as saying
  retired. The other half of that scenario, "was retired, but is now current", is the boundary the command center ruled (the guard is a tripwire for stale text; review reads what it accepts); the module names it.
- Codex :211 and P3-3: a layer-page section with a label twice (a second Route or Overturn when bullet) is a violation, because the page-to-slots.json comparison keeps the first bullet only.
- Codex :63 and P3-4: the target of every slots.md row is checked against <page>#<id>, from the layer of the slot.
- The description line of SKILL.md names the topic that invokes the skill; it is pinned by sha256 to the text the routing was measured with and read as a topic, not as a route.
- Scheduled-tasks (Codex on #1005, scheduling-supervision.md:9, and the command center's ruling): the route no longer bans every model-backed job. The retirement record
  (docs/decisions/2026-10-10-retire-in-github-claude-review.md:5-6, :43) retires Claude review inside GitHub and keeps Codex's GitHub review, so the route says GitHub Actions schedules repository jobs and a
  scheduled Claude task runs locally; a test pins the wording on slots.json, the layer page and the alternatives.
The label of claude-native-slot-manifest.json equals the sha256 of the shipped slots.json again (relabel last); test_the_label_names_the_shipped_slots_file and test_no_other_exported_field_differs
(no skip) are unchanged from ef3f3e7. 72 of 72 single-edit mutants of the guard and its data are caught and 5 controls pass (mutations-v4-forward-commit-3.md).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Align the manifest's scheduled-tasks note, state the rule in every explaining unit, split units after a closing delimiter and pin the scope of the name patterns

The final fix round of #1001 under the command center's convergence ruling: its Claude micro at efaa077 (blockers B1 to B3, P3-2) and its adjudication of 2026-10-11T13:50Z of Codex's third review. Each item was reproduced on that
head before the change.
- claude-native-slot-manifest.json:47 (Codex P2, B1, a text of this PR that is false at the head): the note on the differences from the snapshot still said the route of scheduled-tasks was narrowed "to jobs that run no model",
  while the shipped route says that GitHub Actions schedules repository jobs, that Claude runs inside GitHub are retired (2026-10-10, docs/decisions/2026-10-10-retire-in-github-claude-review.md:5-6, :43) and that a scheduled
  Claude task runs locally. The note says so now, and test_the_scheduled_tasks_route_retires_the_claude_routes_and_not_every_model_backed_job reads the manifest as well as the route (fails with the note undone: M79).
- B2: the module claims that the message of every line-judged surface states the rule, and it did not for the labelled bullets of a layer page or for the Overturn when cell of an index row. Every explaining unit states it now
  (a selecting field names no unit and states nothing); the three expected messages carry the rule and test_every_explaining_unit_of_a_layer_page_and_of_the_index_states_the_rule_and_a_selecting_field_does_not pins all three
  kinds (mutants M83 to M85).
- tests/test_native_practice_retired_routes.py:83 (Codex P2, P3-2): a closing quote, parenthesis or bracket between the full stop and the white space kept `The route was "retired." The current default is claude-code-action.` in one
  unit that said retired. The sentence pattern takes closing delimiters (the curly quotes are built with chr(), so the file stays ASCII); test_a_closing_quote_parenthesis_or_bracket_after_the_full_stop_does_not_join_two_claims fails
  without it (M78, M82) and keeps `claude-code-action was retired (see the record.) No row selects it.` accepted (control C6).
- :48 (Codex P2, workflow-first phrasing) is a follow-up and the class closes (rule 4 of the convergence ruling): the module states that the guard pins the named retired artifacts and the retired slot rows, that generic phrasing of a
  Claude run in a GitHub workflow cannot be enumerated and is out of its scope (the retirement record governs it), and test_generic_workflow_phrasing_is_out_of_scope_and_the_module_says_so pins the boundary. No pattern is added.
- B3 is the description: the two earlier command blocks name the 37 modules they ran (the 46 of the first block without the nine tests.test_local_pages_* modules).
80 single-edit mutants of the guard and its data are caught and 6 controls pass (mutations_retire_v6.py).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* Close the sentence-splitter class by documentation, pin the module's ASCII and the scope list

The command center's confirmation micro of #1001 at bdf60fc (research-cc-role-20261008/pr1001-claude-micro-bdf60fc6.md: blockers 1 and 2, P3s) and its correction #163 of 2026-10-11T16:18Z on Codex's three threads of 15:39:21Z.
No code of the guard changes in this commit.
- Blocker 2: the module said that it stays ASCII and held one U+2026 in a comment (added by efaa077). It is three full stops now, and test_the_source_of_this_module_is_printable_ascii pins the claim; it fails on the module
  of bdf60fc (['U+2026'] != []).
- Blocker 1 (the pull request description, and this message corrects the message of bdf60fc): the earlier statement that the 37 modules ran "without its nine tests.test_local_pages_* modules" was false. They are the first 37
  modules of the 46-module list, and the nine left out are its last nine (tests.test_local_pages_fleet_execution to tests.test_local_pages_workstation, 144 tests, run and counted); 29 of the 46 are local-pages modules.
- Codex :92 (an exclamation mark or a question mark does not end a unit) is not patched: the sentence splitter has drawn findings in five consecutive rounds (the lowercase clause, "e.g.", the joined lines, the closers,
  the exclamation mark and the question mark) and was patched four times, so rule 4 of the convergence ruling closes the class the way line 48 closed. The module docstring states exactly what the guard accepts as a unit end
  and that review reads everything else; test_the_unit_ends_and_the_scope_of_the_name_patterns_are_documented pins the sentence and the behavior, and fails on the module of bdf60fc, where the sentence is missing.
  A pinned upstream sentence segmenter is a research-queue item (rule 8, layer instructions-skills).
- Codex :51 (a carrier-first name of the managed Code Review app) is confirmed within the closed class: the same scope paragraph says that reordered phrasings of a pinned artifact are out of the guard's scope.
- P3-1: the scope list named 11 of the 17 patterns; it names all 17 now, and test_the_scope_of_the_name_patterns_names_every_pattern compares the list itself with PATTERNS (it fails on the module of bdf60fc).
  P3-2: the right single quotation mark closer is tested (its mutant survived). P3-3: the comment at the sentence pattern says what the code does.
- Codex :170 (retired.on is checked for its shape only) is a follow-up under rule 5: the shipped value is the date of the record, so 2099-12-31 is a mutant and not a reproduced failure of the shipped state.
88 single-edit mutants of the guard and its data are caught and 6 controls pass (mutations_retire_v9.py).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
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