100%

Vocabulary go/no-go — confirm the primitive set is bounded

Goal

  • Enumerate primitives across every workflow/invocation/closeout flow.
  • Keep one generic Reminder renderer.
  • Treat root/frame/batch/context/control objects, including ContinueRuntimeView, TerminalReceipt, and ClientTransportDirective, as closed data contracts, not plugins.

Implementation sketch

  • Emit machine-readable content/vocabulary-manifest.json: every executable primitive, control-plane contract, seed mapping, owner, status, and flow usage.
  • Mark ActiveExecution gates/actions, contextual selector facts, mapping activation classes, and adapter boundaries.
  • Map every legacy drain/wait/livelock/batch-pause/terminus/clarification exit to one closed EngineTurn; register FailureDisposition classification, shelve-on-generic-push, and resume effects with one owner each.
  • Register client_transport_state_is and terminal_receipt_matches_transport as the only transport-specific branch gates, and emit_client_transport_directive as the script-owned projection action. Lifecycle tool execution reuses dispatch_llm_task + submit_result; it does not create a client-owned workflow or another plugin kind.
  • Require manifest rows for prompt production and state authority: every LLM-visible control prompt is script/catalog generated, and every domain transition reads/writes the owning plan/tracker API rather than client or transcript state.
  • Record the initial workflow metadata closure state_authority = domain_artifact | virtual_root; require the first for every plan/bug workflow and admit the second only for a VirtualBatchDescriptor with no domain artifact. The later demonstrated direct-service gap reopens this verdict exactly once for the paired protocol_root addition specified in sec 10.3.1; it does not retroactively permit an unpaired value.
  • Validate canonical examples against registered component names, pure gate contracts, canonical status literals, structured result bindings, consume-only opaque protocol references plus named persist Actions, Action args with no successor-state authority, reminder activation references/classes, vocabulary Used by parity, and ledger cycle vocabulary.
  • Cross-check against the existing declarative registries (commit_push rules.py frozensets, EXIT_REASON_ROUTING, REGISTERED_HALT_STATES, banned_actions.DEFAULT_BANNED_ACTIONS, DETECTOR_TO_BATCH) — the primitives that already exist as scattered data.
  • Verdict: bounded/closed (green) — confirm no flow needs a primitive outside the set; any new KIND triggers a re-run before proceeding.
  • Implement verify_vocabulary_manifest to reject uncovered scenario actions, duplicate owners, unknown kinds, aspirational primitives marked ported, and mappings without canonical registry rows.

Spec references

  • plans/workflow-engine-rework/spec/workflow-state-machines.md sec 10.1 (the go/no-go enumeration + convergence verdict); sec 10 (why-not-YAGNI).

Work items

  • Emit machine-readable content/vocabulary-manifest.json with every primitive/contract/mapping, owner, status, and flow usage
  • Cross-check against existing declarative registries (commit_push/exit_reasons/banned_actions)
  • Verify scenario/registry/kind/owner/use-site coverage, closed state_authority assignment, total legacy-exit-to-EngineTurn mapping, explicit failure-classify/result-persist/shelve/resume primitive ownership, reminder selector resolution, no successor names in Action args, and complete ContinueRuntimeView/TerminalReceipt/ClientTransportDirective gate-action-contract coverage without a new plugin kind
  • Record the bounded/closed go/no-go verdict; flag any aspirational primitive as build-not-port

Test strategy / acceptance

Acceptance: the verifier proves every scenario action is covered once, every primitive/contract/mapping has one owner, status, and real use site; every reminder selector resolves with the correct activation class; semantic result paths have sanctioned writers; opaque results reach only their consume/persist Action or engine error; Action args carry no successor state; every control prompt names its script producer; goal/loop can only read ContinueRuntimeAPI and relay its current/next view; transport completion requires an engine-issued matching TerminalReceipt; and unknown kinds fail closed.

Fresh intel (regenerated)

This section is NOT a build section — it is a pre-build enumeration GATE sitting at DAG position 3 of 20, BEFORE the engine store (root-closure, pos 4), the skeleton (walking-skeleton, pos 5), and engine-core (pos 6) exist. Its deliverable (content/vocabulary-manifest.json + verify_vocabulary_manifest) is greenfield, and MOST of the ~155 primitives it enumerates (spec 10.1: 71 LogicGates + 60 Actions + 24 Reminders) plus every control-plane contract it catalogs (ContinueRuntimeView, TerminalReceipt, ClientTransportDirective, VirtualBatchDescriptor, FailureDisposition, EngineTurnall 0 source symbols on disk) are build-not-port. The section’s ONE job the graph can ground is the cross-check against the primitives that already exist as scattered data — and the graph independently confirms that scatter is real and duplicative.

The single most important [JOIN]: the section body’s cross-check list (commit_push rules frozensets, EXIT_REASON_ROUTING, REGISTERED_HALT_STATES, DEFAULT_BANNED_ACTIONS, DETECTOR_TO_BATCH) + MISSING_ABSTRACTION firing EXIT_REASON_ROUTING ~ ROUTING_STATES (0.979), CANONICAL_EXIT_REASONS ~ HALT_REASONS (0.930), DEFAULT_BANNED_ACTIONS ~ DEFAULT_FALLBACK (0.961) + two byte-identical _format_banned_actions clone pairs across four compose_*_cure_prompt.py files + the four already-shipped per-registry PARITY tests (test_exit_reasons_parity is literally a “5-way SSOT parity gate”) → verify_vocabulary_manifest is the plan-wide GENERALIZATION of four per-registry parity gates the codebase already runs. The section is not inventing a verification shape; it is unifying a proven-but-copied one, exactly as the manifest’s own thesis (“the primitives that already exist as scattered data”) states.

Decisions this package forces before any code is written:

  1. Treat the manifest as a FORWARD contract, not a code inventory. ~155 spec-10.1 primitives + 6 control-plane contracts are build-not-port; the go/no-go verifier must mark each row status = build | port with an owner, and only the port rows have a live symbol to reconcile. The section body’s build-not-port flag (w-da563ed1) is load-bearing — do NOT assert a primitive “ported” when its symbol is greenfield.
  2. Cross-check READ-ONLY against the four live registries + the commit_push _LOCKED tuples — never mutate them. They are executing THIS plan (self-hosting) and the commit_push tuples are a locked design. The manifest references them as canonical registry rows; editing them is out of scope AND breaks the run’s own substrate.
  3. verify_vocabulary_manifest reuses the parity-gate shape, not a new one. Model it on test_exit_reasons_parity / test_extension_registry_parity / test_default_banned_actions_parity / test_seam_routing (§3.3) — the “registry IS the contract; every row bridges to its consumers; orphan keys fail at test time” discipline. A parallel verifier shape is LEAK:algorithmic-duplication.
  4. The verdict is a GATE with a reopen trigger, not a one-shot. Spec 10.1: “Keep convergence OPEN until the manifest covers every flow … Reopen vocabulary review when a new gate/action kind is required.” Any new KIND surfaced by a later section re-runs this section (w-da563ed1 / section body line 17). Bake the reopen contract into the verdict, not a comment.
  5. Every design VERDICT inherits the tooling-scope hygiene families (§3H): SCHEMA:unvalidated-config (the manifest JSON must have a validator, not prose), LEAK:algorithmic-duplication (the scatter + the clone pairs — the manifest must CONFIRM they collapse, not add a 5th), LEAK:scattered-knowledge / SSOT (the manifest is the enumeration SSOT), STRUCTURE:script-first-violation, INVERTED-TDD (the verifier’s coverage/uniqueness/kind-closure pins). The deep compiler matrix (dual-exec / L5-L10 backends) is N/A.
["EXIT_REASON_ROUTING", "REGISTERED_HALT_STATES", "DEFAULT_BANNED_ACTIONS", "DETECTOR_TO_BATCH", "TYPE_PREFIXES_ALLOWED_LOCKED", "PUSH_FAILURE_HALT_REASONS_LOCKED", "BYPASS_STRATEGY_LOCKED", "serve_next_v7", "route_walk", "run_state_machine"]

DIG DEEPER

python -m scripts.plan_corpus.read --summary plans/workflow-engine-rework
sed -n '1,31p' plans/workflow-engine-rework/content/vocabulary-go-no-go--s-6c1f9f03.md
sed -n '1972,2159p' plans/workflow-engine-rework/spec/workflow-state-machines.md   # spec 10.1

(full dossier: vocabulary-go-no-go—s-6c1f9f03.intel.md)