07 — Recommendation Before Design
07 — Recommendation Before Design
Date: 2026-05-26 | Scope: Clear recommendation, no design content.
§1. Headline recommendation
Authorise a draft of Điều 45 — "Luật Hàng Đợi & Điều Phối Tác Vụ PG-native" — that ratifies and extends the live substrate, while staying on PostgreSQL 16.13. Do NOT install pg_cron yet. Do NOT introduce a parallel
job_outboxyet. Both are deliberate sub-decisions inside the design pack.
This is the minimum step that:
- Honours the work already shipped (131k+ live events; active worker; dead-letter primitive; lease primitive; staging lifecycle; SQL-event router).
- Avoids bundling PG major-version upgrade risk into design work.
- Forces the pg_cron and job-substrate decisions to be Council-reviewed rather than implementation-lore.
- Costs nothing on the live system.
§2. Why "draft a law" and not "build first"
The substrate is already built. The Phase 2 PoC threshold from 23-P3D4C0X §K has been crossed. The decision deferred there ("decide law placement after PoC") is now ripe.
Building more first would mean making the next additions (Δ1–Δ10 from 06-…) without a ratified law to govern them. That repeats the pattern that produced the current substrate-without-law state. It works, but each new domain consumer has had to re-derive invariants from 23-P3D4C0X and from previous lessons (see memory entries: pg_hba trust unblocks role-channel; G5 is format-check-not-recompute; mark digest canonicalizes via JSONB; etc.). A law-level statement of invariants amortises that cost.
§3. What the design pack must decide (just decide — not necessarily implement)
| Decision | Default if undecided | Recommended question to Council |
|---|---|---|
| D1. pg_cron in scope or out | Out (current state) | "Should the queue assume in-DB scheduling, accept external-only invocation, or both?" |
| D2. Job substrate shape | Event-only (extend event_outbox with event_domain='job') |
"Should long-running Agent/Hermes/MOT work share the event substrate or get a parallel job_outbox?" |
| D3. Inclusion criteria | 23-P3D4C0X §M.3 rubric (3-question gate) |
"Ratify the rubric as enforced at registry insert time?" |
| D4. Retry policy | Manual replay via fn_iu_route_dead_letter_replay |
"Define max_attempts, backoff, and who decides resolution ∈ {replayed,discarded,superseded}?" |
| D5. NOTIFY bridge | Not used by event substrate today | "Should event_outbox INSERT trigger pg_notify for low-latency external workers?" |
| D6. Partitioning policy | None | "When do we partition event_outbox? At 5M rows? At 12 months?" |
| D7. Cross-DB queue | Single-instance only | "Do we ever expect federation? If so, it shapes event_id (uuidv7) and idempotency_key contract." |
| D8. Worker authority | One worker (iu_outbound_default) on domain iu; route_worker_enabled flag global |
"Does each domain get its own worker, or one worker with per-domain cursors?" |
| D9. Subscription resolution rule | View pattern from doc 23-P3D4C0X §D | "Confirm or revise broadcast-fallback rule when no subscription row matches" |
| D10. Cutting flow puller | Operator-driven | "Should there ever be an automated puller pulling approved manifests through to CUT?" |
Each decision can be made independently of the others. Most have a "do nothing" path that preserves current behavior.
§4. What the design pack should NOT do (yet)
- ❌ Install pg_cron (D1 decides first).
- ❌ Add a
job_outboxtable (D2 decides first). - ❌ Migrate
iu_notification_eventlegacy rows (unrelated to queue work; separate cleanup). - ❌ Rename
event_outboxor any other live table. - ❌ Change
event_type_registryrows (vocab decisions belong in design, not survey). - ❌ Touch the cutting flow operator aliases.
- ❌ Upgrade PostgreSQL.
§5. Sequencing
NOW: Survey complete (this pack).
NEXT: GPT review of this survey → User approval.
THEN: Author draft Điều 45 + design pack (separate macro). Council review.
THEN: Sub-decision packs (pg_cron, job_outbox, etc.) as needed.
ONLY THEN: Migration to apply Δ1–Δ10 selectively, under the ratified law.
PARALLEL TRACK: PG 18 upgrade readiness — separate macro, separate timeline.
Each step is reversible up to migration. The migration step is the first irreversible action and must come after law ratification.
§6. Hard refusal — what this survey will not return
This survey will not return:
- The draft Điều 45 text. (Belongs in the next pack.)
- The decision on pg_cron. (Belongs in the next pack.)
- The decision on job_outbox. (Belongs in the next pack.)
- The PG 18 upgrade plan. (Separate macro.)
- Any code, migration, DDL, function body, or trigger spec.
- Approval to mutate production.
If asked to skip ahead to design, the correct answer is: "Author a design pack prompt first; this survey ends at the recommendation."