#000012 Phase 1c: branch-set persistence — fork_score_branches table + CLI
Phase 1a scores one (parent, child) fork at a time; Phase 1b is the consensus paper. Neither persists multiple candidate branches at the same checkpoint — and #000037 §12 Trigger 1 ("ForkScore regularly receives ≥4 candidate branches per checkpoint") gates the multi- branch path of the Prometheus-Σ controller on this data existing. Phase 1c lands the missing seam. Schema (arborist/store.py): _migrate_fork_score_branches creates the sibling table with PK (branch_set_id, branch_id) + indexes on branch_set_id and parent_root. Sibling — never enters audit_events.event_hash preimage, so re-scoring or back-filling cannot break the audit chain. Helpers (arborist/substrate/fork_score.py): persist_branch_score upserts one row via ON CONFLICT (branch_set_id, branch_id) DO UPDATE so re-scoring the same fork under the same checkpoint is a clean overwrite, not a duplicate. branch_set_density(conn, branch_set_id) returns the count of distinct branches recorded under a checkpoint — the function the #000037 §12 Trigger 1 probe reads. ESTIMATOR_VERSION = "fork-score-v1" pins the producer generation on every persisted row. CLI (arborist/cli.py): arborist substrate score gains six new flags (--branch-set, --branch-id, --parent-root, --child-root, --persist-shard, --weights-id). Default off — --branch-set absent preserves Phase 1a pure-function semantics for every existing caller. When present, requires --parent-root and either --branch-id or --child-root; missing inputs return exit code 2. Tests (tests/test_fork_score.py, count 18 → 23): migration creates the table + both indexes; persist writes one row carrying parent/child roots + verdict + weights_id + estimator_version; upsert on the PK refreshes child_root + weights_id + recorded_at without duplicating; branch_set_density counts per-checkpoint and ignores cross-set rows; breakdown_blob round-trips as canonical JSON whose values sum to the persisted score. Status sync: #000012 §7 Phase 1c flipped from "proposed, not yet open" to "landed 2026-05-10" with the original proposal preserved below as design log. TICKETS row 117 mirror-updated. AUTOCOUNT counters in #000012 + cookbook bumped 18 → 23 plus the cookbook's fork_score.py LOC row refreshed (298 → 386 module, 403 → 609 tests, density 1.35 → 1.58). End-to-end smoke verified: arborist substrate score writes a fork_score_branches row with the expected schema (verdict / weights_id / estimator_version) and the row survives a clean SQLite read.
This commit is contained in:
parent
7676af8fb1
commit
d53115efd7
7 changed files with 460 additions and 5 deletions
|
|
@ -125,7 +125,7 @@ Newest first. Update on every open/close.
|
|||
| #000015 | π* domain library + cross-domain composition | closed · landed 2026-05-07 | 2026-05-07 | — |
|
||||
| #000014 | SelfModel: schema, falsification, integration | closed · landed 2026-05-07 | 2026-05-07 | — |
|
||||
| #000013 | Spatial-temporal substrate (Merkle-AGI v7-W) | closed · landed 2026-05-09 (substrate paper + frontier catalog + namespace stub) | 2026-05-07 | — |
|
||||
| #000012 | Selection & consensus protocol (Merkle-AGI v8) | in progress · Phase 1a (ForkScore) landed 2026-05-08; Phase 1b (consensus paper, `docs/_source/merkle-agi-v8-consensus.rst` 834 lines) landed 2026-05-10; Phase 1c (branch-set persistence) remains proposed-not-opened | 2026-05-07 | — |
|
||||
| #000012 | Selection & consensus protocol (Merkle-AGI v8) | in progress · Phase 1a (ForkScore) landed 2026-05-08; Phase 1b (consensus paper, `docs/_source/merkle-agi-v8-consensus.rst` 834 lines) landed 2026-05-10; Phase 1c (branch-set persistence — `fork_score_branches` sibling table, `persist_branch_score` + `branch_set_density`, 6 new CLI flags on `arborist substrate score`, default-off) landed 2026-05-10 — feeds #000037 §12 Trigger 1 | 2026-05-07 | — |
|
||||
| #000011 | SOFT_PREFLIGHT_HINT model-assisted sidecar | closed · landed 2026-05-04 (zero-shot full impl) | 2026-05-04 | D1 (preserves) |
|
||||
| #000010 | Meta-Cognition Preflight Guard (M0 / MCTL) | closed · landed 2026-05-03 (Phases 1–4); DAG binding shipped via #000009 | 2026-05-03 | D1, D3 |
|
||||
| #000009 | Preflight run-DAG node binding (#000008+#000010) | closed · re-landed 2026-05-04 (§8 corrections: reject-path DAG, nested CTI clauses) | 2026-05-03 | D3, D4 |
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ function ahead of the consensus paper:
|
|||
([0, SIGNAL_FLOOR)), REJECT (negative score OR hard-regression
|
||||
flag OR `NEG_INF_REGRESSION` flag).
|
||||
- Reference doc: `docs/v8-fork-score.md`.
|
||||
- Tests: <!--AUTOCOUNT:tests:tests/test_fork_score.py-->18<!--/AUTOCOUNT-->
|
||||
- Tests: <!--AUTOCOUNT:tests:tests/test_fork_score.py-->23<!--/AUTOCOUNT-->
|
||||
cases in `tests/test_fork_score.py` pin the pure ScoredFork
|
||||
dataclass + scoring contract (SIGNAL_FLOOR=0.05,
|
||||
HARD_REGRESSION_FLOOR=0.05, score = sum-of-breakdown closure,
|
||||
|
|
@ -347,7 +347,48 @@ What's deliberately NOT in Phase 1a (now specified in the v8 paper):
|
|||
- Stake mechanics + economic incentives. → Part 6
|
||||
- Cross-validator ZK proof exchange. → Closure §; deferred to #000016
|
||||
|
||||
### Phase 1c — Branch-set persistence (proposed, not yet open)
|
||||
### Phase 1c — Branch-set persistence (landed 2026-05-10)
|
||||
|
||||
**Status:** landed. Pressure-1 satisfied (Phase 1b paper landed
|
||||
2026-05-10 — multi-branch deployment paper-spec is closed); fox
|
||||
operator-go to wire the data path so #000037 §12 Trigger 1 gains
|
||||
empirical surface. Implementation pinned below.
|
||||
|
||||
- **Schema:** `fork_score_branches` sibling table created via
|
||||
`arborist.store._migrate_fork_score_branches`; indexes on
|
||||
`branch_set_id` and `parent_root`. PK `(branch_set_id, branch_id)`.
|
||||
- **Helpers:** `arborist.substrate.fork_score.persist_branch_score`
|
||||
(upsert one row; ON CONFLICT replaces score / verdict /
|
||||
breakdown_blob / weights_id / estimator_version / recorded_at) +
|
||||
`branch_set_density(conn, branch_set_id)` (count distinct branches
|
||||
for a checkpoint — the function the #000037 §12 Trigger 1 probe
|
||||
reads).
|
||||
- **CLI:** `arborist substrate score` gains six flags
|
||||
(`--branch-set`, `--branch-id`, `--parent-root`, `--child-root`,
|
||||
`--persist-shard`, `--weights-id`). Default off — `--branch-set`
|
||||
absent ⇒ pure-function semantics preserved (Phase 1a behavior
|
||||
unchanged for every existing caller).
|
||||
- **Estimator version pin:** module-level
|
||||
`ESTIMATOR_VERSION = "fork-score-v1"` constant; bump when a code
|
||||
change would produce a different `ScoredFork` from the same
|
||||
inputs (algorithm change, weight semantics, hard-regression
|
||||
policy). Persisted on every row so a reader can filter by
|
||||
estimator generation.
|
||||
- **Tests:** 5 new in `tests/test_fork_score.py` —
|
||||
migration-creates-table, persist-writes-one-row, upsert-on-pk,
|
||||
branch_set_density-counts-by-set, breakdown_blob-round-trips-as-
|
||||
json. Test count 18 → 23.
|
||||
- **Hard constraints honored:** sibling table never enters
|
||||
`audit_events.event_hash` preimage; no behavioral change to
|
||||
single-validator scoring; default-off CLI; no mesh wire format
|
||||
change; `weights_id` opaque (folding weights into a hash stays a
|
||||
Phase 1b/wire concern).
|
||||
|
||||
The original Phase-1c proposal text is preserved below for design-
|
||||
log continuity. Re-read it as the authoritative spec; the bullets
|
||||
above are the landing receipt.
|
||||
|
||||
#### Original proposal (preserved)
|
||||
|
||||
**Problem.** Phase 1a scores one ``(parent, child)`` fork at a time;
|
||||
Phase 1b is the consensus paper. Neither persists *multiple
|
||||
|
|
|
|||
|
|
@ -607,7 +607,7 @@ than waiting for bench-time STRICT-rate drift to surface it.
|
|||
input, recommendation-text mode transitions, and the §11
|
||||
worked-example bit-for-bit (with doc-calibration update
|
||||
surfaced through the test).
|
||||
- `tests/test_fork_score.py` — <!--AUTOCOUNT:tests:tests/test_fork_score.py-->18<!--/AUTOCOUNT--> tests for v8 ForkScore
|
||||
- `tests/test_fork_score.py` — <!--AUTOCOUNT:tests:tests/test_fork_score.py-->23<!--/AUTOCOUNT--> tests for v8 ForkScore
|
||||
(#000012 Phase 1a); pins SIGNAL_FLOOR (5pp) + HARD_REGRESSION_FLOOR
|
||||
(5pp), score = sum-of-breakdown closure, security_risk inert
|
||||
under default iota=0 (opt-in), NEG_INF_REGRESSION hard-reject.
|
||||
|
|
@ -675,7 +675,7 @@ than waiting for bench-time STRICT-rate drift to surface it.
|
|||
| warrant_resolver.py | ~800 | ~430 (combined) | 0.54 |
|
||||
| warrant_chain.py | 89 | 320 (<!--AUTOCOUNT:tests:tests/test_warrant_chain.py-->9<!--/AUTOCOUNT--> tests) | 3.6 |
|
||||
| t3_bound_calculator.py | 249 | 446 (<!--AUTOCOUNT:tests:tests/test_t3_bound_calculator.py-->53<!--/AUTOCOUNT--> tests) | 1.79 |
|
||||
| fork_score.py | 298 | 403 (<!--AUTOCOUNT:tests:tests/test_fork_score.py-->18<!--/AUTOCOUNT--> tests) | 1.35 |
|
||||
| fork_score.py | 386 | 609 (<!--AUTOCOUNT:tests:tests/test_fork_score.py-->23<!--/AUTOCOUNT--> tests) | 1.58 |
|
||||
| weights.py | 73 | 180 (<!--AUTOCOUNT:tests:tests/test_weights.py-->16<!--/AUTOCOUNT--> tests) | 2.5 |
|
||||
| pi_star/protocol+registry | 124 | 280 (<!--AUTOCOUNT:tests:tests/test_pi_star_protocol_and_registry.py-->21<!--/AUTOCOUNT--> tests) | 2.3 |
|
||||
| qa/progress.py | 85 | 226 (<!--AUTOCOUNT:tests:tests/test_qa_progress.py-->31<!--/AUTOCOUNT--> tests) | 2.7 |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue