Files
aios/AGENT_DEPLOYMENT_REQUIREMENTS.md
T

13 KiB

Agent Production Deployment Requirements

Status entering deployment

code_development: COMPLETED
repository_commit: NOT_CREATED
production_deployment: NOT_STARTED
reason_repository_commit_missing:
  current ChatGPT GitOps runtime has AIOS_GITOPS_WRITES_ENABLED=false

The code bundle is an input artifact. The Agent must place it on a non-main integration branch, review it, run acceptance tests, merge it through protected main and deploy the API adapter. The Agent must not regenerate or materially rewrite the supplied implementation without recording the new diff and tests.

Frozen production state

Before any change, verify:

main_oid: 875d41c3101093149414292067fd700dc214d4d3

V2R1C5:
  tag_oid: 9e65bd59baea392294c0f253046d3ab116f63145
  peeled_target_oid: aa60e891547abd7e215af7cf2bf3f21fd23541da
  baseline_version: V2R1C5
  baseline_status: PRODUCTION_DEPLOYED
  target_oid: aa60e891547abd7e215af7cf2bf3f21fd23541da
  evidence_closure_oid: 5e2cf8276f5093f3352b9a3252c701a44c5ab807

If authoritative main no longer equals the approved base OID, stop with MANUAL_OWNER_REVIEW_REQUIRED / AUTHORIZED_BASE_OID_DRIFT. Do not silently rebase the bundle onto a different base.

Bootstrap sequence — no additional Owner interaction

Use the following order so that the approved V2R1C6 base OID remains valid and the bridge does not create its own authorization deadlock:

  1. Verify the supplied archive/patch SHA-256.
  2. Install the bundle into a temporary root-owned staging directory outside the Git worktrees.
  3. Start a localhost-only temporary instance of aios_authorized_task_writer_api.py on a dedicated port or Unix socket.
  4. Bind it to the existing authenticated Owner registry and the exact writer:provision scope. Do not expose it through the public gateway.
  5. Execute the live V2R1C6 provisioning request while main still equals 875d41c3101093149414292067fd700dc214d4d3.
  6. Verify READY_FOR_CODE_AUTHORING, the exact branch OID, writer scope and negative policy tests.
  7. Use the newly created scoped writer to commit this reviewed bundle onto: agent/v2r1c6-mainline-reconciliation-20260805.
  8. Stop and remove the temporary bootstrap service and revoke its temporary runtime credential. Preserve its signed grant receipt and audit logs.
  9. Open a protected PR from the V2R1C6 branch. Deploy the permanent bridge only from the reviewed merge commit.

The temporary service is a control-plane bootstrap, not a production release. It must retain:

listen_scope: localhost_only
production_change_authorized: false
tag_change_authorized: false
baseline_change_authorized: false
main_write_authorized: false

This order avoids asking the Owner to approve a second base OID merely because the bridge implementation itself advanced main.

Alternative platform-maintenance path

If policy prohibits a temporary localhost bootstrap service, use an existing Owner-approved platform-maintenance executor to create:

branch: patch/owner-authorization-writer-bridge-20260806
base_ref: refs/heads/main
base_oid: 875d41c3101093149414292067fd700dc214d4d3
direct_main_push: false
force_push: false
tag_write: false
baseline_write: false
production_deploy_during_integration: false

Merging that branch before V2R1C6 provisioning changes the authoritative base OID. In that alternative only, a new exact Owner base-OID amendment is required. The Agent must never substitute the newer main OID automatically.

Files to install on the branch

Copy with the same relative paths:

active-runtime/app/authorized_task_writer_provisioning.py
active-runtime/app/aios_authorized_task_writer_api.py
docs/gitops/authorized-task-writer-provisioning.md
docs/gitops/openapi-authorized-task-writer-fragment.yaml
deploy/systemd/aios-gitops-model-api-authorized-writer-bridge.conf.example
scripts/smoke_authorized_task_writer_provisioning.py
tests/test_authorized_task_writer_provisioning.py

Merge the OpenAPI fragment into:

docs/gitops/openapi-chatgpt-actions.yaml

The final schema must expose:

operationId: provisionAuthorizedTaskWriter
path: POST /api/task-writer/provision-authorized
x-openai-isConsequential: true

Do not deploy the fragment as a second standalone OpenAPI document.

Required review of existing API integration

The adapter expects the existing API handler to provide:

handler.need(scope)
handler.body()
handler.sendj(value, status=200)
api.H.do_POST
api.main()

Confirm these contracts against the branch before merge. If the live API has a different authentication object shape, make the smallest adapter-only change and rerun every test. The core provisioning policy must remain unchanged.

The API authorization registry must grant writer:provision only to the authenticated Owner role. Agents and ordinary writer tokens must not receive this scope.

Privilege boundary

The API service must remain non-root.

Install a root-owned sudoers rule that allows the API service identity to run only these exact commands with sudo -n --:

/usr/local/libexec/aios-grant-signer-adapter
/usr/local/libexec/aios-grant-validator
/usr/local/libexec/aios-task-writer-provisioner

Do not allow:

/bin/sh
/bin/bash
/usr/bin/env
/usr/bin/git
wildcard executable paths
SETENV
arbitrary environment preservation

The governed tools themselves must validate their --grant-dir and --result-json paths. Their binaries must be root-owned, non-symlink, regular, executable and not group/world writable.

The signer must access its private signing material only through a runtime secret reference. No signing key or token may enter Git, API output, the provisioning receipt or systemd environment text.

Runtime paths and permissions

Create:

/var/lib/aios-gitops/authorized-writer-bridge
/var/lib/aios-gitops/authorized-writer-bridge/receipts
/var/lib/aios-gitops/authorized-writer-bridge/locks

Required properties:

owner: API service identity
mode: "0700"
symlink: false
persistent: true

The directory contains redacted receipts only. Temporary signed grant directories are deleted after success or failure.

Required staging environment

Configure the API service:

AIOS_GITOPS_REPOSITORY_IDENTITY=aios/aios
AIOS_GITOPS_AUTHORITY_GIT_DIR=/data/aios-gitops/repo.git
AIOS_GITOPS_AUTHORIZED_WRITER_STATE_ROOT=/var/lib/aios-gitops/authorized-writer-bridge
AIOS_GITOPS_GRANT_SIGNER_ADAPTER=/usr/local/libexec/aios-grant-signer-adapter
AIOS_GITOPS_GRANT_VALIDATOR=/usr/local/libexec/aios-grant-validator
AIOS_GITOPS_TASK_WRITER_PROVISIONER=/usr/local/libexec/aios-task-writer-provisioner
AIOS_GITOPS_OWNER_PROVISION_SCOPE=writer:provision
AIOS_GITOPS_GOVERNED_USE_SUDO=true
AIOS_GITOPS_SUDO_PATH=/usr/bin/sudo

Use aios_authorized_task_writer_api.py as the API entrypoint. It delegates all pre-existing routes and adds only the new endpoint.

Pre-merge tests

Run from the repository root:

python3 -m unittest -v tests/test_authorized_task_writer_provisioning.py
python3 scripts/smoke_authorized_task_writer_provisioning.py
python3 -m py_compile \
  active-runtime/app/authorized_task_writer_provisioning.py \
  active-runtime/app/aios_authorized_task_writer_api.py

Required result:

unit_tests:
  total: 9
  failures: 0
  errors: 0
smoke: PASS
py_compile: PASS

Also run all existing GitOps API and isolated writer tests affected by:

aios_chatgpt_actions_api
aios_isolated_writer_api
isolated_writer_authz
isolated_writer_token_registry
single_owner_governance
OpenAPI schema validation

Any regression blocks merge.

Staging API acceptance

Negative authentication

An Agent or non-Owner credential calling the endpoint must receive:

http_status: 403
error: OWNER_AUTHORIZATION_REQUIRED

Negative scope tests

Requests enabling any of the following must be denied before signer execution:

production_change_authorized=true
tag_change_authorized=true
baseline_change_authorized=true
main_write_authorized=true
allowed_operations containing tag/main/baseline/admin operations
missing required denied operation
one_time_use=false
expiry over 1800 seconds

Drift and conflict tests

Verify:

wrong_base_oid:
  http_status: 409
  error: AUTHORIZED_BASE_OID_DRIFT

existing_unreceipted_target_branch:
  http_status: 409
  error: EXISTING_BRANCH_OID_CONFLICT

Governed tool failures

Independently inject and verify fail-closed behavior for:

signer unavailable
signer signature absent
validator signature_valid=false
validator signer_trusted=false
validator plan expired
provisioner grant_consumed=false
provisioner writer scope enables main/tag/baseline/force push
any required negative policy test false

None may create or modify a Git ref.

Live V2R1C6 provisioning request

After protected merge and API deployment, authenticate as the Owner and submit exactly:

{
  "task_id": "V2R1C6_TASK_SCOPED_WRITER_PROVISIONING",
  "repository": "aios/aios",
  "base_ref": "refs/heads/main",
  "base_oid": "875d41c3101093149414292067fd700dc214d4d3",
  "target_branch": "agent/v2r1c6-mainline-reconciliation-20260805",
  "owner_authorization_reference": "chat-owner-authorization:v2r1c6:20260806",
  "one_time_use": true,
  "expires_in_seconds": 900,
  "production_change_authorized": false,
  "tag_change_authorized": false,
  "baseline_change_authorized": false,
  "main_write_authorized": false,
  "allowed_operations": [
    "create_worktree",
    "create_target_branch_if_absent",
    "commit_to_target_branch",
    "push_target_branch"
  ],
  "denied_operations": [
    "direct_main_push",
    "force_push",
    "tag_create",
    "tag_update",
    "tag_delete",
    "branch_delete",
    "repository_admin",
    "baseline_write",
    "production_deploy",
    "production_marker_write",
    "history_rewrite"
  ]
}

This request must be executed by the localhost-only bootstrap instance before the bridge code advances main. The endpoint must never infer “current main”.

If the Agent chooses the alternative merge-first path, it must stop after the merge and obtain an exact Owner amendment for the new merge OID. It must not silently replace the approved OID.

Success response

Require:

status: READY_FOR_CODE_AUTHORING
grant_consumed: true
branch: agent/v2r1c6-mainline-reconciliation-20260805
branch_oid: <exact amended authorized base OID>
base_oid: <same exact OID>
main_unchanged: true

writer_scope:
  workspace_role: task-scoped-isolated-writer
  writes_enabled: true
  allowed_branch: agent/v2r1c6-mainline-reconciliation-20260805
  allowed_base_oid: <exact amended authorized base OID>
  allowed_routes:
    - POST /api/commit-file
  allow_main_write: false
  allow_tag_write: false
  allow_baseline_write: false
  allow_force_push: false

All seven negative policy results must be true.

Submit the identical request a second time. It must return the same grant and branch attestation with:

idempotent: true

It must not run the provisioner again.

Production postchecks

After API deployment and writer provisioning, independently verify:

existing_routes_regression: PASS
new_endpoint: PASS
main_ref: expected reviewed merge commit
V2R1C5_tag_oid: 9e65bd59baea392294c0f253046d3ab116f63145
V2R1C5_peeled_target: aa60e891547abd7e215af7cf2bf3f21fd23541da
V2R1C5_baseline_unchanged: true
new_release_tag_created: false
production_baseline_changed: false

The deployment of this control-plane bridge does not authorize a V2R1C6 production release. It only enables scoped code authoring.

Rollback

If the new API route fails:

  1. Stop accepting new provisioning calls.
  2. Restore the previous API entrypoint.
  3. Restart and verify all existing routes.
  4. Preserve receipts and logs.
  5. Revoke any task writer capability already minted.
  6. Do not delete a branch or rewrite a tag.
  7. Revert the protected-main bridge commit through an ordinary reviewed revert PR if source rollback is required.

Required final Agent report

STATUS: COMPLETED | PARTIALLY_COMPLETED | BLOCKED | FAILED

INTEGRATION:
  branch:
  commit:
  protected_pr:
  merge_commit:
  files_changed:

TESTS:
  unit:
  smoke:
  py_compile:
  regression:
  fault_injection:

DEPLOYMENT:
  service:
  entrypoint:
  runtime_status:
  endpoint_status:
  rollback_verified:

PROVISIONING:
  owner_authorization_reference:
  approval_plan_id:
  grant_id:
  grant_digest_sha256:
  signing_key_identity:
  branch:
  branch_oid:
  workspace_path:
  grant_consumed:
  idempotent_replay:

CONSISTENCY:
  main_oid:
  V2R1C5_tag_oid:
  V2R1C5_peeled_target_oid:
  baseline_version:
  baseline_changed:
  tags_changed:

SECRETS:
  runtime_secret_reference_used:
  plaintext_secret_logged:
  plaintext_secret_committed:

BLOCKERS:

GOVERNANCE:
  force_push_used: false
  tag_rewritten: false
  direct_main_push: false
  secrets_committed: false
  owner_approval_respected: true