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.