feat(identifiers): verify batch projections

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
This commit is contained in:
tegwick 2026-08-22 23:50:34 +02:00
parent e6cc18bf18
commit 055c6971ab
11 changed files with 2964 additions and 9 deletions

View file

@ -0,0 +1,55 @@
# RMGR-WP-0005 batch 0005 projection preflight
**Observed at:** `2026-08-22T21:46:30Z`
**Scope:** `adaptive-pricing` only
## Outcome
Batch 0005 is source-ready but **not ready for approval**. No database or
repository identifier changed.
The refreshed fleet plan is sealed as
`28cd01bdbc66c53ad5ef11b9821a74ebadd7c8cfdae4c227f37ce7f9d67cbf18`.
The adaptive-pricing unit is clean, synchronized with `origin/main`, and pinned
at `c65a2f1ff9a0b30700ee14818e36e931eb71cae3`. It contains five replacements:
`ADAPTIVE-WP-0010` and its four unfinished tasks.
The projection-aware batch manifest is sealed as
`20decab5521ea5477826d1b2a9c9670912a96c4b8245faf5d270c8d1efc988c5`.
It records `ready_for_approval: false` and `apply_authorized: false`.
## Projection evidence
| Projection | Five current UUIDs | Five derived UUIDs | Result |
| --- | --- | --- | --- |
| Workstation `:8000` | HTTP 200 | HTTP 404 | ready |
| Production tunnel `:18000` | HTTP 404 | HTTP 404 | blocked |
A governed `registrar-reconcile --repair-workplan ADAPTIVE-WP-0010` attempt
used clean source revision `c65a2f1...` and correlation id
`b708a73e-fc09-48ee-aa2d-ff8b3c642466`. State Hub retained the conservative
C-03 rule for the pre-derivation random UUID and did not create it. This is the
correct ordinary-consistency behavior, but it means the existing transactional
migration executor cannot run: that executor requires every old source row to
exist in the target repository projection.
The attempt also exposed a Repo Manager result bug: a failed exact repair could
be labeled `applied` because an empty ordinary-registration set passed
verification vacuously. The wrapper now requires repair/bootstrap mode's own
exact projection proof and does not run ordinary requested-record verification
for an empty request.
## Owner-ready resolution
`helixforge.identifiers.state-hub-sealed-projection-repair.v1` offers State Hub
a bounded repair task. It preserves the default C-03 refusal and permits old-row
restoration only from one clean source revision plus one exact sealed migration
unit, with primary confirmation, atomicity, idempotency, and a receipt. Once
adopted, repeat this batch plan against both projections; only a new manifest
with all current lookups 200 and all derived lookups 404 may be proposed for
approval.
The fleet scan found one other projection-complete candidate, `state-hub`, but
its checkout contains unrelated uncommitted owner evidence. The Git preflight
therefore excludes it until the owner publishes or dispositions that work.

View file

@ -0,0 +1,182 @@
{
"schema": "repo-manager.identifier-migration-batch.v1",
"ok": false,
"ready_for_approval": false,
"apply_authorized": false,
"approval_required": true,
"projection_api_bases": [
"http://127.0.0.1:8000",
"http://127.0.0.1:18000"
],
"namespace": "helixforge",
"source_plan_sha256": "28cd01bdbc66c53ad5ef11b9821a74ebadd7c8cfdae4c227f37ce7f9d67cbf18",
"batch_policy": "repository-atomic, sequential, stop on first failure",
"rollback_order": "reverse files if written, then reverse central projection",
"generated_at": "2026-08-22T21:45:54.917855Z",
"totals": {
"repositories": 1,
"records": 5,
"replace": 5,
"assign": 0,
"unchanged": 0
},
"repositories": [
{
"repo": "adaptive-pricing",
"path": "/home/worsch/adaptive-pricing",
"planned_head_sha": "c65a2f1ff9a0b30700ee14818e36e931eb71cae3",
"source_fingerprint": "977e94daeb0a6955a3d4ba76393d0b273d285537d0789eb59350d5c283901887",
"source_verified": true,
"git_preflight": {
"ok": true,
"head_sha": "c65a2f1ff9a0b30700ee14818e36e931eb71cae3",
"expected_head_sha": "c65a2f1ff9a0b30700ee14818e36e931eb71cae3",
"upstream": "origin/main",
"behind": 0,
"ahead": 0,
"origin": "forgejo-remote:coulomb/adaptive-pricing.git",
"errors": []
},
"projection_preflight": {
"required": true,
"ok": false,
"projections": [
{
"api_base": "http://127.0.0.1:8000",
"ok": true,
"replacement_checks": [
{
"record_id": "ADAPTIVE-WP-0010",
"kind": "workplan",
"current_status": 200,
"derived_status": 404,
"ok": true
},
{
"record_id": "ADAPTIVE-WP-0010-T01",
"kind": "task",
"current_status": 200,
"derived_status": 404,
"ok": true
},
{
"record_id": "ADAPTIVE-WP-0010-T02",
"kind": "task",
"current_status": 200,
"derived_status": 404,
"ok": true
},
{
"record_id": "ADAPTIVE-WP-0010-T03",
"kind": "task",
"current_status": 200,
"derived_status": 404,
"ok": true
},
{
"record_id": "ADAPTIVE-WP-0010-T04",
"kind": "task",
"current_status": 200,
"derived_status": 404,
"ok": true
}
]
},
{
"api_base": "http://127.0.0.1:18000",
"ok": false,
"replacement_checks": [
{
"record_id": "ADAPTIVE-WP-0010",
"kind": "workplan",
"current_status": 404,
"derived_status": 404,
"ok": false
},
{
"record_id": "ADAPTIVE-WP-0010-T01",
"kind": "task",
"current_status": 404,
"derived_status": 404,
"ok": false
},
{
"record_id": "ADAPTIVE-WP-0010-T02",
"kind": "task",
"current_status": 404,
"derived_status": 404,
"ok": false
},
{
"record_id": "ADAPTIVE-WP-0010-T03",
"kind": "task",
"current_status": 404,
"derived_status": 404,
"ok": false
},
{
"record_id": "ADAPTIVE-WP-0010-T04",
"kind": "task",
"current_status": 404,
"derived_status": 404,
"ok": false
}
]
}
],
"errors": [
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T01",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T02",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T03",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T04",
"reason": "projection requires current UUID=200 and derived UUID=404"
}
]
},
"mapping_counts": {
"records": 5,
"replace": 5,
"assign": 0,
"unchanged": 0
},
"ready": false
}
],
"errors": [
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T01",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T02",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T03",
"reason": "projection requires current UUID=200 and derived UUID=404"
},
{
"scope": "http://127.0.0.1:18000:ADAPTIVE-WP-0010-T04",
"reason": "projection requires current UUID=200 and derived UUID=404"
}
],
"batch_sha256": "20decab5521ea5477826d1b2a9c9670912a96c4b8245faf5d270c8d1efc988c5"
}

File diff suppressed because it is too large Load diff