Skip to content

Runtime Engine ​

Policies are Markdown files, but enforcement happens in code. The runtime loads every POLICY.md in scope, evaluates intents against all of them, and returns the most severe decision.

Note: the @sidianlabs/policy package is not on npm yet — run the CLI from a clone (npm install && npm run build, then node bin/policy.js).

The pieces ​

ModuleFileJob
PolicyManagersrc/policyManager.tsDiscovers, loads, and lists policies
AuthorizationEnginesrc/authorizationEngine.tsEvaluates one intent against one policy set
PolicyValidatorsrc/validate.tsSchema, operator, and YAML checking
Installersrc/installer.tsPulls policies from GitHub repos
AgentsMdsrc/agentsmd.tsRegenerates the AGENTS.md policy block
Parsersrc/parser.tsFrontmatter + Markdown body parsing
Codex adapterssrc/adapters/codex.tsExports to OpenAI Codex formats

Load and evaluate ​

typescript
import { createPolicyManager } from '@sidianlabs/policy';

const manager = createPolicyManager();
manager.load(); // searches working dir for POLICY.md files

const engine = manager.createAuthorizationEngine();
const decision = engine.evaluate({
  id: '1',
  workRunId: 'run-1',
  workerId: 'agent-1',
  specialist: 'frontend',
  actionType: 'tool',
  capability: 'file.write',
  riskLevel: 'medium',
  payload: { path: 'src/.env' },
  requester: { type: 'user', id: 'user-1' },
  createdAt: Date.now(),
});

// decision.action === 'deny'
// decision.reason === 'Never write .env or secret files'

Inject into system prompts ​

Policies double as LLM context - the agent reads the same rules the engine enforces:

typescript
import { buildPoliciesContext } from '@sidianlabs/policy';

const prompt = buildPoliciesContext(manager);
// prepend to the agent system prompt

Composite engines ​

Stack an org policy over a repo policy. The composite returns the most severe decision across every engine:

deny > require_approval > allow
typescript
import { createCompositeAuthorizationEngine, createAuthorizationEngine } from '@sidianlabs/policy';

const filePolicyEngine = manager.createAuthorizationEngine();
const orgPolicyEngine = createAuthorizationEngine({ document: orgPolicy });
const final = createCompositeAuthorizationEngine([orgPolicyEngine, filePolicyEngine]);

const result = final.evaluate(intent);

Validation ​

PolicyValidator checks required fields, valid operators, and YAML syntax. With --strict, unknown fields are rejected:

bash
npx @sidianlabs/policy validate POLICY.md --strict

Distribution: install and sync ​

bash
# Pull a team's guardrails into .policies/
npx @sidianlabs/policy install SidianLabs/payment-guardrails

# Regenerate the AGENTS.md <policy_system> block
npx @sidianlabs/policy sync

# See every discovered policy
npx @sidianlabs/policy list

OpenAI Codex adapters ​

Export policies to the formats Codex understands:

typescript
import { toCodexExecpolicy, toCodexGuardianPrompt } from '@sidianlabs/policy/adapters/codex';

// Starlark execpolicy for the Codex runtime
const execpolicy = toCodexExecpolicy(manager.list());

// Guardian prompt text for the Codex harness
const guardianPrompt = toCodexGuardianPrompt(manager.list());

Scope stacking ​

Discovery order is project, then named directories (.policies/payment/), then skill-local files (.devin/skills/<skill>/POLICY.md). A skill policy can be stricter than its project policy; evaluation combines all in-scope policies with most-severe-wins, so a skill-local deny always beats a project-level allow.

Released under the Apache 2.0 License.