Skip to content

feat(#735): agent-first scoping — Phase 1 schema, DB layer, and permissions#738

Merged
chubes4 merged 5 commits intomainfrom
feature/735-agent-first-scoping
Mar 8, 2026
Merged

feat(#735): agent-first scoping — Phase 1 schema, DB layer, and permissions#738
chubes4 merged 5 commits intomainfrom
feature/735-agent-first-scoping

Conversation

@chubes4
Copy link
Member

@chubes4 chubes4 commented Mar 8, 2026

Summary

Phase 1 of agent-first scoping (#735). Makes agent_id the primary scoping key for pipelines, flows, and jobs — decoupling WordPress users from agents so multiple users can share agents and external runtimes (Kimaki, CLI) can execute as agents.

  • Schema: adds agent_id bigint(20) unsigned DEFAULT NULL column to pipelines, flows, and jobs tables via idempotent migrations
  • AgentAccess table: new many-to-many datamachine_agent_access table with role hierarchy (admin > operator > viewer)
  • DB methods: create_pipeline/flow/job accept agent_id, all query methods (get_all_*, count, list_table) support agent_id filter
  • Permissions: PermissionHelper::resolve_scoped_agent_id(), can_access_agent(), owns_agent_resource() for REST API scoping
  • Backfill migration: sets agent_id on existing rows via user_id → owner_id lookup, bootstraps agent_access grants for owners
  • Backward compatible: agent_id = NULL means single-agent mode, existing installs work without changes

Architecture

Agent (agent_id) — primary entity
 ├── pipelines (agent_id column)
 ├── flows (agent_id column)
 ├── jobs (agent_id column)
 └── access grants (datamachine_agent_access)
      ├── User A → role: admin
      ├── User B → role: operator
      └── User C → role: viewer

Files changed

File Change
AgentAccess.php New — access grants repository
Agents.php Added get_agent() by primary key
Pipelines.php agent_id migration + query filters
Flows.php agent_id migration + query filters
Jobs.php agent_id migration
JobsOperations.php agent_id in create + query filters
PermissionHelper.php 3 new methods for agent scoping
migrations.php datamachine_backfill_agent_ids()
data-machine.php Wire up AgentAccess table + backfill

Next phases

  • Phase 2: REST API endpoints use resolve_scoped_agent_id(), Ability input schemas get agent_id
  • Phase 3: Admin UI agent switcher
  • Phase 4: Runtime authentication (Kimaki/REST authenticate as agent)

Closes phase 1 of #735.

…ssions

Add agent_id column to pipelines, flows, and jobs tables with idempotent
migrations. Create agent_access table for many-to-many user↔agent access
grants with role hierarchy (admin/operator/viewer).

- Agents.get_agent(): lookup by primary key (was missing)
- AgentAccess: new repository for role-based access grants
- create_pipeline/flow/job: accept optional agent_id
- get_all_*/count/list_table queries: filter by agent_id
- PermissionHelper: resolve_scoped_agent_id(), can_access_agent(),
  owns_agent_resource() for REST API scoping
- Backfill migration: existing user_id rows get agent_id via owner lookup
- Backward compatible: agent_id=NULL means single-agent mode
@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: 4 errors, 27 warnings
  • Fixable: 28 | Files with issues: 8 of 29
  • PHPStan: PHPSTAN SUMMARY: 207 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: 56 errors, 51 warnings
  • Fixable: 100 | Files with issues: 15 of 369
Top violations
  WordPress.Arrays.ArrayDeclarationSpacing.ArrayItemNoNewLine    51
  Generic.Formatting.MultipleStatementAlignment.NotSameWarning    32
  WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned    15
  Universal.Operators.DisallowShortTernary.Found              3
  Generic.CodeAnalysis.UnusedFunctionParameter.Found          3
- PHPStan: PHPSTAN SUMMARY: 207 errors at level 5 - Tests: 739, Assertions: 2693, 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.698
  • Severity counts: info: 78, unknown: 77, warning: 183
  • Drift increased: no
  • Outliers in current run: 77
  • Parsed outlier entries: 77
  • Top actionable findings:
    1. inc/Abilities/PermissionHelper.php — naming_mismatch — Helper-like name does not match convention suffix 'Abilities': PermissionHelper
    2. inc/Abilities/PermissionHelper.php — missing_import — Missing import: DataMachine\Abilities\PermissionHelper
    3. tests/Unit/Abilities/SystemAbilitiesTest.php — missing_registration — Missing registration: datamachine_cli_bypass_permissions
    4. tests/Unit/Abilities/MultiAgentScopingTest.php — missing_registration — Missing registration: datamachine_cli_bypass_permissions
    5. inc/Api/FlowFiles.php — missing_interface — Missing interface: PermissionHelper

Homeboy Action v1

chubes4 added 4 commits March 8, 2026 16:35
Add agent_id to GetPipelinesAbility, GetFlowsAbility, GetJobsAbility
input schemas so all list/query operations can filter by agent. Agent_id
takes priority over user_id when both are present.

- Ability input schemas: agent_id param added to get-pipelines,
  get-flows, get-jobs
- FlowHelpers: getAllFlowsPaginated/countAllFlows accept agent_id
- RunFlowAbility: propagates flow's agent_id to created job and
  engine snapshot
- REST API (Pipelines, Flows, Jobs): resolve_scoped_agent_id()
  alongside resolve_scoped_user_id(), agent_id takes priority
- Ownership checks: owns_resource() → owns_agent_resource() for
  all mutation endpoints (delete, update, duplicate, memory files)
  on both pipelines and flows
Add shared AgentSwitcher component and param interceptor architecture:

- GET /datamachine/v1/agents REST endpoint (access-scoped per user)
- AgentSwitcher shared component (SelectControl, Zustand-persisted)
- Param interceptor pattern in api.js (client.addParamInterceptor)
- agentInterceptor boot module auto-injects agent_id into all GETs
- AgentSwitcher added to Pipelines, Jobs, Logs, Agent page headers
- TanStack Query cache invalidation on agent switch
- Agents query hook with 10-minute stale time

Transport layer (api.js) stays dumb — interceptors plug in at boot.
… flag

Add DirectoryManager::resolve_agent_slug() as the central resolution
method for multi-agent setups. Accepts agent_slug, agent_id, or falls
back to user_id lookup (single-agent compat).

- resolve_agent_slug(context) + resolve_agent_directory(context)
- wp datamachine agent paths --agent=<slug> bypasses user→agent lookup
- CoreMemoryFilesDirective uses agent_id from payload
- MemoryFilesReader accepts agent_id parameter
- AgentFileAbilities (list/get/write/upload/delete) use resolve_agent_directory
- AgentMemory + DailyMemory constructors accept agent_id
- AgentMemoryAbilities + DailyMemoryAbilities pass agent_id through
- Pipeline/Flow memory directives thread agent_id from payload

All changes are backward compatible — agent_id defaults to 0, which
falls through to existing user_id-based resolution.
@chubes4 chubes4 merged commit 2969377 into main Mar 8, 2026
3 checks passed
@chubes4 chubes4 deleted the feature/735-agent-first-scoping branch March 8, 2026 18:47
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.

1 participant