dot-iu-cutter v0.1 — P0-4 verify_result Migration Design
dot-iu-cutter v0.1 — P0-4 verify_result Migration Design ⚠️ HIGH RISK
Date: 2026-05-15 Status: P0 MIGRATION DESIGN — Item 6 of 6 (HIGH risk; final P0 item; joint with P0-3 per Đ44 Step 2) Scope: DESIGN ONLY. No DDL, no SQL, no CREATE/ALTER TABLE, no column DDL, no migration execution, no PG mutation. Master:
migration-design/dot-iu-cutter-v0.1-p0-migration-design-master-2026-05-15.md
1. Purpose
P0-4 establishes the persistent PG SSOT for VERIFY stage outcomes — round-trip drift measurement (axis-1), axis-2 advisory coverage assessment, DOT-pair joint signature on VERIFY verdict, and PASS/FAIL/NEEDS_HUMAN status. P0-4 is the final P0 item; together with P0-3, it implements criterion 28 (DOT-pair / dual-engine verification mandatory for REPORT PASS).
2. Source Design References
- D1 Operational Design — §4.7 (VERIFY stage), §4.14 (DOT-pair).
- D6 Assembly Axes — §4.4 (verification per axis: axis-1 round-trip mandatory, axis-2 advisory in v0.1).
- G-4 closure — both-signatures rule; tool_revision drift rule.
- Đ44 Step 2 outcome —
cut_change_set+verify_resultjoint ratification. - Council Ratification Outcome §5.5 G-4 acceptance.
- P0-3 design §4.3 (shared
dot_pair_signaturetable). - P0 Schema Planning §5.4 P0-4 detail.
- Gate 2 review §3.4, §4 item 3 — axis-1 drift count unit decision.
3. Logical Object / Table Intent
Primary table: verify_result
Shared with P0-3: dot_pair_signature table (already designed in P0-3 §4.3) is used for VERIFY signatures.
Target DB: directus. Target Schema: same as P0-3 (TAC OR new manifest/cut/verify schema). Target Layer: Não (analytical / state record per P0 Schema Planning §5.4). Authority pattern: PG SSOT; immutable per VERIFY event.
4. Proposed Fields at Conceptual Level
4.1 verify_result
| Field name | Type-class | Nullable | Notes |
|---|---|---|---|
verify_result_id |
uuid | NO | primary identifier |
manifest_id |
FK to manifest_envelope |
NO | manifest being verified |
manifest_version |
text (semver) | NO | exact manifest version |
change_set_id |
FK to cut_change_set (P0-3) |
NO | CUT being verified |
review_decision_id |
FK to review_decision (P0-6) |
NO | the PASSed review that gated CUT (for traceability) |
verify_kind |
enum-ref | NO | values: axis_1_round_trip / axis_2_coverage / joint — what was verified |
axis_1_status |
enum-ref | NO | values: not_run / running / pass / fail |
axis_1_drift_count |
integer | YES | total drift count under chosen unit (§6) |
axis_1_drift_unit |
enum-ref | NO | values: byte / line / ast_node / canonical_token per Gate 2 §4 item 3 + §6 below |
axis_1_drift_details |
JSONB | YES | per-unit drift breakdown (which units, where, magnitude) |
axis_1_threshold |
integer | YES | drift tolerance threshold (typically 0; non-zero only with explicit policy + Đ32 approval) |
axis_2_status |
enum-ref | NO | values: not_run / running / pass / advisory_fail / not_applicable |
axis_2_coverage_score |
numeric (0–1) OR enum-ref (banded) | YES | per Đ44 A.6 #3 JSONB acceptance + Gate 2 §3.4 advisory |
axis_2_advisory_findings |
JSONB | YES | structured findings: missing metadata, weak edge readiness, etc. |
findings |
JSONB | NO | overall structured findings envelope per D2 §4.6 + verify-specific items |
verdict |
enum-ref | NO | values: PASS / FAIL / NEEDS_HUMAN |
verdict_rationale |
text | NO | human-readable rationale; required for FAIL and NEEDS_HUMAN |
executor_signature_id |
FK to dot_pair_signature (shared with P0-3) |
NO | executor's signed verify payload |
verifier_signature_id |
FK to dot_pair_signature (shared with P0-3) |
NO | verifier's signed verify payload (independent context) |
executor_tool_revision |
text | NO | revision at verify |
verifier_tool_revision |
text | NO | revision at verify |
tool_revision_match |
boolean | NO | true iff executor_tool_revision = verifier_tool_revision (G-4 drift rule) |
escalation_ref |
FK to decision_backlog_entry (P0-5) |
YES | when NEEDS_HUMAN, FK to routing entry |
verified_at |
timestamp UTC | NO | when verify completed |
verify_duration_ms |
integer | YES | metric hook |
state |
enum-ref | NO | values: pending / running / completed / superseded |
rollback_triggered |
boolean | NO | true if verify failure triggered automatic rollback (cross-link P0-3) |
rollback_change_set_id_triggered |
FK to cut_change_set |
YES | which change-set was rolled back due to this verify |
version |
text (semver) | NO | record version per Đ38 (typically frozen at 1.0.0) |
5. Field Ownership / Vocabulary Dependency
| Field | Vocabulary owner |
|---|---|
verify_kind, state, axis_1_status, axis_2_status enums |
cutter-local v0.1; Đ24 confirmation path |
axis_1_drift_unit enum |
cutter-local v0.1; Đ24 ratification recommended (Gate 2 closure) |
verdict enum |
cutter-local v0.1 (PASS/FAIL/NEEDS_HUMAN); reused from P0-6 review_decision pattern; Đ24 confirmation path |
findings JSONB |
structured per D2 §4.6 + verify-specific; JSONB-flexible per Đ44 A.6 #3 |
axis_1_drift_details JSONB |
cutter-local structured payload |
axis_2_advisory_findings JSONB |
cutter-local structured payload |
| Signature-related fields | cross-link P0-3 §5 |
6. Axis-1 Drift Count Unit — Options & Recommendation
Per Gate 2 review §4 item 3 (cross-link with P0-2 §9 item 4 — source_span unit must align with axis_1_drift_unit):
options:
byte:
pros: maximally precise; deterministic regardless of language/encoding
cons: trivial encoding differences (CRLF vs LF, BOM) inflate drift count
suitable_for: binary or canonical-form sources
line:
pros: human-readable; aligns with text reviewer mental model
cons: misses character-level drift; CRLF/LF normalization needed
suitable_for: markdown / text-line-oriented sources
ast_node:
pros: semantically meaningful; ignores formatting drift
cons: requires parser per source_kind; high implementation cost; out-of-scope for v0.1
suitable_for: structured artifacts (code, formal documents) — FUTURE capability intake
canonical_token:
pros: balanced: collapses whitespace/CRLF, preserves semantic units
cons: requires canonicalization rule per source_kind; moderate complexity
suitable_for: cutter's typical markdown/law artifacts
recommendation_for_v0_1: canonical_token
rationale:
- aligns with C1A's emphasis on canonical-form comparison
- handles CRLF/whitespace normalization naturally
- implementation cost is moderate (per-source_kind canonicalization rule)
- default canonicalization for markdown: NFC unicode normalization + LF line endings + trailing whitespace trim
fallback_per_source_kind:
code_artifacts: ast_node (FUTURE; mark as `not_applicable` for v0.1)
binary_artifacts: byte (FUTURE; out-of-scope v0.1)
threshold:
default: 0 (any drift = FAIL)
non_zero_only_with_explicit_policy: requires Đ32 approval + risk_class=high override
joint_decision_with_p0_2:
source_span_unit_on_manifest_unit_block must match axis_1_drift_unit so MARK-span ↔ VERIFY-drift align
recommendation: source_span unit = byte offsets (precise span), drift unit = canonical_token (semantic comparison)
conversion: canonicalization rule maps byte spans → canonical_token positions for drift calculation
7. Axis-2 Advisory Coverage Shape
Per D6 §4.4 (axis-2 verification is advisory in v0.1; mandatory hook):
axis_2_coverage_score:
shape: numeric 0–1 (continuous)
rationale: easier to threshold and tune over time; banded enum is derivable
fallback_banded_enum (for human reporting): low (<0.4) / medium (0.4-0.7) / high (>0.7)
axis_2_coverage_assessment:
inputs:
- count of canonical_units having required axis-2 metadata fields populated (section_type, unit_kind, semantic_role, candidate_edges, edge_readiness_notes)
- vocabulary discipline: Đ24-conformant labels
- universal_edges populated where candidate_edges proposed
formula_v0_1: simple weighted average (open decision §9 item 4)
threshold_v0_1: advisory only; FAIL is informational, not blocking CUT-publish
threshold_FUTURE: may become blocking after instrumentation matures + capability intake approves elevation
findings_shape:
axis_2_advisory_findings_jsonb:
missing_metadata:
- unit_local_id
- field_name (e.g. semantic_role)
- severity (advisory v0.1)
weak_edge_readiness:
- unit_local_id
- reason
- suggested_action
vocabulary_gap_observed:
- unit_local_id
- field
- value_observed
- vocabulary_gap_routed_to_backlog: true|false
8. Findings JSONB Shape
findings_envelope:
axis_1:
drift_count: integer
drift_unit: <axis_1_drift_unit>
drift_threshold: integer
per_unit_breakdown: list of {unit_local_id, drift_count, max_drift_point}
canonicalization_rule_used: text (which rule applied)
axis_2:
coverage_score: numeric 0-1
coverage_findings: list per §7
advisory_only: true (v0.1)
c1a_compliance:
revisited: boolean (whether C1A compliance was re-checked at verify)
findings: list per D2 §4.6 checklist (10 items) if revisited
dot_pair_check:
executor_signature_valid: boolean
verifier_signature_valid: boolean
tool_revision_match: boolean
if_any_false_signal: text (which sub-check failed)
birth_gate_check:
all_new_units_passed_birth_gate: boolean
failing_units: list of unit_local_id with reason
rollback_implications:
would_rollback: boolean (if verdict=FAIL → automatic rollback per D1 §4.8)
rollback_change_set_id_planned: uuid
Structured-flexible JSONB acceptable per Đ44 A.6 #3.
9. PASS / FAIL / NEEDS_HUMAN Semantics
verdict_rules:
PASS:
requires_all_of:
- axis_1_status = pass (drift_count <= drift_threshold; default 0)
- axis_2_status in (pass, not_applicable) — advisory in v0.1
- executor_signature_valid AND verifier_signature_valid
- tool_revision_match = true
- birth_gate_check.all_new_units_passed_birth_gate = true
- c1a_compliance.revisited may be false (review already covered); but if revisited, all items pass
effect: change_set may transition to `committed` (cross-link P0-3 state); REPORT emits PASS
FAIL:
triggers (any):
- axis_1_status = fail (drift > threshold)
- axis_2_advisory_findings has severity > advisory threshold (v0.1: never; v0.1 axis-2 is advisory only)
- birth_gate_check failed
- missing or invalid DOT-pair signatures
- tool_revision_match = false
effect:
- automatic rollback per D1 §4.8 (rollback_triggered=true; rollback_change_set_id_triggered populated)
- REPORT emits FAIL with verdict_rationale + findings
- rolled_back state propagated to P0-3 cut_change_set
NEEDS_HUMAN:
triggers (any):
- executor and verifier verdicts disagree
- axis_1 ambiguous (e.g., canonicalization rule itself contested)
- reviewer/verifier raised explicit needs_human flag
- risk_class=high and ambiguous finding
effect:
- no auto-rollback; CUT stays in `executing` state
- escalation_ref populated → P0-5 backlog entry kind=escalation
- human/council resolution required before resolution to PASS or FAIL
- new verify_result row issued upon resolution; this one transitions to `superseded`
10. Executor / Verifier Signature Concept (joint with P0-3)
Per P0-3 §7 + G-4 closure:
dot_pair_signature_for_verify:
executor_signature: signs the executor-internal pre-VERIFY result
verifier_signature: signs the independent VERIFY result run in separate context
both_required_for_verdict_PASS: TRUE (cross-link P0-3 both-signatures-required rule extends to VERIFY)
payload_envelope:
intent: "verify_pass" OR "verify_fail" OR "verify_needs_human"
verify_result_id: uuid (cross-reference)
manifest_id, manifest_version
change_set_id
axis_1_status, axis_1_drift_count, axis_1_drift_unit
axis_2_status
verdict (independent per signer)
signer_dot_id, signer_tool_revision, signed_at
disagreement_handling:
if executor.verdict != verifier.verdict → verdict=NEEDS_HUMAN regardless of individual verdicts
if both PASS but tool_revision_match=false → verdict=NEEDS_HUMAN
if both FAIL → verdict=FAIL (concurrence on failure is conclusive)
boundary_policy (Gate 2 §3.6; cross-link G-3 D4 intake post-G-3 operational):
executor_role: performs pre-VERIFY internally; signs as `executor_verify`
verifier_role: independent VERIFY in separate execution context; signs as `verifier_verify`
final_verdict_authority: both must concur (per criterion 28)
v0_1_implementation_boundary: deferred to G-3 D4 capability intake (per Council Ratification Outcome §5.5 G-4 dependency); design accepts the contract above as binding
11. Lifecycle
[verify_result lifecycle]
pending (VERIFY task created after CUT executor finishes its operations)
↓
running (executor pre-verify + verifier independent verify in parallel; signatures being collected)
↓
completed (both signatures collected; verdict computed)
↓
├── verdict=PASS → REPORT emits PASS; change_set transitions to committed
├── verdict=FAIL → automatic rollback; rollback_triggered=true; change_set transitions to rolled_back
└── verdict=NEEDS_HUMAN → escalation_ref populated; state stays completed; awaits human/council resolution
↓
re-VERIFY (new verify_result row); old one → superseded
12. Open Decisions
axis_1_drift_unitfinal value — recommendationcanonical_token(§6). Đ24 confirm + cross-link with P0-2 source_span unit.- Canonicalization rule per source_kind — default markdown rule (NFC + LF + trim) v0.1; per-source_kind rule extensions FUTURE. Đ24 ratification.
axis_2_coverage_scoreformula — open §7; weighted average v0.1 with weights TBD; FUTURE D4 capability intake for tuning.axis_2_advisory_findingsJSONB schema validation — application-layer v0.1; PGjsonb_checkFUTURE.drift_thresholdnon-zero allowance — policy decision; Đ32 must approve any non-zero default.verdict_rationalemandatory for FAIL/NEEDS_HUMAN — application-layer enforcement; PG check constraint FUTURE.- Disagreement-handling extended cases — what if signatures arrive at different times (race conditions)? Recommendation: state stays
runninguntil both arrive OR timeout fires → NEEDS_HUMAN. - Timeout for signature collection — open; recommendation: per risk_class (e.g., 5min for low, 30min for standard, manual-only for high). Đ32 confirm.
- Multiple VERIFY runs per change_set — allowed for re-verify after NEEDS_HUMAN resolution; chain via prior verify_result FK (open §9 item: add
prior_verify_result_idfield). Recommendation: add field; design above to be amended at next revision. rollback_change_set_id_triggeredcycle — verify_result → change_set rollback → if rollback fails, another verify_result issued? Recommendation: yes; chain via decision_backlog entries; no direct PG cycle.
13. Dependencies
upstream_dependencies:
governance:
- Council Ratification Outcome G-4 ratified_with_notes (both-sig + drift rule)
- Council Ratification Outcome G-2 (backlog tracking)
- Đ44 Step 2 cut_change_set + verify_result joint ratification
- Đ44 governance_event umbrella (signature_failure event sub-kind extension)
- Đ24 Step 1 (risk_class, event kinds)
schema:
- P0-5 decision_backlog_entry (escalation_ref FK)
- P0-2 manifest_envelope + manifest_unit_block (verify target; source_span unit aligned per §6)
- P0-6 review_decision (FK to PASS row that gated CUT)
- P0-3 cut_change_set (FK; shared dot_pair_signature table)
- P0-1 canonical_address (units cited by axis_1 drift_details indirectly)
external:
- dot-iu-cutter executor DOT (existing)
- dot-iu-cutter-verify verifier DOT (FUTURE registration per G-4)
downstream_dependents:
- F2 Health/Correction (D3): verify trends feed health signals
- D4 Capability Intake: axis_2 threshold elevation candidate
- retrieval audit: verify_result is the cut-correctness anchor
operational_dependencies:
- canonicalization rule library (FUTURE per source_kind)
- DOT-pair separate execution context for verifier (FUTURE)
- signature signing scheme (FUTURE per P0-3 §9 item 2)
14. Risks
| Risk | Severity | Mitigation in this design |
|---|---|---|
| Axis-1 drift unit mismatch with P0-2 source_span unit → systematic VERIFY failure | HIGH | §6 joint-decision rule; design refused to ship without consistent units |
| Canonicalization rule changes mid-cycle → ghost drift on previously-passing manifests | HIGH | canonicalization_rule_used field captures rule version; rule changes trigger D4 capability intake; legacy verify_results immutable |
| Both DOT signers in same context (verifier not actually independent) | HIGH | independence evidence required in payload_envelope; FUTURE PG constraint |
| Axis-2 advisory becoming silently mandatory due to mis-tuning | Standard | v0.1 axis_2 is explicitly advisory; elevation requires D4 capability intake + Đ32 |
rollback_triggered=true but rollback fails |
HIGH | rollback failure itself is a new health signal + backlog entry; manual recovery via G-4 Custodian + Đ32 |
| Signature timeout in race conditions | Standard | open §9 item 8 timeout policy per risk_class |
| Verdict drift between verify_result and review_decision | Standard | review precedes verify; if disagreement on what passed review, verify can flag NEEDS_HUMAN |
verdict_rationale left empty on FAIL |
Standard | application enforcement; FUTURE PG constraint |
axis_1_drift_details JSONB unbounded growth |
Standard | per-unit breakdown limited to drift-bearing units only; full-row breakdown only on debug runs |
| Re-VERIFY without prior_verify_result_id chain | Standard | open §9 item 9: add field in next revision |
| Tool revision drift detected but rollback path unclear | HIGH | G-4 closure explicit revert path; Đ32 escalation |
15. Đ32 Risk Review Notes
proposed_risk_class: HIGH
review_inputs_for_dieu32:
- logical design content (this document)
- axis-1 drift unit recommendation (§6) + cross-link with P0-2 source_span unit
- axis-2 advisory shape (§7)
- findings JSONB schema (§8)
- verdict semantics (§9)
- DOT-pair signature concept (joint with P0-3 §7)
- independence enforcement boundary (v0.1 application-layer; FUTURE PG)
- rollback chain integrity
- cross-law dependencies (Đ44, Đ32, Đ37 via G-4)
- migration execution preconditions:
- P0-5, P0-2, P0-6, P0-3 migrated
- dot_pair_signature table operational (shared with P0-3)
- canonicalization rule v0.1 documented
- DOT-pair separate execution context implementation plan
- rollback test plan from P0-3 also covers verify-triggered rollback
- backup directus before migration
- first VERIFY dry-run with synthetic data BEFORE first real cut
review_outputs_expected:
- Đ32 HIGH-RISK approval / approval_with_notes
- G-4 Custodian sign-off on DOT-pair verify boundary
- Đ24 ratification of axis_1_drift_unit value
- canonicalization rule v0.1 ratified
- axis-2 advisory boundary formally accepted
review_authority: Đ32 council (HIGH-risk path) + G-4 DOT Registry Custodian + Đ44 family ratifier + Đ24 vocabulary owner + Đ37 council
review_phase: NOT_STARTED
Special Đ32 attention (HIGH risk):
- Criterion 28 concurrent enforcement with P0-3 — verify_result.verdict=PASS gates cut_change_set.state=committed; both-signature + drift-match rules must align.
- Independence of verifier — independence_evidence MUST be checked; v0.1 application-layer posture acceptable ONLY IF FUTURE PG enforcement is committed via D4 intake.
- Canonicalization rule binding — once chosen and applied to a manifest, it MUST persist with the verify_result; rule changes via D4 capability intake only.
- Axis-2 advisory ≠ silent acceptance — even though advisory in v0.1, findings must route to backlog; elevation path via D4.
- Rollback chain test plan — verify-triggered rollback must be tested in pre-migration dry-run.
16. Explicit Confirmation
no_ddl_written: true
no_sql_written: true
no_create_table_or_alter_table_in_this_document: true
no_column_ddl_in_this_document: true
no_index_ddl: true
no_constraint_ddl_in_this_document: true
no_trigger_or_function_or_rls_policy_written: true
no_cryptographic_scheme_specified_in_this_document: true (deferred per P0-3 §9 item 2)
no_canonicalization_rule_implementation_in_this_document: true (logical reference only)
no_migration_executed: true
no_pg_mutation: true
no_qdrant_mutation: true
no_data_writes: true
no_implementation_planning: true
no_existing_file_modified: true
no_signature_actually_generated: true
no_verify_actually_run: true
output_form: logical_design_only