Skip to content

feat(#742): agent audit trail — structured action logging#745

Closed
chubes4 wants to merge 1 commit intomainfrom
feature/742-agent-audit-trail
Closed

feat(#742): agent audit trail — structured action logging#745
chubes4 wants to merge 1 commit intomainfrom
feature/742-agent-audit-trail

Conversation

@chubes4
Copy link
Member

@chubes4 chubes4 commented Mar 8, 2026

Summary

Adds a queryable audit trail for all agent actions. Every ability invocation, permission change, and resource mutation is recorded in a structured database table — separate from Monolog operational logs, designed for compliance queries and debugging.

Part of the agent-as-service-account architecture (follows #738, precedes #740 agent runtime auth).

What's new

Database

  • datamachine_agent_log table — structured rows with agent_id, action, result, resource_type, resource_id, JSON metadata, timestamps
  • Indexes on (agent_id, created_at), action, (result, created_at), (resource_type, resource_id)

Core

  • AuditLogger::record() — static helper that resolves agent context from PermissionHelper automatically, then writes to DB and fires datamachine_audit_event action for extensibility
  • AgentLog repository — full CRUD with paginated filtered queries and bulk prune

REST API

  • GET /datamachine/v1/agents/{id}/log — paginated, filterable by period (1h/24h/7d/30d/all), action, result, resource_type
  • Permission: can_access_agent($id, 'operator') — operators and admins

CLI

  • wp datamachine agents log <slug> with --period, --action, --result, --limit, --format

Retention

  • AuditCleanup Action Scheduler task — daily recurring, 30-day default (filterable via datamachine_audit_log_max_age_days)
  • Unscheduled on plugin deactivation

Audit hooks (8 trigger points)

Action Location Trigger
flow.run RunFlowAbility Flow execution started
job.complete JobCompleteHandler Job finished successfully
job.fail FailJobHandler Job failed
pipeline.create CreatePipelineAbility Pipeline created
pipeline.delete DeletePipelineAbility Pipeline deleted
agent.access.grant AgentAccess Access granted/updated
agent.access.revoke AgentAccess Access revoked
memory.write AgentMemoryAbilities Agent memory modified

Architecture

Agent action occurs (flow.run, pipeline.create, etc.)
    │
    ▼
AuditLogger::record('flow.run', 'allowed', options)
    │
    ├── Resolves agent_id from PermissionHelper context
    ├── Resolves user_id from PermissionHelper::acting_user_id()
    ├── Writes to datamachine_agent_log table
    └── Fires do_action('datamachine_audit_event', $event)

Testing

  • 764 tests, 0 failures (full suite passes)
  • All 14 files pass php -l syntax check
  • New files follow existing patterns: BaseRepository, ActionScheduler cleanup, REST API registration

Future hooks (when #740/#741 land)

  • auth.token.used — bearer token authenticated
  • auth.token.failed — invalid token attempt
  • policy.denied — tool policy blocked an ability

Closes #742

Adds a queryable audit trail for all agent actions. Every ability
invocation, permission change, and resource mutation is recorded in
a new datamachine_agent_log table with agent_id, action, result,
resource info, and JSON metadata.

New components:
- AgentLog repository (DB table + CRUD + pagination + pruning)
- AuditLogger static helper (resolves agent context automatically)
- REST API: GET /datamachine/v1/agents/{id}/log (with period/action/result filters)
- CLI: wp datamachine agents log <slug> (with --period, --action, --result)
- AuditCleanup Action Scheduler task (daily, 30-day retention)

Audit hooks at 8 trigger points:
- flow.run (RunFlowAbility)
- job.complete (JobCompleteHandler)
- job.fail (FailJobHandler)
- pipeline.create (CreatePipelineAbility)
- pipeline.delete (DeletePipelineAbility)
- agent.access.grant (AgentAccess)
- agent.access.revoke (AgentAccess)
- memory.write (AgentMemoryAbilities)

Closes #742
@github-actions
Copy link

github-actions bot commented Mar 8, 2026

Homeboy Results — data-machine

Lint

Tooling versions

  • Homeboy CLI: homeboy 0.72.0
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: unknown
  • Action: Extra-Chill/homeboy-action@v1

ℹ️ PR test scope resolved to full for compatibility with installed Homeboy CLI

lint (changed files only)

  • PHPCS: LINT SUMMARY: 12 errors, 20 warnings
  • Fixable: 20 | Files with issues: 5 of 14
  • PHPStan: PHPSTAN SUMMARY: 211 errors at level 5

Test

Tooling versions

  • Homeboy CLI: homeboy 0.72.0
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: unknown
  • Action: Extra-Chill/homeboy-action@v1

⚡ PR test scope resolved to changed

test

  • PHPCS: LINT SUMMARY: 64 errors, 65 warnings
  • Fixable: 113 | Files with issues: 18 of 373
Top violations
  WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine    51
  Generic.Formatting.MultipleStatementAlignment.NotSameWarning    38
  WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned    21
  Universal.Operators.DisallowShortTernary.Found              5
  WordPress.DB.PreparedSQL.NotPrepared                        4
- PHPStan: PHPSTAN SUMMARY: 211 errors at level 5 - Tests: 510, Assertions: 1566, Skipped: 3.

Audit

Tooling versions

  • Homeboy CLI: homeboy 0.72.0
  • Extension: wordpress from https://github.com/Extra-Chill/homeboy-extensions
  • Extension revision: unknown
  • Action: Extra-Chill/homeboy-action@v1

ℹ️ PR test scope resolved to full for compatibility with installed Homeboy CLI

audit (changed files only)

  • Actionable audit summary:
  • Alignment score: 0.700
  • Severity counts: info: 15, unknown: 77, warning: 8
  • Drift increased: no
  • Outliers in current run: 77
  • Parsed outlier entries: 77
  • Top actionable findings:
    1. data-machine.php — high_item_count — File has 16 top-level items (threshold: 15)
    2. inc/Abilities/AgentMemoryAbilities.php — duplicate_function — Duplicate function __construct — also in inc/Abilities/AgentAbilities.php, inc/Abilities/Analytics/BingWebmasterAbilities.php, inc/Abilities/Analytics/GoogleAnalyticsAbilities.php, inc/Abilities/Analytics/GoogleSearchConsoleAbilities.php, inc/Abilities/Analytics/PageSpeedAbilities.php, inc/Abilities/DailyMemoryAbilities.php, inc/Abilities/Fetch/FetchFilesAbility.php, inc/Abilities/Fetch/FetchRssAbility.php, inc/Abilities/Fetch/FetchWordPressApiAbility.php, inc/Abilities/Fetch/FetchWordPressMediaAbility.php, inc/Abilities/Fetch/GetWordPressPostAbility.php, inc/Abilities/Fetch/GitHubAbilities.php, inc/Abilities/Fetch/QueryWordPressPostsAbility.php, inc/Abilities/File/AgentFileAbilities.php, inc/Abilities/HandlerAbilities.php, inc/Abilities/InternalLinkingAbilities.php, inc/Abilities/LogAbilities.php, inc/Abilities/Media/ImageGenerationAbilities.php, inc/Abilities/Media/ImageTemplateAbilities.php, inc/Abilities/SEO/MetaDescriptionAbilities.php, inc/Abilities/SettingsAbilities.php, inc/Abilities/StepTypeAbilities.php, inc/Abilities/WorkspaceAbilities.php
    3. inc/Abilities/Engine/RunFlowAbility.php — duplicate_function — Duplicate function __construct — also in inc/Abilities/Engine/ExecuteStepAbility.php, inc/Abilities/Engine/ScheduleFlowAbility.php, inc/Abilities/Engine/ScheduleNextStepAbility.php, inc/Abilities/Flow/CreateFlowAbility.php, inc/Abilities/Flow/DeleteFlowAbility.php, inc/Abilities/Flow/DuplicateFlowAbility.php, inc/Abilities/Flow/GetFlowsAbility.php, inc/Abilities/Flow/UpdateFlowAbility.php, inc/Abilities/FlowStep/ConfigureFlowStepsAbility.php, inc/Abilities/FlowStep/GetFlowStepsAbility.php, inc/Abilities/FlowStep/UpdateFlowStepAbility.php, inc/Abilities/FlowStep/ValidateFlowStepsConfigAbility.php, inc/Abilities/Job/DeleteJobsAbility.php, inc/Abilities/Job/ExecuteWorkflowAbility.php, inc/Abilities/Job/FailJobAbility.php, inc/Abilities/Job/FlowHealthAbility.php, inc/Abilities/Job/GetJobsAbility.php, inc/Abilities/Job/JobsSummaryAbility.php, inc/Abilities/Job/ProblemFlowsAbility.php, inc/Abilities/Job/RecoverStuckJobsAbility.php, inc/Abilities/Job/RetryJobAbility.php, inc/Abilities/Pipeline/CreatePipelineAbility.php, inc/Abilities/Pipeline/DeletePipelineAbility.php, inc/Abilities/Pipeline/DuplicatePipelineAbility.php, inc/Abilities/Pipeline/GetPipelinesAbility.php, inc/Abilities/Pipeline/UpdatePipelineAbility.php
    4. inc/Abilities/Pipeline/CreatePipelineAbility.php — duplicate_function — Duplicate function __construct — also in inc/Abilities/Engine/ExecuteStepAbility.php, inc/Abilities/Engine/RunFlowAbility.php, inc/Abilities/Engine/ScheduleFlowAbility.php, inc/Abilities/Engine/ScheduleNextStepAbility.php, inc/Abilities/Flow/CreateFlowAbility.php, inc/Abilities/Flow/DeleteFlowAbility.php, inc/Abilities/Flow/DuplicateFlowAbility.php, inc/Abilities/Flow/GetFlowsAbility.php, inc/Abilities/Flow/UpdateFlowAbility.php, inc/Abilities/FlowStep/ConfigureFlowStepsAbility.php, inc/Abilities/FlowStep/GetFlowStepsAbility.php, inc/Abilities/FlowStep/UpdateFlowStepAbility.php, inc/Abilities/FlowStep/ValidateFlowStepsConfigAbility.php, inc/Abilities/Job/DeleteJobsAbility.php, inc/Abilities/Job/ExecuteWorkflowAbility.php, inc/Abilities/Job/FailJobAbility.php, inc/Abilities/Job/FlowHealthAbility.php, inc/Abilities/Job/GetJobsAbility.php, inc/Abilities/Job/JobsSummaryAbility.php, inc/Abilities/Job/ProblemFlowsAbility.php, inc/Abilities/Job/RecoverStuckJobsAbility.php, inc/Abilities/Job/RetryJobAbility.php, inc/Abilities/Pipeline/DeletePipelineAbility.php, inc/Abilities/Pipeline/DuplicatePipelineAbility.php, inc/Abilities/Pipeline/GetPipelinesAbility.php, inc/Abilities/Pipeline/UpdatePipelineAbility.php
    5. inc/Abilities/Pipeline/DeletePipelineAbility.php — duplicate_function — Duplicate function __construct — also in inc/Abilities/Engine/ExecuteStepAbility.php, inc/Abilities/Engine/RunFlowAbility.php, inc/Abilities/Engine/ScheduleFlowAbility.php, inc/Abilities/Engine/ScheduleNextStepAbility.php, inc/Abilities/Flow/CreateFlowAbility.php, inc/Abilities/Flow/DeleteFlowAbility.php, inc/Abilities/Flow/DuplicateFlowAbility.php, inc/Abilities/Flow/GetFlowsAbility.php, inc/Abilities/Flow/UpdateFlowAbility.php, inc/Abilities/FlowStep/ConfigureFlowStepsAbility.php, inc/Abilities/FlowStep/GetFlowStepsAbility.php, inc/Abilities/FlowStep/UpdateFlowStepAbility.php, inc/Abilities/FlowStep/ValidateFlowStepsConfigAbility.php, inc/Abilities/Job/DeleteJobsAbility.php, inc/Abilities/Job/ExecuteWorkflowAbility.php, inc/Abilities/Job/FailJobAbility.php, inc/Abilities/Job/FlowHealthAbility.php, inc/Abilities/Job/GetJobsAbility.php, inc/Abilities/Job/JobsSummaryAbility.php, inc/Abilities/Job/ProblemFlowsAbility.php, inc/Abilities/Job/RecoverStuckJobsAbility.php, inc/Abilities/Job/RetryJobAbility.php, inc/Abilities/Pipeline/CreatePipelineAbility.php, inc/Abilities/Pipeline/DuplicatePipelineAbility.php, inc/Abilities/Pipeline/GetPipelinesAbility.php, inc/Abilities/Pipeline/UpdatePipelineAbility.php

Homeboy Action v1

@chubes4
Copy link
Member Author

chubes4 commented Mar 8, 2026

Closing — this adds a redundant log layer instead of fixing the existing one. The real work is modernizing the Monolog system to use agent_id instead of AgentType (pipeline/chat/system).

@chubes4 chubes4 closed this Mar 8, 2026
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.

Agent audit trail: action attribution and logging

1 participant