Mission
Implement MindRail v0.1 permission evaluation and decision flow on branch feature/permission-engine-v0-1, using the already-canonical PermissionRequest / PermissionDecision contracts and ADR-0005 semantics.
Base SHA: 87fbfcf2ed738071f648a3b94bfff1df1f235dba.
Read AGENTS.md, ADR-0001/0003/0004/0005, permission schemas/generated types, security docs, current runtime authority code/tests, and docs/CURRENT_STATE.md before editing. HEAD is authoritative.
Architectural requirement
MindRail permission authority is deterministic. An LLM/model may propose or explain but must never grant authority.
Do not invent a general policy language in this slice. Implement the smallest explicit deterministic policy interface/evaluator needed to prove v0.1 semantics. Policy evaluation must be pure/testable and return only:
ALLOW
DENY
HUMAN_REQUIRED
HUMAN_REQUIRED grants nothing.
A MindRail ALLOW is scoped to the exact PermissionRequest and current Task/Session/Lease/fencing authority. It does not create credentials and cannot override external host/IAM/sandbox/tool approval.
Required flow
RequestPermission
Per ADR-0005:
- require current Task/Session/Lease/fence execution authority;
- construct and canonical-validate
PermissionRequest before append;
- evaluate deterministic MindRail policy;
- append initial
PermissionDecision with:
basis = policy;
- system actor;
- exact
policyRef;
- sequence
1;
- no predecessor/supersession;
- return request + initial decision atomically at runtime semantic level.
The policy evaluator should receive a bounded typed input, not arbitrary runtime objects or metadata blobs.
RecordPermissionDecision
Public v0.1 behavior is authenticated human follow-up to the latest HUMAN_REQUIRED decision.
Input includes:
- request id;
ALLOW | DENY only;
- expected previous decision id;
- reason code;
- optional bounded Reason.
Runtime derives:
- actor from authenticated/controller context supplied to protocol command;
basis = human;
- next sequence;
- supersedes link.
Reject:
- agent/system actor pretending to be human;
- stale expected previous decision id;
- follow-up to a request whose latest decision is not
HUMAN_REQUIRED;
- cross-workspace references;
- malformed canonical records.
A late human decision after Session/Lease loss may close history but must not revive or transfer old execution authority.
Minimum policy design
Create a small policy abstraction with deterministic versioned identity (PolicyRef). Prefer explicit ordered rules/configuration already representable by code/tests over DSL/parsing infrastructure.
At minimum demonstrate deterministic paths for:
- one permission automatically allowed;
- one denied;
- one requiring human decision;
- no matching/invalid policy state failing closed as
POLICY_UNAVAILABLE or DENY according to accepted semantics, with rationale documented.
Do not add model calls, network calls, arbitrary tools, dynamic code execution, or credential storage.
Runtime/protocol integration ownership
Primary ownership should be new modules such as:
src/policy/*
- permission-specific runtime service/module
- permission tests
Minimize edits to src/runtime/in-memory-control-plane.ts and src/runtime/protocol*.ts because Runtime Surface is being implemented in parallel. If protocol command union changes are unavoidable, keep them small and isolated so integration owner can reconcile them after Runtime Surface lands.
Do not edit persistence or transport implementation directories.
TDD / required tests
Mandatory RED -> GREEN. At minimum prove:
- RequestPermission rejects stale Session/Lease/fence before creating records;
- deterministic ALLOW creates request + sequence-1 policy decision;
- deterministic DENY creates authoritative DENY decision;
- HUMAN_REQUIRED creates no grant;
- policy decision uses system actor + exact policyRef;
- human follow-up only accepts human actor and ALLOW/DENY;
- stale
expectedPreviousDecisionId fails;
- late human follow-up after Lease loss records history but cannot authorize old/replacement execution;
- duplicate protocol command replays immutable request/decision IDs rather than appending duplicates;
- policy failure is fail-closed;
- all produced PermissionRequest/Decision records pass canonical schemas.
Run fresh:
pnpm install --frozen-lockfile
pnpm check
pnpm test:coverage
- permanent
Quality on final PR head.
Never call an unexecuted test PASS.
Non-scope
Do NOT:
- add OAuth/auth provider/IAM integration;
- create external credentials/tokens;
- add an LLM policy judge;
- add a policy DSL/interpreter;
- add persistence/D1/DO;
- implement HTTP/MCP;
- modify Domain Contracts unless a proven contradiction requires ADR/schema work;
- make PermissionDecision transferable across Lease/fencing authority.
Definition of done
Open a non-draft PR from feature/permission-engine-v0-1 to main with exact policy semantics, RED/GREEN evidence, final Quality run, and integration notes. Do not merge it yourself unless acting as the integration owner.
Mission
Implement MindRail v0.1 permission evaluation and decision flow on branch
feature/permission-engine-v0-1, using the already-canonicalPermissionRequest/PermissionDecisioncontracts and ADR-0005 semantics.Base SHA:
87fbfcf2ed738071f648a3b94bfff1df1f235dba.Read
AGENTS.md, ADR-0001/0003/0004/0005, permission schemas/generated types, security docs, current runtime authority code/tests, anddocs/CURRENT_STATE.mdbefore editing. HEAD is authoritative.Architectural requirement
MindRail permission authority is deterministic. An LLM/model may propose or explain but must never grant authority.
Do not invent a general policy language in this slice. Implement the smallest explicit deterministic policy interface/evaluator needed to prove v0.1 semantics. Policy evaluation must be pure/testable and return only:
ALLOWDENYHUMAN_REQUIREDHUMAN_REQUIREDgrants nothing.A MindRail ALLOW is scoped to the exact PermissionRequest and current Task/Session/Lease/fencing authority. It does not create credentials and cannot override external host/IAM/sandbox/tool approval.
Required flow
RequestPermissionPer ADR-0005:
PermissionRequestbefore append;PermissionDecisionwith:basis = policy;policyRef;1;The policy evaluator should receive a bounded typed input, not arbitrary runtime objects or metadata blobs.
RecordPermissionDecisionPublic v0.1 behavior is authenticated human follow-up to the latest
HUMAN_REQUIREDdecision.Input includes:
ALLOW | DENYonly;Runtime derives:
basis = human;Reject:
HUMAN_REQUIRED;A late human decision after Session/Lease loss may close history but must not revive or transfer old execution authority.
Minimum policy design
Create a small policy abstraction with deterministic versioned identity (
PolicyRef). Prefer explicit ordered rules/configuration already representable by code/tests over DSL/parsing infrastructure.At minimum demonstrate deterministic paths for:
POLICY_UNAVAILABLEor DENY according to accepted semantics, with rationale documented.Do not add model calls, network calls, arbitrary tools, dynamic code execution, or credential storage.
Runtime/protocol integration ownership
Primary ownership should be new modules such as:
src/policy/*Minimize edits to
src/runtime/in-memory-control-plane.tsandsrc/runtime/protocol*.tsbecause Runtime Surface is being implemented in parallel. If protocol command union changes are unavoidable, keep them small and isolated so integration owner can reconcile them after Runtime Surface lands.Do not edit persistence or transport implementation directories.
TDD / required tests
Mandatory RED -> GREEN. At minimum prove:
expectedPreviousDecisionIdfails;Run fresh:
pnpm install --frozen-lockfilepnpm checkpnpm test:coverageQualityon final PR head.Never call an unexecuted test PASS.
Non-scope
Do NOT:
Definition of done
Open a non-draft PR from
feature/permission-engine-v0-1tomainwith exact policy semantics, RED/GREEN evidence, final Quality run, and integration notes. Do not merge it yourself unless acting as the integration owner.