Skip to content

Permission v0.1: deterministic policy and human decision flow #15

Description

@tim8es

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:

  1. require current Task/Session/Lease/fence execution authority;
  2. construct and canonical-validate PermissionRequest before append;
  3. evaluate deterministic MindRail policy;
  4. append initial PermissionDecision with:
    • basis = policy;
    • system actor;
    • exact policyRef;
    • sequence 1;
    • no predecessor/supersession;
  5. 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:

  1. RequestPermission rejects stale Session/Lease/fence before creating records;
  2. deterministic ALLOW creates request + sequence-1 policy decision;
  3. deterministic DENY creates authoritative DENY decision;
  4. HUMAN_REQUIRED creates no grant;
  5. policy decision uses system actor + exact policyRef;
  6. human follow-up only accepts human actor and ALLOW/DENY;
  7. stale expectedPreviousDecisionId fails;
  8. late human follow-up after Lease loss records history but cannot authorize old/replacement execution;
  9. duplicate protocol command replays immutable request/decision IDs rather than appending duplicates;
  10. policy failure is fail-closed;
  11. 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions