Reconcile PR38 with the salvage line: merged history, AGPL executed, sweettest unblock - #41
Reconcile PR38 with the salvage line: merged history, AGPL executed, sweettest unblock#41kalisam wants to merge 245 commits into
Conversation
…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>
… Stages 1-4 queued)
- 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.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
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>
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
… 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>
There was a problem hiding this comment.
💡 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".
…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>
CodeRabbit autofix run — PR #41 backlogSwept 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 → 215 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 7 were real and are fixed in
Still open (2): the paired On the independence fixTwo 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 reviewThese 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. Green set 1010 → 1030. |
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
…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>
There was a problem hiding this comment.
💡 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".
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>
There was a problem hiding this comment.
💡 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}, |
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
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 👍 / 👎.
Rejoins six weeks of parallel work and lands the corrections found along the way.
origin/mainis fully contained in this branch (0 ahead, 124 behind as of2026-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 thewip/salvage-20260804line (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:
workers/commons-gateway/*— ourmanifest.tsusedFLOSS/-prefixedpaths, producing a doubled URL segment, and listed
INDEX.md, which is not in thisrepo.
voters.py— PR38's_PERSONA_SHARED_GATE_SYSTEMhardening ("apersona may never waive or narrow the shared checklist") prefixed onto our
clean-room persona text, on both personas.
provenance.py—_is_ancestorand_ignored_chain_positionareindependent features, not rival versions.
Licence
FLOSSI_U/and the reuseledger, but
FLOSS/LICENSEstill held GPL-3.0 text. Now the AGPL SPDX line,byte-identical to
FLOSSI_U/LICENSE. GPL text archived, ADR-7 → Verified.MOMUS_PERSONA_SYSTEMwas adapted from oh-my-opencode(SUL-1.0, incompatible with AGPL). Replaced by a clean-room
EXECUTABILITY_REVIEWER_SYSTEMwritten 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. Verifiedholochain 0.6.3shipssweettest, soconsent_gate.test.tscan be ported without a substratemigration. 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()onlychecks
decision_action_hashis 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 andEVIDENCE_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.
_EVIDENCE_REF_TYPESinprovenance.py:564still holds the original six values and is the set
validate_packetactuallyenforces, so a schema-valid packet is rejected downstream. Second occurrence of
this pattern after
spec_gate.GATED_SURFACES.permanently invalidates every earlier packet naming it, and those stay in the
pchain. The spec's Audit Disposition section defines a
supersededstatus forexactly 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
spec_gate --check: 108 registered, 0 missing, 0 reuse violations, 7 stale(non-fatal; 5 are pre-existing
FLOSS/scripts/hook_*.pypath drift — those fileslive in
FLOSS/hooks/)origin/mainmerged 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 aheadof the local spine work, which has been abandoned.