Skip to content

feat(agent): agent audit feed — surface executed actions + approval decisions (#784) - #935

Closed
oktofeesh1 wants to merge 1 commit into
JSONbored:mainfrom
oktofeesh1:feat/issue-784-agent-audit-feed
Closed

feat(agent): agent audit feed — surface executed actions + approval decisions (#784)#935
oktofeesh1 wants to merge 1 commit into
JSONbored:mainfrom
oktofeesh1:feat/issue-784-agent-audit-feed

Conversation

@oktofeesh1

Copy link
Copy Markdown
Contributor

Closes #784. Second of two focused PRs for Phase 3's agent automation control surface (the first, #934, added the MCP approval-queue list/decide tools).

Why

The agent already writes an audit trail — agent.action.<class> from the executor and agent.pending_action.accepted|rejected from the approval queue — but nothing could read it back: no query, no route, no MCP tool. This adds the read side of the audit feed.

What this adds

  • DB: listAgentAuditEvents(repoFullName, since?, limit) — repo-scoped via the repo#pr targetKey prefix range (mirrors listPrVisibilitySkipAuditEvents), filtered to agent.action.* / agent.pending_action.*, newest first, capped at 200.
  • HTTP: GET /v1/repos/:owner/:repo/agent/audit-feed — maintainer-scoped, ?since=ISO&limit=N. Read-only and public-safe (only the action posture is selected — no trust/score metadata).
  • MCP: gittensory_get_agent_audit_feed {owner, repo, since?, limit?} — maintainer-manage scoped.

Scope note on #784

Together with #934 (MCP list/decide approval tools) and the already-merged CLI maintain commands + get_automation_state/propose_action MCP tools, this completes the CLI + MCP + HTTP control surface for agent automation. The dashboard Automation tab is owner-led visual work and is intentionally tracked separately; this closes the backend/control-surface deliverable of #784.

Tests

routes-agent-approval.test.ts + mcp-automation-state.test.ts: repo-scoping (excludes other repos and non-agent events), newest-first ordering, since/limit filters, the maintainer-access gate, and a non-numeric targetKey → null pullNumber. Full npm run test:coverage green (branches 97.02%); new lines fully covered.

🤖 Generated with Claude Code

…ecisions (JSONbored#784)

The agent writes an audit trail (agent.action.<class> from the executor,
agent.pending_action.accepted|rejected from the approval queue) but nothing
could read it back — no query, route, or MCP tool. This adds the read side of
Phase 3's audit feed across HTTP + MCP:

- DB: listAgentAuditEvents(repoFullName, since?, limit) — repo-scoped via the
  `repo#pr` targetKey prefix range (mirrors listPrVisibilitySkipAuditEvents),
  filtered to agent.action.* / agent.pending_action.*, newest first, capped 200.
- HTTP: GET /v1/repos/:owner/:repo/agent/audit-feed — maintainer-scoped,
  ?since=ISO&limit=N. Read-only and public-safe (action posture only — no
  trust/score metadata is selected).
- MCP: gittensory_get_agent_audit_feed {owner, repo, since?, limit?} —
  maintainer-manage scoped.

Tests: route + MCP each assert repo-scoping (excludes other repos and non-agent
events), newest-first ordering, since/limit filters, the maintainer-access gate,
and a non-numeric targetKey → null pullNumber. Full test:coverage green
(branches 97.02%); new lines fully covered.

Closes JSONbored#784

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@oktofeesh1
oktofeesh1 requested a review from JSONbored as a code owner June 20, 2026 15:34
@dosubot dosubot Bot added the size:L label Jun 20, 2026
@ghost ghost added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jun 20, 2026
@ghost

ghost commented Jun 20, 2026

Copy link
Copy Markdown

🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥🟥

⛔ Maintainer review — Blockers found

Reviewed 5 changed file(s) — two independent AI reviewers, synthesized.

ℹ️ This PR conflicts with main and can't be merged as-is. Conflicting file(s): src/api/routes.ts, src/db/repositories.ts, src/mcp/server.ts, test/unit/mcp-automation-state.test.ts, test/unit/routes-agent-approval.test.ts. Resolve the conflict(s) and open a fresh PR.

Merge readiness: ❌ CI is red — approval withheld until it's green. Failing: see the checks tab.

Summary

The change introduces a new audit‑feed feature across MCP, API routes, and DB layer with corresponding tests. While functional, it outputs raw audit event fields (actor, detail) without sanitising against the project's public‑safe word list, risking leakage of forbidden terms. This is a concrete privacy/security defect.

🛑 Hard blockers — must fix before merge

  • Missing sanitisation of public audit‑feed output allows forbidden terms to be returned, violating the public/private boundary.
  • The CI failure for 'Gittensory Gate' indicates a potential issue with the linked issue overlapping another open PR. This needs to be resolved before merging.

💡 Nits — non-blocking, optional

  • Sanitise actor, detail (and any future fields) in listAgentAuditEvents or in the MCP tool/route using the existing sanitizePublicComment logic to guarantee no forbidden words are emitted.
  • Add a comment in the code explaining the public‑safe guarantee and the sanitisation requirement.
  • Consider adding a test that verifies forbidden words are stripped or cause an error when present in audit events.
  • Consider adding a comment to the listAgentAuditEvents function explaining the purpose of the prefix and upperBound variables.
  • Consider adding a test case for the listAgentAuditEvents function to verify that it correctly handles the sinceIso and limit parameters.

This repo uses one-shot review: a rejected PR is closed, not iterated in place. Address the above and open a new focused PR.

@ghost ghost closed this Jun 20, 2026
@superagent-security

superagent-security Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

⚠️ Contributor trust inconclusive. Click here for more info: Superagent Dashboard

@ghost

ghost commented Jun 21, 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 #935 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 21, 2026
@JSONbored JSONbored reopened this Jun 21, 2026
@ghost ghost closed this Jun 21, 2026
@superagent-security

Copy link
Copy Markdown
Contributor

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

@JSONbored JSONbored reopened this Jun 21, 2026
@ghost ghost closed this Jun 21, 2026
@JSONbored JSONbored reopened this Jun 21, 2026
@ghost ghost closed this Jun 21, 2026
This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): automation controls surface (dashboard + CLI + MCP)

2 participants