Skip to content

chore: bump to v0.4.5 — L1 drift wiring fix#10

Merged
jinhongkuan merged 2 commits into
mainfrom
chore/bump-v0.4.5
Apr 14, 2026
Merged

chore: bump to v0.4.5 — L1 drift wiring fix#10
jinhongkuan merged 2 commits into
mainfrom
chore/bump-v0.4.5

Conversation

@jinhongkuan

@jinhongkuan jinhongkuan commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Summary

v0.4.5 fixes the L1 drift wiring bugs that made pending → reflected a 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

  • Baseline hash stamped at ingest. `ingest_payload` now resolves HEAD from `repo_path` when no `commit_hash` is in the payload and computes a `content_hash` for every grounded region. Initial intent status is derived from the hash via `derive_status` instead of a hardcoded `"pending"`.
  • Backfill sweep for legacy ledgers. `handle_link_commit` walks repo-scoped empty-hash regions before the main drift loop and hands them to `HashDriftAnalyzer`, which now self-heals a missing baseline by adopting the current git state as `reflected`. Pre-v0.4.5 ledgers heal opportunistically 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.

Also in this PR

  • `docs(readme)`: restructured so Collaboration Modes and Tool Composition land above "How It Works", rewrote Tool Composition around a single running example (Sprint 14 checkout planning → discount rule → drift at PR review), added an ASCII header, dropped CodeGenome from the roadmap, removed the Roadmap section entirely.

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

  • `pytest tests/test_phase1_l1_wiring.py` — 4 new regression cases (ingest→reflected, edit→drifted, phantom range, legacy backfill) all pass
  • `pytest tests/test_phase2_ledger.py tests/test_vocab_cache.py tests/test_coverage_loop.py tests/test_phase1_code_locator.py` — 52/52 passing, no regressions
  • Live end-to-end: pipx-installed v0.4.5, ran `bicameral_ingest` inside Accountable-App-3.0 against Slack transcripts from `#accountable-tech` + `#accountable-strategy`, got 8/8 reflected / 0 pending (previously was 0/27 reflected)
  • Phase 3 integration tests fail identically on `main` and this branch (pre-existing `TeamWriteAdapter._ensure_connected` issue, unrelated to this change)

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes – Version 0.4.5

  • New Features

    • Added multi-region status aggregation for improved decision tracking across regions.
    • Introduced automatic baseline stamping at HEAD when commit hash is absent.
  • Bug Fixes

    • Fixed self-healing logic for legacy regions with missing content hashes.
    • Improved hash handling during commit and ingest operations.
  • Documentation

    • Enhanced collaboration modes guide (Solo vs Team behavior).
    • Expanded tool composition documentation with workflow examples and payloads.

jinhongkuan and others added 2 commits April 14, 2026 01:16
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>
@jinhongkuan jinhongkuan merged commit 0617e7a into main Apr 14, 2026
1 check was pending
@jinhongkuan jinhongkuan deleted the chore/bump-v0.4.5 branch April 14, 2026 05:25
@coderabbitai

coderabbitai Bot commented Apr 14, 2026

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bf7fe4aa-2c8b-4ea2-913a-86cebda28f28

📥 Commits

Reviewing files that changed from the base of the PR and between aae8809 and fe64e91.

📒 Files selected for processing (8)
  • CHANGELOG.md
  • README.md
  • handlers/link_commit.py
  • ledger/adapter.py
  • ledger/drift.py
  • ledger/queries.py
  • pyproject.toml
  • tests/test_phase1_l1_wiring.py

📝 Walkthrough

Walkthrough

Version 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

Cohort / File(s) Summary
Release & Documentation
CHANGELOG.md, README.md, pyproject.toml
Version bump to 0.4.5, release notes documenting behavior changes around content-hash handling and self-healing flows, updated README with new Collaboration Modes and Tool Composition sections.
Ledger Self-Healing & Status Aggregation
ledger/adapter.py
New async method backfill_empty_hashes() queries regions with missing hashes, runs drift analysis, and persists backfilled hashes with updated intent statuses. Updated ingest_payload() to compute per-region statuses and aggregate them into a single intent status using priority rules (drifted > reflected > pending > ungrounded).
Drift Analysis Self-Healing
ledger/drift.py
Added early return in HashDriftAnalyzer.analyze_region when stored_hash is absent: immediately returns reflected status with actual hash and high confidence, bypassing prior flow.
Ledger Query Utility
ledger/queries.py
New async function get_regions_without_hash() retrieves code regions with unset or empty content_hash fields, optionally filtered by repository.
Handler Integration
handlers/link_commit.py
Added try/except wrapped call to ctx.ledger.backfill_empty_hashes() at start of handle_link_commit, enabling pre-ingest self-healing of legacy regions without aborting on failure.
Regression Tests
tests/test_phase1_l1_wiring.py
New pytest module with four end-to-end async tests covering: immediate reflected state on ingest of existing code, drift detection after code edit, phantom ranges never reporting as reflected, and legacy ledger self-healing via link-commit backfill.

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
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly Related PRs

Poem

🐰 Hashes once lost, now gently found,
Self-healing ledgers spinning 'round,
Intent statuses dance in harmony,
Drift and reflect, in symphony,
Legacy regions rise once more!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/bump-v0.4.5

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Knapp-Kevin added a commit that referenced this pull request May 6, 2026
…+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>
jinhongkuan pushed a commit that referenced this pull request May 19, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant