Action taxonomy
preflight.action and context.assemble take an action type from a closed set of sixteen. The
full list is on the vocabularies page; this page is about
choosing one.
Why the set is closed
Section titled “Why the set is closed”An open string field would make every verdict incomparable. “Is this deploy riskier than the last
five?” needs the last five to be identifiable as deploys — and with free text you get deploy,
deployment, Deploy, release-prod and no way to relate them.
A closed set means policy can be written once against a type, history is comparable, and a typo is a
validation fault at the call site instead of silently creating a new category of one.
The sixteen
Section titled “The sixteen”| Group | Types |
|---|---|
| Code | code.apply_patch · code.delete_file · code.modify_migration · code.modify_dependency · code.touch_fragile_file |
| Version control | vcs.merge_pr · vcs.force_push · vcs.modify_ci_config |
| Deploy | deploy.release · deploy.rollback · deploy.modify_infra |
| Data | data.run_migration · data.bulk_mutation |
| Sensitive | secret.access · tool.exec_shell · tool.network_call |
Picking one
Section titled “Picking one”What is the agent about to do? Not what it is working on. An agent refactoring a migration file
is doing code.modify_migration; one running it is doing data.run_migration. Very different risk,
very different history to consult.
Pick the most specific that fits. code.apply_patch is the general case. If the change touches a
migration, code.modify_migration finds the memory about migrations. Reaching for the general type
gets you a weaker answer.
code.touch_fragile_file is usually not yours to choose. Fragility is a property the corpus knows
about a file, from its incident history. Send code.apply_patch with the real changed_files and
let the server raise fragile_file as a reason. Claiming it yourself pre-empts a judgement the
corpus is better placed to make.
Files matter as much as the type
Section titled “Files matter as much as the type”{ "action_type": "code.apply_patch", "changed_files": ["billing/reconcile.py", "billing/fixtures.py"], "scope_key": "repo:payments", "summary": "Rewrite the reconcile loop"}changed_files is how the corpus finds file-specific history — the three rollbacks caused by
payments/ledger.go, the fixture dependency in billing/. An action with an accurate type and no
files gets a generic answer.
summary is read by the model and by humans reading the audit trail later. “Rewrite the reconcile
loop” beats “changes”.
Risk class is yours; reasons are the server’s
Section titled “Risk class is yours; reasons are the server’s”risk_class — low, medium, high, critical — is your
assessment of this action. The server does not have to agree, and the interesting cases are where
it does not: a low action that the corpus knows broke production twice comes back with reasons
attached.
Do not inflate it to force attention. The reasons carry the argument, and an integration that marks
everything critical has told the server nothing.
Purpose
Section titled “Purpose”purpose — why you are doing it — changes which guides resolve.
The same patch under incident_response and under refactor should surface different standing
advice, because it should.
Which to gate
Section titled “Which to gate”Not all sixteen deserve a CI gate. Gate the hard-to-undo ones:
data.run_migration · vcs.force_push · vcs.modify_ci_config · deploy.modify_infra ·
code.modify_dependency
A gate on everything is a gate people route around.