> The Markdown version of [Constraints](constraints.html) on the aayudha docs site. Every page is listed in [llms.txt](llms.txt).

<!-- Code generated by go generate (internal/config/gen); DO NOT EDIT. -->

# Constraints

The defaults every product repository starts with. Generated from `internal/config/defaults.toml`, the
configuration embedded in the binary, by `go generate ./...`; do not edit by hand. A repository changes them in
`.aayudha/config.toml`, which is a protected path. The Quality Architect seat owns these thresholds; the AI Native
Engineer executes `verify` against them. Changing a default regenerates this file, which is also a protected path.

Source: a WP means docs/BUILD-PLAN.md fixes the value there; "proposed (WP0.5)" means the plan names the key but not
its value, and WP0.5 chose it.

## Floors

| Key | Default | Meaning | Source |
|---|---|---|---|
| `verify.dast` | `true` | Run the ZAP DAST floor against the running app when `[verify] platforms` has web or api. Its active cross-site scripting and injection rules run only against an app `[verify] seed` started on a loopback host (one that did not answer before the seed ran); any other URL gets a passive scan unless its environment sets `active_scan = true` (read only from `.aayudha/config.toml`). ZAP runs under Docker or Podman; with neither, a local run skips and a CI run is blocked. | founder decision 2026-10-17 (DAST) |
| `verify.red_on_base_blocking_from` | `"2026-11-13"` | Date (UTC) from which a Bug story whose mapped proving test passes on the base commit fails the merge gate (red-on-base, P5). Before it the check is advisory: four weeks after the founder decision of 2026-10-15. | 0.2 (P5) |
| `verify.new_floors_blocking_from` | `"2026-11-14"` | Date (UTC) from which the floors and defaults of the founder decision of 2026-10-17 on proof floors fail the merge gate; before it a miss is advisory: four weeks after that decision. | founder decision 2026-10-17 (floors) |
| `verify.drift_blocking_from` | `"2026-11-13"` | Date (UTC) from which feature-map drift (`aayu verify --map`) fails the merge gate's feature-map floor. Before it drift is a warning: four weeks after the founder decision of 2026-10-16. | 0.2 (WP4.5b) |
| `verify.floors.coverage.min_diff_percent` | `90.0` | Minimum coverage of changed lines (lcov, cobertura, or Go coverprofile). 89.9 fails, 90.0 passes. | WP4.3 |
| `verify.floors.sast.max_critical` | `0` | Critical semgrep findings allowed. | WP4.4 |
| `verify.floors.sast.max_high` | `0` | High semgrep findings allowed. | WP4.4 |
| `verify.floors.secrets.max_findings` | `0` | gitleaks findings allowed. | WP4.4 |
| `verify.floors.deps.max_critical` | `0` | Critical osv-scanner vulnerabilities allowed. | WP4.4 |
| `verify.floors.deps.max_high` | `0` | High osv-scanner vulnerabilities allowed. | WP4.4 |
| `verify.floors.a11y.standard` | `"WCAG 2.2 AA"` | Accessibility standard axe checks against. | WP4.5 |
| `verify.floors.a11y.max_critical` | `0` | Critical axe violations allowed. | WP4.5 |
| `verify.floors.a11y.max_serious` | `0` | Serious axe violations allowed. | WP4.5 |
| `verify.floors.a11y.keyboard_only` | `true` | Every Completion Goal state must be reachable by keyboard alone. | WP4.5 |
| `verify.floors.a11y.reduced_motion` | `true` | Every state is captured with reduced motion on. | WP4.5 |
| `verify.floors.a11y.text_scale_percent` | `200` | Text scaling every state must survive. | WP4.5 |
| `verify.floors.a11y.min_target_px` | `44` | Minimum touch target edge, in CSS pixels (44×44). | WP4.5 |
| `verify.floors.screen_reader.layers` | `["L01"]` | Story footprints that run the VoiceOver and NVDA floor (on label or nightly). | WP4.7 |
| `verify.floors.screen_reader.max_missing_phrases` | `0` | Expected phrases from the Ready snapshot that may be missing from the transcript. | WP4.7 |
| `verify.floors.dast.max_high` | `0` | High-risk ZAP alerts allowed when DAST runs (passive baseline plus the active cross-site scripting and injection rules). | proposed (WP0.5) |
| `verify.floors.dast.skipped_blocks_ship` | `true` | A web or api story with no runnable target (no `[verify.environments.<env>] url`, or `dast = false`) records `skipped: dast`, which blocks `ship` unless a floor-waiver Decision exists. A run with no story, such as the security workflow's, records it without blocking. | founder decision 2026-10-17 (DAST) |
| `verify.floors.mobile.skipped_blocks_ship` | `true` | A `skipped: mobile` floor blocks `ship` unless a floor-waiver Decision exists. | WP4.9 |

Performance (Lighthouse CI) and API (k6) budgets are product-specific and have no default (WP4.5, WP4.6). Every floor miss blocks; no model disposition can override it (ground rule 7). A waiver is a recorded Decision (`decide --waiver <floor>`, WP5.6) that `audit` counts.

## Autonomy

| Key | Default | Meaning | Source |
|---|---|---|---|
| `autonomy.streak` | `20` | Consecutive correction-free merges on a layer before agents may merge on it without a human pass. Computed by the protected streak workflow from merged-PR history, never stored where an agent can write it (V4). | WP5.7 |
| `autonomy.never` | `["L04", "L07", "L09"]` | Layers that always need a human CODEOWNER approval and an EM plan-time review, whatever the streak: domain/policy, operational data/state, and platform. | proposed (WP0.5) |
| `autonomy.approver` | `""` | GitHub login that gives the human pass in solo mode. Empty until `init` sets it. | WP5.5 |
| `autonomy.correction_days` | `14` | Days after a merge in which a Bug or Incident that links the PR counts as a correction and resets the streak of every layer the PR touched. | proposed (WP5.7) |
| `autonomy.proof` | `false` | Merge a PR into the integration branch on proof alone: every required check green, the merge gate's pack verified with its floors holding, inspect at merge with a `proof_rungs` rung, and nothing in the narrow set. The streak, never layers and plan review then feed the sampled audit after merge instead of blocking. | WP5.7 |
| `autonomy.proof_rungs` | `["A", "B", "C"]` | Review rungs at the head that let `ship` merge on proof. | WP5.7 |
| `autonomy.always_person` | `[".github/CODEOWNERS", ".aayudha/config.json", ".aayudha/config.local.toml", ".aayudha/config.local.json", "loops/build-ready.toml"]` | The narrow set: paths whose change always needs a person per PR (a trailing `/` covers a directory; otherwise a glob). A workflow that holds a credential (a secret, the workflow token, an environment, or a write permission, or a job left to the default permissions) is in it by rule. | WP5.7 |
| `autonomy.always_person_config` | `[".aayudha/config.toml"]` | Config files whose `always_person_sections` need a person per PR when they change. | WP5.7 |
| `autonomy.always_person_sections` | `["identity", "approvals", "autonomy", "seats", "verify", "inspect", "review", "models", "branches", "decisions", "proof", "delegate", "notify", "integrations", "telemetry", "mcp", "hosts", "lfs", "measure", "budget", "scope", "build"]` | Config tables, by their first key and whatever their case, that decide who may approve or bypass, how a PR is verified, reviewed, and proven, or where a credential is sent. | WP5.7 |
| `autonomy.budget.wall_hours` | `8` | Wall-clock hours one `build` may run before the story is marked `status:blocked` and the owner is paged. | proposed (WP0.5) |
| `autonomy.budget.cost_usd` | `60.0` | Metered model spend, in USD, one `build` may use before it is blocked. It applies only when aayu's own model calls are pay-as-you-go: a `[models.gateway]` endpoint or a direct provider's key (anthropic, openai, google, xai) is configured, or a host reports pay-as-you-go spend in `AAYU_COST_USD`. A lower `budget.per_story_usd` is the limit build reports and enforces, since the breaker would stop the story there. With neither there is no cost limit, because subscription use reports no cost; build and status say so. | proposed (WP0.5) |
| `autonomy.budget.attempts` | `3` | Failed checkpoint attempts before a story is blocked. A second failure on a never-layer blocks regardless. | proposed (WP0.5) |

## Budgets

| Key | Default | Meaning | Source |
|---|---|---|---|
| `build.in_flight` | `1` | Items the build-ready loop (`aayu build --next`) has in progress at once, from claim to merge: its open pull requests and its claims with no pull request yet. 0 stops its picks. | proposed (build loop) |
| `budget.per_story_usd` | `60.0` | Model spend per story, in USD, before the circuit breaker pauses agent lanes (exit 6). At least `autonomy.budget.cost_usd`, so the breaker never stops a story before its build budget does. | proposed (WP0.5) |
| `budget.per_day_usd` | `100.0` | Model spend per repository per day, in USD, before the breaker trips. | proposed (WP0.5) |
| `budget.per_pr_inspect_max` | `5.0` | Model spend, in USD, for `inspect` on one PR across all its cycles. | proposed (WP0.5) |
| `budget.ci_minutes_month` | `2000` | GitHub Actions minutes per month that agent-started workflows may use. | proposed (WP0.5) |

When a budget trips, the breaker pauses agent lanes and pages through `[notify]` once per day (WP1.6).

## Release scope

| Key | Default | Meaning | Source |
|---|---|---|---|
| `scope.budget_percent` | `20.0` | Drift a release may take after a person accepts its baseline, in percent of the baseline's effort points: items added, removed, or resized. Beyond it, `aayu scope` refuses the change until a person accepts it, through GitHub's device flow, against an accepted Decision. | 0.3 (@rahulnakmol: 15 to 20 %) |
| `scope.effort_points` | `[1, 2, 3, 5, 8]` | Effort points of XS, S, M, L, and XL: the weight of each Story and Bug in a plan and in its drift. Initiatives and Features weigh nothing themselves; they count through their Stories and Bugs. | 0.3 |

`aayu scope` stores each accepted baseline and its drift on the `ledger` branch under `releases/<version>/`. Accepting a baseline, and any change over budget, is a person's call.

## Outcomes

| Key | Default | Meaning | Source |
|---|---|---|---|
| `outcomes.session_gap_minutes` | `10` | A gap of more than this many minutes between two human-identity actions in the actions log on the `ledger` branch starts a new founder session. | 0.4 |
| `outcomes.action_minutes` | `2` | Minutes each founder session adds for its last action, on top of its span from its first action to its last. | 0.4 |

`aayu measure` reads `aayu:founder_minutes_per_pr` as the sum of the founder sessions in the window divided by the pull requests merged into the integration branch in it. It is a proxy: it counts time in aayu's recorded human actions, not time spent elsewhere. Bot and human-fallback records never count; a window with no merged pull request has no value.

## Design review

| Key | Default | Meaning | Source |
|---|---|---|---|
| `review.figma_diff_max` | `2.0` | Largest share of pixels, in percent, a prototype screenshot may differ from its Figma frame after the anti-aliasing mask. Colour and typography token mismatches are counted separately and must be zero. | WP6.5 |
| `review.baseline` | `["/"]` | URL paths on the `[verify.environments]` target that `baseline` captures for each commit. | proposed (WP6.6) |

`review` runs lane A (the ui-review model) k = 3 times per state and counts a finding only when 2 of 3 runs report it at Nielsen severity 2 or more; lane B (impeccable, axe, focus-indicator and target-size probes) is deterministic, and its findings cannot be overridden by lane A (ground rule 7). These are fixed by the plan (WP6.6), not configuration.

## Retention

| Key | Default | Meaning | Source |
|---|---|---|---|
| `proof.media` | `""` | Optional private bucket for proof media beyond the merge gate's run artifact; `aayu ship` copies them there. Empty: proof media stay in the run artifact and never reach the `ledger` branch or Git LFS. | WP2.5 |
| `proof.retention_days` | `90` | Days the merge gate keeps its `aayudha-pack` run artifact (media included), at most the repository's limit (GitHub: 90 public, 400 private); also the bucket's lifecycle rule. `pack.json` on the ledger is kept. | proposed (WP0.5) |
