TaskSultan Docs tasksultan.com

Orchestrator

Governance and state

Principals and roles, the authorisation rule for governed operations, the approval and governance journals and state inspection and garbage collection.

Governance is two things in the Orchestrator: the rule that decides whether a principal may perform an operation and the journals that record what was decided. The journals are history. The enforcement state lives beside them.

#Principals and roles

npx tsx orchestrator/cli.ts principals add alice --roles operator,approver
npx tsx orchestrator/cli.ts principals list

A principal is an id plus roles, attested by possession of a bearer secret. The registry file stores only a scrypt hash of the secret, never the secret. Roles are closed to operator and approver. A principal with no roles is refused everywhere. When principals add generates a secret it prints it once. A human operation reads the bearer from the TS_PRINCIPAL_TOKEN environment variable; an id on its own is not an identity.

#Authorisation

The rule is a pure decision over roles and the operation's environment. A non-prod operation needs the operator role. A prod activation, an activate or rewrite that moves the pointer, needs an operator and separately needs an approval record consumed at the write. A principal may no longer activate prod alone. Retiring or rolling back a prod record needs an operator or an approver. A rejection is an authorisation failure, mapped to HTTP 403, distinct from an authentication failure and from an approval failure.

The governed operations are activate, rewrite, retire and rollback. They are the control-plane vocabulary reached through the Orchestrator server's /deployments routes, not the CLI.

#Approvals and the journals

approvals.json is the enforcement record for the two-principal rule. An approval is an exact tuple of package, slot, content hash and the environment prod. It is single-use: a consumed approval cannot be reused. A replay gets no valid approval. Consumption is atomic with the write. Self-approval is refused, because the approver's id must differ from the activator's id.

governance.ndjson is the history, a sibling journal. Its rows are typed: approve, consume and delete. Every actor is the verified principal id supplied by the governing operation, never a free-form string. The approval record is the enforcement state; these rows are history and never enter the retention window.

#Inspecting and collecting run state

npx tsx orchestrator/cli.ts state gc --keep-days 30
npx tsx orchestrator/cli.ts state gc --force --keep-days 30

The bare form is inspection only. The inspector contains no deletion primitive. It reports the size, age and file count of the jobs, evidence and queues classes, the job rows with their status and age, every evidence directory with what references it, the orphaned evidence that nothing references and the protected class. With --keep-days it also reports what a policy would collect, as counts.

The --force form performs the collection. It requires an explicit --keep-days N with N at least 1. The policy:

  • Evidence is collectable only when no job row references it and it is older than the window. Referenced evidence is never collectable, at any age.
  • A job row is collectable only when it is terminal, not failed, older than the window and with its evidence already gone, so a collection can never orphan a directory.
  • Failed runs are keeper by default, because failures are the audit value.
  • The protected class is never collectable: the vault, key material, the governance, approvals and principals journals, the request store, robots, schedules and deployments.
  • Every removal is journaled to state-gc.ndjson after it succeeds.

#Things that catch people out

The usage text still describes state gc as inspection only and says it refuses --force until the policy is ratified, but the implementation has collected since the policy was ratified. Read the implementation: --force --keep-days N removes and requires N at least 1.

The protected list is one list, shared by the inspector's report and the destructive guard, so the report about the guard and the guard itself cannot disagree.

The trust boundary is the server and store API. A direct filesystem writer bypasses the registry, as the single-operator host model allows.