Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@ jobs:
PGPASSWORD: agentplat_test
- name: Verify optional Jev example and experiment contracts
run: node --test examples/rooms-api/test/proposal-reviewer.test.mjs experiments/jev-artifact-review/run.test.mjs
- name: Verify standalone action control and independent consumers
run: pnpm run verify:action-control
env:
AGENTPLAT_POSTGRES_TEST: "1"
PGHOST: 127.0.0.1
PGPORT: "5432"
PGDATABASE: agentplat_test
PGUSER: agentplat_test
PGPASSWORD: agentplat_test
- name: Verify purpose governance and packed consumers
run: |
pnpm run verify:purpose-governance /tmp/purpose-governance-ci
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/release-direct.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ jobs:
pnpm --filter @agentplat/collective-runtime --filter @agentplat/audit type-check
else
pnpm run check
pnpm run verify:action-control
pnpm run verify:mesh-postgres-faults
pnpm run verify:mesh-soak -- --messages 9 --repetitions 2
pnpm run benchmark:mesh-adapters
Expand Down Expand Up @@ -122,6 +123,7 @@ jobs:
pnpm run verify:pack
pnpm run verify:purpose-consumer
pnpm run verify:jev-consumer
pnpm run verify:action-control-consumer
fi
env:
AGENTPLAT_PREPACKED_TARBALL_DIRECTORY: ${{ github.workspace }}/release-artifacts
Expand Down Expand Up @@ -224,6 +226,11 @@ jobs:
run: pnpm run verify:public-consumer
env:
AGENTPLAT_PUBLIC_CONSUMER_SOURCE: registry
- name: Verify standalone action-control registry entry points and types
if: ${{ inputs.scope == 'all' }}
run: pnpm run verify:action-control-consumer
env:
AGENTPLAT_PUBLIC_CONSUMER_SOURCE: registry
- name: Verify complete coordinated registry distribution
if: ${{ inputs.scope == 'all' }}
run: node scripts/npm-distribution-readiness.mjs --require-complete --tag "$NPM_DIST_TAG"
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ jobs:
pnpm --filter @agentplat/collective-runtime --filter @agentplat/audit type-check
else
pnpm run check
pnpm run verify:action-control
pnpm run verify:mesh-postgres-faults
pnpm run verify:mesh-soak -- --messages 9 --repetitions 2
pnpm run benchmark:mesh-adapters
Expand All @@ -113,6 +114,7 @@ jobs:
pnpm run verify:public-consumer
else
pnpm run verify:pack
pnpm run verify:action-control-consumer
fi
env:
AGENTPLAT_PREPACKED_TARBALL_DIRECTORY: ${{ github.workspace }}/release-artifacts
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/verify-npm-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ jobs:
env:
AGENTPLAT_PUBLIC_CONSUMER_SOURCE: registry
NPM_CONFIG_USERCONFIG: /dev/null
- name: Verify standalone action-control registry entry points and types
if: ${{ inputs.scope == 'all' }}
run: pnpm run verify:action-control-consumer
env:
AGENTPLAT_PUBLIC_CONSUMER_SOURCE: registry
NPM_CONFIG_USERCONFIG: /dev/null
- name: Verify complete coordinated public distribution
if: ${{ inputs.scope == 'all' }}
run: node scripts/npm-distribution-readiness.mjs --require-complete --tag "${{ inputs.dist_tag }}"
Expand Down
92 changes: 92 additions & 0 deletions docs/action-control/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Standalone governed external actions

**Status:** additive, opt-in source profile; qualification passed in an isolated
checkout on 2026-09-30. Introduced by the coordinated 1.2.0 release; consult the release record for
publication status. Operational obligations and release
steps remain explicit; no production-scale or universal external guarantee is claimed.

This profile supports hosts such as The Agent Control without requiring Agent Rooms.
Existing ActionGateway, grants, authority/assessment resolvers and dispatchers retain
execution ownership. Existing entry points/default behavior, historical rows and
migration bytes remain unchanged.

## Public surfaces

| Entry point | Responsibility |
| --- | --- |
| `@agentplat/inference-control/tools` | Existing gateway/repositories; additive typed grant preparation and conservative recovery of interrupted reservations |
| `@agentplat/inference-control/action-approvals` | Exact reviewed targets, authenticated independent decisions, persistent monotonic lifecycle and a narrowing assessment resolver |
| `@agentplat/inference-control/action-admission` | Atomic revocation fences, shared resource accounts, effect receipts and verified reconciliation |
| `@agentplat/inference-control/action-effects` | Explicit atomic conditional-write and idempotent receipt contract |
| `@agentplat/collective-control-postgres/action-approvals` | Tenant-scoped durable approval store and separately invoked migration |
| `@agentplat/collective-control-postgres/action-admission` | Transactional admission store and separately invoked migration |

Read [integration.md](integration.md) for composition, trusted ports, migration and
recovery instructions. [release-plan.md](release-plan.md) defines coordinated delivery
and publication. [qualification.md](qualification.md) maps requirements to evidence.

## Guarantees and boundaries

Approval targets bind input, full action binding, trusted preconditions, policy and
revocation versions. Decisions require an authenticated authorized independent person.
Approval does not grant authority or override base denial. Changed facts invalidate;
unavailable facts deny. Expiry/invalidation cannot be undone by a restart or old clock.
One approval cannot authorize multiple logical effects.

Admission atomically verifies active agent/connector/organization epochs and required
approval evidence, then reserves all configured charges or none. Account IDs include
scope and immutable period, with safe-integer units and revisioned limits. Policy
changes/reactivation do not reset consumption. A trusted host selects every applicable
account and quotes an upper bound that the adapter must enforce.

Admission is the linearization point: suspension/invalidation committed first blocks;
admission committed first may finish. The external destination must apply approved
resource preconditions atomically with its write to close the read/write race.
Capabilities are host-attested integration contracts, requiring adapter conformance.
Unsupported destinations must display a weaker profile; no universal interception,
rollback, cancellation or exactly-once promise exists.

Effects begin indeterminate before dispatch. Unknown outcomes retain reservations and
never automatically retry/refund. Terminal not_applied proof refunds once; succeeded
retains cost. A temporary lookup miss is insufficient. Interrupted reserved grants
require proof the original worker stopped or was fenced before conservative recovery.
Recovery never reissues authority. Grant and effect reconciliation are separate
idempotent durable operations, still allowed while suspended.

## Reproduce qualification

Use a disposable PostgreSQL database with schema-creation privileges. Tests only
create/drop isolated UUID-named schemas; no production migration or deployment runs.

```sh
pnpm install --frozen-lockfile
AGENTPLAT_POSTGRES_TEST=1 PGHOST=127.0.0.1 PGDATABASE=postgres \
pnpm run verify:action-control
```

The focused gate refuses missing database enablement, builds the workspace, checks
public types, requires zero failed/skipped/TODO/cancelled scenarios and runs independent
prepared-tarball consumption. Set connection/authentication for your local database;
connection strings are not written into qualification metadata.

Broader validation separately covers full type checks, unit/adapter suites, public
surface, platform/specification and stable compatibility. Skips/TODOs are reported,
not passed evidence. CI release gates still apply before publication.

## Host obligations

- Verified identity, role checks, policy evaluation, server clock and exact payload
storage/display; no client tenant IDs, costs or claimed approvers as authority.
- Durable grant-to-approval mapping, trusted facts/quotes and all required accounts;
required approval references cannot be omitted from admission.
- Adapter-owned idempotency/fencing, conditional writes and terminal receipts;
actual consumption cannot exceed quotes.
- Credentials, redaction/retention, backups, scheduling, diagnostics and recovery.
- Deployment capacity verification. The reference admission adapter serializes by
tenant and retains full receipt history; throughput/compaction/partitioning require
separate operational qualification preserving accounting and idempotency evidence.

Record digests detect accidental corruption, not a malicious infrastructure admin.
MCP routing, UI, business policies, connectors, licensing and commercial portal remain
exclusively owned by The Agent Control. Its npm dependency update follows actual
coordinated publication, not the presence of these source files.
101 changes: 101 additions & 0 deletions docs/action-control/integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Integrating standalone governed actions

The optional additions require the coordinated 1.2.0 release. Consult its
release record and install only after distribution is verified. No Agent Rooms, Agent Mesh or remote ACL service is required.

## Composition and owners

```text
Authenticated host -> grant repository -> ActionGateway
approval assessment -> |
admission dispatcher
|
conditional dispatcher
|
external executor
```

The host owns verified identity, policy, approver roles, exact request storage/display,
clocks, trusted resource facts and selection of ALL applicable budget accounts.
AgentPlat owns the linkage to a logical effect, currentness, reservations and receipts.

Use the existing PostgresActionGrantRepositoryV1 and existing collective migration
runner for durable grants. Explicitly invoke runActionApprovalMigrationsV1 and
runActionAdmissionMigrationsV1 for the optional stores. Imports/upgrades never invoke
migrations. Old rows and migration bytes remain unchanged. Use one intended tenant
and schema across these stores; missing required storage must deny, not use memory.

## Request and approval

Authenticate the requesting agent in the host, normalize and retain its exact payload,
and read trusted policy/resource facts. createActionApprovalTargetV1 binds input,
complete action binding, resource preconditions and authority/policy versions.

For required review, ActionApprovalServiceV1.request/decide consume authenticated
context. Show the exact retained request in the UI. A purpose, explanation, signal
or claimed actor cannot grant permission. Reevaluation of current policy remains
required: human approval cannot override a hard denial.

Use createActionGrantV1 with the reviewed target digest as assessmentTargetDigest,
then issueActionGrantV1 through the existing repository. Persist the exact grant-to-
approval mapping. The approval assessment resolver narrows the base resolver and
reloads trusted current facts. Changed targets invalidate; unavailable facts deny.

All timestamps come from the host clock. Expired/invalidated decisions never revive;
a changed target requires new reviewed identity. Do not forward agent-supplied times.

## Admission and effect

Configure three active revocation fences (agent, connector, organization) through
trusted administrative operations. Epoch changes invalidate old work. Configure
budgets with explicit safe-integer units, immutable period boundaries, revisions
and stable account IDs that include scope/period. Renewal creates a new account ID;
changes do not reset consumption. Calendar/timezone/rolling policy belongs to the host.

The trusted quote includes all applicable accounts, upper-bound charges, actual
fences and a stable logical effect ID. Adapters must not exceed quoted consumption;
reject operations whose maximum cannot be bounded. Agent-supplied cost is not a fact.

createActionAdmissionDispatcherV1 wraps the existing dispatcher after gateway checks.
Include the persisted approval reference when policy requires one; null is only for
explicitly authorized unreviewed actions. Admission locks approval evidence alongside
fences/budgets. Missing schema or port cannot disable a required check.

For destinations supporting atomic conditional writes AND idempotent terminal receipts,
use createConditionalActionDispatcherV1 as the downstream dispatcher. Resolve the
immutable reviewed constraints, not a permissive fresh baseline. Its execution port
must check conditions and perform the effect atomically at the destination. Receipts
correlate idempotency key, action/input/precondition digests and terminal outcome.
Pin executor identity/version/capability profile in the binding handler digest.
Declarations are contracts; conformance tests must verify the actual adapter.

A destination without conditional writes cannot support the strict precondition
profile. Expose weaker integrations with their race boundary explicitly identified.
Read-before-write alone is insufficient. There is no universal cancellation,
rollback or exactly-once promise for arbitrary external services.

## Recovery

Admission committed first may finish after suspension; suspension committed first
denies. Unknown effects retain all budget holds and never automatically retry/refund.
ActionAdmissionServiceV1.reconcile requires an authoritative receipt bound to the
request digest. not_applied must prove the original attempt cannot later apply;
lookup misses are insufficient. Concurrent refunds happen once.

If a process terminated with a grant still reserved, recoverReservedActionGrantV1
requires the host to prove its original worker stopped or was fenced. It transitions
to indeterminate, never issued. Reconcile the effect receipt and existing grant via
reconcileActionGrantV1 with original reservation/attempt identity. A crash between
those two durable boundaries is handled by repeating reconciliation, not dispatch.
Facts can be reconciled while suspended without restoring execution authority.

## Operations and evidence

The initial admission store serializes by tenant and retains all receipts: a bounded
correctness reference, not production-scale throughput evidence. Compaction/partitioning
must preserve accounting and idempotency receipts. Record digests detect corruption,
not a malicious administrator. Credentials, redaction, scheduling, backup, connectors,
MCP integration and user-facing review workflows remain host responsibilities.

See README.md for verification and release-plan.md for coordinated delivery. Source
qualification and prepared tarballs do not constitute an npm release.
Loading
Loading