chore: bump to v0.4.5 — L1 drift wiring fix#10
Conversation
Fixes the two wiring bugs that made `pending → reflected` a no-op for freshly-ingested decisions: 1. ingest_payload now resolves HEAD from repo_path when no commit_hash is in the payload, computes a baseline content_hash for every grounded region, and derives the intent's initial status from that hash instead of hardcoding "pending". 2. handle_link_commit runs a repo-scoped backfill sweep that walks empty-hash regions and hands them to HashDriftAnalyzer, which now self-heals a missing baseline by adopting the current git state. Legacy ledgers self-heal on the next bicameral_status / link_commit call — no forced migration. Intent status aggregation picks the loudest value across regions (drifted > reflected > pending > ungrounded) so a single drifted region always raises an alarm. New regression test: tests/test_phase1_l1_wiring.py (4 cases covering ingest→reflected, edit→drifted, phantom range, and legacy backfill). Live-verified against Accountable-App-3.0: 8/8 decisions reflected after bulk Slack ingest, vs the prior 27/27 pending. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Hoist Collaboration Modes and Tool Composition above "How It Works" so the workflow narrative lands before the implementation detail. - Rewrite Tool Composition around a single running example (Sprint 14 checkout planning → discount rule → drift catch at PR review) showing how ingest / search / drift compose across a decision's lifecycle. - Drop CodeGenome mentions from the roadmap — superseded by the drift ladder plan and the planned CocoIndex re-grounding workstream. - Add ASCII art header with the decisions↔code chamber diagram. - Remove the Roadmap section entirely. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughVersion 0.4.5 adds self-healing for legacy regions with missing content hashes, a new backfill mechanism in the ledger adapter, updated drift analysis to handle absent hashes, per-intent multi-region status aggregation, a new query to locate regions without hashes, and comprehensive regression tests covering the updated ingest and link-commit flows. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Handler as link_commit Handler
participant Ledger as SurrealDB Ledger
participant Analyzer as Drift Analyzer
participant Query as Query Module
Client->>Handler: link_commit(ctx, commit_hash)
activate Handler
alt Backfill phase (new)
Handler->>Ledger: backfill_empty_hashes(repo_path)
activate Ledger
Ledger->>Query: get_regions_without_hash(repo)
activate Query
Query-->>Ledger: regions with empty hashes
deactivate Query
loop for each legacy region
Ledger->>Analyzer: analyze_region(..., stored_hash="")
activate Analyzer
Analyzer-->>Ledger: DriftResult(status="reflected", content_hash=actual)
deactivate Analyzer
Ledger->>Ledger: update_region_hash(region_id, actual_hash)
Ledger->>Ledger: update_intent_status(intent_id, aggregated_status)
end
Ledger-->>Handler: {healed_count, failed_count}
deactivate Ledger
end
Handler->>Ledger: ingest_commit(payload, commit_hash)
activate Ledger
loop for each region in payload
Ledger->>Analyzer: analyze_region(stored_hash, actual_hash)
activate Analyzer
Analyzer-->>Ledger: DriftResult with status
deactivate Analyzer
Ledger->>Ledger: persist region_hash & derive status
end
Ledger->>Ledger: _aggregate_intent_status(region_statuses)
Ledger->>Ledger: update_intent_status(intent_id, aggregated_status)
Ledger-->>Handler: ingestion result with region_ids
deactivate Ledger
Handler->>Handler: _reground_ungrounded(ctx)
Handler-->>Client: LinkCommitResponse
deactivate Handler
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly Related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…+Gemini+Codex-2 (#205) Authors a single Reviewer Disposition Pass table at the top of the brief reconciling all 32 review points across four review layers (Codex first-pass, Kilo, Gemini CLI, Codex second-pass) into one post-review consensus before downstream P1 issue-filing — per the explicit Codex-2 #1 directive. Decisions: 21 applied this commit, 6 already applied in 1d82658, 3 deferred to follow-up, 2 note-only. Net new gap IDs added per disposition: GDPR-08 (ephemeral data), GDPR-09 (consent versioning + revocation), LLM-11 (cross-tool config-file modification surface), MCP-01 (host UX as external dependency), CFG-01 (config precedence + fail-closed model). Reclassification: LLM-06 P0/M → P1/M with scope narrowed to future remote-skill-loading channel (per Kilo #2). Major content additions to the brief: - § 1.1: MCP host UX is external dependency, not security gate (new gap MCP-01) — host that auto-approves tool calls bypasses any "operator will see this" assumption. - § 1.2: SurrealDB version pinning supply-chain callout (Kilo #11). - § 1.7: cross-tool config-file modification surface (new gap LLM-11) distinct from skill-content surface — `setup_wizard` writes shell commands into `.claude/settings.json` that run host-side at hook fire. - § 1.11 (new): Configuration precedence + fail-closed model — single uniform precedence rule across all knobs (env > config.yaml > hardcoded defaults), fail-closed semantics on missing/malformed/ contradictory config (Codex-2 #5). - § 2.4 (a): LLM02 mapping note clarifying it folds into LLM-07 + OWASP-04 (Kilo #13). - § 2.4 (b): explicit `confirm=True` is agent-supplied not HITL (Kilo #3) — security context cannot rely on agent-filled params. - § 2.4 (c) LLM-01 + LLM-04: extensible classifier (Gemini #2) + guardrail-not-classifier framing (Codex-1 #6) + control-acceptance template (Codex-2 #4) — quarantine, override, test fixtures, measurement counters. - § 2.4 (c) LLM-03: timeouts as `.bicameral/config.yaml` knobs (Gemini #3). - § 2.4 (c) LLM-05 + LLM-09: out-of-band operator confirmation, not agent-supplied confirm parameters (Kilo #3). - § 2.4 (c) LLM-06: scope-narrowed to future remote-skill-loading; in current install model the wheel-trust covers it (Kilo #2). - § 2.4 (c) LLM-11 (new): cross-tool config-file gate (signed hooks-manifest.json) distinct from skill manifest. - § 2.1 (c) GDPR-01: three remediation candidates — tombstone-and- rebuild with signed manifest (Kilo #12), crypto-shredding (Gemini #1), or scope-out via PII detect-and-refuse. - § 2.1 (c) GDPR-02: data-subject-access search must cover full identifier surface (description, source_ref, topic, file paths) not just signer email (Codex-1 #5). - § 2.1 (c) GDPR-08 (new): ephemeral data surfaces (tempfiles, swap, WAL, crash dumps) (Kilo #7). - § 2.1 (c) GDPR-09 (new): consent versioning + revocation semantics (Kilo #8 + Codex-2 #3). - § 5: gap table updated with new rows + LLM-06 reclassification; gap counts post-disposition (5 P0 / 19 P1 / 16 P2 / 5 P3 = 45 total, up from 41). - § 6.1 (new): epic grouping for deferred P1 batch (Codex-1 #10) — ingest boundary guardrails, per-tool authority gradation, supply- chain signing, telemetry & consent. - § 6.2 (new): six-section control-acceptance template for every DG gap (Codex-2 #4) — positive / negative / bypass / fail-closed / telemetry / docs. Filed-issue updates: - Issue #214 (LLM-06): relabeled P0 → P1, retitled to reflect scope narrowing, full disposition comment added. - Issue #212 (LLM-01) + #213 (LLM-04): disposition comments added capturing the guardrail framing, classifier extensibility, and control-acceptance template applicable to both. Deferred for follow-up: Codex-1 #4 (controller/processor restructure of standards table), Codex-1 #9 (full evidence appendix beyond the methodology softening), Codex-2 #2 (full 3-column deployment-profile matrix beyond the single-column trigger). Brief now 706 lines (up from 606); +124 line diff. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Schema v24 → v25: add non-unique key indexes on `symbol.name` and `vocab_cache.(query_text, repo)` so the UPSERT-WHERE call sites in `ledger/queries.py` stop falling back to full table scans. Today's bug: `idx_sym_name` and `idx_vocab_query` are both SEARCH/BM25 indexes — they accelerate `@0@` semantic matches but NOT `WHERE field = $value` equality lookups. The corresponding UPSERTs (`upsert_symbol`, the vocab_cache UPSERT) scan O(n) per call; replays of large event logs cross the 5.0s read budget near completion and surface as `LedgerTimeoutError`. Reproduced today via PR #412's recovery path on a 3,002-event log. Per `docs/DEV_CYCLE.md` §4.7: - Additive only — new indexes alongside existing BM25 ones. ✅ Allowed. - No flag-gate — invariant fix per the §4.7.2 carve-out, not new feature surface. - Migration in its own commit, idempotent via `_execute_define_idempotent`. `init_schema` is the real mechanism; `_migrate_v24_to_v25` is the version-boundary safety belt. Verification mechanism: SurrealDB 2.x's trailing `EXPLAIN` modifier. Pre-migration `SELECT * FROM symbol WHERE name = 'x' EXPLAIN` plans to `Iterate Table` (full scan); post-migration it plans to `Iterate Index` with `detail.plan.index = "idx_sym_name_lookup"`. Same shape for vocab_cache. Empirically validated against memory:// during the audit. Tests (`tests/test_schema_index_lookup_perf.py`, sociable): - `test_upsert_symbol_returns_single_row_for_unique_name` — UPSERT semantics: novel name → exactly one row, valid id returned. Seeds 1000 background rows first. - `test_upsert_vocab_cache_returns_single_row_for_unique_compound_key` — same against vocab_cache compound key. - `test_symbol_name_lookup_uses_equality_index_post_migration` — EXPLAIN-based; asserts `Iterate Index` + `idx_sym_name_lookup`. Fails loudly when DEFINE INDEX silently fails to land. - `test_vocab_cache_lookup_uses_compound_index_post_migration` — same for `idx_vocab_query_lookup`. - `test_schema_version_advances_to_25` — runs init+migrate, asserts `schema_meta.version == 25` and `_MIGRATIONS[25]` is the v24→v25 function. Audit trail: plan + AUDIT_REPORT.md (R1 VETO, R2 PASS), META_LEDGER Entry #53 / #53-R2, SHADOW_GENOME Entry #54 (heuristic #10: introspection-mechanism commitment). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
v0.4.5 fixes the L1 drift wiring bugs that made
pending → reflecteda no-op for freshly-ingested decisions. Live-verified against Accountable-App-3.0: 8/8 decisions reflected after bulk Slack ingest, vs the prior 27/27 stuck at pending.Fixes
Also in this PR
Out of scope
CocoIndex-driven re-grounding on delta, AST (L2) and LLM-judge (L3) drift layers, and the single-token BM25 degeneracy guard (FC-1) are all tracked in separate plan files and are not in this PR.
Test plan
🤖 Generated with Claude Code
Summary by CodeRabbit
Release Notes – Version 0.4.5
New Features
Bug Fixes
Documentation