diff --git a/CHANGELOG.md b/CHANGELOG.md index 8603413a..d2b2492d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,20 +4,38 @@ All notable changes to `github-delivery` are documented here. ## [Unreleased] +## [1.0.0] - 2026-08-22 + +### Added + +- SHA-bound remote repository context: resolve `owner/repo` or GitHub URLs, discover the real default branch, optionally pin a workflow-selected branch, capture its exact commit SHA, and read files against that snapshot instead of guessing `main`, `master`, or `HEAD`. Workflows that already load evidence policy compose this through `GD-EVID-007` without a new public route or mutation authority (PR #300). +- Optional Windows Authority **PR sessions**: after one Hello approval, later exact-scope `push_code` and `merge_pr` batches on one allowlisted repo, one PR, one head branch, and the approved merge base can skip repeated Hello for 5, 15, 30, or 60 minutes (`approvalMethod: pr_session`). A retargeted base requires Hello again. Branch leases stay `push_code` only for 1–10 minutes. Comments, human replies, close, and delete still need Hello (PRs #348, #351). + +### Changed + +- First stable public release after `0.8.7`. +- Bumped the package version from `0.8.7` to `1.0.0`. +- `watch PR #N and merge it` stays on prepare-and-merge. `watch and autonomously merge PR #N` stays on watch with merge authority and hands a ready PR to `merge-pr-driver.mjs`. Bare `watch autonomously` still does not merge. Autonomous is not the default mutation mode (PRs #312, #323, #348). +- Policy modules are the mandatory workflow context. `references/shared-rules.md` is a compatibility index only; evals and `policy-bundle --validate` reject loading it as required context (PRs #342, #343). +- Router merge intent is explicit: `merge it` / `ship it` prefixes, negated merge, and attributed GitHub text such as `comment says: merge it` are not user merge authority even when the attributed quote continues past the first sentence (PRs #321, #322, #347, #350). +- Durable GitHub prose now deletes chatbot phrases, process narration, puffery, and `not just X, but Y` crutches. It still must not add personality, score "sounds human," or ban em dashes, and it still cannot strengthen `unknown` / `blocked` evidence states (PR #354). + ### Fixed -- The mutation-boundary scanner still inspects privileged broker and lifecycle files, so secret and variable writes there cannot skip the direct-write checks. -- Installer now journals staging before the copy, promotes only a verified staged tree, and never installs a leftover staging directory that has no journal. -- Behavioural-evaluation docs now show the run pack and `.transcript.json` sidecar, matching the scorer that rejects in-pack `trace` objects. -- Installer restore now journals before moving the live target aside, and journal updates replace a complete temp file instead of truncating the live journal, so a crash still leaves a recoverable tree. -- Automatic NuGet dependency submission can restore the Windows Authority host on Linux by setting `EnableWindowsTargeting`, so GitHub's hosted `submit-nuget` job no longer fails with NETSDK1100. -- Offline evals and `policy-bundle --validate` now treat `shared-rules.md` as a compatibility index only: workflows cannot instruct loading it, evals cannot list it as expected context, and each routed workflow's SKILL+kernel+module payload must stay 60% under the old monolith baseline. -- Routed workflows, compact review contract, and Cursor overrides no longer instruct loading `shared-rules.md` as mandatory context; they load the declared policy modules instead. -- `authorityMode=off` no longer treats caller-supplied `explicitInstruction` or `exactTextConfirmed` as independently authenticated consent; those actions still require a verified host grant at execution. -- Mutation-document retry identity hashes the full canonical mutation payload when no idempotency key is present, so retarget, reviewer, and draft differences cannot skip as already applied. Stale autonomous-claim recovery refuses to delete a ref whose SHA or freshness changed, and a timed-out `push_code` re-reads the remote tip instead of assuming failure. -- Release SBOMs now describe the package, use the source-commit created time, emit SPDX package verification codes, and fail closed against the SPDX 2.3 JSON schema. -- Installed manifest comparison now rejects symlink/directory substitutions and enforces declared POSIX modes instead of following links and hashing only. -- Release ZIP construction and extraction now use a portable NFC/case-fold path identity and re-read the extracted tree before trusting it. +- Ship-gate and merge fail closed on GitHub `UNKNOWN` mergeability instead of treating it as ready, and snapshot capture retries rate-limited read-only GitHub calls instead of failing the first 429 (PRs #303, #361). +- Native GitHub stacked PRs are a hard stop: github-delivery will not `gh pr merge` a native-stack member, and native-stack protection is evaluated against the stack base (PRs #304, #306). +- Merge grants bind the approved base; Windows Hello `merge_pr` and `close_linked_issue` scopes hash the same fields Node already required; `close_linked_issue` binds the governing PR (PRs #335, #336, #349). +- Live repository-policy CI fails closed when it cannot attest ruleset bypass actors or cannot see protected release tags (PRs #305, #308). +- `authorityMode=off` still requires a verified host grant for lifecycle intent; caller-supplied `explicitInstruction` / exact-text flags are not independently authenticated consent (PR #340). +- Mutation retries hash the full canonical payload, including draft-state ready identity, so retarget, reviewer, and draft differences cannot skip as already applied (PRs #341, #344, #346). +- GitHub write transport no longer expands GraphQL `-F` values as local files, folds sibling API body fields into JSON stdin, and treats `gh api --input` as a write for rate-limit retry (PRs #313, #324, #325). +- The mutation-boundary scanner still inspects privileged broker and lifecycle files, rejects constructed or spread mutation argv, and allows only registered REST/GraphQL shapes there (PRs #360, #362). +- Install, update, and Authority cutover keep the previous skill/broker when a step fails: staged installer payloads, dist-not-cwd identity, exclusive reconcile/hooks locks, skill-backup restore, broker keep-alive, Startup-shortcut autostart, bundle-root fallback, crash recovery after `target → backup` before `staging → target`, staging journalled before copy with no promotion of unverified or journal-less leftover staging, restore journaling before aside swap, journal updates that replace a complete temp file, and journal replacement that moves the previous valid journal aside instead of deleting it (PRs #314, #326–#332, #353, #355, #357, #359). +- Release artifacts fail closed on SPDX 2.3 schema, non-regular installed-manifest substitutions, and extraction path identity. Windows Authority can restore on Linux CI via `EnableWindowsTargeting`. `npm pack` spawns through Node, not a Windows shell (PRs #307, #337–#339, #345). +- Watchdog hooks fail closed on throw, fence stale lock steals, do not treat an empty model as a quarantine wildcard, and spawn `verify-pr-head` as argv (PRs #309, #310, #315–#317). +- Pre-open review treats agent-instruction markdown, Copilot MCP `servers.json`, and Cursor `mdc` project rules as operational policy, and classifies code paths with trailing format characters as logic (PRs #311, #318–#320). +- Orphan-workflow cleanup rechecks ref SHAs before each delete. Behavioural eval scores require a hash-bound transcript sidecar instead of in-pack traces (PRs #333, #334, #352). +- Behavioural-evaluation docs show the run pack and `.transcript.json` sidecar, and set `transcriptsSha256` to the SHA-256 of `canonicalJson` of the parsed sidecar object, matching `hashBehaviouralTranscripts` (PRs #356, #358). ## [0.8.7] - 2026-08-19 diff --git a/README.md b/README.md index d550c43b..05486152 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ -> [!WARNING] -> **Active development.** The complete issue/PR lifecycle and core safety architecture are implemented, but the project is not yet 100% production-ready. I currently consider it roughly **80% of the way there**. See [Current state](#current-state). +> [!NOTE] +> **1.0.0.** The complete issue/PR lifecycle and core safety architecture are the first stable public release. Host-specific runtime integrations and the experimental Codex streaming boundary remain constrained by what each agent host exposes. Native GitHub stacked-PR merge is an intentional fail-closed gap. See [Current state](#current-state). > [!IMPORTANT] > **Natural language is the public API.** The Node scripts, policy modules, evaluators, mutation broker, and optional Authority host are internal safety/evidence machinery. You normally do not invoke them yourself. @@ -83,26 +83,23 @@ For installation edge cases, backup/restore, downgrade behavior, manual recovery | **Merge readiness** | `fix the review comments on PR #18 and make it merge ready` | Feedback triage, code fixes, validation, publication, refreshed readiness | | **Competing PRs** | `triage the competing PRs in this repo` | Read-only deterministic clustering and evidence for potentially overlapping implementations | | **Visual changes** | `full review PR #42` on a UI diff | Conditional screenshot/video/render evidence bound to the exact reviewed head | -| **Stacks** | `inspect this PR stack and tell me the safe merge order` | Stack discovery, restack/retarget analysis, conflict recovery, parent/child revalidation | +| **Watch** | `watch PR #77 until it merges or needs me` | CI and review monitoring until merged, closed, or a human blocker. `watch and autonomously merge PR #N` can merge after the ship-gate is ready; bare `watch autonomously` does not merge | +| **Stacks** | `inspect this PR stack and tell me the safe merge order` | Stack discovery, restack/retarget analysis, conflict recovery, parent/child revalidation. Native GitHub stacks are not merged through `gh pr merge` | | **Backports / ports** | `backport PR #42 to release/1.x and release/2.x` | One independent head-bound port per target base, with deterministic provenance and completion tracking | | **Supersede / overtake** | `supersede PR #12 with PR #45` | Explicit replacement or maintainer-takeover workflows with bounded mutation authority | | **Merge / close-out** | `merge PR #32` | Final gate, exact transaction authority, head-pinned merge, verification, thanks, linked-issue close-out | | **Self-update** | `update github-delivery to the latest stable release` | Stable-release discovery, checksums/manifest/tag/attestation verification, safe apply and postconditions | -### What changed after 0.8.2 +### What changed in 1.0.0 -The 0.8.6 line adds the major workflow and safety work developed after 0.8.2, plus delivery integrity and bounded GitHub/Git subprocesses: +`1.0.0` is the first stable public release after `0.8.7`. User-facing work since that release: -- least-privilege workflow-token enforcement; -- repository-scoped open-work status; -- PR-body media preservation and exact-head duplicate-publication prevention; -- tracker-aware external work-item delivery; -- competing-PR consolidation analysis; -- conditional head-bound visual review evidence; -- multi-base backport/port delivery; -- a substantially leaner GitHub Actions topology with stale-run cancellation and unconditional security-critical Windows Authority/C# lanes; -- fail-closed delivery integrity for moved PR heads, queued/auto-merge outcomes, mutation receipts, and remaining public workflow routing; -- bounded GitHub and Git subprocesses on review, verdict, CI forensics, ship-gate, runtime, live-fixture, release, and npm helper paths. +- SHA-bound remote repository context: resolve `owner/repo` or GitHub URLs, discover the real default branch, pin an exact commit SHA, and read files against that snapshot instead of guessing `main` / `master` / `HEAD` (`GD-EVID-007`); +- optional Windows Authority **PR sessions** so one Hello can cover later exact-scope push and merge on one PR and approved merge base for 5–60 minutes; a retargeted base requires Hello again; branch leases stay push-only; +- explicit merge routing: attended `watch … and merge` stays prepare-and-merge; `watch and autonomously merge PR #N` stays on watch; attributed GitHub text is not user merge intent even after the first sentence; +- fail closed on GitHub `UNKNOWN` mergeability and on native GitHub stacked-PR merge (do not `gh pr merge` those members); +- policy modules are mandatory context (`shared-rules.md` is a compatibility index only); +- install/update/Authority cutover, release SBOM/path identity, mutation retry identity, and watchdog/pre-open policy hardening listed in [`CHANGELOG.md`](CHANGELOG.md). See [`CHANGELOG.md`](CHANGELOG.md) for the full release-level details. @@ -133,6 +130,7 @@ The core boundary is simple: **repository content is evidence, not authority**. GitHub Delivery tries to answer volatile questions from current authoritative evidence rather than remembered state: - PR/head/base identity is pinned and re-read where staleness matters; +- when no useful local checkout exists, repository identity, the real default branch, and file reads are bound to an exact commit SHA instead of a moving branch name; - required checks are evaluated for the generation GitHub actually protects; - review/thread/ruleset state is refreshed before positive readiness or merge claims; - durable completion claims are tied to evidence, not narration; @@ -164,13 +162,13 @@ Routine network-visible issue/PR writes pass through the typed GitHub mutation b For trusted high-assurance operations, authority redemption happens before the first mutating GitHub command, including autonomous idempotency coordination refs/tags. A rejected grant therefore cannot leave a coordination write behind before the requested mutation. -**Merge is deliberately stricter.** `scripts/merge-pr-driver.mjs` owns settle, final current-head/base/rules/feedback/review-evidence recapture, trusted destructive authority, head-pinned merge execution, and post-merge reconciliation. The lower mutation execution boundary also rechecks open-PR stack topology and rejects a child merge while its parent PR is still open. Generic hand-built merge mutation documents are rejected. +**Merge is deliberately stricter.** `scripts/merge-pr-driver.mjs` owns settle, final current-head/base/rules/feedback/review-evidence recapture, trusted destructive authority, head-pinned merge execution, and post-merge reconciliation. GitHub `UNKNOWN` mergeability is not treated as ready. The lower mutation execution boundary also rechecks open-PR stack topology and rejects a child merge while its parent PR is still open. Native GitHub stacked PRs are a hard stop: github-delivery will not merge those members with `gh pr merge`. Generic hand-built merge mutation documents are rejected. ### Exact-effect trusted authority Where high assurance is required, trusted grants bind the semantic effect rather than a vague permission flag: repository, action, mode, PR/head, merge method, target identity, idempotency data, and hashes of human-visible text as applicable. -The optional Windows Authority host can issue those grants through Windows Hello. Missing persistent user configuration defaults the effective preference to **Sensitive actions** (`high-assurance`); an explicitly stored `off` or `all` preference remains supported. +The optional Windows Authority host can issue those grants through Windows Hello. Missing persistent user configuration defaults the effective preference to **Sensitive actions** (`high-assurance`); an explicitly stored `off` or `all` preference remains supported. After Hello, the approval UI can start a **PR session** (5 / 15 / 30 / 60 minutes) for later exact-scope push and merge on one PR and the approved merge base, or a **branch lease** (1–10 minutes) for repeated `push_code` only. Mixed-action batches, comments, human replies, close, and delete still need Hello. `off` does not turn caller-supplied lifecycle flags into independently authenticated consent. ### Safe retries and idempotency @@ -187,11 +185,13 @@ Code pushes, base updates, simplification, and other branch mutations require th The implementation-level contracts live in: - [`references/policy-kernel.md`](references/policy-kernel.md) -- [`references/shared-rules.md`](references/shared-rules.md) +- [`references/policy/`](references/policy/) (per-domain modules loaded by each workflow) - [`references/github-mutation-broker.md`](references/github-mutation-broker.md) - [`references/merge-pr.md`](references/merge-pr.md) - [`references/completion-claims.md`](references/completion-claims.md) +[`references/shared-rules.md`](references/shared-rules.md) is a compatibility index only. Do not load it as mandatory workflow context. + --- ## Review and merge readiness @@ -230,6 +230,8 @@ The final ship decision is one authoritative `ready`, `blocked`, or `unknown` re - review decision, stale approvals, last-push requirements, unresolved threads; - conflicts, behind state, merge queue / auto-merge state; - unknown ruleset/state values failing closed; +- GitHub `UNKNOWN` mergeability failing closed; +- native GitHub stacked-PR membership as a merge hard stop; - open stack-parent topology before destructive merge execution; - exact-head merge execution and read-only reconciliation after ambiguous write results; - partial success when merge succeeded but non-destructive post-merge ceremony did not. @@ -244,6 +246,8 @@ These are intentionally three different concepts. A stack is a dependency chain where a child PR targets a parent PR branch. Stack operations discover repository-qualified topology, restack bottom-up, preserve layer ownership, and revalidate every surviving child after an upstream head changes. The mutation execution boundary independently rejects a merge while the target PR still points at another open PR's head, so merge-order safety does not depend only on workflow prose. +When GitHub reports native stack membership, that identity is authoritative over inferred bases. github-delivery will not merge a native-stack member with `gh pr merge`; restack, inspect, and inferred-stack merge-order safety still apply. + ### Competing PRs Competing-PR analysis is read-only. A shared work-item key establishes related work, not automatic replacement. Supersede-grade planning requires direct substantial implementation overlap between the selected canonical PR and every PR proposed for replacement; transitive A-B-C clustering cannot let A supersede C without direct evidence. @@ -321,6 +325,8 @@ On supported Windows systems, the stable GitHub Release can include the separate The host is not silently installed for a user whose protection mode is `off` and who has never installed Authority. +Control Center lists active branch leases and PR sessions and can revoke either. Rebuild/install the host from this release before PR sessions are available on a machine that still runs an older Authority build. + ### Manual / repository install ```bash @@ -393,7 +399,7 @@ For the complete budgets, trust model, incident replays, false-positive controls | **Competing PRs** | Analyze overlapping/duplicate implementations | `references/consolidate-prs.md` | | **Status** | What is left / why blocked / merge readiness | `references/status.md` | | **Make merge-ready** | Fix humans/bots, own review work, validate | `references/fix-pr-bots.md` | -| **Watch** | Poll CI/reviews/gates until merged/closed/blocked | `references/watch-pr.md` | +| **Watch** | Poll CI/reviews/gates until merged/closed/blocked; autonomous merge only when explicitly requested | `references/watch-pr.md` | | **Re-review** | Re-evaluate after head/review evidence changes | `references/re-review-pr.md` | | **Full review** | Deep Bug + Security + Spec + Standards review | `references/full-review-pr.md` | | **Visual evidence** | Conditional rendered-surface evidence axis | `references/visual-evidence.md` | @@ -412,7 +418,7 @@ For the complete budgets, trust model, incident replays, false-positive controls | **Supersede** | Replace an obsolete PR with a canonical PR | `references/supersede-pr.md` | | **Maintainer overtake** | Take over an unresponsive author's PR | `references/overtake-pr.md` | | **Conflicts** | Resolve active conflicts from both sides' intent/evidence | `references/resolve-conflicts.md` | -| **Stacked PRs** | Inspect/restack/retarget/recover/review/merge stacks | `references/stacked-prs.md` | +| **Stacked PRs** | Inspect/restack/retarget/recover/review stacks; native GitHub stack merge is fail-closed | `references/stacked-prs.md` | | **Backports / ports** | Parallel delivery to one or more target bases | `references/multi-base-delivery.md` | | **Update installed skill** | Verify/check/apply latest stable release | `references/update.md` | | **Progress watchdog** | Runtime generation bounds and workflow convergence | `references/agent-progress-watchdog.md` | @@ -437,6 +443,7 @@ is PR #42 safe to merge? full review PR #42 fix the review comments on PR #18 and make it merge ready watch PR #77 until it merges or needs me +watch and autonomously merge PR #32 simplify PR #42 without changing behavior review PR #42, fix it, and merge it when green merge PR #32 @@ -517,6 +524,7 @@ The public interface stays small even though the enforcement surface is not. Key | `scripts/github-mutate.mjs` | Typed non-merge GitHub mutation entrypoint | | `scripts/lib/authority-scope.mjs` | Exact-effect trusted authority scope | | `authority-host/windows/` | Optional Windows Hello trusted-authority issuer | +| `scripts/repository-context.mjs` | SHA-bound remote repository identity, default-branch resolution, and exact-SHA file reads | | `scripts/review-scope.mjs` | Evidence-ranked review scope and required probes | | `scripts/lib/visual-evidence.mjs` | Conditional head-bound rendered-evidence planning/validation | | `scripts/lib/work-item-delivery.mjs` | Tracker milestone/reconciliation planning | @@ -532,24 +540,34 @@ The architecture uses progressive disclosure: route once, load the selected work ## Current state -Implemented today: +`1.0.0` is the first stable public release of the complete issue/PR lifecycle and core safety architecture. + +Stable in this release: - natural-language routing for the issue/PR lifecycle; - read-only open-work and competing-PR analysis; - issue research, implementation, publication, external work-item delivery, and exact-head duplicate prevention; - deep current-head review with deterministic probe coverage and conditional visual evidence; - mutation authority, exact-effect receipts, stale-head protection, and head-pinned merge execution; -- stack restacking/merge-order safety and independent multi-base delivery; -- verified stable install/update and optional Windows Authority host; +- optional Windows Authority Hello grants, push-only branch leases, and PR sessions for later exact-scope push and merge on one PR and approved merge base; +- inferred-stack restacking/merge-order safety and independent multi-base delivery; +- SHA-bound remote repository context when a useful local checkout is not already available; +- verified stable install/update; - progress watchdog/runtime convergence controls; - deterministic bundles, repository security checks, CodeQL, Dependency Review, live-fixture contracts, and release preparation. -Still active-development territory: +Known limits, documented and fail-closed: +- native GitHub stacked-PR merge is not implemented; those members are a hard stop rather than `gh pr merge`; +- GitHub `UNKNOWN` mergeability is not treated as ready; +- autonomous is not the default mutation mode; overnight unattended use is not the 1.0 claim; - host/runtime integrations remain constrained by what each agent host exposes; -- the protected Codex App Server streaming boundary depends on an experimental upstream interface; -- broader tracker adapters beyond the normalized work-item contract can be added without weakening GitHub authority boundaries; -- more real-world fixture coverage and adversarial incident replays are still valuable as the system expands. +- the protected Codex App Server streaming boundary depends on an experimental upstream interface. + +Still expanding without blocking this release: + +- broader tracker adapters beyond the normalized work-item contract; +- more real-world fixture coverage and adversarial incident replays. The project intentionally fails closed rather than claiming unsupported coverage. diff --git a/package.json b/package.json index 4453d8a2..67905595 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "github-delivery", - "version": "0.8.7", + "version": "1.0.0", "description": "Guided installer and safety tooling for GitHub Delivery workflows", "type": "module", "engines": { diff --git a/references/github-mutation-broker.md b/references/github-mutation-broker.md index 2acd2c41..4566cd99 100644 --- a/references/github-mutation-broker.md +++ b/references/github-mutation-broker.md @@ -66,7 +66,7 @@ Caller fields such as `mutationMode` and `explicitInstruction` are policy assert Trusted grants bind a deterministic `scopeSha256` to the exact effect. Depending on action, this includes repository, action, mode, PR head, merge method, target IDs, reviewer set, idempotency key, and hashes of human-visible text. Changing a bound value after approval invalidates the grant. -Batch approval is ordered and finite. Every operation receives a distinct nonce and exact scope. There is no wildcard grant. Bounded branch leases (`push_code` only, 1–10 minutes) and PR sessions (`push_code` and `merge_pr` on one PR, 5/15/30/60 minutes) only skip repeated Windows Hello; they still issue one-time redeemable grants for each exact operation. +Batch approval is ordered and finite. Every operation receives a distinct nonce and exact scope. There is no wildcard grant. Bounded branch leases (`push_code` only, 1–10 minutes) and PR sessions (`push_code` and `merge_pr` on one PR and the approved merge base, 5/15/30/60 minutes) only skip repeated Windows Hello; they still issue one-time redeemable grants for each exact operation. Legacy Ed25519 public-key verification remains supported through `GITHUB_DELIVERY_AUTHORITY_PUBLIC_KEY`. Algorithm-agile issuers use the public trust store configured by `GITHUB_DELIVERY_AUTHORITY_TRUST_STORE`; the Windows host uses ES256 and a public-only trust store. diff --git a/references/mutation-modes.md b/references/mutation-modes.md index 06928e2a..df9b8ac9 100644 --- a/references/mutation-modes.md +++ b/references/mutation-modes.md @@ -47,7 +47,7 @@ The persistent user config defaults to `high-assurance`. It lives outside the in Dry-run planning never requires trusted authority. When the selected mode requires authority at `--execute`, the trusted grant must contain `scopeSha256`; a legacy resource-only signature is not enough. -A **PR session** is an opt-in Hello grant, distinct from a branch lease. After Windows Hello, the approval UI may start a 5–60 minute session bound to one allowlisted repo, one PR, and one head branch. Later exact-scope `push_code` and `merge_pr` batches on that tuple skip Hello (`approvalMethod: pr_session`) but still receive one-time redeemable grants. Branch leases remain `push_code` only for 1–10 minutes. Comments, human replies, close, and delete still need Hello. Mixed-action batches are not session-eligible. +A **PR session** is an opt-in Hello grant, distinct from a branch lease. After Windows Hello, the approval UI may start a 5–60 minute session bound to one allowlisted repo, one PR, one head branch, and the approved merge base for merge. Later exact-scope `push_code` and `merge_pr` batches on that tuple skip Hello (`approvalMethod: pr_session`) but still receive one-time redeemable grants. A retargeted base requires Hello again. Branch leases remain `push_code` only for 1–10 minutes. Comments, human replies, close, and delete still need Hello. Mixed-action batches are not session-eligible. The canonical enabled high-assurance action set is listed below. CI verifies exact set equality against the executable registry. The list remains an intrinsic risk classification even when a user explicitly selects `off`.