Files

110 lines
6.4 KiB
Markdown
Raw Permalink Normal View History

> Core 中立版(Increment 2 改写)。术语对照见 core/adapters/TERMINOLOGY.md;本组织实例表述见 dogfood 对应文件。
## Auto-approve stages
The `auto_approve` block in the instance config controls which pipeline gates
the agent passes without asking the user. Stage identifiers are matched
against the stage registry (harness 内建的阶段注册模块). Unknown or retired
identifiers fall back to manual confirmation (fail-closed) with a one-time
`auto_approve.unknown_stage` warning — copy ids verbatim from the table
below.
## Scope boundary: `auto_approve` vs `permission`
Two **independent mechanisms** — confusing them is the most common
"auto-approve isn't working" report:
- **`auto_approve`** gates **only the `question` tool** (pipeline decision
questions; the harness 内建的自动批准判定模块); no effect on tool
execution.
- **`permission`** gates **tool / file-system operations** (`bash`, `read`,
`write`, `external_directory`, …) and **never consults `auto_approve`**.
`external_directory` defaults to ask, so outside-project prompts are
expected even with every stage enabled.
**`auto_approve` does NOT suppress permission prompts — intentionally so.**
To stop a permission prompt, change the matching `permission` rule or use the
UI's "auto-accept permissions" toggle (browser-local, not the project
`auto_approve` config).
| Stage | Gate | Risk |
| --------------- | ---------------------------- | -------------------------------------------- |
| `review-dag` | DAG single-gate review | Medium — sets direction |
| `review-code` | Code review | Medium — gates what reaches main |
| `verify` | Iteration verification | Medium — runs tests / DoD matrix |
| `audit-process` | Process infrastructure audit | Medium — read-only but gates process changes |
| `merge-pr` | Create PR + merge to main | High — irreversible landing |
> Risk values mirror the stage registry's `BUILTIN_STAGES[].risk` — the
> registry is the runtime authority; if this table and the registry disagree,
> fix this table. `merge-pr` is excluded from default/preset `stages` arrays
> (not structurally blocked; explicitly adding it is not recommended).
> Legacy stage retirement (12 → 5): the phase-3 retirement ruling doc
> (Tier-2 reference, reachable via the ticket backend).
Config shape: `"auto_approve": { "stages": ["review-code", "verify"], "stageless": false }``stages` empty (`[]`) = all manual; `stageless: true` also auto-approves questions called without a stage. Absent block defaults to `{ stages: ["review-code", "verify", "audit-process"], stageless: false }`; the removed `enabled` field migrates on load (mapping: Tier-2 reference page `rules/auto-approve-detail`). Presets (`safe`/`full`/`off`/`show`): same reference page — `full` never includes `merge-pr`.
### Stage matching behavior
- Question has a stage → auto-approved iff that stage is in `stages`.
- Stageless question → auto-approved iff `stageless: true`; otherwise prompts.
- `destructive: true` → ALWAYS prompts, regardless of config — the safety net
for irreversible actions; business-decision questions are never covered by
a stage whitelist (§"Mandatory destructive list").
Check logic: the harness 内建的问询与自动批准判定模块
(resolveAutoApproveDecision).
### Live-gate degradation chain ([org-internal #3531])
An auto-approved question is NOT consumed instantly: L1 — a live human
watching the session (SSE declaration / fresh presence ping) answers within
`question_live_gate.timeout_sec` (default 600) and overrides the default;
L2 — blocking questions with a `#<ticket>` title and a ticket-backend token
fall back to a ticket comment answered as `**answer <question-id>** <label>`
(default 3600s); L3 — auto default (first option, annotated
`live-gate … → auto default`). `timeout_sec: 0` disables the whole gate
(legacy instant default); `l2_timeout_sec: 0` disables only L2.
`nonblocking: true` questions never reach L2/L3 — no live human → parked in
the pending-answer queue, answered later from the console. Every final
decision publishes a `question.degradation.routed` event.
**`destructive: true` is untouched by the chain**: `decide()` rejects it
before the gate runs (iron law).
### Mandatory destructive list (业务决策类问询强制清单)
Origin: [org-internal #3223] — a stage whitelist auto-answered two
irreversible production data changes because nothing marked them
`destructive`. A stage whitelist grants "execution gates may proceed
uninterrupted"; it must NEVER grant "business decisions may be
self-answered". `stage` names the pipeline phase, `destructive` names the
business risk.
**Iron Law: a question whose recommended/executed action falls in ANY category
below MUST be called with `destructive: true`. The auto-approve stage whitelist
is never a substitute for human confirmation of these categories.**
1. **Merge / release landing** — merging a PR to main, cutting a tag or
release, deploying/promoting to production (server-side auto-merge is a
human-configured policy robot, never agent self-answer latitude; kill
switch: the auto-merge-low-risk runbook, Tier-2 reference via the ticket
backend).
2. **Production database writes** — upsert/update/delete against production
data stores, production data migrations, live-data backfills.
3. **Billing / plan changes** — plan or tier migration, pricing/concurrency
changes, anything touching billing state.
4. **Org / tenant structure changes** — org or workspace migration, tenant
topology changes, moving resources between orgs.
5. **Deletion of durable resources** — deleting data, branches, worktrees,
deployments, or any resource outside `/tmp` and session-scratch space.
6. **Persistent config writes** — config changes that outlive the session
(writing to the instance config file, the instance process-config area,
deploy/systemd units, or other on-disk configuration consumed by other
sessions/services).
This list is the floor, not the ceiling: any other irreversible
business-visible decision also carries `destructive`. When in doubt, mark it —
a redundant prompt costs one round-trip; an auto-approved production write can
cost the data. Mirrored in the question tool's self-description for paths
without L1 injection.