dot-iu-cutter v0.4 — CUT/VERIFY UUID-safe Signing Body Fix Completion Report (2026-05-17)
dot-iu-cutter v0.4 — CUT/VERIFY UUID-safe Signing Body Fix — Completion Report
Date: 2026-05-17 · Phase: bounded code-authoring — fix the CUT/VERIFY signing-body UUID-not-JSON-serializable defect the PG-backed dry-run found at S6. Code SSOT = VPS /opt/incomex/dot. No PG-backed dry-run rerun, no production connection/secret/CUT/VERIFY, no deploy, no schema/index/JSONB/vector/label work.
1. Defect & fix
phases.cut()/verify() build the DOT signing body via json.dumps({"entry": entry_id, "manifest": manifest_id}, sort_keys=True). With the SB-DEC-1 real-schema lineage read, manifest_id is read back from the Postgres uuid column, which psycopg3 returns as uuid.UUID → TypeError: Object of type UUID is not JSON serializable. Latent vs the in-memory suite (str ids).
Fix (preferred minimal):
- Added
schema_binding.json_safe_id(value)—uuid.UUID|str → stable str,Nonepassthrough; documented that it is applied only at the signing-body call sites (no globalfind()normalisation). phases.cut()signing body nowjson.dumps({"entry": sb.json_safe_id(entry_id), "manifest": sb.json_safe_id(manifest_id)}, sort_keys=True).phases.verify()likewise (cs["manifest_id"]).json.dumps(..., sort_keys=True)kept; StubSigning semantics unchanged (only input-type normalisation).- No global
RealPostgresAdapter.find()row normalisation;db_adapter.pyuntouched.
2. Requirement compliance
| Req | Status |
|---|---|
| cut signing body = stable strings | ✅ sb.json_safe_id on entry+manifest |
| verify signing body = stable strings | ✅ same |
| no signature-stub semantic change except input normalisation | ✅ only id→str before json.dumps |
| no row-count change; r3 = 15 | ✅ test test_r3_baseline_unchanged asserts exactly 15 |
| no principal-routing change | ✅ unchanged |
| no db_adapter txn-lifecycle change | ✅ db_adapter.py not modified |
| no hardcoded DSN/password/IP/container/vector | ✅ grep NONE_FOUND |
| no label/metadata-key hardcoding | ✅ no label cols / registry / ALTER / CREATE TABLE — grep NONE_FOUND |
3. Tests
- New
tests/test_uuid_json_contract.py:json_safe_idcorrectness + stable/serializable + a negative-control proving the unfixed pattern raisesTypeError; aUuidReturnAdapter(mimics psycopg3 — returnsuuid.UUIDfor id-shaped values while keeping str-coerced lineage/CAS equality like a real DB) drives the acceptedMARK→SWEEP→REVIEW→CUT→VERIFYpipeline and asserts: cut with UUID manifest does not raise; verify with UUID manifest does not raise; signing bodies parse as JSON withstrentry/manifest; r3 baseline == 15 unchanged. test_phase_contracts.pynot modified (helper is identity onstr; existing in-memory behaviour unchanged).- Command & result:
python3 -m unittest discover -s tests→Ran 117 tests … OKon VPS py3.12 (110 prior + 7 new; all existing pass).
4. Static no-hardcode & metadata/label statement
grep -nE 'postgres://|PGPASSWORD|<ipv4>|incomex-*|qdrant|collection_name' over the modified phases.py + schema_binding.py → NONE_FOUND. grep -nE 'ALTER TABLE|ADD COLUMN|label_registry|CREATE TABLE' → NONE_FOUND. No runtime label/key hardcoding introduced; no label columns added; no label-registry/metadata schema change; SQL remains SSOT; JSONB is not made hidden authority; vector/NoSQL untouched.
5. Git SSOT proof
- Branch:
main - Parent commit:
6060e1ae8b958fcb8a61ed45b597dc553b8688be - New commit:
db4aa58b50a95a8df2655073effde3a0ed0eede6 - Files changed (scoped, 3):
cutter_agent/schema_binding.py(M),cutter_agent/phases.py(M),tests/test_uuid_json_contract.py(A) —3 files changed, 195 insertions(+), 3 deletions(-). No change to db_adapter.py/ledger.py/state_machine.py/idempotency.py/signing.py/signal.py/cli.py (none needed → no STOP).test_phase_contracts.pynot touched. - Scoped add: explicit 3 paths; no
git add -A; no unrelated WIP. git status --short -- iu-cutter(throwaway dry-run WD excluded): empty (clean).- Test command & result:
python3 -m unittest discover -s tests→Ran 117 tests … OK.
6. Limitations / next gate
No PG-backed dry-run rerun (forbidden until this fix PASSes review). No production connection/secret/row write/CUT/VERIFY/deploy; no schema migration / index DDL / JSONB normalization / vector integration / label-registry change. The txn-lifecycle fix 6060e1a remains validated; this fix is additive and count-invariant (r3=15).
Next gate: GPT review of commit db4aa58 + this report. On PASS, the PG-backed dry-run may be re-authorised (command-review r1 / verification-plan r3 unchanged). No self-advance.