Files
aios/docs/superpowers/specs/2026-08-19-release-preparation-online-agent.md
T

3.2 KiB

Release Preparation Online Agent

Purpose

This worker closes the release-preparation execution gap without widening the ChatGPT connector identity.

The dedicated Agent identity is:

online-release-worker-cn-network-mkt-20260819

Its only advertised task capability is:

release:candidate

The worker may create an immutable release candidate, but it never submits Owner approval and never starts deployment, publishes a tag, finalizes a baseline, switches runtime or writes Git.

Credentials

The worker uses two independently scoped credentials:

agent_token
release_candidate_token

agent_token is the Online Agent registration credential. It must be encrypted into systemd's credential store and must never be written to Git, Task metadata, evidence or logs.

release_candidate_token is provisioned during Owner-authorized runtime activation. Only its SHA-256 record is stored in the release API token registry; the plaintext is immediately encrypted into systemd credstore and the temporary plaintext is removed. Its only allowed scope is:

release:candidate

It is explicitly not an Owner signing key and must not grant:

submitOwnerApproval
startDeployment
tag_publish
baseline_registry_finalize
runtime_switch

The unit reads both credentials through systemd LoadCredentialEncrypted; neither plaintext token is kept in the unit, repository, Task metadata, evidence, or logs.

Task contract

The worker will only claim Tasks whose exact required capability set is:

["release:candidate"]

The Task must provide a bounded constraints.release_candidate payload (metadata is accepted only for compatibility):

{
  "candidate_id": "...",
  "source_commit": "<40 hex>",
  "version": "V2R2C2",
  "projection_id": "projection-..."
}

No caller-supplied URL, method, headers, command, shell, environment, credential path, deployment operation or arbitrary release route is accepted.

The release API base is host configuration, not Task input. The only release mutation invoked by the worker is:

POST /createReleaseCandidate

Lifecycle

poll
→ claim
→ heartbeat
→ createReleaseCandidate
→ result submit
→ official verifier

The result declares:

writer_lease=NONE
changed_files=[]
direct_main_write=false
production_write=false
tag_write=false
baseline_write=false
runtime_switch=false
owner_approval_submitted=false

Remaining high-risk gate

Successful release-candidate creation does not authorize Production.

The next stage remains:

release candidate
→ immutable approval envelope
→ Owner signature
→ startDeployment

That separation is mandatory even when release preparation is fully unattended.

Unattended availability

The release worker has its own systemd watchdog rather than modifying the shared worker-availability guard contract.

Every successful Task poll and Task heartbeat emits:

WATCHDOG=1

and the service uses:

Type=notify
WatchdogSec=90
Restart=always

A process that is technically alive but no longer polling/heartbeating therefore gets restarted by systemd. The worker also writes worker-liveness.json for operator diagnostics.