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:
parent
e6cc18bf18
commit
055c6971ab
11 changed files with 2964 additions and 9 deletions
|
|
@ -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.
|
||||
182
docs/evidence/RMGR-WP-0005-batch-0005-adaptive-pricing.json
Normal file
182
docs/evidence/RMGR-WP-0005-batch-0005-adaptive-pricing.json
Normal 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
|
|
@ -47,6 +47,8 @@ rmgr identifier migration-verify --plan uuid-migration.json --repo repo-manager
|
|||
rmgr identifier migration-batch-plan \
|
||||
--plan uuid-migration.json \
|
||||
--repo whynot-design \
|
||||
--projection-api-base http://127.0.0.1:8000 \
|
||||
--projection-api-base http://127.0.0.1:18000 \
|
||||
--output batch.json
|
||||
rmgr identifier migration-batch-verify \
|
||||
--plan uuid-migration.json \
|
||||
|
|
@ -73,7 +75,12 @@ package. Each selected repository must still match the planned Git HEAD, have a
|
|||
clean worktree, exactly match its configured upstream, and use a non-retired
|
||||
origin. The batch records these facts and its own SHA-256 seal, but always emits
|
||||
`apply_authorized: false`. An explicit decision must cite that batch hash before
|
||||
any database or file mutation.
|
||||
any database or file mutation. Repeat `--projection-api-base` for every hub in
|
||||
the cutover: each replacement must resolve its current UUID with HTTP 200 and
|
||||
its derived target with HTTP 404 on every named projection, or the manifest is
|
||||
not ready for approval. Saved projection endpoints are rechecked by
|
||||
`migration-batch-verify`; omitting the option retains the offline source/Git-only
|
||||
planning mode.
|
||||
|
||||
Activation and applying a bulk migration remain separate governed steps.
|
||||
Publishing or planning this function does not retroactively rewrite existing
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue