KB-1824

dot-iu-cutter v0.4 — CUT/VERIFY UUID-safe Signing Body Fix Completion Report (2026-05-17)

5 min read Revision 1
dot-iu-cutterv0.4uuid-safesigning-bodycompletion-reportdieu44

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.UUIDTypeError: Object of type UUID is not JSON serializable. Latent vs the in-memory suite (str ids).

Fix (preferred minimal):

  1. Added schema_binding.json_safe_id(value)uuid.UUID|str → stable str, None passthrough; documented that it is applied only at the signing-body call sites (no global find() normalisation).
  2. phases.cut() signing body now json.dumps({"entry": sb.json_safe_id(entry_id), "manifest": sb.json_safe_id(manifest_id)}, sort_keys=True).
  3. phases.verify() likewise (cs["manifest_id"]).
  4. json.dumps(..., sort_keys=True) kept; StubSigning semantics unchanged (only input-type normalisation).
  5. No global RealPostgresAdapter.find() row normalisation; db_adapter.py untouched.

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_id correctness + stable/serializable + a negative-control proving the unfixed pattern raises TypeError; a UuidReturnAdapter (mimics psycopg3 — returns uuid.UUID for id-shaped values while keeping str-coerced lineage/CAS equality like a real DB) drives the accepted MARK→SWEEP→REVIEW→CUT→VERIFY pipeline and asserts: cut with UUID manifest does not raise; verify with UUID manifest does not raise; signing bodies parse as JSON with str entry/manifest; r3 baseline == 15 unchanged.
  • test_phase_contracts.py not modified (helper is identity on str; existing in-memory behaviour unchanged).
  • Command & result: python3 -m unittest discover -s testsRan 117 tests … OK on 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.pyNONE_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.py not 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 testsRan 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.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.4-db-adapter-dry-run/dot-iu-cutter-v0.4-cut-verify-uuid-safe-signing-fix-completion-report-2026-05-17.md