Skip to content

Latest commit

 

History

History
26 lines (24 loc) · 6.92 KB

standards.md

File metadata and controls

26 lines (24 loc) · 6.92 KB

Standards and prior art

decree 0.5 composes existing, well-specified ideas. Nothing here is new; the value is in the narrow combination. Where decree deviates, the reason is to keep machines small enough to validate statically and to run from bash.

decree concept Drawn from What decree takes Deliberate deviation
Machine semantics: states, compound states, finals, initial, onentry/onexit, invoke W3C SCXML 1.0 (Recommendation, 2015), itself built on Harel statecharts (1987) The normative standard. Terms, key names and behaviour are SCXML's; SCXML subset lists the exact subset. YAML instead of XML. No <parallel>, <history>, cond on transitions, <send>, <raise>, <assign> or other executable content; one transition per event. Extensions and differences are listed in SCXML subset: root onentry/onexit, unhandled events becoming error, a failing onentry on a root final, and child results named after the final state.
Exit and entry order, transition domain SCXML Appendix D (Algorithm for SCXML Interpretation) Exit innermost-first below the transition domain; enter outermost-first; entering a compound state enters its initial. Transitions are external unless declared type: internal, as in SCXML. One transition per event, so SCXML's conflict resolution never arises.
person and replies SCXML external events; AWS Step Functions callback pattern (.waitForTaskToken, SendTaskSuccess) A run pauses until an external event arrives; a token (the wait id) correlates the reply. Replies are files in the inbox, so any tool can answer; decree does not know who is asked.
invoke → done / error SCXML <invoke> (done.invoke.<id>, error.execution) Long-running work belongs to a state; its completion is an event. The invoked thing is a script, not an SCXML session; done and error are the prefix descriptors SCXML would match. onentry and onexit scripts are processes that block, where SCXML executable content is instantaneous.
Decision invokes (check, model, person) SCXML <invoke type> (types are platform-defined); AWS Step Functions Choice and Task states A state's work is one invoked function; its result is an event. decree's own invoke types, each named by the one key under invoke. Conditions are typed YAML objects with one subject (output, data, visits or confidence) and one operator, evaluated by a check state rather than on transitions.
One key names the invoke's kind serde's externally tagged enums ({ variant: value }); GitHub Actions steps (uses: or run:) The key that is present says what the value is, so a reader never infers the kind from other fields. invoke: <name> is short for invoke: { script: <name> }.
attempts, timeout, unhandled error → failed AWS Step Functions (Amazon States Language: Retry.MaxAttempts, TimeoutSeconds, Catch on States.ALL, Fail state); Temporal RetryPolicy; model gateway fallback lists (LiteLLM fallbacks, OpenRouter models) Per-task retry and timeout, and a catch-all failure path. Both sit inside the script invoke, as Step Functions puts them on the Task. attempts: <n> caps attempts as MaxAttempts does; a list tries each entry in order until one succeeds, as a fallback list does, and hands the script the entry as DECREE_ATTEMPT_VALUE. No backoff or jitter; attempts are immediate.
model and router machines LangGraph conditional edges; typed-choice decision models (TypeSafe Jev); SCXML child sessions A model picks the next edge from a fixed set, with a recorded confidence; the asking is itself a replaceable machine. Options and descriptions come from the calling machine, the reply is validated by decree, and below min_confidence the state produces unsure. The model never names a state or a machine.
events.jsonl as the record; decree process --retry Event sourcing; JSON Lines (jsonlines.org); durable-execution engines (Temporal) An append-only log is the source of truth; current state is derived from it; work is at-least-once, so steps must be idempotent. No automatic recovery: an interrupted run waits for decree process --retry, because a kill may be deliberate. Continuing re-runs root and ancestor onentry scripts, so setup such as a git baseline is re-established.
Telemetry Grafana Loki and Alloy label practice; OpenTelemetry span model Structured JSON Lines with a small label set; start time plus duration per unit of work. No exporter or metrics endpoint; a log shipper tails the files.
Messages Markdown with YAML frontmatter (the Jekyll convention, also used by Hugo and agent skill files); YAML 1.2 via serde_norway Structured header, free-text body. None.
Inbox claim and writes Maildir delivery (write to a temp name, rename into place); POSIX rename(2) atomicity Readers never see partial files; a rename is the claim. One directory with dot-prefixed temp names instead of tmp//new//cur/.
Run lock pidfile with O_EXCL and kill(pid, 0) liveness check Single owner per run; a stale lock marks a crash. A stale lock never causes a takeover: the run becomes interrupted.
Long-running services systemd user units (Conflicts=, Restart=, journald); llama-swap Supervision, mutual exclusion on a shared GPU, logs. Outside decree: onentry scripts start what a state needs (Long-running services).
Durations (timeout, prune --older-than, daemon --interval) Kubernetes and Go durations (time.ParseDuration: 90s, 10m, 12h) A number followed by its unit, readable where seconds are not (7d, not 604800). One whole-number term only: no fractions, no combinations such as 1h30m, and no sub-second units; d is added, as Kubernetes and Go have none.
Process control POSIX process groups; SIGTERM, grace period, SIGKILL (as docker stop, 10 s default) Kill the whole script tree on stop or timeout. None.
Exit codes and events POSIX exit status; 128 + n for signals (130 = SIGINT); GitHub Actions' $GITHUB_OUTPUT file 0 is done, non-zero is error. A script writes outputs to a file whose path is in an environment variable, never to stdout. One output only: the event name, written to $DECREE_EVENT_FILE.
Ids and timestamps ISO 8601 basic format; RFC 3339 Sortable, human-readable ids and log times. 6 hex chars instead of a UUIDv7 (RFC 9562) suffix, to stay readable without a dependency.
Cron files Standard cron expressions (the cron crate) Unchanged. None.
Graph Mermaid stateDiagram-v2 in Markdown (renders in VS Code 1.121+, GitHub, GitLab, Obsidian, mermaid.live; MIT, self-hostable) Generated from the arena the interpreter runs; viewing is left to existing tools. No built-in image rendering, to keep decree small. SCXML (XML), DOT and other exports are out of scope.