Releases and migration safety for agents
This reference extends https://app.tokay.io/llms.txt with release and migration safety actions for AI agents. Use these actions only when the user explicitly asks or a named readiness action requires them.
Last updated
AI agent? Start with llms.txt.
The release model
- Tokay rehearses every managed database migration against a disposable clone of the production data before anything touches production. The evidence from that rehearsal, not the SQL text, is what release policy judges.
- Each release execution provides two kinds of evidence.
impactAssessmentcontains observed facts, including schema diffs and the policy result inplanRollup.releaseAnalysiscontains the AI verdicts.liveSafeevaluates whether the current code can use the migrated schema,deployOkevaluates the new code, anddataSafetyclassifies the change assafe,risky, oruncertain. releaseSafetyModedecides how much of that authority is automatic.MANUALparks everything, including rollbacks.STRICTapplies only deterministically additive changes automatically.NORMAL, the default, adds changes the AI judged safe.UNRESTRICTEDapplies everything automatically, still snapshotting managed databases first. Deploy calls accept an optionalreleaseSafetyModewhere the strictest value wins, so a request can narrow authority for one deploy but never widen it.- A parked release is not a failure.
deployReadiness.action: CONFIRM_RELEASEmeans evidence is waiting for a human decision. Your job is to read it, summarize it faithfully, and confirm only after the user agrees. - External databases that Tokay does not host get no rehearsal and no snapshot, and park under every mode except
UNRESTRICTED.
What to call
| To | Use |
|---|---|
| Detect a park | deployReadiness { action targetDeployment { id } } |
| Read the evidence | targetDeployment.releaseExecutions |
| Apply the parked plan | confirmDeploymentRelease |
| Change the dial through GraphQL | updateProject / updateService patch releaseSafetyMode |
| Change the dial through Tokay MCP | set_release_safety |
| Review a proposed migration command | service.serviceReleaseActionOverrides, updateServiceReleaseActionOverride |
| Recover a maintenance hold | recoverServiceMaintenanceHold |
Read a parked release
When deployReadiness.action is CONFIRM_RELEASE, read deployReadiness.targetDeployment. Do not assume the newest deployment row is the parked one.
query ReleaseConfirmation($serviceId: ID!) {
service(id: $serviceId) {
deployReadiness {
state reason action message
targetDeployment {
id deployState deployWaitReason releaseSafetyMode releaseStrategy
releaseExecutions(orderBy: ACTION_INDEX_ASC) {
nodes {
id actionName command releaseExecutionPhase releaseExecutionState
impactAssessment releaseAnalysis
projectResource { id resourceType runtimeName }
}
}
}
}
}
}
impactAssessment and releaseAnalysis are JSON with camelCase keys. Each database's final REHEARSAL row carries impactAssessment.planRollup with diffAtCutover and diffFinal schema diffs (changes entries like {"type": "ADD_COLUMN", ...}) and the policy object. policy.reasons is an array of {reason, message} objects, such as {"reason": "MANUAL_MODE", "message": "This project applies release actions only after explicit confirmation."}. Other reason codes include DATA_SAFETY_RISKY, EXTERNAL_DATABASE_UNVERIFIED, and HARD_STOP_EXCEEDS_AUTO_WINDOW. Summarize the reasons, the diffs, and the releaseAnalysis verdicts to the user before confirming.
Confirm
mutation Confirm($deployment: ID!) {
confirmDeploymentRelease(input: { deployment: $deployment }) {
deployment { id deployState }
}
}
Confirming runs the rehearsed plan against production. Tokay snapshots each managed database immediately before mutating it. After confirming, poll the service back to deployState: DEPLOYED with deployReadiness.state: UP_TO_DATE. A release that applied automatically shows the same evidence trail afterward, a REHEARSAL row and then a PRODUCTION row per action, so you can always answer what ran and why it was allowed.
The safety dial
releaseSafetyMode lives on the project (project.releaseSafetyMode) and services inherit it. A service can override with its own value, where null means inherit. Direct API clients keep the generated update contract, for example updateProject(input: { id: $id, patch: { releaseSafetyMode: MANUAL } }). Tokay MCP blocks that protected field in its generic mutation tool and uses set_release_safety, which previews the exact authority change before consuming a one time review receipt. Under NORMAL, do not expect every statement that looks destructive to park. The rehearsal runs against real data, and a drop that loses nothing observable can be judged safe and apply on its own. Change the dial only when the user asks for it. If the user wants a guaranteed gate, set MANUAL and treat CONFIRM_RELEASE as the routine path. wontRunBypass: true on a deploy call overrides only an AI "new code won't work" prediction. Rehearsal failures always block.
Migration command overrides
UNCONFIRMED_RELEASE_ACTION as a deploy blocker means Tokay found migration machinery it cannot run automatically and proposed a command. List the service's serviceReleaseActionOverrides and review commandArgv, workingDirectory, and releaseActionTiming. Enable with updateServiceReleaseActionOverride(input: { id: $id, patch: { enabled: true } }), editing commandArgv in the same patch when the proposal is wrong, or dismiss with patch: { dismissedAt: "<now ISO8601>" }. Never enable a command you have not shown the user.
Maintenance holds
deployReadiness.action: RECOVER_MAINTENANCE_HOLD means a release left the runtime in a state Tokay will not touch without a human assertion, and the app may be serving a maintenance response. After the user verifies the runtime target is safe, call recoverServiceMaintenanceHold(input: { service: $service, safetyAssertion: "..." }) with a sentence recording what was verified, then poll readiness.
Error shapes
| You see | It means | Do this |
|---|---|---|
deployReadiness.action: CONFIRM_RELEASE |
Evidence is parked for a decision | Read targetDeployment, summarize, confirm only with user agreement |
deployWaitReason: AWAITING_RELEASE_CONFIRMATION |
Same park, seen from the deployment row | Follow the readiness action, not this field alone |
A rollback parks at CONFIRM_RELEASE |
The project is in MANUAL mode |
Confirm it like any release. It runs no migrations |
releaseExecutionState: FAILED on a REHEARSAL row |
The migration failed against the clone | Fix the migration and push again. Rehearsal failures never reach production |
policy.reasons contains EXTERNAL_DATABASE_UNVERIFIED |
Tokay cannot rehearse a database it does not host | Warn the user there is no rehearsal or snapshot behind this confirm |