Skip to content

Reconcile PR38 with the salvage line: merged history, AGPL executed, sweettest unblock - #41

Open
kalisam wants to merge 245 commits into
mainfrom
reconcile/pr38-salvage-20260817
Open

Reconcile PR38 with the salvage line: merged history, AGPL executed, sweettest unblock#41
kalisam wants to merge 245 commits into
mainfrom
reconcile/pr38-salvage-20260817

Conversation

@kalisam

@kalisam kalisam commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Rejoins six weeks of parallel work and lands the corrections found along the way.
origin/main is fully contained in this branch (0 ahead, 124 behind as of
2026-08-24), so there is no content to reconcile here — only review.

PR #38 has since merged to main on its own (merge commit 873cc0c,
2026-08-18). It is an ancestor of both main and this branch, so the merge
described below is now history rather than the point of the PR. What remains
unique here is the salvage line.

Merge

pr/38 (65 commits) merged into the wip/salvage-20260804 line (93 commits).
Merge-base 3e82a33, 2026-07-05. 13 conflicts, each resolved on its merits.

Both sides won on different files, and one conflict caught a real bug:

  • PR38 won workers/commons-gateway/* — our manifest.ts used FLOSS/-prefixed
    paths, producing a doubled URL segment, and listed INDEX.md, which is not in this
    repo.
  • Both won on voters.py — PR38's _PERSONA_SHARED_GATE_SYSTEM hardening ("a
    persona may never waive or narrow the shared checklist") prefixed onto our
    clean-room persona text, on both personas.
  • Both won on provenance.py_is_ancestor and _ignored_chain_position are
    independent features, not rival versions.

Licence

  • ADR-7 executed. Accepted 2026-04-15, propagated to FLOSSI_U/ and the reuse
    ledger, but FLOSS/LICENSE still held GPL-3.0 text. Now the AGPL SPDX line,
    byte-identical to FLOSSI_U/LICENSE. GPL text archived, ADR-7 → Verified.
  • SUL-1.0 removed. MOMUS_PERSONA_SYSTEM was adapted from oh-my-opencode
    (SUL-1.0, incompatible with AGPL). Replaced by a clean-room
    EXECUTABILITY_REVIEWER_SYSTEM written from this repo's own consensus schema.

ADR-12

The stated unblock — "pin compatible client+tryorama versions for the 0.6 line" —
cannot be made to exist: no Tryorama version pairs with hc 0.6.1, and Tryorama is
retired upstream in favour of Rust sweettest. Verified holochain 0.6.3 ships
sweettest, so consent_gate.test.ts can be ported without a substrate
migration. Sequencing recorded deliberately: tests first, 0.7 migration second.

Also separates the two blockers the ADR had conflated — the sweettest port proves
the zome; the consent anchor is what blocks ADR-19. entry_has_consent() only
checks decision_action_hash is a non-empty string and never resolves it.

Provenance spec

v1.5 delta items D2 (multisig headroom) and D3 (evidence types file/log/
activity/source_chain) applied to spec, schema and EVIDENCE_TYPES. D1 held —
blocked on ADR-12.

ADR-20 — provenance validator reconciliation

Added 2026-08-23. The provenance spine has run since 2026-08-10 and landed zero
claims: hooks fire, packets are signed, and the validator rejects 100% of them.
Two causes, both reproduced at head, both documented and neither yet fixed —
ADR-20 is Proposed and carries no code.

  • D3 missed a fourth allow-list. _EVIDENCE_REF_TYPES in provenance.py:564
    still holds the original six values and is the set validate_packet actually
    enforces, so a schema-valid packet is rejected downstream. Second occurrence of
    this pattern after spec_gate.GATED_SURFACES.
  • Ancestor artifact validation is fatal on hash mismatch. Editing a file twice
    permanently invalidates every earlier packet naming it, and those stay in the p
    chain. The spec's Audit Disposition section defines a superseded status for
    exactly this; it was never built.

An adversarial ensemble audit (6 voters, 5 provider surfaces, 6 model families)
rewrote the proposed remedy and is recorded in the ADR, including the finding that
the synthesizer's "6/6 unanimous" label was wrong — one voter answered nothing, one
dissented on blast radius, and the sequencing question split three ways.

Verification

  • 262 tests pass (this line alone before the merge: 162; pr/38 alone: 223)
  • spec_gate --check: 108 registered, 0 missing, 0 reuse violations, 7 stale
    (non-fatal; 5 are pre-existing FLOSS/scripts/hook_*.py path drift — those files
    live in FLOSS/hooks/)
  • No conflict markers; no SUL-1.0-derived text remains
  • origin/main merged in 2026-08-24 (CI and dependabot fixes only, clean)

Not included

The preservation spine is not in this branch. It ships via #43
(feat/preservation-spine-standalone) with #59 stacked on top; that line is ahead
of the local spine work, which has been abandoned.

kalisam and others added 30 commits July 6, 2026 18:41
…s read gateway

Source-only (inner .gitignore keeps node_modules/dist/.wrangler out): src (index,
manifest, responses, security) + tests + wrangler.jsonc + tsconfig. The read-only
public edge that fronts the commons; the local gateway/Holochain remains the truth
substrate (ADR-16 boundary). npm scripts already wired in root package.json.

Verified: tsc --noEmit clean; 7/7 vitest tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… projections

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Digests the externally produced "Holo-RBI Recursive Event Swarm 2.0"
chat-paste intake against the layer stack. Reaffirms ADR-10
router-not-controller (coordinator may only propose; assignments must be
Claims subject to Votes, gated on a future ADR); logs four deltas incl.
valid_context/known_failures/expiry_or_retest_date fields for the ADR-17
KnowledgeTriple review. Trading/RBI vertical out of scope. No adoption.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Root cause of the 2026-06-16/17 1.23M-event intake storm: default_watch_specs()
registers overlapping specs (canon→FLOSS/docs AND shared-surface→FLOSS/),
so every FLOSS/docs file was fingerprinted twice per scan with different
watch_domain values; state oscillated and emitted a spurious 'modified'
event per overlapped file per scan, indefinitely.

- scan_once: first-spec-wins dedup on abs_path (kills the oscillation)
- MAX_INCOMING_QUEUE_DEPTH=5000 backpressure guard (early-exit scandir count;
  suppresses emission + prints drain hint when queue is flooded)
- tests/test_watch_intake.py: 4 pytest tests covering dedup, real-modify
  signal preservation, and backpressure (4/4 green, isolated tmp workspaces)

Docs reconciled same session:
- OPERATOR_PRIMER: heartbeat row (resumed 2026-05-26, user-session process,
  LocalSystem prohibition re-verified 2026-07-07); STOP/LocalSystem/double-loop
  rules in What-Not-To-Do
- CLAUDE.md Inference Posture: Cowork 2x window ended; Fable-5 durable access
  via Pioneer.ai subscription; pullback note superseded
- working-todo A.00000: full repair record + canonical heartbeat invocation
Hermes Agent is now a first-class skill-projection target alongside
codex/claude/gemini/opencode. install_path: Hermes skills dir.
All 9 corpus skills materialized 2026-07-07 (--check OK).

Also added .hermes.md project-context at workspace root (auto-loads
FLOSSI0ULLK rules into every Hermes session in C:\~shit\).
Approved Agent C patch from 2026-07-07-doc-drift-sweep.md Part 1.2.
ticks_today was incremented at L711 but only saved at L757 (end of tick),
so a SIGKILL/OOM/crash mid-tick lost the count — and a frozen daily_state
date was an observed symptom (date stuck 2026-06-14 while ticks continued).

Adds save_daily_state() at two points:
- immediately after the ticks_today increment (L711) — covers any hard kill
- after each rounds_today accumulation in the work loop — preserves partial
  round-cap accounting if a later item crashes

End-of-tick save at L757 remains as the final authoritative write.
save_daily_state() is a ~200-byte JSON write already wrapped in try/except;
2+N extra writes per tick is negligible I/O.

Verified: test_heartbeat_budget.py 7/7 green; targeted ad-hoc test confirms
ticks_today=1 persists through a simulated mid-tick crash (old behavior lost
it). Date-rollover reset confirmed correct (both rounds_today + ticks_today
reset to 0 on date change).
Per 2026-07-07-doc-drift-sweep.md (Agent C report), approved by Anthony 2026-07-08.

OPERATOR_PRIMER.md (0.1.0 -> 0.2.0, updated 2026-05-19 -> 2026-07-08):
- Phase 0 row: 'Tryorama' -> 'Rust Sweettest' (directive 2026-07-03)
- Orchestration bridge row: note ADR-17 as active Phase 1 focus
- Consent gate row: Tryorama -> Sweettest
- Decision history: ADR-Suite v2.0 -> INDEX v2.1.0 (supersedes for ADR-13..17)
- Current Best Next Moves: refresh from 2026-05-19 set to 2026-07-08 set
  (ADR-17, ADR-12 action-time, spec_gate adoption, Sweettest migration,
  synthesis budget decision)

RUNTIME_SURFACES.md (0.1.0 -> 0.2.0, updated 2026-05-24 -> 2026-07-08):
- Add 4 missing Runtime Inventory rows: watch_intake (with 2026-07-07
  overlap-dedup + backpressure guard note), process_intake_events,
  autonomous_synthesis, spec_gate

No remaining 'Tryorama suite unvalidated' / 'current focus is Phase 0'
contradictions across the 4 orientation files (grep-verified).
- autonomous_synthesis timeout 900s → 1800s (pathologically large files
  like Holistic_Vision.md = 932KB → ~78 chunks need more than 900s)
- test_heartbeat_persist.py: 3 new pytest tests for the 2026-07-08
  save_daily_state mid-tick persistence patch (test_mid_tick_crash_persists
  _tick_count, test_date_rollover_resets_both_counters, test_rounds_accum
  ulation_persists_per_item). 10/10 green with existing budget suite.

Also: 2 ACCEPT drafts committed to source chain (foss-ai-personal-
assistant-landscape 69febf3, HI_ROI_NAO bb231a2); 14 root intake files
relocated to intake_raw/2026-07-07-root/ (sha256 verified, move log at
.agent-surface/intake/root-intake-moves-2026-07-07.json).
… + drift reports

- 2026-07-07-root-intake-digestion.md: status flipped from read-only to
  'Relocation completed 2026-07-08 (14 files moved, sha256 verified)'
- TRIAGE-2026-07-07.md: Agent A triage of 17 synthesis staging drafts
  (2 ACCEPT / 2 REVISE / 8 REJECT / 2 MERGE / 3 DEFER)
- 2026-07-07-doc-drift-sweep.md: Agent C drift sweep + heartbeat patch proposal
- APPEND_ONLY_KNOWLEDGE_LOG.md: regenerated after 2 ACCEPT draft commits
  (foss-ai-personal-assistant-landscape 69febf3, HI_ROI_NAO bb231a2)
- 14 root intake files relocated to intake_raw/2026-07-07-root/{reports,reference}/
  (sha256 verified; move log .agent-surface/intake/root-intake-moves-2026-07-07.json)
9 reports + 5 reference PDFs moved from workspace root with sha256
pre/post verification. Covers Lovable synthesis cluster, agent-coordination
cluster, memory-infra survey, and external research PDFs.
Move log: .agent-surface/intake/root-intake-moves-2026-07-07.json
Add MAX_CHUNKS_PER_FILE=20 to autonomous_synthesis_loop.py. Files exceeding
the cap (e.g. Holistic_Vision.md=932KB→78 chunks) are skipped with a logged
deferral reason, not processed. This prevents pathologically large files from
monopolizing the heartbeat tick budget.

Consensus claim 019f4a9f APPROVED mean +0.617 variance 0.0006 (3/3 voters:
groq-gpt-oss-20b +0.6, groq-qwen3-32b +0.6, cerebras-gpt-oss-120b +0.65).
First claim 019f4a9e was REJECTED (-0.43) for missing evidence — resubmitted
with spec/commit/ADR/test provenance and approved.

Option E (FLOSS_HEARTBEAT_DISABLE_SYNTHESIS=1) remains Anthony's call — the
cap alone bounds the per-file cost; disabling stops automatic spend entirely
while 15 staged drafts await triage.

14/14 tests green (budget + persist + watch_intake suites).
Two models in voter_registry.json were dead (verified against live providers):
- mistral/devstral-small-2507 -> "Invalid model" (used in 6 profiles).
  Replaced with mistral/devstral-small-latest so future version bumps don't
  re-break it.
- openai/gpt-4.1-mini -> OpenAI quota exhausted (no billing). Replaced with
  openrouter/openai/gpt-4o-mini (OpenRouter key present).

Updated the three gateway tests that pinned the old IDs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The ensemble was Ollama-only and reliably degraded (0-of-4 embeddings) under
GPU serialization on 16GB hardware, then gave up in the degraded branch.

Add transport.py: online-primary voter pool resolved from the consensus-gateway
roster (reusing resolve_default_voter_specs + Flowith helpers), transport
routing (litellm/flowith/ollama), and a single-embedder-per-run resolver (local
mxbai preferred, cloud fallback) so the ensemble runs with Ollama fully down.

synthesizer.py resolves the pool from FLOSS_ENSEMBLE_VOTER_MODE (default
online), threads the resolved embedder through dispatch, and emits honest
per-provider labels. 7 new unit tests; live deliberation reaches tier1 with 6
cross-provider voters where the local path degraded. Spec + .env.example updated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two non-canon intake/design notes:
- Levin-corpus K-metric intake: defers ADR on the chat-synthesis proposal to
  adopt K=log10(tau_blind/tau_agent) as primary benchmark; figures unverified;
  records the ensemble-unavailable + consensus-REJECTED adjudication trail.
- Hermes MCP cross-harness design sketch: grounded in the verified .hermes.md
  (Hermes is an active harness consuming project MCP servers today); separates
  safe Shape B (premium voter lane) from ADR-gated Shape A (CLI dispatch).

No adoption; no wiring; not canon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- packages/mcp_daemon.py: claim_singleton(), audit_appender(), run_http_daemon()
- Windows-safe _pid_alive() (WinError 87 on impossible PIDs)
- 4/4 tests passing, 43/43 existing tests still green
- Purely additive: no existing files modified
- Part of omniroute-inference-plane-migration Stage 1 Task 1.1
- server.py: run_http_daemon(consensus.pid, :7331) replaces bare mcp.run()
- mcp_server.py: run_http_daemon(reasoning_ensemble.pid, :7332) replaces bare mcp.run()
- Both carry lens instruction injection via FastMCP(instructions=...)
- Windows-native _pid_alive() via ctypes.OpenProcess (os.kill unreliable)
- Verified: both daemons start, respond to initialize + tools/list, singleton guard works
- Part of omniroute-inference-plane-migration Stage 1 Task 1.2
Idempotent PowerShell launcher for consensus (:7331) + ensemble (:7332).
Register: schtasks /Create /TN FLOSS-MCP-Daemons /TR ... /SC ONLOGON /RU MSI\kalis
Part of omniroute-inference-plane-migration Stage 1 Task 1.4
- packages/omniroute_client.py: completion() + embedding() via httpx
- 3/3 tests passing (monkeypatched, no live daemon needed)
- Part of omniroute-inference-plane-migration Stage 3 Task 3.3
Groq decommissioned qwen3-32b (verified via live API: only qwen/qwen3.6-27b
remains). Updated all 8 profile entries + 3 test files + docstring.
27/27 tests passing.
…OSS_MODEL_BACKEND)

All 8 litellm call sites now branch on FLOSS_MODEL_BACKEND=litellm|omniroute:
- voters.py: 3 voter closures (make_litellm_voter, make_omo_momus_voter, make_omo_critic_voter) via shared _model_completion()
- transport.py: _litellm_generate + _cloud_embed_fn
- autonomous_synthesis_loop.py: chunk extraction
- major_consolidation_sweep.py: chunk extraction

Default remains litellm. OmniRoute is opt-in via env var.
All parsing logic (_strip_thinking, _parse_weight, _parse_rationale) unchanged.
70/70 tests passing.
System blast radius. Operator-consented 2026-07-17.
Stages 0-3.4 implemented + 70/70 tests passing.
Consensus claim submission pending.
…OmniRoute blocked on provider config

Litellm baseline: 3/3 voters parseable, consensus gate LIVE.
OmniRoute: daemon running but needs provider config via dashboard + model-ID mapping.
FLOSS_MODEL_BACKEND stays litellm (correct per plan Task 3.2 gate).
…se fix

- OmniRoute 3.8.48 with 1249 models across 23 providers configured
- All 3 voter models resolve with identical litellm-style IDs (no mapping needed)
- Consensus round via OmniRoute: 3/3 voters parseable, identical weights vs litellm
- Token compression active: articlesx1 strategy, ~21 tokens/request (~4%)
- Fix: added stream:false to omniroute_client.py (OmniRoute defaults to SSE)
- 3/3 TDD tests still passing
- start_mcp_daemons.ps1: now starts OmniRoute (:20128) alongside FLOSS daemons
- stop_mcp_daemons.ps1: clean shutdown of all daemons + orphan cleanup
- Fixes the 'million processes never killed' problem
Design for repairing materialize_shared_agent_surface.py (crashing on
HTTP-transport servers since 01bdeb8, which is why every harness config
drifted and needed manual repair), adding Codex + Hermes targets, and
adding a single runner over all six materializers.

Also lands the execution notes for the 2026-07-24 MCP migration fixup:
8 fixes applied/verified, root causes recorded.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
11 TDD tasks: extract classify_transport, fix the OpenCode HTTP crash,
add Codex (tomlkit) + Hermes (ruamel) merge-preserving writers with a
gateway liveness guard, user-scope gating, and refresh_agent_surfaces.py.

Task 9 is the acceptance gate: the propagator must reproduce the
2026-07-24 verified harness configs, not revert them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Unblocks materialize_shared_agent_surface.py, which has crashed on every
run since 01bdeb8 moved consensus/ensemble to HTTP daemon URLs.

Also folds in code-review follow-ups from Task 1 (classify_transport):
document the both-transports precedence (stdio wins, url ignored) and
add coverage tests for its non-dict/blank-command/non-string-env/
non-string-headers branches.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

Extends the learnings document through the nine rounds since it was written,
and corrects two things it got wrong about itself.

The central addition is that FM-9's prediction was tested in the same session
by accident. Round 8 replaced the file lock's mechanism with an OS lock; over
the six rounds after it the lock was edited three more times and not once for
a locking-correctness defect, having produced six consecutive rounds of exactly
those before. The hand-rolled claim protocol next door, same reviewers, same
rounds, produced six more. Stated precisely, because the loose version is
false: the lock did not stop being edited -- the class of defect became
inexpressible. And the comparison argues against blaming the claim protocol's
tail on carelessness, because that protocol has no layer below it: a claim has
to outlive the process that makes it, and no OS primitive offers that.

FM-16 is new and was not visible from one machine: three defects, one per
platform, including one that was green locally and red in CI on the first push.
FM-17 is new and is the marker story -- one change of state, three rounds of
defects, every one of them in a reader.

Two corrections to the previous draft. The count of open review threads was
seven; it is two, and it was restated from memory and wrong more than once,
which is FM-13 committed inside a document about FM-13. And the first draft of
the FM-9 paragraph claimed the lock produced zero findings afterwards, which
`git log` disproves in three commits; the table now lists each one and says
what it actually was.

Section 3 is at thirteen. The newest is a test written by the author of this
section, in the round after drafting it, that reproduced shape 4 with the
description of shape 4 on screen -- and was caught by the ordinary green run
rather than the red one, which is luck and is labelled as such.

Green set 984, spec_gate green.

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

@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: 344e05cc8b

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

Comment thread packages/mcp_daemon.py Outdated
Comment thread scripts/start_mcp_daemons.ps1 Outdated
Comment thread scripts/stop_mcp_daemons.ps1 Outdated
kalisam and others added 3 commits August 31, 2026 23:01
Three findings, one property: no process may mutate a claim it does not own.
Four PowerShell sites and one Python write violated it in the same way.

--record-identity validated the reservation token and then wrote, with two
process probes in between. A launcher whose reservation goes stale has it
legitimately reclaimed in that gap, and the write then lands on the new
owner's claim having verified only the old one -- the original
two-servers-one-record bug surviving the fix meant to close it. There is no
compare-and-swap write for a file, so the transition is now the two primitives
that ARE atomic and are already how every other mutation here works:
CAS-remove the exact instance we inspected, then O_CREAT|O_EXCL the pid file.
Losing either step reports STALE_RESERVATION instead of clobbering.

The four release sites -- the start script's could-not-record and launch-failed
cleanups, and both of the stop script's OURS branches -- used Remove-Item on a
pathname. On stop, a start script that reclaims the record between Stop-Process
and the removal owns the slot, and deleting its files leaves its server live
and untracked. On start, the cleanup runs precisely BECAUSE another launcher
now owns the slot. The FOREIGN branches had already been taught to reclaim by
instance; it was the branches that succeed that were still removing blind.

All four now go through --release-claim <pid_file> token|pid <value>, which
releases only a record matching what the caller expects to find, sidecar first,
through the same shared instance-checked helper. NOT_RELEASED means someone
else owns the slot, which is the state the cleanup wanted anyway.

Two existing guards moved rather than being deleted. The sidecar-before-pid
ordering they asserted in the scripts now lives in _release_claim_cli, and is
asserted there. One of them also broke for a bad reason: it strips lines
starting with "#" but not <# #> blocks, so the first block comment in these
scripts -- which merely NAMES Stop-Process -- was read as a call site. Shape 4
from the learnings doc, inside the guard against it. _code_lines() now strips
both.

Green set 984 -> 991. All six new tests plus the two rewritten ones run red
against the unfixed source.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
FM-9 closed by saying the claim protocol has no layer below it -- a claim must
outlive the process that makes it, no OS primitive offers that, so a long tail
of findings was the correct expectation rather than a failure of care. Three
rounds later that was falsified in its general form and confirmed only in its
narrow one.

A claim's LIFETIME has no primitive underneath it. Its TRANSITIONS have two,
and the fix that closed three findings at once is built from them: CAS-remove
of the inspected instance plus an exclusive create, and one instance-checked
release replacing four pathname deletions. Both were available from round one.

So the corrected rule is narrower and more useful: "no layer below" is almost
never true of a whole component. Decompose it into the properties it maintains
and ask per property. The comparison now reads worse for the work, not better
-- going down a layer was available for most of the protocol and was taken nine
rounds late, because mechanism/policy/recovery was applied to the component
instead of to each property it holds.

Section 3 is at fourteen. The newest is a pair of guards written to stop call
sites drifting, which read a PowerShell docstring as a call site because their
comment-stripping knew about "#" and not "<# #>". Shape 4 has now produced five
of the fourteen and is the only shape to have recurred inside its own guard.

Counts refreshed: 43 commits, ~52 findings, suite 908 -> 991. The scope note no
longer says the loop ended; it says the loop has never converged and has only
ever paused when a reviewer stopped.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a fourth isomorphism to the Levin/CCES implications doc. The first three
were distilled from an external synthesis; this one runs the other way -- found
in PR #41's data first, matched to the corpus afterwards -- which is both why
it is worth recording and why it is labelled Specified rather than Verified.

The claim: the session's dominant defect shape (a correct mechanism attached to
a boundary one step smaller than the property it protects) and Levin's account
of cancer (intact machinery, contracted self/world boundary, optimising below
the scope the tissue needs held) are the same statement. His therapeutic --
restore the connection, do not repair or kill the cell -- is the shape of the
one intervention that worked here: replacing the lock's mechanism ended a
defect class by making it inexpressible, not by improving the code.

Two secondary mappings. The barrier experiment and the red run are one
epistemology: neither a light cone nor a test's power can be read off the
artifact, only measured under perturbation. And a reviewer roster is a
competency architecture rather than a redundancy stack -- CodeQL found a
permissions defect two model reviewers had each read past twice, because that
question is outside their goal space. Voters already have a diversity policy
for this reason; reviewers have none.

The prediction is recorded before the observation that would test it:
components with a layer below should show finding-rate collapse after a
mechanism swap, components without one should show a tail. This PR has exactly
one instance of each arm, which is a hypothesis.

Also corrects three restatements of the light cone that change what one would
measure: it is not perceptual (Levin excludes sensory and causal reach by
name), not a multiplier on intelligence (cone size and ingenuity are the two
axes he separates), and not fractal (nested scales have different goal spaces;
no cell knows what a finger is).

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

@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: bfe3f6127b

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

Comment thread packages/activity_log/filelock.py
Comment thread packages/mcp_daemon.py Outdated
…e second

The green set failed on Linux only. The failing test was the one added last
commit to cover the record-identity window, and it failed for the reason this
repository has now been bitten by three times: ext4 hands a freed inode
straight back, so a file unlinked and rewritten with identical bytes is the
same (st_dev, st_ino) AND the same contents. On NTFS it is a different inode,
so the test discriminated locally and could not in CI.

The important part is not the portability. The state the test staged -- a
reservation carrying OUR token on a different instance -- cannot occur. A
reservation token is 96 random bits; an instance carrying ours is ours. The
test was asserting a property the system does not need and cannot provide.

The real race is a replacement carrying a DIFFERENT token, which is the only
reservation another launcher can write, and which discriminates on every
filesystem because it differs in content rather than in identity. Restaged
there. Verified red against 8ab23a3's unconditional write.

FM-16 in the learnings doc gains the fourth sighting and the second-order rule
it argues for: a platform assumption does not stay fixed by being documented,
and it was reintroduced in a test -- the one place the reintroduction is
invisible until CI, because a test that cannot discriminate still passes.

Green set 991.

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

@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: e379bca893

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

Comment thread packages/mcp_daemon.py Outdated
Comment thread scripts/stop_mcp_daemons.ps1 Outdated
…g harder

Four findings, and the first one is the layer this protocol has been avoiding
for fifteen rounds.

reclaim_if_unchanged is atomic in its rename and racy in everything around it.
A contender that replaces the record between the caller's inspection and the
rename has its LIVE record moved aside; the pathname is briefly free; a third
party can take it; the rollback's exclusive create then fails and the helper
drops what it is holding as "superseded". That reasoning is sound for a LOCK,
because only a dead holder's lock is ever reclaimed. It is false for a CLAIM,
whose displaced owner is still running -- so the owner is deleted, stays alive
untracked, and the newcomer starts a second server. FM-10 in the reverse
direction: same function, second domain, and the branch that became wrong is
the one nothing in the diff pointed at.

The module docstring said this had no fix at this layer. It has one, and it was
sitting in the same file: filelock.guarded(), an OS lock on a sibling .lock
that is never unlinked. Re-entrant, so the helper takes it and so does a caller
sequencing several helpers. The property that made locks safe -- nothing to
reclaim -- is what makes claims safe one level up.

Findings 2 and 3 are the same defect twice: --record-identity and
--release-claim each inspected the identity sidecar at the moment they were
about to delete it, not alongside the claim. A launcher that replaced the
record in the gap had ITS sidecar captured and deleted, and only then did the
claim check refuse to touch its claim -- leaving a live daemon whose
--check-identity says UNKNOWN, which both scripts then refuse to manage. Both
halves are now snapshotted together inside one guard.

Finding 4: --release-claim printed NOT_RELEASED both for "another launcher owns
the slot" and for "the record is stuck and still there". Both callers dropped
the boolean and the stop script went on to print unconditional success over a
record that will block the next start -- the fourth time these scripts have
announced a state they did not reach. Split into RELEASED / SUPERSEDED /
NOT_RELEASED, and only the last one reaches $unresolved.

Green set 991 -> 996. Four of the five new tests run red; the fifth is the
complement pinning the case that must keep saying NOT_RELEASED, and says so.

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

@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: 7bbc725394

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

Comment thread packages/mcp_daemon.py Outdated
Comment thread packages/mcp_daemon.py
… free pass

Two findings. The first indicts the commit before it.

Last round put reclaim_if_unchanged under a shared guard and left the two
exclusive creates it races against -- --reserve-slot and claim_singleton --
outside it. A guard only half the writers take is not mutual exclusion: a slow
reclaimer could still have its inspected claim replaced by one of those
creates, move the LIVE replacement aside, and lose it to a rollback that could
not reacquire the pathname. The right lock around the wrong span, which is the
shape this session has produced more than any other, committed one round after
writing that sentence down. Both creators now take the guard, with a short
budget so a daemon fails fast instead of hanging at startup and a shutdown
never blocks on it at all.

Second: --record-identity's token test only fired when the record was still a
RESERVATION. A launcher suspended past the stale window resumes to find the
winner has already converted the slot to a PID claim, _reservation_token_of
returns None for that, the mismatch branch never fired, and the loser deleted
the winner's claim AND sidecar and recorded itself. The comment called this "a
re-record, which was always allowed" -- true only when the pid is ours, which
is now the actual test. Moving a slot to a different PID is a release followed
by a record and has to be asked for in those words.

claim_singleton and its release callback split into _claim_singleton_guarded
and _release_guarded so the guard wraps each whole transition. Three
source-splitting guards needed repointing at the new names, which is the
standing cost of asserting on text rather than behaviour, and is noted in
them.

Green set 996 -> 1000. Three of the four new tests run red; the fourth pins the
idempotent re-record that must keep working.

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

@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: 283b48385b

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

Comment thread scripts/review_independence.py Outdated
Comment thread packages/activity_log/anchor.py
kalisam and others added 4 commits September 1, 2026 00:26
…read

anchor.py bounded the packet sequence from above only, so int() admitted "-1"
as an ordinary Merkle leaf: publish counted the schema-invalid file as a
packet, emitted an identity summary with max_seq -1, and left it OUT of the
signed unreadable set -- a later verify then called the anchor intact and
nothing named the malformed entry. The correct guard already existed, written
correctly, at the retained-anchor reader in the same file (`top < 0 or top >
MAX_SEQUENCE`); this was the sibling path that never got it.

Now canonical, not merely nonnegative, because leaf_preimage binds `s` as a
STRING: "+1", "01", "1_0" and Unicode digits all int() to the same slot while
producing different leaves, so admitting them lets one chain position occupy
several leaves in a signed tree. `sequence == str(slot)` rejects all of them.

review_independence.py excluded reviewers who raised NOTHING from the panel
size and not those who raised EVERYTHING, although phi() returns NaN for
either and its own comment says so. kish_neff drops those pairs from the mean
while the reviewer stays in k -- numerator and (k-1) -- so an unmeasurable
reviewer inflated n_eff and flattered the panel. The all-ones half is the more
likely one: a broad automated reviewer against a narrow union produces exactly
it. Exclusion is now iterated, because removing a reviewer removes the keys
only it raised and can leave a survivor constant in turn.

Also, in the same function and not asked for: the refusal branch printed "the
formula returns a finite number that is meaningless" and returned 0, so a
refusal was indistinguishable from a measurement to anything reading the exit
code. Ruff had been reporting the dead `REFUSED` local (F841) the whole time,
and this repo's own governance notes cite a corpus the tool "refuses to report
n_eff on, correctly" -- a refusal that was advisory only. It returns 2 now.

The fixture for the sequence tests re-signs through anchor_lib._said_digest
rather than hashing the document by hand. The hand-rolled version produced a
SAID the scanner rejects and passed every noncanonical case for the wrong
reason; it only surfaced when a case was added that had to get PAST the
sequence guard. The existing implausible-sequence test above has the same
hand-rolled shape and is protected by the same accident.

Green set 1000 -> 1010. Seven of the eleven new tests run red; the four that
pass are the complements pinning the cases that must keep working.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Triage first: 15 of PR41's 24 open threads were already fixed and never
resolved, which is why the same defects kept being re-derived. Those are
resolved. Six of the remaining nine are fixed here; the two hashline
patch-verification threads are deferred as their own change.

VOTER INDEPENDENCE. An unclassified model counted as its own family keyed on
the FULL route, so `groq/openai/x`, `nvidia/openai/x`, `openrouter/openai/x`
and `huggingface/openai/x` -- one model behind four vendors -- cleared a
four-family bar and the gateway reported it as independent consensus.

Collapsing all unclassified models into one bucket fixes that and breaks what
the branch exists for: a custom FLOSS_VOTER_ROSTER of four genuinely different
models across four providers would be refused. Two existing tests pin that
second case, deliberately, and they failed. They were right. Both cases are
real and they differ in the SUFFIX, not the count, so the unverified family key
is now the route minus its provider -- the mirror of _derive_surface. Both
tests pass unchanged. An unprobed model whose lineage matches a probed one now
inherits that family, or three probed families plus one unprobed twin would
reach four.

MIXED-MODE INDEPENDENCE. _online_pool() raised before the local voters were
appended, so a narrow online subset refused a run whose combined roster is
three surfaces and seven families -- reachable only through the degraded
override, which asserts the opposite of what is true about it. The check moved
to the combined pool. The first version read the surface off the model id,
which is the mistake generate() documents sixty lines above: the local pool's
`hf.co/unsloth/...` entry is an Ollama tag with two slashes in it, so four
local voters read as two surfaces. Transport is the authority, never the id.

UNREADABLE SOURCES. A read failure returned a plain string carrying neither
the deferral prefix nor "LLM Extraction Failed", so both caller guards missed
it and stage_draft() recorded the I/O error as the file's semantics; --commit
then wrote a completed distillation whose whole content was that error. Now
UNREADABLE::, its own branch, its own summary -- an operator sent to
--force-full for a permissions problem is sent to the wrong fix.

OPENCODE HEADERS. classify_transport() validates and returns the header map
and the OpenCode branch emitted only type and url, so an MCP authenticated by
header was projected unauthenticated -- a config that parses, installs, and
fails at connect with nothing in it to suggest anything was removed.

STALE SKILL PROJECTIONS. The materializer visited only skills still in the
registry, so a withdrawn or renamed skill kept its installed directory forever
and --check reported no drift. Only directories carrying the managed marker are
pruned; the marker is what makes the removal safe.

HERMES ATTRIBUTION. infer_surface() had no Hermes case, so `write_file` was
labelled gemini-cli and `patch` fell through to agent-tool. That label reaches
the Claim, the packet's source_systems, the summary and background memory.
`write_file` is both harnesses' tool name, so the event separates them, joined
to the manifest's own event_map by a test.

Green set 1010 -> 1028. 14 of 17 new tests run red; the three that pass are
complements pinning behaviour that must not change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reviewed before pushing, by an independent subagent and by two models through
OmniRoute. Two reviewers converged on the same silent-collision shape and the
subagent found a third defect on its own. All three were in the commit before
this one.

RETRY PATH. The rate-limit retry re-called extract_semantics and re-checked
only DEFERRED_PREFIX, so a file that became unreadable BETWEEN the two attempts
-- a permissions change, a dropped network share -- returned UNREADABLE::, was
neither a deferral nor an "LLM Extraction Failed", and fell through to
stage_draft with the I/O error as its extracted semantics. That is the exact
failure the comment three lines above it describes happening once already with
`force_full`: third marker to reach this site, second to be missed by it. Both
sites now share one `pending_marker()` predicate rather than growing a third
copy of the check.

MIXED-POOL ROSTER. assert_roster_is_independent takes a dict keyed by
voter_id, and the combined pool is built from two sources. A collision between
an online id and a LOCAL_VOTER_POOL id would silently drop an entry, so the
check would approve a smaller roster than the list returned two lines below
actually votes with, and the duplicate would vote twice. No profile collides
today -- online ids are provider-prefixed, local ones are bare -- which is
precisely what would make it silent if that stopped being true. Refused
loudly instead.

REGISTRY SELF-DISAGREEMENT. probed_by_lineage was a dict comprehension, so two
probed routes sharing a lineage but recording different families resolved by
iteration order, and an unprobed twin inherited whichever happened to be later:
a wrong family, chosen nondeterministically, inside the check that decides
whether a poll counts as independent. The registry currently agrees with itself
everywhere (12 entries, 10 lineages, 0 conflicts). A conflict now prints and
falls back to the unverified key rather than picking a side.

Green set 1028 -> 1030.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… to remove

THE HELPER DID NOT REPLACE WHAT IT WAS FOR. `pending_marker()` was introduced
last commit so the first-attempt and rate-limit-retry sites could not disagree
about which results are not-processed. It was then wired into the retry site
only, and the first site kept its own hand-rolled pair of startswith checks --
so the duplicate predicate survived the commit that existed to remove it. Two
copies of that classification is exactly how UNREADABLE:: came to be missing
from the retry. Both sites now go through pending_marker() and a shared
record_pending().

REGISTRY CONFLICT MARKER. Writing "" into probed_by_lineage to mark a conflict
is indistinguishable from a registry entry whose family really is empty, and
`.get(lineage) or lineage` conflated the two. It also re-reported on every
later route sharing the lineage, so three conflicting routes printed twice. A
`conflicted` set drops the lineage instead, reports once, and needs no
sentinel that can collide with real data.

CLASH DETECTION. The duplicate-voter_id check used a set comprehension whose
filter relied on `set.add` returning None. Verified correct, and replaced with
Counter anyway: on this file's history, correct-and-unreadable is a defect
waiting for the next edit.

And a test guard, twice. `test_caller_skips_staging_before_it_can_stage_a_
deferral` asserted the name DEFERRED_PREFIX appeared in main(); that name moved
into the shared helpers, so the guard broke on a refactor that did not touch
the invariant -- the fourth source-splitting guard this session to need
repointing. Rewritten against pending_marker(), whereupon its call count read 3
instead of 2 because a COMMENT in main() names the function: matching prose
instead of code, inside the test written to replace a test that matched prose
instead of code. Counted over code lines now.

Green set 1030.

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

kalisam commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator Author

CodeRabbit autofix run — PR #41 backlog

Swept every open PR for review threads, then worked PR #41's backlog.

Across all 10 open PRs: 59 unresolved threads on four branches (#43 has 32, #41 had 24, #59 has 2, #61 has 1; the six dependabot PRs have none).

PR #41: 24 open → 2

15 were already fixed and had never been resolved. They are the reason the same defects kept being re-derived by automated review. Each was verified against current HEAD before resolving — force-full retry threading, %LOCALAPPDATA% on POSIX, the FLOSS_HOOKS platform default, patch in MUTATING_TOOL_NAMES, pre-write repo containment, transport attribution on the error path, the stop-script exit code, empty-pid-as-in-progress, online-roster independence, profile-alias normalisation, deferral starvation, the OmniRoute provider label, exception breadth at the voter boundary, user-scope opt-in, and the renamed-ADR references.

7 were real and are fixed in 2a55711, 29feb91, 222d27b:

Area Defect
voters.py Unclassified models each counted as a distinct family, so four routes to one model cleared a four-family independence bar and the gateway reported false independence
transport.py Mixed mode judged the online subset before appending local voters, refusing rosters that are independent once combined
autonomous_synthesis_loop.py A read failure was staged as extracted semantics; --commit then recorded an unread file as a completed distillation
materialize_shared_agent_surface.py OpenCode HTTP projection dropped headers, emitting authenticated MCPs unauthenticated
materialize_shared_skill_surface.py Withdrawn or renamed skills kept their installed projection forever and --check reported no drift
hook_post_write.py infer_surface() had no Hermes case, so every Hermes edit was attributed to gemini-cli or agent-tool

Still open (2): the paired hashline.py Hermes-patch verification threads. Deferred deliberately — normalising a Hermes patch payload into a verifiable pre/post image is a design change to the path that gates every Claim, not a guard, and it belongs in its own change with its own review.

On the independence fix

Two existing tests failed against the first version, and they were right: collapsing all unclassified models into one bucket would have refused a custom roster of four genuinely different models across four providers, which is what that accounting exists to permit. Both cases are real and differ in the suffix, not the count. The unverified family key is now the route minus its provider, and both tests pass unchanged.

Pre-push review

These commits were reviewed before pushing, by an independent subagent and by models routed through OmniRoute. That review found three further defects in the first commit and two in the second, including one the helper introduced to remove a duplicate predicate had itself left in place.

Worth flagging separately: of seven OmniRoute surfaces probed, two responded. nvidia/z-ai/glm-5.2 returned 410 (EOL 2026-08-21) and is priority 1 in the floss-cheap-capable combo; pioneer/grok-4.5 is sunset; cerebras returned "no active credentials" while check_quota reports its token valid. The configured combos need re-probing.

Green set 1010 → 1030. spec_gate --check green.

@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: 222d27b422

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

Comment thread scripts/materialize_shared_agent_surface.py
kalisam and others added 2 commits September 1, 2026 22:13
The OpenCode header fix was applied to the projection in view and not to its
siblings. classify_transport() documents `headers` as part of its contract and
four targets consume it; three of them wrote only type and url, so an MCP
authenticated by header was emitted as an unauthenticated server -- a config
that parses, installs, and fails at connect time with nothing in the generated
file to suggest anything was removed. Codex was raised by review; Antigravity
and Hermes were found by sweeping the other readers, which is the step that
should have been taken with the first fix.

Codex now projects `http_headers`, written with the tables rather than the
managed scalars because TOML re-parents every later scalar into a preceding
table -- the ordering constraint that function already exists to honour. It
also joins MANAGED_TRANSPORT_FIELDS, so a server converted to stdio drops its
old header table instead of preserving it: the same reasoning the `env`
handling documents, in the other direction.

Antigravity and Hermes have no verified header field. Inventing one would be
the same silent failure with extra steps, so a header-bearing HTTP server
aimed at them raises at materialization, naming the server and the target. One
definition of that refusal, three callers -- a per-target copy is how the first
fix reached one projection out of four.

No shared HTTP entry carries headers today, so all of this is latent. It is
also exactly the shape that is invisible until the day someone adds an
authenticated server.

One of the new tests passed against the unfixed code for a vacuous reason --
it built its stale header table by projecting first, and the old code never
wrote http_headers at all, so the absence assertion held either way. It seeds
the stale config directly now.

Green set 1030 -> 1035.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… of mine

Reviewed before pushing. All four defects are in the commit before this one.

STRANDED CREDENTIALS. Manifest overrides are applied last and can set `type`
to anything, including flipping an http entry to stdio after http_headers was
written -- leaving credentials on an entry that will never send them, in a
file an operator reads as current. Reconciled from the FINAL type rather than
from the transport the projection started with, because the override is what
decides it.

OVERRIDE ORDERING. Overrides were applied wholesale after the tables, which
contradicts the ordering rule this function exists to honour: tomlkit can
re-parent a scalar written after a table into it. That was harmless while the
only table was `env` on stdio entries, and adding http_headers put a table in
front of the override loop for exactly the entries that carry credentials.
Split by shape -- override scalars before the tables, override tables after --
so overrides still beat everything of their own kind. Verified that the pinned
tomlkit re-orders on render today, so this is the documented defense-in-depth
being restored rather than a live bug being fixed, and the test that pins it
says so instead of implying coverage it does not have.

HERMES SYMMETRY. Its two branches pop the other transport's keys so a stale
one cannot survive a transport change, and neither popped http_headers. Hermes
never writes one, but a hand edit can, and a credential table outliving its
transport is the same shape the Codex path now reconciles.

DUPLICATE ASSERTION. The guard that both header-less targets refuse called
build_antigravity_payload twice with the same argument and only varied the
match pattern -- and both patterns appear in the one error message, so the
second assertion tested nothing the first had not. It exercises Hermes now,
which is the sibling it was supposed to cover: testing one target twice is how
the other stays uncovered, which is the same mistake as the finding this whole
commit chain started from.

Green set 1035 -> 1037.

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

@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: 172a70ba98

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

Comment thread packages/reasoning_ensemble/synthesizer.py Outdated
Comment thread hooks/hook_post_write.py
…hing noticed

`materialize_shared_agent_surface.py --check` raised AgentMemoryError before
doing any work at all. The note landed in 726d568 with a `#` heading where its
two siblings carry a YAML block, and split_frontmatter refuses a file without
one -- inside the walk, so the whole projection failed, not just that entry.
Four days, from a docs-only commit, with the green set green throughout.

The guard is the second half. Every existing test in this file builds its
fixtures in tmp_path, so nothing here had ever read the real tree; the walk
that the materializer performs on every run was the only thing that could
catch this, and it is not in CI. The new test mirrors
`canonical_root.glob("*/*.md")` exactly -- top-level files like MEMORY.md are
indexes the materializer never reads, and a wider glob would fail on files it
does not care about. Verified by planting a frontmatter-less note and
confirming the test names it and fails.

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

@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: 616deaa0f1

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

Comment thread scripts/start_mcp_daemons.ps1
Comment thread scripts/materialize_shared_agent_surface.py Outdated
…wice

A companion to the packet written the same day from `feat/coordination-room`.
That one covers topology, tooling traps and concurrency hazards; this one covers
branch state, the merge condition, and the four threads still live on PR41.
Neither repeats the other, and the continuation-artifact map now points at both,
so a cold reader on any harness finds the pair rather than one half.

The pair is its own evidence. Four fixes were written twice inside 48 hours by
agents on different branches who could not see each other, and one pair --
the frontmatter block on the memory note -- came out byte-identical two days
apart. The duplicate implementation branch was deleted rather than merged,
because the other agent's version was better: it projects Codex `http_headers`
against Codex's documented reference where mine only refused to project them.

The merge condition is the part worth surfacing loudest. Every substantive PR
has zero failing checks and REVIEW_REQUIRED; nothing is APPROVED; and the
`copilot_code_review` rule in `safety rulez` cannot be satisfied, because
requesting that reviewer succeeds and adds nobody. As configured, nothing can
ever merge without the owner bypass. That is a standing condition on the
repository, not a backlog item on any one PR.

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

@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: e2d02af226

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

Comment thread packages/mcp_daemon.py Outdated
kalisam and others added 3 commits September 5, 2026 13:42
A COMMENT THAT DESCRIBED THE OPPOSITE OF THE CODE. The incomplete-reservation
arm in start_mcp_daemons.ps1 said "fall through and let the slot claim decide"
while being the FIRST arm of an if/elseif/else, which structurally guaranteed
the else block -- where --reserve-slot lives -- could never run. A launcher
that died between reserving and recording left a reservation that was
recognised, announced, and never reclaimed even past its stale window, so
OmniRoute stayed disabled until someone deleted the file by hand; and because
that arm added nothing to $skipped, the closing summary still reported every
daemon started. The message is now a statement, not a branch, and the
UNVERIFIABLE arm excludes reservations explicitly.

A FAILURE TO JUDGE IS NOT A JUDGEMENT. claim_singleton returned False for
OSError and ImportError -- the same False that means "someone else holds this"
-- so run_http_daemon printed "already running" and exited 0, and Start-Daemon
reads a clean exit as a healthy daemon. A machine that could not load the
shared lock helper or write its agent directory reported a successful startup
with the port unserved. ClaimUnavailable now separates the two; genuine
contention is still a plain False, because that is an answer rather than a
failure to produce one.

TWO VIEWS OF ONE ROSTER, AGAIN. The survivor recheck exempted `mixed`
alongside `local`. That stopped being defensible when resolve_voter_pool()
began judging the COMBINED mixed pool: a mixed run is admitted precisely
because online and local voters together clear the bar, so an outage that
kills the online half leaves a correlated subset the exemption would report as
a normal consensus tier. `local` stays exempt -- narrow by construction, not
degraded by circumstance.

INDETERMINATE IS NOT ABSENT. An unreadable or malformed Hermes gateway.pid
returned None, which every caller reads as "no live gateway" before rewriting
config.yaml -- which a running gateway then overwrites from memory on
shutdown. A half-written pid file is likeliest during the gateway's own
startup, so it failed open exactly when a gateway was most likely alive.
_pid_alive already fails closed for this reason; the reader was the half that
did not.

IDENTICAL EVENTS CANNOT BE TOLD APART BY GUESSING. Codex and Claude register
this hook with the same matcher and the same command, so the payload carries
nothing that separates them and the tool-name branch labelled every Codex edit
`claude-code` -- persisted in the Claim summary and the signed packet's
`source_systems`. Each registration now declares itself with `--surface`, and
inference is what remains for an unmanaged install. The first version of this
read an environment variable while the manifest wrote a flag: plumbed at one
end, read at the other, declaring nothing. A test now joins the manifest to
the hook, and it immediately caught a fourth registration (gemini) that the
first sweep missed.

Green set 1037 -> 1050. 8 of 11 new tests run red; the 3 that pass are
complements pinning behaviour that must not change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A REFUSAL IS A RESULT, NOT A TRACEBACK. Making hermes_gateway_alive raise was
right -- the caller writes on its answer -- but letting it escape broke the
rule the surrounding block states in its own comment: an unusable file must
become one actionable line naming the path, not a traceback that discards every
result gathered so far and skips the downstream sub-materializers. It also
crashed `--check`, which has to be read-only and has to survive whatever it
finds on disk. Caught at the call site and reported as REFUSED, exactly like
the live-gateway branch beside it.

AN UNKNOWN LABEL MUST NOT REACH A SIGNED RECORD. `--surface` was accepted
verbatim, so `--surface codexx` from a manifest typo or a hand-edited target
config would be stamped into the Claim summary and the packet's
`source_systems` with nothing to notice it. Validated against a closed set:
the runtime refuses an unrecognised label and falls back to inference, because
an imprecise label is recoverable and an uninterpretable one is not. The real
guard is the manifest-side test, which catches a typo where it is introduced
rather than where it is consumed.

AND ONE I PUSHED BACK ON. The review called the PowerShell change a bug because
UNKNOWN plus a FRESH reservation now prints twice and ends in "already claimed
by another launcher". The behaviour is correct: a fresh reservation means a
launcher is mid-flight, refusing is right, and the $skipped entry it now
records is precisely the half that was missing before. What was fair in the
finding is that the two lines read as contradictory verdicts rather than as
diagnosis and outcome, so the first now says what it is handing on and under
what condition the slot claim will reclaim it.

Green set 1051 -> 1054. All three new guards run red against the code they
guard.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The external review bundle for this branch was sitting in a session scratchpad
under AppData\Local\Temp -- outside the repository, session-scoped, and gone
the moment that directory is cleaned. This directory already exists for exactly
that problem, and its own README says why: ADR-18's reuse gate requires
`reuse.reviewer.record` to be a repository-relative path to a real file, and
`.agent-surface/` fails that twice over by sitting above the repo and being
gitignored. A review record only the author can resolve is not a record.

So the packet lands at docs/reviews/2026-09-05-pr41-fix-sweep/, and README
gains a second packet type beside the protocol reviews it already documents.
The two are genuinely different shapes: a protocol review puts one question to
several reviewers and scores their independence; a fix-sweep handoff puts one
commit range to an outside reviewer after an internal pass.

The README records the four things such a packet must carry, each of them
learned by having been missing:

- the internal review's own findings, disclosed, so an outside reviewer spends
  attention on new ground rather than re-deriving known results;
- an explicit ledger of what the author could NOT verify, and what breaks if
  each unverified claim is false, because a reviewer can aim at stated
  uncertainty and cannot aim at unstated confidence;
- disagreements recorded rather than dropped, since a rejected finding that
  leaves no trace is indistinguishable from one never raised;
- the provenance of every commit in range, so another session's work is named
  and excluded instead of being handed over as the author's own.

It also records why the source and test diffs are split into two files: given
one diff, a reviewer reads the test as documentation of the fix and inherits
the author's blind spot, which is how a test that cannot fail survives review.

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

@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: c5159e5e24

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


return roster_independence_problem(
transport.active_online_profile(),
{r.voter_id: r.model for r in embedded},

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 Preserve transport when checking mixed-mode survivors

When mixed mode loses every online voter but all four local voters still embed, this recheck passes their bare model tags to roster_independence_problem(). That helper derives the provider from the text before /, so the three bare Ollama tags and the hf.co/... Ollama tag count as four provider surfaces even though every response's transport_name is ollama; the run consequently proceeds to ordinary tier classification with only one real surface. Fresh evidence after the resolved mixed-survivor finding is that the recheck now runs but discards the transport normalization already used by resolve_voter_pool(); reconstruct the independence routes from transport_name before checking.

Useful? React with 👍 / 👎.

if not values:
return float("nan"), float("nan"), 0
mean_phi = sum(values) / len(values)
if mean_phi <= 0:

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 Allow zero-correlation panels through the Kish calculation

When the panel's mean pairwise phi is exactly zero—for example, three reviewers each raise one shared finding plus one distinct finding—the Kish denominator is exactly 1 and the valid result is n_eff = k. This <= 0 condition instead returns NaN, causing report() to refuse the measurement and exit 2 even though the accompanying rationale only applies below zero; reserve the refusal for mean_phi < 0.

Useful? React with 👍 / 👎.

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.

2 participants