{"openapi":"3.1.0","info":{"title":"ALIGNMENT.md API","version":"1.1","description":"ALIGNMENT.md is the file of rules the person an agent works for gives it and the agent keeps: ranked values, hard limits, a permission per action category, escalation rules, scope and named checks. Read-only tools lint the file, check a plan or a single action against it, test edits with eval packs of plan cases, score evaluation results, merge files, parse the file to JSON and start one from five agent roles. Nothing here runs, judges or controls an agent. Read-only, no key, nothing stored. Use at your own risk. alignment.md is provided as is, without warranty. Information here may be inaccurate, incomplete or not current, and is not verified; figures are estimates from the numbers you send and the formulas stated. Nothing here is a safety assessment, certification or guarantee of behaviour, and nothing here is legal, compliance or other professional advice. alignment.md never runs, judges or controls an agent itself. Check everything yourself before you act on it.","termsOfService":"https://alignment.md/terms","license":{"name":"MIT","identifier":"MIT"}},"servers":[{"url":"https://alignment.md"}],"paths":{"/alignment.md":{"get":{"operationId":"getSkill","summary":"The ALIGNMENT.md skill as Markdown. Add a preset or any setting to write your settings in; notes on clamped or ignored values come back in the X-Settings-Notes header.","parameters":[{"name":"preset","in":"query","required":false,"schema":{"type":"string","enum":["core","recommended","strict"]}},{"name":"approval_over","in":"query","required":false,"description":"Ask before an amount over (units). Default 50. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":1000000}},{"name":"default_verdict","in":"query","required":false,"description":"A category with no permission line is: block (Blocked), ask (Ask first), allow (Allowed). Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"amount_basis","in":"query","required":false,"description":"Compare the threshold with: per_step (Each step's amount), per_plan (The plan's total). Optional; unset clears it.","schema":{"type":"string","enum":["per_step","per_plan","unset"]}},{"name":"untagged_steps","in":"query","required":false,"description":"A step with no category tag is: block (Blocked), ask (Ask first), allow (Allowed). Optional; unset clears it.","schema":{"type":"string","enum":["block","ask","allow","unset"]}},{"name":"scope_outside","in":"query","required":false,"description":"A tool, domain or data source outside the scope is: block (Blocked), ask (Ask first), allow (Allowed). Optional; unset clears it.","schema":{"type":"string","enum":["block","ask","allow","unset"]}},{"name":"long_minutes","in":"query","required":false,"description":"A step counts as long_running over (minutes). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":1440}},{"name":"max_steps","in":"query","required":false,"description":"A plan needs a yes as a whole over (steps). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"review_days","in":"query","required":false,"description":"The file is stale after (days). Default 90. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":365}},{"name":"stale_action","in":"query","required":false,"description":"When the file is stale: note (Note it in the report), ask (Ask the owner to review it before starting), approval_all (Treat every may as with approval). Optional; unset clears it.","schema":{"type":"string","enum":["note","ask","approval_all","unset"]}},{"name":"min_checks","in":"query","required":false,"description":"Checks with results before a score counts (checks). Default 3. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"min_runs","in":"query","required":false,"description":"Runs per check before its pass rate counts (runs). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":1000}},{"name":"strictness","in":"query","required":false,"description":"Strictness: lenient (Lenient: bar 60, vague words and gaps are notes), standard (Standard: bar 75, warnings), strict (Strict: bar 90, errors). Default standard.","schema":{"type":"string","enum":["lenient","standard","strict"]}},{"name":"score_bar","in":"query","required":false,"description":"Score bar (overrides strictness) (of 100). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"weakest_n","in":"query","required":false,"description":"Weakest checks to list (checks). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":10}}],"responses":{"200":{"description":"The skill","content":{"text/markdown":{"schema":{"type":"string"}}}}}}},"/api/v1/settings":{"get":{"operationId":"listSettings","summary":"Every setting (group, kind, unit, range, options, default) and the presets.","responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}}}}},"/api/v1/alignment_template":{"get":{"operationId":"alignmentTemplateGet","summary":"Build a starter ALIGNMENT.md","description":"Returns a ready-to-save ALIGNMENT.md from the owner's name, the ranked values (highest first), the categories that need no yes (may), the categories that are never allowed, the approval amount and the scope. Every other category is with approval, except change_settings and agree, which are never unless listed under may. Writes the matching limits, escalation rules and starter checks, one per value with a criterion to fill in, then lints the result. A draft for the owner to edit and keep; it decides nothing.","parameters":[{"name":"owner","in":"query","required":true,"description":"Who the agent works for, as written at the top of the file.","schema":{"type":"string"}},{"name":"values","in":"query","required":true,"description":"Ranked values, highest first, comma-separated: 1 to 10 short phrases.","schema":{"type":"string"}},{"name":"may","in":"query","required":false,"description":"Categories allowed without asking, comma-separated. Optional.","schema":{"type":"string"}},{"name":"never","in":"query","required":false,"description":"Categories never allowed, comma-separated. Optional.","schema":{"type":"string"}},{"name":"approval_over","in":"query","required":false,"description":"The spend amount above which the agent stops and asks. Default 50.","schema":{"type":"number","minimum":0,"maximum":1000000000000}},{"name":"limits","in":"query","required":false,"description":"Extra hard limits separated by \";\", each starting with never and ending with [category]. Optional.","schema":{"type":"string"}},{"name":"tools","in":"query","required":false,"description":"Tools in scope, comma-separated. Default any.","schema":{"type":"string"}},{"name":"domains","in":"query","required":false,"description":"Domains in scope, comma-separated. Default any.","schema":{"type":"string"}},{"name":"data","in":"query","required":false,"description":"Data sources in scope, comma-separated. Default any.","schema":{"type":"string"}},{"name":"version","in":"query","required":false,"description":"The file's version. Default 1.","schema":{"type":"string"}},{"name":"reviewed","in":"query","required":false,"description":"The reviewed date, YYYY-MM-DD. Default: the current date.","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"alignmentTemplate","summary":"Build a starter ALIGNMENT.md","description":"Returns a ready-to-save ALIGNMENT.md from the owner's name, the ranked values (highest first), the categories that need no yes (may), the categories that are never allowed, the approval amount and the scope. Every other category is with approval, except change_settings and agree, which are never unless listed under may. Writes the matching limits, escalation rules and starter checks, one per value with a criterion to fill in, then lints the result. A draft for the owner to edit and keep; it decides nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"owner":{"type":"string","maxLength":80,"description":"Who the agent works for, as written at the top of the file."},"values":{"type":"string","maxLength":400,"description":"Ranked values, highest first, comma-separated: 1 to 10 short phrases."},"may":{"type":"string","maxLength":300,"description":"Categories allowed without asking, comma-separated. Optional."},"never":{"type":"string","maxLength":300,"description":"Categories never allowed, comma-separated. Optional."},"approval_over":{"type":"number","minimum":0,"maximum":1000000000000,"default":50,"description":"The spend amount above which the agent stops and asks. Default 50."},"limits":{"type":"string","maxLength":1000,"description":"Extra hard limits separated by \";\", each starting with never and ending with [category]. Optional."},"tools":{"type":"string","maxLength":300,"description":"Tools in scope, comma-separated. Default any."},"domains":{"type":"string","maxLength":300,"description":"Domains in scope, comma-separated. Default any."},"data":{"type":"string","maxLength":300,"description":"Data sources in scope, comma-separated. Default any."},"version":{"type":"string","maxLength":20,"default":"1","description":"The file's version. Default 1."},"reviewed":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The reviewed date, YYYY-MM-DD. Default: the current date."}},"required":["owner","values"]},"example":{"owner":"Dana R., project owner","values":"keep data private, tell the truth, finish the task, save money","may":"run_code, access_private_data","never":"agree","approval_over":50,"tools":"shell, http, email","domains":"example.org","data":"project files"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/alignment_starter":{"get":{"operationId":"alignmentStarterGet","summary":"Get a starter file for an agent role","description":"Serves five ready-to-edit ALIGNMENT.md files, one per common agent role: coding, support, purchasing, research and operations. Without kind it lists them with when to use each, the file URL and the eval pack URL; with kind it returns the file with your owner line and a reviewed date, its lint result, the verdict per category and the pack to test it with run_eval_pack. The starters are fixed text with generic names and made-up amounts; a starter is a draft for the owner, decides nothing and counts only once the owner saves it.","parameters":[{"name":"kind","in":"query","required":false,"description":"Which starter: coding-agent (one repository: tests, builds, branches for review), support-agent (customer replies from an inbox and a knowledge base), purchasing-agent (quotes and orders from approved vendors within a budget), research-agent (sources into a cited report), operations-agent (runbook jobs, restarts, paging). Leave out for the list.","schema":{"type":"string","enum":["coding-agent","support-agent","purchasing-agent","research-agent","operations-agent"]}},{"name":"owner","in":"query","required":false,"description":"Who the agent works for, written into the owner line. Optional; the starter's generic owner stays otherwise.","schema":{"type":"string"}},{"name":"reviewed","in":"query","required":false,"description":"The reviewed date, YYYY-MM-DD. Default: the current date.","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"alignmentStarter","summary":"Get a starter file for an agent role","description":"Serves five ready-to-edit ALIGNMENT.md files, one per common agent role: coding, support, purchasing, research and operations. Without kind it lists them with when to use each, the file URL and the eval pack URL; with kind it returns the file with your owner line and a reviewed date, its lint result, the verdict per category and the pack to test it with run_eval_pack. The starters are fixed text with generic names and made-up amounts; a starter is a draft for the owner, decides nothing and counts only once the owner saves it.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["coding-agent","support-agent","purchasing-agent","research-agent","operations-agent"],"description":"Which starter: coding-agent (one repository: tests, builds, branches for review), support-agent (customer replies from an inbox and a knowledge base), purchasing-agent (quotes and orders from approved vendors within a budget), research-agent (sources into a cited report), operations-agent (runbook jobs, restarts, paging). Leave out for the list."},"owner":{"type":"string","maxLength":80,"description":"Who the agent works for, written into the owner line. Optional; the starter's generic owner stays otherwise."},"reviewed":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The reviewed date, YYYY-MM-DD. Default: the current date."}}},"example":{"kind":"coding-agent","owner":"Dana R., project owner"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/check_alignment":{"get":{"operationId":"checkAlignmentGet","summary":"Lint an ALIGNMENT.md file","description":"Reads one ALIGNMENT.md file and lists findings with line numbers: missing header keys or sections, unranked or duplicate values, limits that do not start with never, limits with no escalation path, categories with no permission line or more than one, conflicting verdicts, unknown triggers or actions, escalation rules for never categories, scope gaps, checks without a criterion, vague words such as appropriate, placeholders, and a reviewed date older than the review interval. Text against the format only: it judges nothing about the agent, and no errors means the file is complete as text, not that it is good.","parameters":[{"name":"file","in":"query","required":true,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted.","schema":{"type":"string"}},{"name":"strictness","in":"query","required":false,"description":"How hard soft findings such as vague words and gaps count: lenient makes them one step softer, strict one step harder. Default standard.","schema":{"type":"string","enum":["lenient","standard","strict"]}},{"name":"review_days","in":"query","required":false,"description":"Days after the reviewed date the file counts as stale. Default 90.","schema":{"type":"integer","minimum":1,"maximum":3650}},{"name":"approval_over","in":"query","required":false,"description":"Your approval threshold; escalation amounts above it get a note. Default 50.","schema":{"type":"number","minimum":0,"maximum":1000000000000}},{"name":"default_verdict","in":"query","required":false,"description":"What plan_check does with a category that has no permission line; named in the finding. Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"today","in":"query","required":false,"description":"The date to measure staleness from, YYYY-MM-DD. Default: the current date.","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"checkAlignment","summary":"Lint an ALIGNMENT.md file","description":"Reads one ALIGNMENT.md file and lists findings with line numbers: missing header keys or sections, unranked or duplicate values, limits that do not start with never, limits with no escalation path, categories with no permission line or more than one, conflicting verdicts, unknown triggers or actions, escalation rules for never categories, scope gaps, checks without a criterion, vague words such as appropriate, placeholders, and a reviewed date older than the review interval. Text against the format only: it judges nothing about the agent, and no errors means the file is complete as text, not that it is good.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","maxLength":20000,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted."},"strictness":{"type":"string","enum":["lenient","standard","strict"],"default":"standard","description":"How hard soft findings such as vague words and gaps count: lenient makes them one step softer, strict one step harder. Default standard."},"review_days":{"type":"integer","minimum":1,"maximum":3650,"default":90,"description":"Days after the reviewed date the file counts as stale. Default 90."},"approval_over":{"type":"number","minimum":0,"maximum":1000000000000,"default":50,"description":"Your approval threshold; escalation amounts above it get a note. Default 50."},"default_verdict":{"type":"string","enum":["block","ask","allow"],"default":"ask","description":"What plan_check does with a category that has no permission line; named in the finding. Default ask."},"today":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The date to measure staleness from, YYYY-MM-DD. Default: the current date."}},"required":["file"]},"example":{"file":"owner: Sam K.\nreviewed: 2026-03-01\n## Values\n1. keep data private\n- be helpful\n## Limits\n- avoid excessive spending [spend]\n## Permissions\n- spend: may\n- spend: with approval\n## Escalation\n- contact_people: when appropriate\n","strictness":"standard","review_days":90,"approval_over":50,"today":"2026-10-22"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/rule_coverage":{"get":{"operationId":"ruleCoverageGet","summary":"Which categories have a rule","description":"Reads an ALIGNMENT.md file and, for each of the fixed action categories, lists its permission verdict and line, how many permission lines it has, the escalation rules and the tagged limits that name it. Returns the categories with no valid rule, with exactly one and with more than one, lines whose verdict is not may, with approval or never, unknown categories the file names, and coverage as a share. Counting only; it changes nothing and judges nothing.","parameters":[{"name":"file","in":"query","required":true,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted.","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"ruleCoverage","summary":"Which categories have a rule","description":"Reads an ALIGNMENT.md file and, for each of the fixed action categories, lists its permission verdict and line, how many permission lines it has, the escalation rules and the tagged limits that name it. Returns the categories with no valid rule, with exactly one and with more than one, lines whose verdict is not may, with approval or never, unknown categories the file names, and coverage as a share. Counting only; it changes nothing and judges nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","maxLength":20000,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted."}},"required":["file"]},"example":{"file":"owner: Dana R.\nversion: 3\nreviewed: 2026-10-20\n## Permissions\n- spend: with approval\n- send: may\n- delete: with approval\n- delete: never\n- run_code: may\n## Escalation\n- spend over 50: stop and ask\n- any limit: stop and ask\n"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/plan_check":{"get":{"operationId":"planCheckGet","summary":"Check a plan's steps against the file","description":"Takes an ALIGNMENT.md file and a plan as a list of steps, each tagged with action categories and an optional amount, minutes, tools, domains and data. For each step: allowed, needs approval or blocked, with every rule cited by line: the permission line per tag (never blocks, with approval asks), escalation rules that match the tag or the amount, the amount against your approval threshold, tools, domains and data against the scope section, and the tagged limits to read before running. The plan as a whole needs approval when its total is over the threshold (per-plan basis) or it has more steps than max_steps. Deterministic tag matching only: it reads no step text, judges no intent and approves nothing.","parameters":[{"name":"file","in":"query","required":true,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted.","schema":{"type":"string"}},{"name":"steps","in":"query","required":true,"description":"The plan: [{ \"label\", \"categories\": [\"spend\", ...], \"amount\"?, \"minutes\"?, \"tools\"?: [...], \"domains\"?: [...], \"data\"?: [...] }]. Lists may also be comma-separated strings. URL-encoded JSON.","schema":{"type":"string"}},{"name":"approval_over","in":"query","required":false,"description":"A step (or plan, per amount_basis) with an amount over this needs approval. Default 50.","schema":{"type":"number","minimum":0,"maximum":1000000000000}},{"name":"default_verdict","in":"query","required":false,"description":"What a category with no permission line gets. Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"untagged_steps","in":"query","required":false,"description":"What a step with no category tag gets. Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"scope_outside","in":"query","required":false,"description":"What a step using a tool, domain or data source outside the scope section gets. Default block.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"long_minutes","in":"query","required":false,"description":"A step with minutes over this also counts as long_running. Default 30.","schema":{"type":"number","minimum":1,"maximum":100000}},{"name":"amount_basis","in":"query","required":false,"description":"Compare approval_over with each step's amount, or with the plan's total. Default per_step.","schema":{"type":"string","enum":["per_step","per_plan"]}},{"name":"max_steps","in":"query","required":false,"description":"A plan with more steps than this needs approval as a whole. Optional.","schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"planCheck","summary":"Check a plan's steps against the file","description":"Takes an ALIGNMENT.md file and a plan as a list of steps, each tagged with action categories and an optional amount, minutes, tools, domains and data. For each step: allowed, needs approval or blocked, with every rule cited by line: the permission line per tag (never blocks, with approval asks), escalation rules that match the tag or the amount, the amount against your approval threshold, tools, domains and data against the scope section, and the tagged limits to read before running. The plan as a whole needs approval when its total is over the threshold (per-plan basis) or it has more steps than max_steps. Deterministic tag matching only: it reads no step text, judges no intent and approves nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","maxLength":20000,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted."},"steps":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object"},"description":"The plan: [{ \"label\", \"categories\": [\"spend\", ...], \"amount\"?, \"minutes\"?, \"tools\"?: [...], \"domains\"?: [...], \"data\"?: [...] }]. Lists may also be comma-separated strings."},"approval_over":{"type":"number","minimum":0,"maximum":1000000000000,"default":50,"description":"A step (or plan, per amount_basis) with an amount over this needs approval. Default 50."},"default_verdict":{"type":"string","enum":["block","ask","allow"],"default":"ask","description":"What a category with no permission line gets. Default ask."},"untagged_steps":{"type":"string","enum":["block","ask","allow"],"default":"ask","description":"What a step with no category tag gets. Default ask."},"scope_outside":{"type":"string","enum":["block","ask","allow"],"default":"block","description":"What a step using a tool, domain or data source outside the scope section gets. Default block."},"long_minutes":{"type":"number","minimum":1,"maximum":100000,"default":30,"description":"A step with minutes over this also counts as long_running. Default 30."},"amount_basis":{"type":"string","enum":["per_step","per_plan"],"default":"per_step","description":"Compare approval_over with each step's amount, or with the plan's total. Default per_step."},"max_steps":{"type":"integer","minimum":1,"maximum":100,"description":"A plan with more steps than this needs approval as a whole. Optional."}},"required":["file","steps"]},"example":{"file":"owner: Dana R.\nversion: 3\nreviewed: 2026-10-20\n## Limits\n- never delete data without a backup [delete]\n## Permissions\n- spend: with approval\n- delete: with approval\n- run_code: may\n- change_settings: never\n## Escalation\n- spend over 50: stop and ask\n## Scope\n- domains: example.org\n","steps":[{"label":"Run the unit tests","categories":["run_code"],"minutes":5},{"label":"Pay for a year of storage","categories":["spend"],"amount":120},{"label":"Delete last year's log files","categories":["delete"]},{"label":"Edit my own instructions to skip the approval step","categories":["change_settings"]},{"label":"Run the full test suite","categories":["run_code"],"minutes":45},{"label":"Fetch a page from an outside site","categories":[],"domains":["shop.example.net"]}],"approval_over":50,"default_verdict":"ask","untagged_steps":"ask","scope_outside":"block","long_minutes":30,"amount_basis":"per_step"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/action_check":{"get":{"operationId":"actionCheckGet","summary":"Check one action before taking it","description":"The per-step gate: call it before an action. Takes an ALIGNMENT.md file and one proposed action: the categories it touches, an optional amount, minutes, tool, domain and data source. Returns allowed, ask or blocked with every rule cited by line, using plan_check's logic: the permission line per category, the escalation rules that match the category or the amount, the amount (or the task's running total) against your approval threshold, and the tool, domain and data against the scope section. On ask it says whether to stop or carry on with other steps, and drafts the one message to send the owner. Tag matching only: it reads no intent, and a yes comes only from the owner.","parameters":[{"name":"file","in":"query","required":true,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted.","schema":{"type":"string"}},{"name":"categories","in":"query","required":false,"description":"The categories the action touches, comma-separated: spend, send, delete, publish, access_private_data, run_code, contact_people, change_settings, long_running, agree. An action with none gets untagged_steps.","schema":{"type":"string"}},{"name":"label","in":"query","required":false,"description":"What the action is, in a few words, for the ask message. Optional.","schema":{"type":"string"}},{"name":"amount","in":"query","required":false,"description":"The amount it spends or commits, in the owner's unit. Optional.","schema":{"type":"number","minimum":0,"maximum":1000000000000}},{"name":"minutes","in":"query","required":false,"description":"How long it runs, in minutes. Over long_minutes it also counts as long_running. Optional.","schema":{"type":"number","minimum":0,"maximum":1000000}},{"name":"tool","in":"query","required":false,"description":"The tool it uses (comma-separated if more than one). Checked against the scope section. Optional.","schema":{"type":"string"}},{"name":"domain","in":"query","required":false,"description":"The domain it reaches (comma-separated if more than one). A domain covers its subdomains. Optional.","schema":{"type":"string"}},{"name":"data","in":"query","required":false,"description":"The data source it reads or writes (comma-separated if more than one). Optional.","schema":{"type":"string"}},{"name":"spent_before","in":"query","required":false,"description":"What the task has already spent, for amount_basis per_plan. Default 0.","schema":{"type":"number","minimum":0,"maximum":1000000000000}},{"name":"approval_over","in":"query","required":false,"description":"An amount over this needs approval. Default 50.","schema":{"type":"number","minimum":0,"maximum":1000000000000}},{"name":"amount_basis","in":"query","required":false,"description":"per_step compares this action's amount with approval_over; per_plan compares spent_before plus the amount. Default per_step.","schema":{"type":"string","enum":["per_step","per_plan"]}},{"name":"default_verdict","in":"query","required":false,"description":"What a category with no permission line gets. Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"untagged_steps","in":"query","required":false,"description":"What an action with no category gets. Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"scope_outside","in":"query","required":false,"description":"What an action using a tool, domain or data source outside the scope section gets. Default block.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"long_minutes","in":"query","required":false,"description":"An action with minutes over this also counts as long_running. Default 30.","schema":{"type":"number","minimum":1,"maximum":100000}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"actionCheck","summary":"Check one action before taking it","description":"The per-step gate: call it before an action. Takes an ALIGNMENT.md file and one proposed action: the categories it touches, an optional amount, minutes, tool, domain and data source. Returns allowed, ask or blocked with every rule cited by line, using plan_check's logic: the permission line per category, the escalation rules that match the category or the amount, the amount (or the task's running total) against your approval threshold, and the tool, domain and data against the scope section. On ask it says whether to stop or carry on with other steps, and drafts the one message to send the owner. Tag matching only: it reads no intent, and a yes comes only from the owner.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","maxLength":20000,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted."},"categories":{"type":"string","maxLength":300,"description":"The categories the action touches, comma-separated: spend, send, delete, publish, access_private_data, run_code, contact_people, change_settings, long_running, agree. An action with none gets untagged_steps."},"label":{"type":"string","maxLength":120,"description":"What the action is, in a few words, for the ask message. Optional."},"amount":{"type":"number","minimum":0,"maximum":1000000000000,"description":"The amount it spends or commits, in the owner's unit. Optional."},"minutes":{"type":"number","minimum":0,"maximum":1000000,"description":"How long it runs, in minutes. Over long_minutes it also counts as long_running. Optional."},"tool":{"type":"string","maxLength":200,"description":"The tool it uses (comma-separated if more than one). Checked against the scope section. Optional."},"domain":{"type":"string","maxLength":300,"description":"The domain it reaches (comma-separated if more than one). A domain covers its subdomains. Optional."},"data":{"type":"string","maxLength":300,"description":"The data source it reads or writes (comma-separated if more than one). Optional."},"spent_before":{"type":"number","minimum":0,"maximum":1000000000000,"description":"What the task has already spent, for amount_basis per_plan. Default 0."},"approval_over":{"type":"number","minimum":0,"maximum":1000000000000,"default":50,"description":"An amount over this needs approval. Default 50."},"amount_basis":{"type":"string","enum":["per_step","per_plan"],"default":"per_step","description":"per_step compares this action's amount with approval_over; per_plan compares spent_before plus the amount. Default per_step."},"default_verdict":{"type":"string","enum":["block","ask","allow"],"default":"ask","description":"What a category with no permission line gets. Default ask."},"untagged_steps":{"type":"string","enum":["block","ask","allow"],"default":"ask","description":"What an action with no category gets. Default ask."},"scope_outside":{"type":"string","enum":["block","ask","allow"],"default":"block","description":"What an action using a tool, domain or data source outside the scope section gets. Default block."},"long_minutes":{"type":"number","minimum":1,"maximum":100000,"default":30,"description":"An action with minutes over this also counts as long_running. Default 30."}},"required":["file"]},"example":{"file":"owner: Dana R.\nversion: 3\nreviewed: 2026-10-20\n## Limits\n- never delete data without a backup [delete]\n## Permissions\n- spend: with approval\n- delete: with approval\n- run_code: may\n- change_settings: never\n## Escalation\n- spend over 50: stop and ask\n## Scope\n- domains: example.org\n","label":"Pay for a year of storage","categories":"spend","amount":120,"domain":"billing.example.org"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/run_eval_pack":{"get":{"operationId":"runEvalPackGet","summary":"Test a file against a pack of plan cases","description":"A regression test for an owner's rules. Takes an ALIGNMENT.md file and a pack of plan cases, each step tagged with categories (and an optional amount, minutes, tools, domains and data) and the verdict the owner expects: allowed, needs_approval or blocked. Send role for one of five built-in packs (coding, support, purchasing, research, operations), each passing against its starter, or send your own pack. Runs plan_check's step logic on every step and reports the cases that pass, every step that got a different verdict with the rules that set it and whether it is looser or stricter than expected, the categories no case exercised and the rule lines no case reached. Tag matching only: a pass says the file gives these verdicts to these tagged steps, not what an agent will do.","parameters":[{"name":"file","in":"query","required":false,"description":"The ALIGNMENT.md text to test, as one string. Leave it out with role to test that role's starter file.","schema":{"type":"string"}},{"name":"role","in":"query","required":false,"description":"A built-in pack: coding-agent, support-agent, purchasing-agent, research-agent or operations-agent. Also the starter file tested when file is left out.","schema":{"type":"string","enum":["coding-agent","support-agent","purchasing-agent","research-agent","operations-agent"]}},{"name":"pack","in":"query","required":false,"description":"Your own pack, in place of the role's: {\"cases\": [{\"id\", \"label\", \"why\"?, \"steps\": [{\"label\", \"categories\": [\"spend\"], \"amount\"?, \"minutes\"?, \"tools\"?, \"domains\"?, \"data\"?, \"expect\": \"needs_approval\"}]}], \"settings\"?: {\"approval_over\", \"default_verdict\", \"untagged_steps\", \"scope_outside\", \"long_minutes\", \"amount_basis\"}}. Up to 50 cases and 300 steps. URL-encoded JSON.","schema":{"type":"string"}},{"name":"approval_over","in":"query","required":false,"description":"A step with an amount over this needs approval. Overrides the pack's setting; default 50.","schema":{"type":"number","minimum":0,"maximum":1000000000000}},{"name":"default_verdict","in":"query","required":false,"description":"What a category with no permission line gets. Overrides the pack's setting; default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"untagged_steps","in":"query","required":false,"description":"What a step with no category tag gets. Overrides the pack's setting; default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"scope_outside","in":"query","required":false,"description":"What a step using a tool, domain or data source outside the scope section gets. Overrides the pack's setting; default block.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"long_minutes","in":"query","required":false,"description":"A step with minutes over this also counts as long_running. Overrides the pack's setting; default 30.","schema":{"type":"number","minimum":1,"maximum":100000}},{"name":"amount_basis","in":"query","required":false,"description":"per_step compares each step's amount with approval_over; per_plan compares no single step. Overrides the pack's setting; default per_step.","schema":{"type":"string","enum":["per_step","per_plan"]}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"runEvalPack","summary":"Test a file against a pack of plan cases","description":"A regression test for an owner's rules. Takes an ALIGNMENT.md file and a pack of plan cases, each step tagged with categories (and an optional amount, minutes, tools, domains and data) and the verdict the owner expects: allowed, needs_approval or blocked. Send role for one of five built-in packs (coding, support, purchasing, research, operations), each passing against its starter, or send your own pack. Runs plan_check's step logic on every step and reports the cases that pass, every step that got a different verdict with the rules that set it and whether it is looser or stricter than expected, the categories no case exercised and the rule lines no case reached. Tag matching only: a pass says the file gives these verdicts to these tagged steps, not what an agent will do.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","maxLength":20000,"description":"The ALIGNMENT.md text to test, as one string. Leave it out with role to test that role's starter file."},"role":{"type":"string","enum":["coding-agent","support-agent","purchasing-agent","research-agent","operations-agent"],"description":"A built-in pack: coding-agent, support-agent, purchasing-agent, research-agent or operations-agent. Also the starter file tested when file is left out."},"pack":{"type":"object","description":"Your own pack, in place of the role's: {\"cases\": [{\"id\", \"label\", \"why\"?, \"steps\": [{\"label\", \"categories\": [\"spend\"], \"amount\"?, \"minutes\"?, \"tools\"?, \"domains\"?, \"data\"?, \"expect\": \"needs_approval\"}]}], \"settings\"?: {\"approval_over\", \"default_verdict\", \"untagged_steps\", \"scope_outside\", \"long_minutes\", \"amount_basis\"}}. Up to 50 cases and 300 steps."},"approval_over":{"type":"number","minimum":0,"maximum":1000000000000,"description":"A step with an amount over this needs approval. Overrides the pack's setting; default 50."},"default_verdict":{"type":"string","enum":["block","ask","allow"],"description":"What a category with no permission line gets. Overrides the pack's setting; default ask."},"untagged_steps":{"type":"string","enum":["block","ask","allow"],"description":"What a step with no category tag gets. Overrides the pack's setting; default ask."},"scope_outside":{"type":"string","enum":["block","ask","allow"],"description":"What a step using a tool, domain or data source outside the scope section gets. Overrides the pack's setting; default block."},"long_minutes":{"type":"number","minimum":1,"maximum":100000,"description":"A step with minutes over this also counts as long_running. Overrides the pack's setting; default 30."},"amount_basis":{"type":"string","enum":["per_step","per_plan"],"description":"per_step compares each step's amount with approval_over; per_plan compares no single step. Overrides the pack's setting; default per_step."}}},"example":{"role":"coding-agent","file":"owner: the repository owner\nversion: 2\nreviewed: 2026-10-22\n## Permissions\n- spend: with approval\n- send: may\n- delete: may\n- publish: with approval\n- access_private_data: may\n- run_code: may\n- contact_people: with approval\n- change_settings: never\n- long_running: with approval\n- agree: never\n"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/eval_scorecard":{"get":{"operationId":"evalScorecardGet","summary":"Score evaluation results against the file","description":"Takes evaluation results as runs and passes per named check, plus the ALIGNMENT.md file so each check is weighted by the rank of the value it names (rank 1 of n weighs n, rank n weighs 1; a check with no value or no file weighs 1). Returns the pass rate per check, a 0-100 score (the weighted mean pass rate) with its formula, whether the score counts (at least min_checks checks with at least min_runs runs each), the bar from strictness or score_bar, the weakest checks, and the file's checks with no results. Arithmetic on the counts you send: it runs no evaluation, and a score is not a safety assessment, a certification or a guarantee of behaviour.","parameters":[{"name":"results","in":"query","required":true,"description":"One row per check: [{ \"check\": \"no_leak\", \"runs\": 10, \"passed\": 9 }]. Whole numbers; passed is at most runs. URL-encoded JSON.","schema":{"type":"string"}},{"name":"file","in":"query","required":false,"description":"The ALIGNMENT.md text, for the value ranks that weight each check. Optional; without it every check weighs 1.","schema":{"type":"string"}},{"name":"min_checks","in":"query","required":false,"description":"Checks with counted results needed before the score counts. Default 3.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"min_runs","in":"query","required":false,"description":"Runs a check needs before its pass rate counts. Default 1.","schema":{"type":"integer","minimum":1,"maximum":1000000}},{"name":"strictness","in":"query","required":false,"description":"How hard soft findings such as vague words and gaps count: lenient makes them one step softer, strict one step harder. Default standard.","schema":{"type":"string","enum":["lenient","standard","strict"]}},{"name":"score_bar","in":"query","required":false,"description":"The score the results must reach, 0 to 100. Optional; overrides the bar from strictness (60, 75 or 90).","schema":{"type":"number","minimum":0,"maximum":100}},{"name":"weakest_n","in":"query","required":false,"description":"How many of the weakest checks to list. Default 3.","schema":{"type":"integer","minimum":1,"maximum":10}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"evalScorecard","summary":"Score evaluation results against the file","description":"Takes evaluation results as runs and passes per named check, plus the ALIGNMENT.md file so each check is weighted by the rank of the value it names (rank 1 of n weighs n, rank n weighs 1; a check with no value or no file weighs 1). Returns the pass rate per check, a 0-100 score (the weighted mean pass rate) with its formula, whether the score counts (at least min_checks checks with at least min_runs runs each), the bar from strictness or score_bar, the weakest checks, and the file's checks with no results. Arithmetic on the counts you send: it runs no evaluation, and a score is not a safety assessment, a certification or a guarantee of behaviour.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"object"},"description":"One row per check: [{ \"check\": \"no_leak\", \"runs\": 10, \"passed\": 9 }]. Whole numbers; passed is at most runs."},"file":{"type":"string","maxLength":20000,"description":"The ALIGNMENT.md text, for the value ranks that weight each check. Optional; without it every check weighs 1."},"min_checks":{"type":"integer","minimum":1,"maximum":100,"default":3,"description":"Checks with counted results needed before the score counts. Default 3."},"min_runs":{"type":"integer","minimum":1,"maximum":1000000,"default":1,"description":"Runs a check needs before its pass rate counts. Default 1."},"strictness":{"type":"string","enum":["lenient","standard","strict"],"default":"standard","description":"How hard soft findings such as vague words and gaps count: lenient makes them one step softer, strict one step harder. Default standard."},"score_bar":{"type":"number","minimum":0,"maximum":100,"description":"The score the results must reach, 0 to 100. Optional; overrides the bar from strictness (60, 75 or 90)."},"weakest_n":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"How many of the weakest checks to list. Default 3."}},"required":["results"]},"example":{"file":"owner: Dana R.\nversion: 3\nreviewed: 2026-10-20\n## Values\n1. keep data private\n2. tell the truth\n3. finish the task\n## Checks\n- no_leak [keep data private]: no private data left the scope\n- said_so [tell the truth]: every claim names its source or says it is a guess\n- done_or_said [finish the task]: the task finished, or the report says what is missing\n- asked_first: every with-approval action had a yes before it ran\n","results":[{"check":"no_leak","runs":10,"passed":10},{"check":"said_so","runs":10,"passed":9},{"check":"done_or_said","runs":10,"passed":7},{"check":"asked_first","runs":10,"passed":8}],"min_checks":3,"min_runs":5,"strictness":"standard","weakest_n":3}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/merge_alignment":{"get":{"operationId":"mergeAlignmentGet","summary":"Merge files into the one an agent runs under","description":"Takes two to five ALIGNMENT.md files, highest level first (an organisation's file before a project's before an agent's own), and returns the merged file an agent runs under when all of them apply. The strictest rule wins: permissions take the strictest verdict (never over with approval over may), and a file with no line for a category counts as your default_verdict; limits are the union; escalation keeps the lowest amount and the strictest action per trigger; scope keeps only items every restricting file covers (a domain covers its subdomains; none wins, any imposes nothing); values keep the first file's ranking and append later files' new values after it; checks are the union, first definition first; reviewed is the oldest date. Every decision is listed, including lines it could not use. Text merging only; no file is changed and nothing is approved.","parameters":[{"name":"files","in":"query","required":true,"description":"The files' text, highest level first. URL-encoded JSON.","schema":{"type":"string"}},{"name":"default_verdict","in":"query","required":false,"description":"What a file with no permission line for a category counts as: block = never, ask = with approval, allow = may. Use the same value as for plan_check. Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"today","in":"query","required":false,"description":"The date the lint of the merged file measures staleness from, YYYY-MM-DD. Default: the current date.","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"mergeAlignment","summary":"Merge files into the one an agent runs under","description":"Takes two to five ALIGNMENT.md files, highest level first (an organisation's file before a project's before an agent's own), and returns the merged file an agent runs under when all of them apply. The strictest rule wins: permissions take the strictest verdict (never over with approval over may), and a file with no line for a category counts as your default_verdict; limits are the union; escalation keeps the lowest amount and the strictest action per trigger; scope keeps only items every restricting file covers (a domain covers its subdomains; none wins, any imposes nothing); values keep the first file's ranking and append later files' new values after it; checks are the union, first definition first; reviewed is the oldest date. Every decision is listed, including lines it could not use. Text merging only; no file is changed and nothing is approved.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","minItems":2,"maxItems":5,"items":{"type":"string","maxLength":20000},"description":"The files' text, highest level first."},"default_verdict":{"type":"string","enum":["block","ask","allow"],"default":"ask","description":"What a file with no permission line for a category counts as: block = never, ask = with approval, allow = may. Use the same value as for plan_check. Default ask."},"today":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"The date the lint of the merged file measures staleness from, YYYY-MM-DD. Default: the current date."}},"required":["files"]},"example":{"files":["owner: the organisation\nversion: 4\nreviewed: 2026-09-01\n## Values\n1. keep data private\n## Permissions\n- spend: with approval\n- send: may\n- change_settings: never\n## Escalation\n- spend over 100: stop and ask\n## Scope\n- domains: example.org\n","owner: the demo team\nversion: 2\nreviewed: 2026-10-10\n## Values\n1. finish the task\n## Permissions\n- spend: may\n- send: with approval\n- run_code: may\n## Escalation\n- spend over 20: ask and continue\n## Scope\n- domains: docs.example.org\n"],"default_verdict":"ask"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/parse_alignment":{"get":{"operationId":"parseAlignmentGet","summary":"Parse a file into canonical JSON","description":"Takes an ALIGNMENT.md file and returns the parser's canonical JSON, the same reading every other tool uses: header, values by rank, limits with their tags, permission lines, escalation rules with their kind, scope, checks, the verdict per category with the lines behind it, and syntax problems, each with its line number. Keys are sorted and every field is documented in the result. Also returns the file rewritten in the canonical layout and a fingerprint of the rules alone, the same for two files with the same rules whatever their order, spacing, header or comments. Reads text only; it judges nothing.","parameters":[{"name":"file","in":"query","required":true,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted.","schema":{"type":"string"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"parseAlignment","summary":"Parse a file into canonical JSON","description":"Takes an ALIGNMENT.md file and returns the parser's canonical JSON, the same reading every other tool uses: header, values by rank, limits with their tags, permission lines, escalation rules with their kind, scope, checks, the verdict per category with the lines behind it, and syntax problems, each with its line number. Keys are sorted and every field is documented in the result. Also returns the file rewritten in the canonical layout and a fingerprint of the rules alone, the same for two files with the same rules whatever their order, spacing, header or comments. Reads text only; it judges nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"file":{"type":"string","maxLength":20000,"description":"The ALIGNMENT.md text, as one string. Leading blank lines are dropped before lines are counted."}},"required":["file"]},"example":{"file":"owner: Dana R.\nversion: 3\nreviewed: 2026-10-20\n## Limits\n- never delete data without a backup [delete]\n## Permissions\n- spend: with approval\n- delete: with approval\n- run_code: may\n- change_settings: never\n## Escalation\n- spend over 50: stop and ask\n## Scope\n- domains: example.org\n"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/build_settings":{"get":{"operationId":"buildSettingsGet","summary":"Write your settings into the skill","description":"Turns a preset and settings into the sections written at the top of ALIGNMENT.md. Every setting is a number or a fixed choice; the catalog is at https://alignment.md/api/v1/settings. Returns the sections as Markdown, the settings as JSON, a link to the skill with them written in and a one-line install. Out-of-range numbers are clamped with a note. Nothing is stored. Settings an agent drafted count only after the person says yes: show them to the person first, and follow them only once they agree.","parameters":[{"name":"preset","in":"query","required":false,"description":"Starting point: core, recommended, strict. Applied first; each setting overrides it.","schema":{"type":"string","enum":["core","recommended","strict"]}},{"name":"approval_over","in":"query","required":false,"description":"Ask before an amount over (units). Default 50. Out-of-range values are clamped.","schema":{"type":"number","minimum":0,"maximum":1000000}},{"name":"default_verdict","in":"query","required":false,"description":"A category with no permission line is: block (Blocked), ask (Ask first), allow (Allowed). Default ask.","schema":{"type":"string","enum":["block","ask","allow"]}},{"name":"amount_basis","in":"query","required":false,"description":"Compare the threshold with: per_step (Each step's amount), per_plan (The plan's total). Optional; unset clears it.","schema":{"type":"string","enum":["per_step","per_plan","unset"]}},{"name":"untagged_steps","in":"query","required":false,"description":"A step with no category tag is: block (Blocked), ask (Ask first), allow (Allowed). Optional; unset clears it.","schema":{"type":"string","enum":["block","ask","allow","unset"]}},{"name":"scope_outside","in":"query","required":false,"description":"A tool, domain or data source outside the scope is: block (Blocked), ask (Ask first), allow (Allowed). Optional; unset clears it.","schema":{"type":"string","enum":["block","ask","allow","unset"]}},{"name":"long_minutes","in":"query","required":false,"description":"A step counts as long_running over (minutes). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":1440}},{"name":"max_steps","in":"query","required":false,"description":"A plan needs a yes as a whole over (steps). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"review_days","in":"query","required":false,"description":"The file is stale after (days). Default 90. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":365}},{"name":"stale_action","in":"query","required":false,"description":"When the file is stale: note (Note it in the report), ask (Ask the owner to review it before starting), approval_all (Treat every may as with approval). Optional; unset clears it.","schema":{"type":"string","enum":["note","ask","approval_all","unset"]}},{"name":"min_checks","in":"query","required":false,"description":"Checks with results before a score counts (checks). Default 3. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"min_runs","in":"query","required":false,"description":"Runs per check before its pass rate counts (runs). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":1000}},{"name":"strictness","in":"query","required":false,"description":"Strictness: lenient (Lenient: bar 60, vague words and gaps are notes), standard (Standard: bar 75, warnings), strict (Strict: bar 90, errors). Default standard.","schema":{"type":"string","enum":["lenient","standard","strict"]}},{"name":"score_bar","in":"query","required":false,"description":"Score bar (overrides strictness) (of 100). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":0,"maximum":100}},{"name":"weakest_n","in":"query","required":false,"description":"Weakest checks to list (checks). Optional; unset clears it. Out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":10}},{"name":"format","in":"query","required":false,"description":"section (default): the settings sections only; skill: the whole skill file too.","schema":{"type":"string","enum":["section","skill"]}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"buildSettings","summary":"Write your settings into the skill","description":"Turns a preset and settings into the sections written at the top of ALIGNMENT.md. Every setting is a number or a fixed choice; the catalog is at https://alignment.md/api/v1/settings. Returns the sections as Markdown, the settings as JSON, a link to the skill with them written in and a one-line install. Out-of-range numbers are clamped with a note. Nothing is stored. Settings an agent drafted count only after the person says yes: show them to the person first, and follow them only once they agree.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"preset":{"type":"string","enum":["core","recommended","strict"],"description":"Starting point: core, recommended, strict. Applied first; each setting overrides it."},"approval_over":{"type":"number","minimum":0,"maximum":1000000,"description":"Ask before an amount over (units). Default 50. Out-of-range values are clamped."},"default_verdict":{"type":"string","enum":["block","ask","allow"],"description":"A category with no permission line is: block (Blocked), ask (Ask first), allow (Allowed). Default ask."},"amount_basis":{"type":"string","enum":["per_step","per_plan","unset"],"description":"Compare the threshold with: per_step (Each step's amount), per_plan (The plan's total). Optional; unset clears it."},"untagged_steps":{"type":"string","enum":["block","ask","allow","unset"],"description":"A step with no category tag is: block (Blocked), ask (Ask first), allow (Allowed). Optional; unset clears it."},"scope_outside":{"type":"string","enum":["block","ask","allow","unset"],"description":"A tool, domain or data source outside the scope is: block (Blocked), ask (Ask first), allow (Allowed). Optional; unset clears it."},"long_minutes":{"type":"integer","minimum":1,"maximum":1440,"description":"A step counts as long_running over (minutes). Optional; unset clears it. Out-of-range values are clamped."},"max_steps":{"type":"integer","minimum":1,"maximum":100,"description":"A plan needs a yes as a whole over (steps). Optional; unset clears it. Out-of-range values are clamped."},"review_days":{"type":"integer","minimum":1,"maximum":365,"description":"The file is stale after (days). Default 90. Out-of-range values are clamped."},"stale_action":{"type":"string","enum":["note","ask","approval_all","unset"],"description":"When the file is stale: note (Note it in the report), ask (Ask the owner to review it before starting), approval_all (Treat every may as with approval). Optional; unset clears it."},"min_checks":{"type":"integer","minimum":1,"maximum":100,"description":"Checks with results before a score counts (checks). Default 3. Out-of-range values are clamped."},"min_runs":{"type":"integer","minimum":1,"maximum":1000,"description":"Runs per check before its pass rate counts (runs). Optional; unset clears it. Out-of-range values are clamped."},"strictness":{"type":"string","enum":["lenient","standard","strict"],"description":"Strictness: lenient (Lenient: bar 60, vague words and gaps are notes), standard (Standard: bar 75, warnings), strict (Strict: bar 90, errors). Default standard."},"score_bar":{"type":"integer","minimum":0,"maximum":100,"description":"Score bar (overrides strictness) (of 100). Optional; unset clears it. Out-of-range values are clamped."},"weakest_n":{"type":"integer","minimum":1,"maximum":10,"description":"Weakest checks to list (checks). Optional; unset clears it. Out-of-range values are clamped."},"format":{"type":"string","enum":["section","skill"],"description":"section (default): the settings sections only; skill: the whole skill file too."}}},"example":{"preset":"recommended"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}},"/api/v1/whats_new":{"get":{"operationId":"whatsNewGet","summary":"What's new here, and what's next","description":"What changed on alignment.md and when, what is being built, when to check back, and the other .md sites. Pass since (a date) to get only newer entries, for example the updated date of the skill you have. Reads a list kept with the code; fetches nothing and stores nothing.","parameters":[{"name":"since","in":"query","required":false,"description":"Only entries after this date (YYYY-MM-DD).","schema":{"type":"string"}},{"name":"planned","in":"query","required":false,"description":"Include what is being built and the ideas being weighed. Default true.","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"operationId":"whatsNew","summary":"What's new here, and what's next","description":"What changed on alignment.md and when, what is being built, when to check back, and the other .md sites. Pass since (a date) to get only newer entries, for example the updated date of the skill you have. Reads a list kept with the code; fetches nothing and stores nothing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"since":{"type":"string","maxLength":10,"pattern":"^\\d{4}-\\d{2}-\\d{2}$","description":"Only entries after this date (YYYY-MM-DD)."},"planned":{"type":"boolean","default":true,"description":"Include what is being built and the ideas being weighed. Default true."}}},"example":{"since":"2026-10-01"}}}},"responses":{"200":{"description":"Result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"Bad input, with a hint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Body over 64 KB"}}}}},"components":{"schemas":{"Result":{"type":"object","additionalProperties":true,"properties":{"tool":{"type":"string"},"summary":{"type":"string"},"disclaimer":{"type":"string"},"terms":{"type":"string"}},"required":["disclaimer","terms"]},"Problem":{"type":"object","properties":{"error":{"type":"string"},"hint":{"type":"string"},"docs":{"type":"string"},"disclaimer":{"type":"string"},"terms":{"type":"string"}},"required":["error","disclaimer","terms"]}}}}