Skip to content

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

Open
tim8es wants to merge 11 commits into
mainfrom
feature/permission-engine-v0-1
Open

Permission v0.1: deterministic policy and human decision flow#22
tim8es wants to merge 11 commits into
mainfrom
feature/permission-engine-v0-1

Conversation

@tim8es

@tim8es tim8es commented Aug 29, 2026

Copy link
Copy Markdown
Owner

Purpose

Implement GitHub issue #15: the smallest deterministic Permission Engine required by MindRail protocol v0.1. Model/LLM output is never execution authority; policy authority is explicit, deterministic, versioned, and fail-closed.

Closes #15.

Scope

Implemented RequestPermission and RecordPermissionDecision for the in-memory reference runtime and protocol dispatcher.

Exact default policy semantics (PolicyRef { id: "mindrail.permission", version: "0.1.0" }):

Permission Outcome Reason code
workspace.read ALLOW policy.automatic_allow
external.publish DENY policy.denied
repository.write HUMAN_REQUIRED policy.human_required
unmatched DENY policy.no_matching_rule

RequestPermission:

  • reuses the existing Task/Session/Lease/fencing authority checker before record creation;
  • constructs and canonical-validates PermissionRequest;
  • evaluates the pure versioned policy;
  • constructs and canonical-validates sequence-1 policy PermissionDecision with system actor system:mindrail.permission-policy, exact PolicyRef, and no superseded predecessor;
  • appends request + decision only after both records are valid, providing an atomic semantic boundary in the in-memory implementation;
  • exact protocol retry replays the stored request/decision IDs and creates no duplicate;
  • policy exception, invalid PolicyRef, or invalid evaluation shape fails closed with POLICY_UNAVAILABLE and appends no records.

RecordPermissionDecision:

  • public v0.1 follow-up is human-only and only ALLOW / DENY;
  • requires expectedPreviousDecisionId to name the latest decision and requires the latest outcome to be HUMAN_REQUIRED;
  • derives basis=human, next sequence, and supersedesDecisionId;
  • rejects stale predecessor, cross-workspace request reference, non-human actor, and repeated follow-up after a terminal human decision;
  • canonical-validates before append.

Grant effectiveness is deliberately separate from audit history: an ALLOW applies only to its exact request authority tuple (workspace, task, session, lease, fencingToken) and is effective only while the existing runtime authority checker still accepts that tuple. A late human decision may finish audit history after authority loss, but cannot revive the old execution or transfer a grant to replacement execution authority.

Intentionally out of scope: OAuth/IAM/auth-provider integration, credentials/tokens, model calls, arbitrary tools, network calls, policy DSL/interpreter, persistence, HTTP/MCP transports, or Domain Contract changes.

Architecture / ADR impact

  • No architecture decision changes.
  • Relevant accepted ADRs were reviewed.
  • A new/superseding ADR is included or linked.

Details:

  • ADR-0001, ADR-0003, ADR-0004, and ADR-0005 were treated as authoritative.
  • New pure policy code is isolated in src/policy/permission-policy.ts.
  • Permission record/effectiveness logic is isolated in src/runtime/permission-service.ts.
  • in-memory-control-plane.ts has only the constructor/delegation/dispatch seam and directly reuses requireExecutorAuthority; no second execution-authority implementation was introduced.
  • Protocol edits are limited to the two v0.1 commands and bounded canonical fields.
  • main remained exactly at common base 87fbfcf2ed738071f648a3b94bfff1df1f235dba during final diff review, so there was no current parallel-stream merge conflict. Runtime/protocol files are expected integration hotspots if sibling streams merge first.

Verification evidence

Mandatory TDD RED was obtained before production implementation:

GitHub Actions run 33258164017 @ 934b7ec7fd50cbb16bebec3da3874f7cb4416526
pnpm install --frozen-lockfile -> PASS
pnpm exec vitest run test/runtime/permission-engine.test.ts -> RED, 9/9 failed for the intended missing permission surface (`requestPermission` absent / RequestPermission INVALID_INPUT)
pnpm check -> skipped after RED
pnpm test:coverage -> skipped after RED

Fresh GREEN branch verification after implementation, formatting, and invalid-policy regressions:

GitHub Actions run 33258675982 @ 1ecea722f3620f1d95f83f8c878d33dc615d5ece
pnpm install --frozen-lockfile -> PASS
focused permission regressions -> PASS, 2 files / 11 tests
pnpm check -> PASS, 12 files / 40 tests
pnpm test:coverage -> PASS, 12 files / 40 tests
coverage -> 83.48% statements, 67.93% branches, 94.28% functions, 83.86% lines overall
src/policy -> 100% statements/branches/functions/lines
src/runtime/permission-service.ts -> 95.89% statements/lines, 82.14% branches, 100% functions

Permanent PR Quality verification on the final feature head:

GitHub Actions Quality run 33258804556 / job 99117069526
feature head: ccfeb44983c6504629a1a7139e8dea0d75dee1f5
PR merge ref tested: 046728fa546bd72e138ed4e8685f53d637451cef
pnpm install --frozen-lockfile -> PASS
pnpm check -> PASS, 12 test files / 40 tests
pnpm test:coverage -> PASS, 12 test files / 40 tests
coverage -> 83.48% statements, 67.93% branches, 94.28% functions, 83.86% lines overall

Documentation

  • docs/CURRENT_STATE.md remains accurate.
  • Architecture/docs were updated where repository truth changed.
  • Roadmap text is not used as evidence of implementation.

Security / permissions

No credentials, external IAM authority, network access, or persistence were added. A MindRail ALLOW does not create credentials and cannot bypass host/IAM/sandbox/tool approval. HUMAN_REQUIRED creates no grant. Policy authority is system-authored and deterministic; model/LLM output is not consulted.

Final diff review found:

  • no model-based authority;
  • no duplicate Task/Session/Lease/fencing authority implementation;
  • no permission transfer path across Lease/fence authority;
  • no arbitrary metadata/payload bags added to permission records or commands;
  • no temporary branch-only TDD/formatter/integration workflow or transformation script in the final diff.

The permanent Quality workflow remains read-only and now executes pnpm test:coverage after pnpm check, so the required frozen install, full check, and coverage commands are all permanent PR-gate evidence.

Limitations / unverified claims

  • Runtime state remains in-memory/single-process; no persistence semantics are implemented here.
  • Policy v0.1 is intentionally hard-coded and small; there is no DSL, dynamic-code policy engine, IAM system, or credential manager.
  • Actor authentication/identity proof remains a transport/deployment concern; this slice enforces the protocol/domain actor type and human-only follow-up semantics but does not add an auth provider.
  • An ALLOW is only a MindRail decision record/effectiveness check. External hosts, IAM, sandboxes, and tools retain their own authority and approval requirements.
  • No local checkout command execution is claimed: this environment had no mounted repository checkout, so all stated command evidence comes from executed GitHub Actions on the exact commits/merge ref shown.

Review gate

  • Scope is minimal and coherent.
  • No speculative dependency/framework/abstraction was introduced.
  • No unexecuted check is described as passing.
  • New persistent concepts/boundaries have ADR coverage (no new persistence concept introduced in this slice).

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

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.

Permission v0.1: deterministic policy and human decision flow

1 participant