Skip to content

feat(agent): kill-switch + dry-run + action audit (#776) - #842

Merged
JSONbored merged 1 commit into
mainfrom
feat/agent-killswitch-dryrun
Jun 17, 2026
Merged

feat(agent): kill-switch + dry-run + action audit (#776)#842
JSONbored merged 1 commit into
mainfrom
feat/agent-killswitch-dryrun

Conversation

@JSONbored

Copy link
Copy Markdown
Owner

Closes #776. Phase-0 safety controls the action layer (#778) must consult before any action — the second gate alongside resolveAutonomy (#773).

What

  • src/settings/agent-execution.ts (pure, 100% covered):
    • resolveAgentActionModepaused | dry_run | live. Safest wins: a global OR per-repo pause halts everything; else dry-run logs without mutating; else live. agentActionModeExecutes is true only for live.
    • isGlobalAgentPause — the operator emergency brake via env AGENT_ACTIONS_PAUSED (truthy-string idiom).
    • buildAgentActionAudit — a structured who / what / why / outcome / mode record (eventType: agent.action.<class>) so live actions AND dry-run shadows record on one shape, extending the existing audit-event infra.
  • Per-repo settings agentPaused + agentDryRun (migration 0044, default false), wired like badgeEnabled across types / schema / repositories / openapi / yml settings block, plus the maintainer PUT /settings.
  • Dashboard: kill-switch + dry-run toggles in the "Auto-maintain" section.
# emergency: pause all agent actions on a repo
settings: { agentPaused: true }

Scope

Establishes the primitives; the action layer that honors the mode, the dry-run feed into the recommendation-outcome loop, and revert-where-possible are #778 (they need real actions to act on/revert).

Verification

typecheck clean · migration guard (0001..0044, no dup) · full suite 2021 passed, 1 skipped (pre-existing pngjs skip) · OpenAPI regenerated + drift-clean · UI lint/typecheck/build clean · the new module is 100% covered, every changed line covered.

Note: migration 0044 follows #773/#774's 0042/0043, ahead of the open #833.

Relates #768 (Phase 0), #773/#774 (the other Phase-0 gates), #778 (the action layer that consults all three).

Phase-0 safety controls the action layer (#778) must consult before any
action — the second gate alongside resolveAutonomy.

- src/settings/agent-execution.ts (pure, 100% covered):
  - resolveAgentActionMode -> paused | dry_run | live. Safest wins: a
    global OR per-repo pause halts everything; else dry-run logs without
    mutating; else live. agentActionModeExecutes is true only for live.
  - isGlobalAgentPause: the operator emergency brake via env
    AGENT_ACTIONS_PAUSED (truthy-string idiom).
  - buildAgentActionAudit: a structured who/what/why/outcome/mode audit
    record (eventType agent.action.<class>) so live actions AND dry-run
    shadows record on one shape — extends the existing audit-event infra.
- Per-repo settings agentPaused + agentDryRun (migration 0044, default
  false), wired like badgeEnabled across types/schema/repositories/openapi
  /settings-preview yml block, plus the maintainer PUT /settings.
- Dashboard: kill-switch + dry-run toggles in the auto-maintain section.

Deferred to #778 (needs real actions): the action layer honoring the mode,
the dry-run feed into the recommendation-outcome loop, and revert-where-
possible.

NOTE: migration 0044 follows #773/#774's 0042/0043, ahead of the open #833.
@dosubot dosubot Bot added the size:L label Jun 17, 2026
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 17, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
gittensory-ui 2bd4408 Commit Preview URL

Branch Preview URL
Jun 17 2026, 09:41 PM

@ghost

ghost commented Jun 17, 2026

Copy link
Copy Markdown

Note

Gittensory Gate skipped

PR closed before full evaluation. No late first comment was created.

Signal Result Evidence Action
Gate result ⚠️ Skipped #842 is no longer open. No action.

💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by Gittensory, a quiet PR intelligence layer for OSS maintainers.

@ghost ghost added the gittensory:reviewed label Jun 17, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@ghost

ghost commented Jun 17, 2026

Copy link
Copy Markdown

gittensory · advisory review

Reviewed 14 changed file(s) — two independent AI reviewers.

Changed files (14)
  • apps/gittensory-ui/public/openapi.json
  • apps/gittensory-ui/src/components/site/app-panels/maintainer-settings.tsx
  • migrations/0044_agent_kill_switch.sql
  • src/api/routes.ts
  • src/db/repositories.ts
  • src/db/schema.ts
  • src/env.d.ts
  • src/openapi/schemas.ts
  • src/settings/agent-execution.ts
  • src/signals/focus-manifest.ts
  • src/types.ts
  • test/integration/api.test.ts
  • test/unit/agent-execution.test.ts
  • test/unit/data-spine.test.ts

Suggested action: 🛠️ Request changes. (reviewers split: request changes / merge) Address the suggestions below before merging.

Reviewer A · gpt-oss-120b — recommends 🛠️ request changes
The PR adds a global and per‑repo kill‑switch and dry‑run mode, extends DB schema, UI, OpenAPI, and adds utility functions with tests. However the API schema now requires the new fields, breaking existing callers that omit them.

Suggestions

  • Make agentPaused and agentDryRun optional (e.g. z.boolean().optional()) in maintainerSettingsSchema to preserve backward compatibility.
  • Add default handling for these fields in the route handler so missing values default to false.
  • Consider adding a unit test that updates settings without the new fields to verify the API still works.

Worth double-checking

  • Existing clients may receive validation errors due to the newly required fields.
  • If the new fields are not integrated into the actual agent execution flow, the kill‑switch may not be enforced.

Reviewer B · nemotron-3-120b-a12b — recommends ✅ merge
This PR adds a comprehensive agent action safety system with global kill-switch (env AGENT_ACTIONS_PAUSED), per-repo pause/kill-switch, and per-repo dry-run/shadow mode. It includes backend logic, database schema changes, UI controls, audit logging, and tests. The implementation follows deny-toward-safety precedence (global pause > per-repo pause > dry-run > live) and properly integrates with existing systems like audit events, settings persistence, and API schemas. All changes are well-tested with unit and integration tests covering the new functionality.

Suggestions

  • Consider adding a comment in resolveAgentActionMode clarifying that null/undefined agentPaused/agentDryRun are treated as false (consistent with UI defaults).
  • In MaintainerSettings.tsx, the default values when loading existing data (agentPaused: result.data.agentPaused ?? false) are good, but ensure this aligns with the DB migration's DEFAULT 0 for existing rows.
  • The audit function buildAgentActionAudit uses input.reason ?? null for detail - verify this matches the existing AuditEventRecord's detail field expectations (likely string | null).

Worth double-checking

  • Ensure the global kill-switch env var AGENT_ACTIONS_PAUSED is properly documented for operators (not in this PR but should be noted elsewhere).
  • Verify that the audit event recording (recordAuditEvent) correctly handles the new agent.action.* event types and doesn't expose forbidden terms in public outputs (though audit is internal).
  • Check that the UI toggle labels/hints are clear to maintainers about the distinction between 'Pause all agent actions' (kill-switch) and 'Dry-run / shadow mode'.

Before = production · After = this PR's preview deploy.

Route Viewport Before After
/ desktop before desktop after desktop
mobile before mobile after mobile

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.59%. Comparing base (965c6ae) to head (2bd4408).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #842   +/-   ##
=======================================
  Coverage   96.59%   96.59%           
=======================================
  Files          99      100    +1     
  Lines       14229    14240   +11     
  Branches     5182     5190    +8     
=======================================
+ Hits        13744    13755   +11     
  Misses        105      105           
  Partials      380      380           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@JSONbored
JSONbored merged commit 27a3ba6 into main Jun 17, 2026
22 checks passed
@JSONbored
JSONbored deleted the feat/agent-killswitch-dryrun branch June 17, 2026 21:42
@github-actions github-actions Bot mentioned this pull request Jun 18, 2026
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): action audit log + kill-switch + dry-run/shadow mode

1 participant