docs: align Cataclysm brand blueprint with repo state - #195
Conversation
|
Caution Review failedThe pull request is closed. WalkthroughThis pull request introduces substantial platform updates encompassing strategic business documentation, financial analysis tooling, security-critical database schema changes with row-level security (RLS), major framework upgrades (Next.js 16 + React 19), authentication refactoring, and testing infrastructure migration from Vitest to Jest + Playwright. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Browser
participant NextJS
participant Supabase as Supabase<br/>(RLS Enabled)
participant FileService
User->>Browser: Upload file to Ingestion
Browser->>NextJS: POST /api/uploads/presign<br/>(authenticated session)
NextJS->>Supabase: Fetch session user<br/>(auth.uid())
Supabase-->>NextJS: User ID + auth state
alt Authentication Failed
NextJS-->>Browser: 401 Unauthorized
else Authenticated
NextJS->>Supabase: SELECT upload_events<br/>WHERE owner_id = auth.uid()
Supabase-->>NextJS: Event record<br/>(RLS enforced)
NextJS->>FileService: Generate presigned URL<br/>(with owner namespace)
FileService-->>NextJS: Presigned URL<br/>(namespace/users/{userId}/...)
NextJS-->>Browser: Presigned URL + owner_id
Browser->>FileService: Upload to presigned path
FileService-->>Browser: Upload complete
Browser->>NextJS: POST /api/uploads/persist<br/>(with owner_id, namespace)
NextJS->>Supabase: Validate session &<br/>UPDATE upload_events<br/>SET owner_id, status
Supabase-->>NextJS: ✓ Updated<br/>(RLS policy checked)
NextJS-->>Browser: Upload persisted
end
sequenceDiagram
participant Dev
participant CLI as Make / npm
participant LocalDB as Local Supabase<br/>Postgres
participant Schema as Schema<br/>Version
Dev->>CLI: make supabase-bootstrap
CLI->>LocalDB: Replay SQL migrations<br/>(06_upload_events.sql)
LocalDB->>LocalDB: Add owner_id column<br/>+ FK to auth.users
LocalDB->>LocalDB: Create RLS policies<br/>(owner-scoped select/modify)
LocalDB->>LocalDB: Migrate existing data<br/>from meta->'owner_id'
LocalDB->>Schema: Update schema version
Schema-->>CLI: ✓ Schema synced
CLI-->>Dev: Bootstrap complete
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Areas requiring extra attention:
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Free ⛔ Files ignored due to path filters (38)
📒 Files selected for processing (84)
Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Pro by visiting https://app.coderabbit.ai/login. Comment |
…o-cloudflare docs: align Cataclysm brand blueprint with repo state
CodeQL js/resource-exhaustion on serviceHealth.ts:71 is a false positive — timeout is already clamped to [1s, 60s] via Math.min(Math.max()) at line 69. Added lgtm suppression comment. Dashboard updated with final CodeQL status. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs(dashboard): refresh post-PRs #867-871 + branch sync Update Production Audit Dashboard with PRs #867-871 (port registry, smoke test remaps, CodeQL #196 fix, Jellyfin smoke codes). Sync main → Hardened (c6bc276). CodeQL #195 FP correctly suppressed, pending GitHub dismissal. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix(healthcheck): replace wget with node for supabase-meta postgres-meta image lacks wget/curl — use built-in Node.js http module for the /health endpoint check. Verified healthy in local testing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Shaela Bello <slbello@uncg.edu> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Post-unification (PR #865) smoke tests failed because: - test_env_uses_selfhosted_urls only accepted supabase-postgrest, not supabase-kong - test_supabase_pg_isready used hardcoded container name instead of resolving from docker ps - test_supabase_url_consistency didn't accept supabase-kong URL pattern Also: dashboard header reconciled to ade4248, CodeQL #195 closed, SUPABASE_REALTIME_ENC_KEY added to bootstrap registry. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Two of these were false claims this PR introduced or left standing, which is the same defect it was chartered to remove. The gate was case-SENSITIVE while the cheap-reject two lines below already used text.lower(). A tracked .py holding `# LGTM[py/path-injection]` returned "OK -- no markers", EXIT=0. An uppercase marker is not an evasion, it is someone typing, and it is the likeliest real spelling to reach a gate whose whole job is catching this comment. re.IGNORECASE on both patterns. The rewritten media-video rmtree comments asserted "CodeQL py/path-injection flags this anyway; triage it in the code scanning UI". Measured across open+dismissed+fixed: the only alerts ever raised on media-video/media-audio are 332 @ media-video:372 and 333 @ media-audio:492. No alert has ever existed on either rmtree line. A false suppression claim was swapped for a false alert claim. The safety reasoning is correct and stays; the two false sentences are gone. PRODUCTION_AUDIT_DASHBOARD.md:146 still said "#195 suppressed ... Added lgtm[js/resource-exhaustion] suppression comment". Alert 195 is state=fixed, closed by the Math.min/max clamp, and serviceHealth.ts contains no marker at all. The sweep was complete in code and incomplete in the doc a reader consults -- in a file class the gate deliberately never scans. Per-file read failure was a green result that measured nothing: chmod 000 on a file holding a real marker gave "OK ... in 4111 tracked files", EXIT=0, swallowed AND counted. scan() now raises UnreadableFile and main() exits 3. The success line counted 74 submodule gitlink DIRECTORIES it never opened; gitlinks are now dropped at discovery by index mode 160000 and the message reports what was actually read. P3-1 is the one that matters most, because a dismissal comment is the permanent public reason for not fixing a real PAT write: the cited "0700 parent" never fires, since mkdir(mode=0o700, exist_ok=True) only applies its mode to directories it creates and the default parent already exists at 775. Withdrawn in the comment and in the live dismissals -- alerts 265 and 387 re-dismissed through the API with corrected text. Hardened the mitigation that IS cited: the .tmp holding the PAT was created 0664 at the ambient umask and narrowed afterwards; it is now created 0600 via os.open, and a POSIX chmod failure exits 3 instead of printing OK over a 0664 PAT. Scope matching used substrings, so `.git/` matched pmoves/docs/ARTSTUFF/Ultimate-TTS-Studio.git/ and silently excluded 12 tracked, hand-written launcher scripts -- real content, not a synthetic probe. Now whole-segment. BACKTICKED_RE dropped the whole line instead of the quoted span. Added % and ; comment styles; deliberately did NOT add the no-prefix case, which would flag the prose the gate promises not to flag. Tests 13 -> 29. Each new test fails at 0ae13af and passes here; against the old gate with missing symbols shimmed, exactly the 12 new defect-tests fail and all 13 originals pass. test_markdown_is_skipped asserted a constant, so is_judgeable() moved out of discovery and the harness now exercises the scope rule instead of stubbing past it. Not regressed: 0 code markers, prose still greppable, no OPEN alert on any touched file, merge-decision still requires success from all eight gates. Carry forward: these edits move the flagged lines again, so 387 will be re-fingerprinted on the next scan and need re-dismissing after merge -- the dismiss-then-edit trap, observed a second time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FkwiW3VY1xWmahTAtVioxz
…re-entry (#2857) * docs(agnote): CLAIM SUPPRESSION-GATE lane — lgtm[] markers suppress nothing 10 `# lgtm[<rule>]` markers across 5 files advertise a suppression GitHub code scanning ignores entirely. Alerts 334/335/336/265 are HIGH and open on the exact marked lines. Separately, two markers name a rule id that does not exist (`py/clear-text-storage-of-sensitive-data`, no such rule). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FkwiW3VY1xWmahTAtVioxz * fix(security): remove 10 lgtm[] markers that suppress nothing, gate re-entry `# lgtm[<rule>]` is LGTM.com syntax. LGTM.com was folded into GitHub code scanning, which ignores the pragma entirely. Every marker advertised a suppression it never performed, which is worse than no comment: it reads as triage while the alert stays open. Measured, not assumed. Four of the marked lines carried OPEN HIGH alerts: 334/335/336 launcher_profile_select.py:212,243,216 265 inject_docker_hub_pat_from_cli.py:153 while two lines dismissed through the real API (332/333, the media-audio and media-video path-injection pair) were genuinely closed. Same repo, same rule family: the mechanism worked, the marker did not. Second, independent defect: both inject_docker_hub_pat_from_cli.py markers named `py/clear-text-storage-of-sensitive-data`. No such rule exists — enumerating every rule id observed across open+dismissed+fixed alerts returns 19 ids, none with the "of". Those two would have missed even on LGTM.com. The comment TEXT was load-bearing and is preserved, minus the false claim: - launcher_profile_select: verified render_env_template() emits `f"{secret}="` — key NAMES, values always blank. The rationale was true; it is kept. - media-*: verified _safe_input_path() does realpath + commonpath root confinement, and MinIO paths are mkdtemp + uuid4, never client text. - inject_docker_hub_pat: had no rationale to keep, and is NOT a false positive — a live PAT genuinely is written in clear text. The replacement comment says so, and records the real mitigations (0700 parent, 0600 file, atomic replace, value never printed). Calling it an FP would swap one false claim for another. Gate: pmoves/tools/lgtm_marker_check.py, stdlib-only, `git ls-files` discovery, matching the hardening_ratchet/action_pin_audit pattern; wired as an eighth merge-gate job. Exit codes 0 clean / 1 findings / 3 could-not-measure — 3, not 0, when discovery fails, because a gate that reports OK having judged nothing is the same defect in a different costume. Proven to say no: run against unmodified origin/main it finds exactly the 10 markers and exits 1, and it does not flag the prose in github_secret_capacity_audit.py that documents this defect. 13 tests, mostly negative controls. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FkwiW3VY1xWmahTAtVioxz * fix(test): build lgtm pragmas at runtime so the gate has zero exemptions CI caught the gate flagging its own test fixtures, which is correct behaviour and a real re-entry. My local run had reported clean because the test file was still UNTRACKED at that moment and `git ls-files` does not see untracked files — so the check ran against a tree that did not yet contain it. The gate was right; the verification was wrong. Fixed by assembling the pragma from parts at runtime rather than writing it literally. The alternative was exempting the test path, which is an allowlist with one entry, and an allowlist is how a gate quietly stops applying to the thing it was written for. Zero exemptions was worth keeping. Verified with the file STAGED this time: 4110 tracked files, exit 0; 13 passed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FkwiW3VY1xWmahTAtVioxz * docs(agnote): RELEASE SUPPRESSION-GATE lane — 10 markers gone, 10 alerts dismissed Records two findings worth carrying forward: verify gates with new files STAGED (git ls-files does not see untracked files, which made a local run report clean), and edit-before-dismiss (removing a marker re-fingerprints the alert and strands the dismissal). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FkwiW3VY1xWmahTAtVioxz * fix(gate): close 5xP2 + 4xP3 from the #2857 pre-merge review Two of these were false claims this PR introduced or left standing, which is the same defect it was chartered to remove. The gate was case-SENSITIVE while the cheap-reject two lines below already used text.lower(). A tracked .py holding `# LGTM[py/path-injection]` returned "OK -- no markers", EXIT=0. An uppercase marker is not an evasion, it is someone typing, and it is the likeliest real spelling to reach a gate whose whole job is catching this comment. re.IGNORECASE on both patterns. The rewritten media-video rmtree comments asserted "CodeQL py/path-injection flags this anyway; triage it in the code scanning UI". Measured across open+dismissed+fixed: the only alerts ever raised on media-video/media-audio are 332 @ media-video:372 and 333 @ media-audio:492. No alert has ever existed on either rmtree line. A false suppression claim was swapped for a false alert claim. The safety reasoning is correct and stays; the two false sentences are gone. PRODUCTION_AUDIT_DASHBOARD.md:146 still said "#195 suppressed ... Added lgtm[js/resource-exhaustion] suppression comment". Alert 195 is state=fixed, closed by the Math.min/max clamp, and serviceHealth.ts contains no marker at all. The sweep was complete in code and incomplete in the doc a reader consults -- in a file class the gate deliberately never scans. Per-file read failure was a green result that measured nothing: chmod 000 on a file holding a real marker gave "OK ... in 4111 tracked files", EXIT=0, swallowed AND counted. scan() now raises UnreadableFile and main() exits 3. The success line counted 74 submodule gitlink DIRECTORIES it never opened; gitlinks are now dropped at discovery by index mode 160000 and the message reports what was actually read. P3-1 is the one that matters most, because a dismissal comment is the permanent public reason for not fixing a real PAT write: the cited "0700 parent" never fires, since mkdir(mode=0o700, exist_ok=True) only applies its mode to directories it creates and the default parent already exists at 775. Withdrawn in the comment and in the live dismissals -- alerts 265 and 387 re-dismissed through the API with corrected text. Hardened the mitigation that IS cited: the .tmp holding the PAT was created 0664 at the ambient umask and narrowed afterwards; it is now created 0600 via os.open, and a POSIX chmod failure exits 3 instead of printing OK over a 0664 PAT. Scope matching used substrings, so `.git/` matched pmoves/docs/ARTSTUFF/Ultimate-TTS-Studio.git/ and silently excluded 12 tracked, hand-written launcher scripts -- real content, not a synthetic probe. Now whole-segment. BACKTICKED_RE dropped the whole line instead of the quoted span. Added % and ; comment styles; deliberately did NOT add the no-prefix case, which would flag the prose the gate promises not to flag. Tests 13 -> 29. Each new test fails at 0ae13af and passes here; against the old gate with missing symbols shimmed, exactly the 12 new defect-tests fail and all 13 originals pass. test_markdown_is_skipped asserted a constant, so is_judgeable() moved out of discovery and the harness now exercises the scope rule instead of stubbing past it. Not regressed: 0 code markers, prose still greppable, no OPEN alert on any touched file, merge-decision still requires success from all eight gates. Carry forward: these edits move the flagged lines again, so 387 will be re-fingerprinted on the next scan and need re-dismissing after merge -- the dismiss-then-edit trap, observed a second time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FkwiW3VY1xWmahTAtVioxz --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…r stacked defects fixed
…t regen (#2941) * docs(register): land the stranded B850 session journal (18 rows) + tooling audit regen The 2026-09-03/04 B850-CLAUDE session rows lived only in the main worktree's uncommitted state while their PRs (#2915, #2917, #2894, #2933, #2935 lanes) merged through other branches. Row text is landed verbatim, authored by B850-CLAUDE (Knuckles); transported by crush_glm52 per operator direction. Two draft rows (fix/branch-audit-protected-divergence, docs/hardened-branch-topology at 21:02/21:03) were dropped - main already carries the later 21:14 filings. The composio secrets_manifest edit was dropped - identical content landed via #2888. The tensorzero dynamic:: minimax fix is already on main (verified byte-identical). TOOLING_SCRIPT_AUDIT.md regen (2026-08-19 -> 2026-09-03, 529 scripts, +session keyword) is included - main still carried the stale generation. * docs(register): land the B850-CLAUDE handoff rows (9) - lane closeouts + CRUSH handoff Closes data-tier-bringup (delivered, corrects CRUSH's host-side misread), nats-cli-and-leaf-settle (delivered, nats CLI installed, leaf question settled, no-broker finding), embedding-path-restore (partial, cites #2895, ollama bind open), kilo/instance-integration (delivered, #2918 merged), dsh-linux-boot (delivered, dsh builds on Linux, cordis composes), skills-constellation (delivered, provisioning is deliberately non-recursive), node-steward-topology (#2933 open), and the chore/register-scope-expansion-guard CLAIM+RELEASE handoff pair to CRUSH. Row text authored by B850-CLAUDE (Knuckles), verbatim transport by crush_glm52. * docs(register): NOTE - grounded-personas corpus is prior art for the identity lane Bridge for the B850 identity work (#2935 + the G5 alter step): the v5.12 grounded-personas program already provisioned a threshold-bearing gate table (pmoves_core.persona_eval_gates, measured live: all zero rows), PERSONAS.md is a distinct persona data layer whose '8/8 seeds deployed' is stale on this node, and CONTROL_B850-CLAUDE_PRE-GROUNDING.md is a pre-grounding control specimen of B850-CLAUDE itself awaiting its post-grounding comparison. Also carries B850-CLAUDE's two in-flight CLAIM rows (fix/node-steward-mcp-access, fix/openroom-unblock-stack), verbatim, uncommitted in the shared worktree again. PR comment filed on #2935 so reviewers see it beside the proposal. * docs(register): land the review-thread-adjudication CLAIM + signing-card count correction Carries B850-CLAUDE's in-flight lane row (27 open PRs, 78 threads, 73 unresolved, 60 never replied - 27 P1 / 33 P2; #2935 threads resolved against head 32a87f7) verbatim from the shared worktree, plus a CRUSH count correction measured against signing_identity_cards.yaml: 20 of 25 cards are github-app with null installation_id (not 22), and the other 5 are ssh-bound with real fingerprints - substance holds, number corrected. Also notes gh REST works while account-wide GraphQL rate-limit bites. * docs(register): Knuckles node sitrep + mesh/NATS connectivity review Measured: bus tier effectively off the bus (local broker removed, NATS_URL targets localhost:4222 that nothing serves, mesh-agent at 1246 restarts under a cannot-fail healthcheck), botz-mcp-bridge genuinely degraded on a relative-import defect, agent-zero/tensorzero-gateway/ p7-orchestrator/openroom absent, port-audit Known Road broken in-tree, core healthy (63 containers, cipher on rebuilt pin, data tier up). Refresh order recorded; lane unclaimed. * docs(register): land the tokenism-identity-settlement-signature CLAIM (B850, stranded) ToKenism-Multi identity + settlement signature lane, opened on a KiloClaw survey and independently verified on B850: tally-signer-ed25519 confirmed as real Ed25519 k-of-n committee multisig (third-party verifiable, no shared secret) - the pattern the main CHIT runtime verifier should adopt now that #2965 made kid load-bearing. Row verbatim from the shared worktree; transport only. * docs(register): preserve the B850 journal that existed in no commit (28 rows) Three days of B850 register bookkeeping -- 2026-09-06 through 2026-09-08, 27 CLAIM/RELEASE rows -- existed only as uncommitted working-tree state on one filesystem of one node. Measured before this commit: git log --all -S'2026-09-08T21:15:27Z' -- <register> -> empty origin/main rows dated 2026-09-0[678] -> 0 HEAD rows dated 2026-09-0[678] -> 0 working tree rows dated 2026-09-0[678] -> 27 intersection(main, worktree) -> 0 The node's disk was scheduled to be physically pulled for an NVMe swap. An unrecoverable loss of the fleet's coordination memory was one hardware step away, and nothing would have reported it: the register would simply have reverted to a state asserting B850 still held ten lanes it had released. This is the node-local-state defect class -- a thing that works here, is reproducible nowhere, and reports success throughout -- applied to the one artifact every agent reads to avoid colliding with every other agent. Also lands the b850-ledger alter declaration in identity_vocabulary.yaml (node-qualified deliberately: _resolve_alter_parent() returns the FIRST parent declaring a matching alter with no duplicate gate, so a generic `ledger` would misattribute trails fleet-wide once a second node declared it). The 28th row is this session's RETURN-TO-SERVICE CLAIM, filed through register_append.py before this commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(identity): alias bare KILOCODE + registry key kilocode_glm Merging origin/main into docs/register-b850-journal-2026-09-04 (PR #2941) surfaced a pre-existing gap: register rows 2790/2804 co-own to bare `KILOCODE`, which was declared only under `harnesses:` (not loaded into the identity index), so test_identity_lineage.py failed closed with "undeclared co-owner 'KILOCODE'" on both the pre-merge branch HEAD and after the merge. `KILOCODE` is the same identity as `kilocode-glm` (`agent_registry.yaml`'s `kilocode_glm` entry declares `signature: "kilocode"`), so alias it there rather than split it. That in turn tripped test_the_registry_alias_rule_still_holds_against_both_files, which requires the registry KEY (`kilocode_glm`, underscore) to fold to the same identity once its signature resolves -- added as a further alias, per this file's own documented doctrine for the `claude_b850` key. 62/62 pmoves/tests/test_identity_lineage.py pass. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(audit): exempt the tracked pmoves-nats-mcp dir from orphan checks pmoves-nats-mcp is a repository-tracked, intentionally in-tree module; the orphan warning against it was false and told operators to add an unnecessary submodule mapping. Regenerate TOOLING_SCRIPT_AUDIT.md in an environment with submodules initialized to drop the warning from the report. CRUSH assist. Generated with Crush. * docs(register): re-claim the expired B850 lane, narrowed to the open half The 2026-09-09 CLAIM (24h) expired 1d18h ago while this node's session was down. Re-claiming rather than releasing: the clock ran out, not the work. A RELEASE would move live, half-finished items out of OPEN LANES, where the fleet looks, into a RELEASE row, which nobody scans for todos. Records what was delivered (journal preserved, #2941 dirty -> mergeable with union integrity proven, #2982 reviewed on the artifact) and the three measurement errors corrected in public -- wrong API surface, backtick pairing in grep patterns, and an unstated denominator. Remaining scope narrowed to the NATS-ownership disposition CRUSH put to this node on #2950; the anchors-ratchet and orphan-check work is left with CRUSH, who is actively on both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(register): bus-restore lane CLAIM+RELEASE - local broker live, round-trip PASS make up-bus restored pmoves-nats-1 (nats:2.11.8-alpine, -js -m 8222, auth). Verified per the five handoff traps: real pub/sub round-trip via nats-py inside the network, ports genuinely published (4222 0.0.0.0 auth-gated, 8222 loopback:9223 varz answering), restarts=0, 6 connections. No leaf wired (Z890-hub topology decision outstanding). Orphans reported. * docs(register): NATS schooling lane CLAIM+RELEASE - PR #3027 correspondence map delivered * docs(register): NOTE - operator records: floating-topology call + provenance testimony (1) Hub question answered by direction, not selection: no pinned hub - a three-in-one floating topology (split-brain-safe local brokers, capacity- following lanes, mesh-to-mesh), recorded in PR #3027 section 5.1. (2) DARKXSIDE provenance testimony filed for the attribution record: prior agent message-board capability, signal-mixing methodology, DoX process, scrapbook, Transcribe-and-Fetch, the friends-calc origin, the git+playlist grounding corpus, and the vision restated. CHIT-worth routed to the attribution machinery + gated Tokenism lane, not answered here. Also repairs a row-split fault introduced while appending (both rows restored byte-complete; postdate check clean). * docs(register): schooling lane attestation-mint RELEASE + three defects filed * docs(register): union-merge with main for PR #2941 - zero rows lost, 2 exact duplicates removed * docs(register): skills-first-class pair-review CLAIM+RELEASE - 3 COMMENTED reviews with verified evidence * docs(register): github-notification-pool CLAIM - wiring map for the review/notification triage pool * docs(register): release the B850 journal lane — unblocks CRUSH's refused re-claim The collision gate correctly refused CRUSH-GLM52's re-claim because this owner's expired row still stood. Closes BOTH B850 rows on this branch: the 2026-09-09 row that expired 1d18h unnoticed, and the 2026-09-11 narrowed re-claim whose scope is discharged. Lane is FREE. Disposition is complete, and the four self-corrections are the substantive output: wrong API surface on #2982; backtick pairing that made one file measure 10 and 0 in the same command; an unstated denominator; and judging #2950 against the pre-change version of the contract section that PR adds. Also records the correction in the other direction -- CRUSH was right that this node has no NATS broker. pmoves-nats-event-bus is a FastAPI facade (uvicorn nats_event_bus.app:app), publishes no host port, and reads healthy because its healthcheck probes its own /healthz. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(register): claim the orphaned bus-tier restore on B850 The node's top blocker had no owner. CRUSH asked whether to claim it, B850-CLAUDE answered GO, CRUSH then filed a different plan and no bus lane was ever opened. A verbal go-ahead is not a claim -- measured: zero open rows mentioned bus, nats or broker. Records the corrected ground truth: this node has NO NATS broker. Zero of 62 running containers have nats-server in image or cmd. pmoves-nats-event-bus is a FastAPI facade that publishes no host port and reads healthy because its healthcheck probes its own /healthz. CRUSH's original report was right and B850-CLAUDE's contradiction of it was wrong. Leaf wiring is explicitly out of scope: the leaf configs name a Z890 hub while the register guardrail makes Knuckles the single data-tier home. Operator call. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(register): resolve kilo findings - drop orphaned GRAPHITI_MARKs, repair folded test name, apply manifest exemption to audit - AGNOTE4482PHI.t1.md: remove 2 orphaned GRAPHITI_MARKs left by exact-duplicate row removals in the union merge (kept copies keep their marks; each row and mark now appears exactly once) - identity_vocabulary.yaml: unfolded the test-name reference so YAML folding no longer renders 'test_the_registry_alias_rule_still_ holds_against_both_files' with a spurious space - TOOLING_SCRIPT_AUDIT.md: apply the pmoves-nats-mcp known_non_submodule_dirs exemption from dd53005 (drop the ORPHAN warning, 6->5 findings) without a full rescan - a rescan from this node's main checkout contaminates the report with that checkout's local submodule state (ClawZ cap, A0-codex-docker orphan) NATS 'nats:pmoves@' credential finding: not changed - false positive, the string is the documented in-compose default already on main 111+ times (#1668). * fix(hermes): fail loudly at step 1 when the CLI interpreter chain is broken hermes-fleet-bootstrap.sh's step 1 used `command -v hermes` (passes for a wrapper whose exec target is a dangling symlink), discarded stderr on the --version probe (the only diagnostic: "cannot execute: required file not found"), and checked the pipeline's exit status via `|| echo unknown`, which never fires because `head -1` succeeds regardless of hermes's rc. The result: a broken interpreter chain surfaced three steps later as an opaque "Could not create profile" failure instead of failing where the actual defect was. Now step 1 actually runs `hermes --version`, requires a non-empty result, and fails immediately with the real stderr on failure. Added diagnose_broken_hermes(), which walks the resolved hermes binary (one level of wrapper `exec` if present) to its venv's pyvenv.cfg and calls out the known, recurring cause on this fleet: a venv provisioned against a python living under an editor's snap revision dir, which becomes a dangling symlink once that revision is garbage-collected. Also fixes a second-order bug introduced by the first pass: under `set -euo pipefail`, a bare `VAR=$(failing_cmd)` triggers errexit before the next line can inspect $?, which would have made the hardened check die silently instead of printing the diagnostic. The failing probe is now the condition of an if/else so errexit does not fire on it. Verified: a throwaway wrapper pointed at a dangling shebang now fails at step 1 with exit 1 and names the snap-revision cause, without touching the real (broken, pending rebuild) hermes-agent venv. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * fix(hermes): prefer the actual version banner over stderr noise Capturing stdout+stderr together for the broken-chain diagnostic (previous commit) had a side effect on the success path: hermes can print unrelated startup warnings to stderr before its version banner (observed here: a GATE_API_KEY env var with a non-ASCII dash, unrelated to this fix), and `head -1` on the combined output reported that warning as the "version" even though the CLI works fine. Prefer the line matching the actual "Hermes Agent v..." banner, falling back to line 1 if that pattern isn't found (keeps failure-path behavior unchanged). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * docs(register): claim guard-proportionality + secret-shape lane Operator principle recorded as the acceptance criterion: what is off limits must be a KNOWN known, enumerable up front, not a known unknown discovered by tripping it. A guard that only teaches by refusal spends the fleet's discovery budget on its own configuration instead of on real unknowns. Measured: edit/write damage-control guards each consult known_roads.py (4 refs each); the BASH guard has ZERO, so it is the only one that refuses without handing back the sanctioned road. Not a missing capability -- an unwired one. Also: GATE_API_KEY ships with an em-dash (U+2014) inside the key, is absent from the code-level secrets registry, and the funnel has no charset validation anywhere. Same family as the truncated E2B key. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(guard): resolve paths instead of substring-matching command text The Bash damage-control guard matched every protected entry against COMMAND TEXT. Each template bridges the verb and the path with `.*`, so two classes of legitimate work were refused: 1. a host-level interpreter environment rebuilt OUTSIDE this repo, because patterns.yaml lists bare artifact-directory names with no repository scope; 2. a claim-register note, because the note quoted the strings it documented -- the matcher reads text, not intent. The regex stage is unchanged and becomes CANDIDATE DETECTION. path_scope.py adds a confirmation stage that is MONOTONIC: it can only turn a candidate block into an allow, never the reverse, and fails CLOSED when the command cannot be lexed. It drops a candidate in exactly two cases -- no token in the command resolves to a path the entry covers (prose only), or the entry is repo-scoped and every match resolves outside the repository. New patterns.yaml key `repoScopedPaths` declares that second set explicitly, so which entries are repo-scoped is readable rather than inferred from code. Entries and tokens are compared component-wise, so a sentence is a single component and an absolute entry anchors on its leading empty component. Existing suite: 75 assertions across 5 files, green before and after. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(register): release bus-tier lane — restored, verified, 9 JetStream streams Proven by probes that can fail: varz real server fields, a pub/sub round-trip on bus.restore.probe, published host ports plus a raw /dev/tcp handshake returning the NATS INFO banner. 9 streams live including GEOMETRY_CGP, which closes the documented GEOMETRY BUS gap (no stream caught core publishes). Corrects my own brief: up-bus is Makefile:1470 not 1416, and it runs only 'up -d nats' -- NOT nats-init -- so it leaves JetStream at 0 streams while printing an unconditional '✅ NATS ready' after a self-probing gate whose failure branch is '|| echo'. Fourth check-that-cannot-fail found tonight. New defect for its own lane: nats-streams-validate CANNOT PASS. validate_streams.py parses 'nats stream ls -n' expecting 3 columns, but -n emits names only, so every line is discarded and it reports 0 streams and 9 MISSING immediately after creation. Needs an owner: broker takes --user/--pass as argv, exposing nats:pmoves in docker inspect and the process list. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * docs(register): CLAIM submodule-promotion-audit + botz-bridge-relative-import * docs(register): union-merge remote journal rows, dedupe * docs(register): botz-bridge lane RELEASE - PR #195 live-verified, four stacked defects fixed * fix(submodules): restore all 24 gitlinks to main — register PR must not carry submodule rollbacks The journal branch predates main's mass submodule promotion; union merges preserved its stale pointers (gitlink gate: 29 FAILs — ROLLBACK/DIVERGED/ SIDEWAYAS across Agent-Zero, Archon, Pipecat, etc). PR substance is register/ docs/scripts only; all gitlinks restored to origin/main values. * docs(register): notification-pool slice 1 RELEASE - PR #3033 live-verified, #2951 triage finding surfaced * fix(submodules): restore remaining gitlinks to main (pmoves-cipher-mcp, pmoves-keygen, integrations/archon) — second concurrent-push cleanup * fix(submodules): restore OpenRoom + pretext gitlinks to main (post-merge stragglers) --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: HERMES-AGENT <hermes-agent@pmoves.ai>
Summary
Testing
Follow-up
make vendor-httpx/ uv workflow to other Python services (publisher, notebook-sync, etc.) so offline bundles stay consistent.Summary by CodeRabbit
Release Notes
New Features
Improvements
Documentation