Automation Orchestrator Design · 01 Operational Goal & User Input Model
Automation Orchestrator Design · 01 Operational Goal & User Input Model
doc 1 of 7 · 2026-05-20 · design-only macro, effort xhigh
phase : G1 — fix the operational goal + user input contract outcome : G1 PASS — single-line user command defined; everything else discoverable / survey-first production_mutation : NONE (design only)
1. Operational goal (one paragraph)
A sovereign User issues one Vietnamese-language command of the form
"Cắt văn bản <X>". From that single utterance the orchestrator must
discover, plan, back up, write, verify, govern, enact, and report the
cut of document <X> — without the user ever supplying a digest,
secret, path, UUID, count, or KB id. The orchestrator runs sequenced
phases with internal fail-closed gates, stops only at real sovereign
gates (write authorization, lifecycle authorization, failure
escalation), and produces an evidence trail on the KB that mirrors the
v0.5 Constitution cycle.
The pattern proven in v0.5 (≈20+ separately-stopped macros) becomes one supervised run for v0.6+, while preserving every safety invariant that earned PASS rulings during v0.5.
2. Lessons honoured from v0.5
| Lesson (from KB) | Honoured by orchestrator design |
|---|---|
| Survey-first before any production action (post-cut-verify §5) | Phase preflights re-read live PG before deciding (§3.4 of this doc) |
| Macro tasks default 45–60 minutes (release-automation-readiness doc 5) | Per-phase soft-cap + per-run hard-cap = 60 min (doc 02 §6) |
| StubSigning carries until sovereign upgrade (DQ_2) | SigningProvider interface; default Stub; real-crypto deferred (doc 06 §7) |
| Backups are GPG-encrypted, narrow-scope, sha-pinned (CUT execution doc 02) | Phase 5 (Backup) reproduces the same shape per document (doc 03 §5) |
fn_iu_create is the canonical writer (canonical-path final report) |
Adapter prod_iu_adapter is the only IU writer; cutwrite stays dry-run-only (doc 06 §2.3) |
fn_iu_enact only implements enact today (DQ_3) |
Orchestrator MVP supports only draft→enacted; other transitions = explicit STOP (doc 03 §9) |
| review_decision must be a fresh one per (document, phase) (DQ_6) | GATE_CUT_AUTHORIZATION and GATE_LIFECYCLE_ENACT_AUTHORIZATION each require a new sovereign-signed KB doc (doc 03 §4) |
| Idempotency keys make replay safe (G-CUT-ONCE / G-LEG-B-ONCE / G-VERIFY-ONCE) | Per-phase idempotency key recorded in JSON sidecar + DB (doc 04 §4) |
| Hardcoded PINs were a constitution-only exception (hardcode audit doc 03) | Per-document runtime values live in RunContext object, NOT as module constants (doc 06 §2.2) |
| KB-as-SSOT (every macro produces KB evidence) | Each phase MUST upload its KB doc to receive a green internal gate (doc 04 §3) |
3. User input model (minimum viable command)
3.1 The one-line command
$ cutter orchestrate cut --document-id <id>
The single mandatory argument is --document-id (or positional). The
<id> is the document's canonical-address prefix (e.g.
ICX-CONST, ICX-LAW-2026-001). The orchestrator looks the id up in
the source-document registry (source_document table; surveyed
read-only) and fans out from there.
Three OPTIONAL flags exist for sovereign control:
--scope=<enacted_only|all> (default: enacted_only)
--actor=<email-or-handle> (default: $LARK_AGENT env or 'sovereign@unknown')
--mode=<dryrun|live> (default: dryrun ; live REQUIRES approval token)
No other flags are accepted in the MVP. Everything else is discovered:
| Datum | How orchestrator discovers it |
|---|---|
source_document_id |
SELECT id FROM source_document WHERE doc_code=<id> |
source_version_id (latest) |
SELECT id, version_string FROM source_version WHERE source_document_id=$1 ORDER BY created_at DESC LIMIT 1 |
| Manifest digest | Re-compute via compute_manifest_digest(source_version) (cutplan helper) |
| Region sha | Re-compute via compute_region_sha(source_version) (cutplan helper) |
| Candidate count | Output of cut-plan dry-run (no hardcoded 60) |
| Writer digest | Output of cut-plan dry-run (stable across replays) |
| Backup target | Read from cutter_orchestrator.backup_policy dot_config (deployment-set) |
| Grant principal | Read from cutter_orchestrator.grant_apply_principal dot_config |
change_set_id |
Generated at cut_leg_a phase (UUID7) |
review_decision_id |
NEW row created per sovereign approval (doc 03 §4) |
cutter_governance.* schema |
pg_class introspection at preflight |
| Function md5(prosrc) | SELECT md5(prosrc) FROM pg_proc at preflight |
| iu_lifecycle_vocab presence | pg_class introspection |
| Secrets / DSN / passwords | NEVER user-supplied; read from GSM (secrets.<env>.cutter_orchestrator) |
3.2 When the orchestrator MUST go back to the user
Only on these four conditions:
- Unknown document:
<id>not present insource_documentAND no--source-uriprovided — orchestrator stops withSTOP_DOCUMENT_UNKNOWNand a list of nearest-match doc_codes. - Sovereign gate hit:
GATE_CUT_AUTHORIZATIONorGATE_LIFECYCLE_ENACT_AUTHORIZATIONreached; orchestrator waits for a KB approval document id passed back via--approval-kb-id=<path>on resume. - Drift detected during live survey: e.g.
fn_iu_createmd5 no longer matches the fingerprint pin insql/lifecycle/fingerprints.yaml, or live row-count for the doc_prefix is non-zero on a fresh run. - Idempotent re-run conflict: a prior run for the same
(canonical_address_prefix, source_version)already exists and has not been formally voided — orchestrator emitsSTOP_REPLAY_CONFLICT.
In every other case the orchestrator continues without prompting the user.
3.3 Open-goal prompting form (when calling sub-agents)
When the orchestrator needs to delegate (e.g. to a Claude Code sub-agent for an exploratory survey step), prompts use the operation form, never technique form. Pattern:
"Cắt văn bản <id> qua orchestrator, giai đoạn <phase>, run_id <id>."
Never:
"Hãy chạy cutprod_canonical với --expect-writer-digest <d99a31d4…> …"
The orchestrator computes the long-form invocation itself and persists it in the run sidecar. This mirrors the v0.5 doctrine that the user provides intent, the agent provides technique.
3.4 Discover-first vs Survey-first
The orchestrator distinguishes:
- Discover-first (find existing): used for vocab keys, dot_config rows, function presence, KB approval ids — if it exists, reuse it; do not create a duplicate.
- Survey-first (read live before mutate): used for row counts, schema columns, grants, triggers — take a fresh live snapshot at the start of each phase; refuse to write against a stale snapshot.
Both reuse the existing cutter_governance SECDEF probe pattern
(directus principal) — no new role is introduced for the MVP.
4. Inputs the orchestrator REFUSES to accept from the user
To preserve "no hardcode, no hand-fed authority":
refused_from_user:
- DSN / connection string / PGPASSWORD / GSM payload (G-1 refusal)
- Manifest digest / region sha / writer digest (must be discovered)
- Candidate count (must be discovered)
- change_set_id / review_decision_id / signature_id (must be created or surveyed)
- Bypass flags (--skip-verify, --force, --no-backup) (NO such flag exists)
- Direct SQL (orchestrator owns SQL surface)
- Production environment variables (modules refuse on env-guard)
If any of these is present on the command line, the orchestrator
exits with STOP_REFUSED_INPUT and the offending argument echoed
back (token-sanitised).
5. Verdict
g1_outcome : PASS
user_input_complexity : 1 mandatory arg + 3 optional flags
discover_first_data_points : ≥ 14 (table §3.1)
survey_first_phases : every phase preflight (§3.4)
user_re_prompt_conditions : 4 (§3.2)
hardcoded_per_document_constants : 0 (PINs become RunContext fields)