A local deterministic CLI can record a human-agent intent/action chain and flag narrow classes of drift between an original human request and a later proposed agent action.
This is v0.1.0. It is a small proof, not a framework.
agent-intent-ledger compares three declared JSON inputs:
- Original human intent.
- Agent interpreted objective or plan.
- Proposed agent action.
It emits:
- A readable terminal report.
- A machine-readable JSON drift report / receipt.
The CLI does not execute the proposed action. It only evaluates the declared proposal against the declared original intent constraints.
This does not understand human intent. It compares declared intent constraints against declared agent proposals and flags deterministic mismatch classes.
It does not:
- Use an LLM in the critical path.
- Make network calls.
- Integrate with AgentGate, MCP, or browser automation.
- Store data in a database.
- Enforce runtime behavior.
- Provide a UI.
- Prevent misalignment.
- Claim broad human-agent governance coverage.
- AgentGate handles after-action accountability: identity, bond, execution record, verification, settlement.
- ActionProof checks whether a proposed side-effecting JSON intent matches policy.
- ContextGate checks whether claims or compressed summaries should enter parent context.
- MemLedger records structured memory claims and memory-use receipts.
- agent-intent-ledger checks whether a later proposed agent action still traces to the original declared human mandate.
npm install
npm test
npm run typecheck
npm run buildRun the CLI:
npx tsx src/cli.ts evaluate \
--intent examples/intent-repo-summary.json \
--plan examples/plan-repo-summary.json \
--proposal examples/proposal-within-intent.json \
--json-out .agent-intent-ledger/within-intent-report.jsonAfter npm run build, the package binary points at dist/cli.js:
node dist/cli.js evaluate \
--intent examples/intent-repo-summary.json \
--plan examples/plan-repo-summary.json \
--proposal examples/proposal-within-intent.json \
--json-out .agent-intent-ledger/within-intent-report.jsonnpm run demo:within-intent
npm run demo:driftExpected demo outputs:
npm run demo:within-intentwrites.agent-intent-ledger/within-intent-report.jsonwith verdictwithin_intent.npm run demo:driftwrites.agent-intent-ledger/drift-report.jsonwith verdictauthority_drift.
The drift demo proposes sending a repo summary to external@example.com even though the original request only allowed reading/listing repo/** and declared no allowed external recipients. The receipt includes all deterministic drift classes found, including authority drift and human reapproval.
Intent:
{
"intent_id": "intent-repo-summary-001",
"human_request": "Summarize this repo.",
"allowed_objectives": ["summarize_repository"],
"allowed_action_types": ["read_file", "list_files"],
"allowed_resources": ["repo/**"],
"allowed_external_recipients": [],
"disallowed_action_types": ["send_email", "delete_file", "modify_file", "post_public"],
"requires_reapproval_for": ["external_communication", "file_mutation", "credential_access", "public_posting"],
"created_at": "2026-05-25T00:00:00.000Z"
}Plan:
{
"plan_id": "plan-001",
"intent_id": "intent-repo-summary-001",
"interpreted_objective": "summarize_repository",
"planned_steps": [
{
"step_id": "step-1",
"action_type": "list_files",
"resource": "repo/"
}
],
"created_at": "2026-05-25T00:01:00.000Z"
}Proposal:
{
"proposal_id": "proposal-001",
"intent_id": "intent-repo-summary-001",
"plan_id": "plan-001",
"proposed_action": {
"action_type": "send_email",
"objective": "summarize_repository",
"resource": "external@example.com",
"recipient": "external@example.com",
"effect_summary": "Send the repository summary to an external recipient."
},
"created_at": "2026-05-25T00:02:00.000Z"
}v0.1.0 uses only deterministic checks:
objective_drift: proposed objective is not inallowed_objectives.authority_drift: proposed action type is not inallowed_action_types, is explicitly indisallowed_action_types, or declares a recipient not inallowed_external_recipients.resource_drift: proposed resource does not match an allowed resource pattern.requires_human_reapproval: proposed action matches a declared reapproval trigger.scope_drift: chain IDs mismatch, or multiple lower-level drift classes are present.
When multiple drift classes are present, the primary verdict is selected deterministically using this priority:
objective_driftauthority_driftresource_driftrequires_human_reapprovalscope_drift
The drift_classes array still includes every class found, in stable order.
Resource matching is deliberately simple:
- Exact string match.
- Prefix glob only for patterns ending in
/**.
For example, repo/** matches repo/README.md and repo/src/index.ts. No complex glob engine is implemented.
{
"schema_version": "0.1.0",
"receipt_id": "receipt-example",
"intent_id": "intent-repo-summary-001",
"plan_id": "plan-001",
"proposal_id": "proposal-send-email-drift-001",
"verdict": "authority_drift",
"drift_classes": [
"authority_drift",
"resource_drift",
"requires_human_reapproval",
"scope_drift"
],
"reasons": [
{
"code": "ACTION_TYPE_NOT_ALLOWED",
"message": "Proposed action type send_email is not listed in the original intent allowed_action_types."
},
{
"code": "ACTION_TYPE_DISALLOWED",
"message": "Proposed action type send_email is explicitly disallowed by the original intent."
},
{
"code": "RECIPIENT_NOT_ALLOWED",
"message": "Proposed recipient external@example.com is not listed in the original intent allowed_external_recipients."
},
{
"code": "RESOURCE_NOT_ALLOWED",
"message": "Proposed resource external@example.com does not match any original intent allowed_resources pattern."
},
{
"code": "REAPPROVAL_REQUIRED_EXTERNAL_COMMUNICATION",
"message": "Proposed action matches declared reapproval trigger external_communication."
},
{
"code": "MULTIPLE_DRIFT_CLASSES",
"message": "Multiple deterministic drift classes were found, so the proposal is also marked as scope drift."
}
],
"chain": {
"human_request": "Summarize this repo.",
"interpreted_objective": "summarize_repository",
"proposed_action_type": "send_email",
"proposed_resource": "external@example.com"
},
"created_at": "2026-05-25T00:03:00.000Z"
}The tool only compares declared constraints and declared proposals. If those declarations are incomplete, misleading, or wrong, the receipt reflects that declared data. It does not infer true human intent.