Skip to content

Agent lifecycle

Agent lifecycle controls answer four questions about every agent: who owns it and how risky it is, what changed and who approved it, whether it was tested before release, and when it is due for review again. This page describes these controls in the order an agent meets them:

  1. Registry and risk tiers
  2. Change requests and approvals
  3. Evaluation gate
  4. Releases, revisions and rollback
  5. Recertification
  6. Attestations

The tier table, the recertification cadence and the lapse action are platform settings; see Configure the tier policy.

An organisation cannot govern agents it cannot list. Without one record per agent, nobody can say which agents exist across projects, who answers for each one, how much harm it could do, or whether anyone reviewed it.

Every agent and pipeline has a registry record. The platform creates it when the agent is created. The record holds:

  • a business owner and a technical owner (platform users);
  • a risk tier: low, medium, high or critical;
  • the intended use and the out-of-scope use, as short text;
  • the data classes the agent may touch, as labels you choose;
  • the certification state: uncertified, certified, due, lapsed or suspended, with the certified release, the time of certification and the recertify-by date.

The tier decides how much control applies. See the tier table. New agents start at low, so personal and experimental agents keep a one-step publish.

Lowering a tier needs the governance role. An owner, or anyone holding the governance role, may raise a tier. Only a holder of the governance role (models.applications.governance) may lower it. Otherwise an author could drop an agent to low to skip approval. The refusal is HTTP 403 tier_lowering_requires_governance. When the agent has owners, only an owner or the governance role may edit its record (403 registry_owner_required).

Existing agents. When an install is upgraded, every existing agent gets a record that is uncertified at tier medium, with the author of its first version as technical owner. Agents in a personal project are the exception: they get tier low, because a personal project has one member and nobody else could approve. From then on, publishing a medium agent needs a change request.

One view across projects. Platform administrators see every agent in Admin › Agent registry, filtered by tier, certification state, owner and project, and can export the list as CSV or JSON.

  • Data classes are free labels. The platform has no classification catalogue to check them against.
  • An agent with no owners can be edited by anyone allowed to publish it. Set the owners when you raise the tier.
  • Catalog copies of an agent get their own registry record.

A single person who can publish an agent can put an unreviewed definition into production. Change management in a regulated organisation needs a second person, evidence of testing, and a record of who approved what.

Above the tier’s threshold, publishing needs an approved change request. A direct publish of such an agent is refused with HTTP 409 change_request_required. The author creates a change request for a draft version with a summary and submits it. Submitting starts the agent’s evaluation gate. The change request records the candidate version, its latest revision, the gate, the approvals and, after publishing, the release.

Default tier table:

TierApprovalsFrom the governance roleEvaluation gate
low0: publish directly0Not run
medium1, not the author0Runs when the agent has gate suites
high1, not the author1Runs when the agent has gate suites
critical2 distinct, neither the author1Runs when the agent has gate suites

A platform administrator can raise these numbers (up to 5) in the tier policy. The numbers in the table are floors: a saved value below them is raised to them.

Four eyes. The author of a change request can never approve it (403 self_approval_refused). A database constraint repeats this rule, so it holds even if application code is bypassed. Approvals that need the governance role are refused without it (403 approver_role_required).

Approval is blocked until the evidence is in. An approval is refused while:

  • the gate is still running (409 release_gate_pending);
  • the gate failed and nobody overrode it (409 release_gate_failed, with the failures);
  • a mandatory attestation is missing or expired (409 attestation_missing, with the missing kinds).

The final approval publishes. The approval that completes the tier’s requirement publishes the candidate in the same transaction and records the release. The change request moves to published and the agent becomes certified, with a recertify-by date from its tier’s cadence.

One open change request per agent. A second one is refused (409 change_request_open). At submit, the platform records the candidate’s draft revision and a digest of everything its release would record: the definition, the attached toolkits with their settings and selected tools, skills and sub-agents, and the configurations the toolkits reference. A recertification certifies the release that is current at submit. If the candidate changes while it is being submitted, the submit is refused (409 change_request_stale) and the request stays a draft. If the candidate version was saved again or published after the request was submitted, an attachment changed, or, for a recertification, the agent’s current release changed, the approval is refused (409 change_request_stale). Withdraw the request and submit a new one, so that approvers review what will be published. The author or a governance role holder can withdraw a request; an approver can reject it with a reason.

Low-tier publishes are recorded too. A direct publish of an agent that needs no approval records a self-approved change request, so every release has one.

  • Approve, reject and withdraw use the publish permission (models.applications.publish.post). There is no separate reviewer permission. Give the publish permission to the people who may review.
  • The project admin role holds the governance role by default. In a project where one person is the only admin, that person cannot approve their own requests, but can approve other people’s at any tier.
  • A project cannot set its own, higher minimums. The tier table is platform-wide.
  • Versions published before the upgrade are recorded as change requests of kind legacy_unreviewed, already published and uncertified.

A change that passes review can still make an agent worse. Without a test run tied to the release, nobody can prove that the release was tested, or which test cases it broke.

Gate suites. Any evaluation dataset of the agent (or of no agent) can be marked as a release gate suite, with 1 to 5 criteria, one per scoring dimension:

  • threshold: the dimension’s mean normalised score (0–100) must be at least min_score;
  • no worse than: the score must not drop more than max_drop points below the agent’s current release.

One suite can also be marked as the regression suite. An agent can have at most 10 gate suites.

Only the governance role loosens a governed gate. For an agent whose tier needs approval, the author cannot weaken the gate their own change request is tested against. Unmarking a suite, unsetting the regression flag, removing a criterion, changing a criterion’s kind, lowering a min_score or raising a max_drop needs the governance role (models.applications.governance); without it the change is refused with HTTP 403 governance_role_required. Adding a suite or a criterion, or making one stricter, stays open to anyone who can edit the dataset and publish the agent.

What a gate runs. Submitting a change request runs every gate suite against the candidate. The regression suite, and any suite with a “no worse than” criterion, also runs against the version of the agent’s current release. The instructions and model of both are copied when the gate starts, so an edit made while the gate runs does not change what is measured.

How a gate decides. When every run has finished:

FailureMeaning
gate_threshold_not_metA threshold criterion was not met
gate_score_regressedA score dropped more than max_drop
gate_regressionCases that passed on the current release fail on the candidate; each one is listed
gate_dimension_unscored, gate_dimension_incompleteA criterion’s dimension has no score, or some of its cases errored or were skipped
gate_run_errored, gate_run_cancelled, gate_run_missingA run did not finish
gate_suite_not_runnableThe suite was deleted, has no active case, or its run could not start
gate_start_failedA run of the gate could not be started (the evaluation store or queue failed), or the process starting the runs stopped. The runs already started are cancelled and kept on the gate. Submit again, or ask for an override

A run that errors or is cancelled fails the gate. It never passes it. An agent with no gate suites passes at once. Once recorded, a gate’s outcome cannot change.

Override. A holder of the governance role who is not the request’s author can accept a failed gate, with a reason of 1 to 200 characters. The gate stays failed, and the override is recorded with the person, the time and the reason.

Scheduled re-evaluation. A gate suite can be set to re-run every N days against the agent’s current release. A scheduled run that fails the suite’s criteria makes a certified agent due (see Recertification). The runs are made for the user who last saved the suite’s schedule. If that user has lost the permission to run evaluations, the scheduled gate is recorded as failed (gate_schedule_actor_refused) and runs nothing, and it does not make the agent due.

  • An evaluation run sends each case to the agent’s instructions and model in one call, without its tools, toolkits or sub-agents. The gate measures instruction and model changes, not tool behaviour.
  • Gate runs share the evaluation runner’s capacity (two runs at a time per instance) and cost model calls like any evaluation run.
  • A gate settles when its runs finish, either when someone reads it or on the next pass of the main.release_gate routine (every 5 minutes).
  • A person who can edit the dataset and publish the agent can add or tighten its criteria; loosening a governed agent’s gate needs the governance role. Each gate keeps the criteria it ran with, so approvers see them.
  • If a change request is submitted and later withdrawn, the gate’s runs still finish and are paid for.

An agent’s behaviour comes from its instructions, model settings, tools and toolkit configuration. If these change without a record, nobody can answer “what did this agent run last week, and who changed it?”, and there is no reliable way to return to a known-good definition after a bad change. Before this control, a published version could be unpublished, edited and published again, and the earlier definition was lost.

A publish creates a release. When a version is published, the platform records an immutable release:

  • the version’s definition, with every toolkit’s settings removed, because settings can hold credentials;
  • the SHA-256 definition digest of that definition;
  • a pin for each attached toolkit: the hash of its stored settings and of the settings the agent saw, the agent’s tool selection, and, for each configuration it references, the configuration’s id, project and the hash of its data. Credential reference ids are pinned. Secret values are never stored.

A database trigger refuses any change to a release except marking it withdrawn. Publishing the same version again returns the same release. The release is recorded in the publish’s own transaction, together with the copies of the agent’s sub-agents: if it cannot be recorded, the publish fails with HTTP 500 and nothing is published.

One release is current. Each agent has one current release, which a run executes when it does not name a release. A publish makes its release current. An unpublish marks the releases of that version as withdrawn and makes the newest release that is still published current, if there is one. This happens in the same transaction as the revert to draft: if the releases cannot be withdrawn, the unpublish fails and the version stays published, so you can retry it.

Published versions are read-only. A published version cannot be changed in place, through any route. To change an agent, edit a draft and publish it.

Every draft save is a revision. Each save of a version records a revision with its number, author, time, a snapshot and a JSON diff of what changed. The first save of a version also records a baseline. A save that changes nothing records no revision.

Runs record their release. A run of a published agent records the id of the release it executes (agent_execution_jobs.release_id). A run can also name a release explicitly (release_id on the chat start body); it then executes that release, even a withdrawn one, unless the agent has sub-agents (see Limits).

Rollback re-points the current release. A user with the permission to publish (models.applications.publish.post) can make an earlier published release current again. A rollback needs no change request, so for an agent whose tier needs approval it also needs the governance role (models.applications.governance); without it the rollback is refused with 409 change_request_required. New runs then execute that release. Runs already in progress keep the release they started with.

Drift is refused, not hidden. When a run executes a release that is not the agent’s live version (an explicit release id, or after a rollback), the platform reads the live toolkit settings and configurations and compares them with the release’s pins. If any of them changed, the run is refused with HTTP 409 release_toolkit_drifted, which names the toolkit and the reason. A rollback to a release whose toolkits drifted is refused the same way. The platform never runs an old release with new toolkit settings without telling you.

  • When the current release is the agent’s live published version and one of its toolkits was edited after the publish, the run is not refused. It runs the live version and records no release id. Toolkits are shared and edited in place, and refusing every run of every agent that uses an edited toolkit would stop production. Publish the agent again to record a release with the new settings.
  • A withdrawn release of an agent with sub-agents cannot run. A publish makes private copies of the agent’s sub-agents and pins them in the release, and unpublishing deletes those copies. A run that names such a release is refused with HTTP 409 release_withdrawn_dependencies_removed. Run the agent’s current release, or publish the agent again.
  • A rollback stops the agent’s mandate-bound inbound triggers. With credential governance on, a trigger runs under a mandate whose agent binding binds the version the trigger names. After a rollback, a run of that version executes the earlier release’s version, which the mandate does not bind, so the trigger answers HTTP 403 with the code MANDATE_RELEASE_ROLLED_BACK. The run is refused rather than run under a mandate that never approved that definition. To resume, roll the agent forward to the release of the trigger’s version, or point the trigger at the release’s version and attach a mandate bound to that version.
  • A configuration that resolves per user (a private configuration reference) is pinned by its path and title only.
  • Sub-agents’ versions and skill content are read when the run starts. They are not pinned in the parent’s release.
  • Revisions cover the version’s own fields. Toolkit and skill attachments are covered by the release pins.
  • A release is recorded in the project that publishes it, not in the Catalog copy.
  • Versions published before this release have no release. They run as before and their runs record no release id. Their first release is recorded when they are next published.

Nothing needs to be turned on. For the steps of each role (author, approver, governance role), see Publish with approval. To see an agent’s history, open the agent, select the ⋮ menu beside the version bar, and select Release history. See Roll back an agent to an earlier release.

The same data is available with the API:

Method and pathPermissionReturns
GET /api/v2/elitea_core/application_releases/prompt_lib/{project_id}/{application_id}models.applications.versions.getEvery release, newest first
GET /api/v2/elitea_core/application_releases/prompt_lib/{project_id}/{application_id}/{release_id}models.applications.version.detailsOne release with its definition, pins and changes against the release before it
POST /api/v2/elitea_core/application_releases/prompt_lib/{project_id}/{application_id}/{release_id}/rollbackmodels.applications.publish.post; for an agent whose tier needs approval, also models.applications.governanceBody {"reason": "..."} (at most 200 characters); answers the releases it moved from and to
GET /api/v2/elitea_core/version_revisions/prompt_lib/{project_id}/{application_id}/{version_id}models.applications.versions.getThe version’s revisions with their diffs

A rollback is refused with 400 when the reason is longer than 200 characters, with 404 release_not_found, or with 409 and application_not_published, release_already_published, release_withdrawn, release_toolkit_drifted or change_request_required (an agent whose tier needs approval, rolled back without the governance role).

  • Releases (elitea_lifecycle.application_releases): who published, when, the definition, its digest and the toolkit pins. They are never edited or deleted.

  • Revisions (elitea_lifecycle.version_revisions): every save with its author, time and diff.

  • The run’s release (agent_execution_jobs.release_id): joins a run to the exact definition it executed.

  • Audit events. Publish and unpublish are recorded as before. A rollback is an api audit event with the action application_release.rolled_back:

    {
    "event_type": "api",
    "action": "application_release.rolled_back",
    "user_id": 4,
    "project_id": 7,
    "entity_type": "application_release",
    "entity_id": 12,
    "entity_name": "application:31 from release:15 reason: regression in the summary step",
    "status_code": 200
    }

    entity_id is the release that became current. The reason is at most 200 characters, so a reason in ASCII is always kept whole in entity_name. The audit store keeps at most 256 bytes of the name, so a long reason in a non-Latin script can be cut.

  • Decide who may publish and roll back agents, and give models.applications.publish.post only to them.
  • Keep links between the platform’s change requests and your own change records (tickets) in either direction: cite the change request and release id in your ticket, or put the ticket link in the change request summary.
  • Publish an agent again after you change one of its toolkits, so that its current release matches what runs.

An approval is a statement about one point in time. Models are retired, toolkits change, and an agent that passed its tests six months ago may not pass them today. Without a deadline, a certification never expires.

A certification has a deadline. When a change request certifies an agent, its recertify-by date is set from the tier’s cadence. The defaults are critical 90 days, high 180 and medium 365. Low-tier agents have no deadline.

A tier change moves the deadline. When a certified agent’s tier changes, its recertify-by date becomes the time of certification plus the new tier’s cadence, or none when the new tier has no cadence. Raising a tier can therefore make an agent due or lapsed at once. When a due, lapsed or suspended agent moves to a tier with no cadence, it returns to certified with no deadline and its certification suspension is resumed. Both are recorded as agent.certification.certified with the reason tier_without_cadence. An agent at a tier with no cadence never lapses by time.

A certified agent becomes due when:

  • its recertify-by date is less than 30 days away (recertify_window);
  • a release other than the certified one is published (new_release);
  • a toolkit or configuration pinned in the certified release changed (release_toolkit_drifted);
  • a scheduled re-evaluation failed its criteria (evaluation_regressed);
  • someone, or an external tool, marked it due through the API, with a reason (external_mark). Only a certified agent can be marked due.

A due or certified agent becomes lapsed when its recertify-by date passes. What happens then is a platform setting (lapse_action):

  • warn (the default): the agent keeps running; its state shows as lapsed in the registry and the agent’s Governance dialog.
  • suspend: the platform suspends the agent with the kill switch, with source certification. Its runs are refused with HTTP 409 agent_certification_lapsed and its state is suspended. Only a holder of the governance role can resume it.

Recertifying. Open the agent, select ⋮ › Governance › Change requests, and select Start recertification. This is a change request of kind recertification for the agent’s current release, with no definition change. It runs the gate again and collects the approvals and attestations the tier requires. Its approval certifies the agent again, sets a new recertify-by date and lifts a certification suspension. A due, lapsed or suspended agent can always be recertified, whatever its tier. At a tier that needs no approval, a recertification still needs one approval from someone other than its author.

The routine main.agent_recertification runs every hour (Admin › Schedules & Tasks). It checks drift and scheduled evaluations for up to 50 agents per pass, the oldest checked first.

  • The platform has no signal for a model being retired. An external tool, or a person, can mark the agent due through the API.
  • Drift and regression checks cover 50 agents per hour, so a deployment with many certified agents notices drift later.
  • Switching lapse_action back to warn resumes the certification suspensions on the next pass.

Some reviews cannot happen inside the platform: enterprise architecture, legal and compliance, model-risk classification, data ownership and data accuracy. If their outcome is not recorded next to the agent, nobody can prove the review happened before release, or notice when it expired.

An attestation records a review done elsewhere. It has:

  • a kind: architecture, legal, model_risk, data_owner, data_accuracy or custom;
  • a subject: an agent, a release, a toolkit or an index;
  • the attester, an optional valid-until date, an evidence link (an http or https URL, for example a ticket or a document) and a note.

Attestations are never deleted. A revocation is stamped with who revoked it and when.

Mandatory kinds per tier. The tier policy can make kinds mandatory. By default, critical agents need a model_risk and a legal attestation. An attestation counts when its subject is the agent, or the agent’s current release. A change request for an agent with a missing, expired or revoked mandatory attestation cannot be approved (409 attestation_missing).

Written by people or by your GRC tool. Anyone holding lifecycle.attestations.write can record or revoke an attestation, in the Governance dialog or through the API. Give an API token with this permission to your GRC system, so the outcome of a review is recorded automatically. See Record an attestation from a GRC tool.

  • The agent’s Attestations tab lists attestations whose subject is the agent. Attestations on a release, toolkit or index are listed through the API (GET agent_attestations/prompt_lib/{p}?subject_type=release&subject_id=...).
  • The platform does not perform or model the reviews. It records that they happened and enforces that they exist.
  • For toolkit and index subjects, the platform does not check that the subject exists.
  • The custom kind cannot be made mandatory.

A platform administrator sets the tier policy in Admin › Configuration › Agent Lifecycle (permission configuration.governance), or with PUT /api/v2/admin/plugin_config_values/administration/agent_lifecycle.

SettingDefaultRange
low_approvals, low_governance_approvals0, 0from the default up to 5
medium_approvals, medium_governance_approvals1, 0from the default up to 5
high_approvals, high_governance_approvals1, 1from the default up to 5
critical_approvals, critical_governance_approvals2, 1from the default up to 5
low_recertify_days, medium_recertify_days, high_recertify_days, critical_recertify_days0 (none), 365, 180, 900 to 1095
low_attestations … critical_attestationscritical: model_risk, legal; others nonekinds except custom
lapse_actionwarnwarn or suspend

Governance approvals never exceed approvals. A value below the default is raised to the default.

PermissionDefault holdersAllows
models.applications.publish.postProject roles that publishCreate, submit, approve, reject and withdraw change requests; edit the registry record
models.applications.governancePlatform super_admin and admin; project adminApprove where the tier needs the governance role, lower a tier, override a failed gate, withdraw anyone’s request
lifecycle.attestations.writeProject adminRecord and revoke attestations
lifecycle.registry.mark_dueProject adminMark an agent due
configuration.governancePlatform administratorsThe tier policy and the cross-project registry

All paths are under /api/v2/elitea_core, with {p} the project id and {app} the agent id.

Method and pathPermissionDoes
GET, PUT agent_registry/prompt_lib/{p}/{app}read: models.applications.versions.get; write: models.applications.publish.postRead or edit the registry record
POST agent_registry/prompt_lib/{p}/{app}/mark_duelifecycle.registry.mark_dueMark a certified agent due, with a reason
GET, POST change_requests/prompt_lib/{p}/{app}read: models.applications.versions.get; create: models.applications.publish.postList, or create a draft change request
GET change_requests/prompt_lib/{p}/{app}/{cr}models.applications.versions.getOne request with its approvals and gate state
POST change_requests/prompt_lib/{p}/{app}/{cr}/submit, approve, reject, withdrawmodels.applications.publish.postMove the request
POST change_requests/prompt_lib/{p}/{app}/{cr}/gate_overridemodels.applications.governanceAccept a failed gate, with a reason
GET, POST agent_attestations/prompt_lib/{p}; POST agent_attestations/prompt_lib/{p}/{id}/revokeread: models.applications.versions.get; write: lifecycle.attestations.writeList, record or revoke attestations
GET release_gate_suites/prompt_lib/{p}/{app}; PUT release_gate_suites/prompt_lib/{p}/{app}/{dataset}read: models.applications.evaluation.dataset.read; write: …evaluation.dataset.update and models.applications.publish.post, and models.applications.governance to loosen the gate of an agent whose tier needs approvalRead or set the gate suites
GET release_gates/prompt_lib/{p}/{app}[/{gate}]models.applications.evaluation.run.readGates with their runs, results, failures and override
GET /api/v2/admin/agent_registryconfiguration.governanceThe cross-project registry; tier, state, owner_id, project_id, limit, offset; format=csv exports up to 10,000 rows

Create an API token for a service user that holds lifecycle.attestations.write in the project, then have your GRC tool call:

Terminal window
curl -X POST "$ELITEA_URL/api/v2/elitea_core/agent_attestations/prompt_lib/7" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{
"kind": "model_risk",
"subject_type": "agent",
"subject_id": "31",
"attester": "Model Risk Committee",
"valid_until": "2027-10-29T00:00:00Z",
"evidence_url": "https://grc.example.com/reviews/MR-2291",
"note": "Tier 2 model risk; approved for internal use"
}'

To mark an agent due from an ML-monitoring tool, call POST agent_registry/prompt_lib/7/31/mark_due with {"reason": "output drift above threshold"}.

Every change to the registry, a change request, a certification or an attestation is written to the tamper-evident security audit log, in the same transaction as the change, with the event type ai.elitea.security.v1.agent.lifecycle:

ActionWhen
agent.change.submitted, approved, rejected, withdrawn, publishedA change request moves
agent.change.gate_overriddenA failed gate is accepted, with the reason
agent.registry.tier_changedA tier changes
agent.certification.certified, due, lapsed, suspendedThe certification state moves, with the reason codes
agent.attestation.recorded, revokedAn attestation is written or revoked

Changes to a dataset’s gate settings are recorded in the audit trail as agent.gate_suite.updated. Both logs reach your SIEM through the audit export. The registry export is the inventory to hand to an auditor; the change request read shows, for one release, the candidate, its gate with the criteria it ran with, the approvals and the release that was published.

  • Classify each agent’s risk and set its tier. The platform enforces the controls of the tier you choose; it does not decide the tier.
  • Perform the architecture, legal, model-risk and data reviews in your own process and record their outcome as attestations.
  • Write the evaluation datasets and choose the pass criteria. The platform runs them; it does not ship a fairness or accuracy methodology.
  • Monitor production traffic for statistical drift in your ML-monitoring tool, which can mark agents due through the API.