Skip to content

site/ops: the reducer's bot/state inputs are release-affecting - #75

Merged
Deicyde merged 3 commits into
mainfrom
claude/release-policy-reducer-inputs
Oct 17, 2026
Merged

Deicyde merged 3 commits into
mainfrom
claude/release-policy-reducer-inputs

Conversation

@Deicyde

@Deicyde Deicyde commented Oct 17, 2026 •

Copy link
Copy Markdown
Owner

Two mismatches between site/ops/brain_release_authority.py and what the Brain build actually reads.

1. The reducer's bot/state inputs were release-neutral

brain/authority/reducer-inputs-v1.json declares these as curated_git_input, read by brain/build_cells.py:

  • bot/state/brain_queue.json
  • bot/state/cut_log.json
  • bot/state/pool_candidates.json (gitignored today)
  • bot/state/recycle_queue.json
  • bot/state/seed_queue.json

They sit under bot/, a neutral directory. So a commit that changed one let main move past a release built from the old bytes. That is the unsafe direction: the promoter and bundle freezer would accept a release that doesn't match main's reducer inputs.

They are now in AFFECTING_EXCEPTIONS. The rest of bot/state/ (bot_state.json, batchN_approved.json, …) stays neutral; it is bot operating state, not a reducer input.

2. The nightly's check is a different set, not a mirror

The comment on AFFECTING_EXCEPTIONS said that list must agree with brain-nightly.sh's uncommitted-source check. The two sets differ in both directions:

  • The nightly watches more files than the policy treats as affecting. Among tracked files it refuses local edits to 54 files under wiki/test/, 4 under wiki/e2e/, wiki/README.md, two test_*.py files under wiki/scripts/, and site/ops/brain-canary.py. None of them reach release bytes, so refusing them is harmless. The canary entry is a leftover: the nightly stopped running brain-canary.py in afdf3a67, and the promoter and .github/workflows/brain-canary.yml run it now. The repo's own tests already treat the canary both ways: test_brain_nightly.py pins it in the nightly list, and test_brain_promote_release.py uses it as a neutral change.
  • The nightly watches no curated inputs at all, neither bot/state/ nor catalog/data/. It expands $REDUCER_SCOPE to the inventory's scope code files only.

The comment now describes that instead of claiming agreement.

Not changed here, and worth a decision: the nightly runs brain/build_cells.py against its working tree. A local edit to a curated input on the nightly host would therefore be frozen into a release whose authority commit doesn't hold those bytes. Running python3 bot/brain_queue.py, which bot/README.md documents, is one way that edit happens. Closing that means adding the curated inputs to the nightly's source check. That is a brain-nightly.sh change, which is itself release-affecting, so I left it out.

Tests (site/ops/test_brain_release_authority.py)

  • test_reducer_code_and_curated_inputs_are_release_affecting: across all four brain/authority/reducer-inputs-v*.json inventories, every reducer scope file, every curated_git_input path and every input rooted in the repository ("root": "repo") must be release-affecting. It fails on main for the five bot/state files.
  • test_the_canary_is_the_only_nightly_watched_file_left_neutral: among the files the nightly names explicitly, the canary is the only one the policy calls neutral. It doesn't look inside watched directories like wiki/.
  • New examples: bot/state/bot_state.json and batch7_approved.json neutral, bot/state/cut_log.json and seed_queue.json affecting.
  • The nightly pathspec parser is shared as _nightly_watched() with the existing NEUTRAL_FILES test.

Docs

  • docs/BRAIN-RELEASE-RUNBOOK.md, the operator runbook, now excepts the five bot/state/ files the reducer reads from its neutral list.
  • bot/README.md's fold-back instructions note that folding any of the four tracked Brain-build files from bot-state into main is release-affecting, so the next promotion needs a new release.
  • docs/BRAIN-ACTIVATION-2026-10-04.md is a record whose values can be checked at 37b7036d, so its list stays as it was. One sentence notes Release policy: AGENTS.md and CONTRIBUTING.md are release-neutral #68's change and this one.

Effect

Testing

CI runs the updated test file through scripts/ci-python.sh; the first push's run passed all 10 tests. I didn't run it locally because machine load was above the agreed limit. I checked the classifications directly: bot/state/cut_log.json is affecting, while bot/state/bot_state.json, bot/poll.py and site/ops/brain-canary.py are neutral.

brain/authority/reducer-inputs-v1.json declares five bot/state/*.json
files as curated_git_input, read by brain/build_cells.py, but bot/ is a
neutral directory, so a commit changing one let main move past a release
built from the old bytes. They are now affecting exceptions, and a test
checks every reducer scope file and curated input against the policy.

The comment on AFFECTING_EXCEPTIONS claimed the list must agree with
brain-nightly.sh's uncommitted-source check. That check is broader: it also
refuses local edits to Worker tests, READMEs and site/ops/brain-canary.py,
none of which reach release bytes. The comment now says so, and a test pins
the canary as the only file the nightly names that the policy leaves
neutral. docs/BRAIN-ACTIVATION-2026-10-04.md's copy of the neutral list
picks up these exceptions and #68's AGENTS.md and CONTRIBUTING.md.
Review fixes:
- The AFFECTING_EXCEPTIONS comment called brain-nightly.sh's
  uncommitted-source check "broader". It is a different set: it watches
  code, not curated inputs, so it covers Worker tests, READMEs and the
  canary but never bot/state/ or catalog/data/. The comment also gave a
  reason for site/test_frontier_page.py that other neutral gating tests
  contradict; it now just names the file.
- The curated-input test reads every brain/authority/reducer-inputs-v*.json,
  not only v1.
- The canary test's comment says it checks only the files the nightly names
  explicitly.
- docs/BRAIN-ACTIVATION-2026-10-04.md is a record checkable at 37b7036, so
  its neutral list is restored and one sentence notes #68's and this PR's
  changes. The operator runbook's neutral list gains the bot/state
  exception instead.
@Deicyde

Deicyde commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

Recommendation: fix (comment and doc wording only), then merge. An independent adversarial review of feed0d06 found the policy change and its tests correct. CI is green (10 policy tests). The PR is release-neutral, merges cleanly with #73, #74 and #78 in either order, and changes nothing operationally today: git diff --name-only 2eb31baa a8bb2882 -- bot/state is empty, so no recorded bundle lists these files.

  • Fix: "the canary it runs" is false.
    • It appears in site/ops/brain_release_authority.py:45 and in the canary test's comment (site/ops/test_brain_release_authority.py, about line 110).
    • brain-nightly.sh mentions brain-canary.py only in its git status pathspec (line 833). afdf3a67 removed run_release_canary in September.
    • The promoter (brain_promote_release.py:3146) and .github/workflows/brain-canary.yml run the canary now. The watch entry is a leftover.
  • Fix: tighten the same comment.
    • "watches code, not curated inputs, so it also refuses…" isn't a causal link.
    • "READMEs" is just wiki/README.md.
    • The check also watches brain/authority/schemas and reducer-inputs-v1.json, so "code" is loose.
  • Fix: the docs' bot/state/*.json reads as the whole directory.
    • Where: docs/BRAIN-RELEASE-RUNBOOK.md:293 and docs/BRAIN-ACTIVATION-2026-10-04.md:133.
    • Only the five reducer inputs are affecting; bot_state.json, batchN_approved.json and the rest stay neutral. Say "the five bot/state/ files the reducer reads".
  • Worth noting, not blocking:
    • pool_candidates.json is gitignored. Listing it only keeps the inventory test free of special cases. Its real exposure is the nightly host's working tree, and a future git status-based nightly check wouldn't see an ignored file without --ignored or an explicit check.
    • The test checks only scope and curated_git_input paths. A future repo-root immutable_source_object under a neutral directory would slip through. None exists today.
    • Folding bot state into main now forces a new release. That applies to any fold from bot-state that touches cut_log, seed_queue, recycle_queue or brain_queue. This is intended, but neither the runbook nor bot/README.md says so.
    • Pre-existing: .agents/ is not neutral while .claude/ is.

…ate files

Review fixes:
- brain-nightly.sh still names site/ops/brain-canary.py in its
  uncommitted-source check but has not run it since afdf3a6 (the promoter
  and .github/workflows/brain-canary.yml run it). The policy comment and
  the canary test's comment no longer say "the canary it runs", and the
  comment drops the loose "watches code" causality.
- The runbook and the activation record said `bot/state/*.json`, which
  reads as the whole directory; they now say the five files the reducer
  reads.
- The inventory test also checks every input v2+ inventories root in the
  repository ("root": "repo"), not only curated_git_input entries.
- bot/README.md's fold-back instructions note that folding any of the four
  tracked Brain-build files is release-affecting.
@Deicyde

Deicyde commented Oct 17, 2026

Copy link
Copy Markdown
Owner Author

Follow-up: fixes applied in f3477291. Recommendation: merge. CI is green (run 39077219274; the 10 policy tests pass).

  • Canary wording: the AFFECTING_EXCEPTIONS comment and the canary test's comment no longer say the nightly runs the canary. They say the nightly still names brain-canary.py but stopped running it in afdf3a67, and that the promoter runs it now. The loose "watches code, so…" causality is gone.
  • Docs wording: docs/BRAIN-RELEASE-RUNBOOK.md and docs/BRAIN-ACTIVATION-2026-10-04.md say "the five bot/state/ files the reducer reads" instead of bot/state/*.json.
  • Wider test: the inventory test also checks every input that v2 and later inventories root in the repository ("root": "repo"), not only curated_git_input. That is 47 paths across the four inventories, none neutral.
  • Fold-back note: bot/README.md's fold-back steps say that folding any of the four tracked Brain-build files from bot-state into main is release-affecting, so the next promotion needs a new release.

Still open, as decisions rather than fixes:

  • Nightly source check: should it refuse local edits to curated inputs? That needs --ignored or an explicit check for pool_candidates.json.
  • POLICY ID: whether to bump it.
  • .agents/: it is not neutral while .claude/ is.

@Deicyde
Deicyde merged commit cc02172 into main Oct 17, 2026
4 checks passed
Deicyde added a commit that referenced this pull request Oct 17, 2026
site/ops: the reducer's bot/state inputs are release-affecting
@Deicyde

Deicyde commented Oct 19, 2026

Copy link
Copy Markdown
Owner Author

Re-review on main (eaa5950b): fine. The five exceptions are exactly what brain/build_cells.py:101-105 reads, and removing any one fails the inventory test (checked with mutants). With #83 on top, the module comment, the tests and the nightly agree. Classifying every one of main's 18,659 tracked paths turned up no neutral path that reaches release, public-asset or Worker bytes. The inventory test's 47-path set has no neutral member.

Optional test hardening:

  • test_every_file_the_nightly_names_is_release_affecting can't fail for directory entries such as site/assets: is_release_neutral() is never true for a bare directory string.
  • The inventory test skips path_pattern inputs (site/annotations/*.json, catalog/data/user_repos/*.jsonl) and v1 entries that are neither curated nor root: repo. A mutant making catalog/data/user_repos neutral passes. Nothing is misclassified today.

Stale docs:

  • bot/.gitignore:6-7 says pool_candidates.json "only feeds the /queue publish". build_cells.py reads it.
  • docs/BRAIN-RELEASE-RUNBOOK.md:291 calls test_*.py neutral without the site/test_frontier_page.py exception.

Outside this PR, and the most important item:

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