Capture any AI capability into a vetted roster; every invoke is gated, bounded, and provable.
Phylact is a local-first governance layer for the capabilities your AI agents reach for. It does not try to police an agent's whole life — not every keystroke, shell command, or native file edit. The thesis is sharper: govern capabilities, not agents.
A capability is a rostered MCP server, skill, or agent-backed tool with a known contract. When Claude Code, Codex, Hermes, or a human invokes that capability, Phylact normalizes the request, evaluates policy, enforces bounds where the boundary is observable, and writes the result into a tamper-evident chain. You get the thing most agent stacks are missing: an allow-listed runtime path plus a verifiable record of what was allowed, what was denied, and why.
v0.1 · single Python package · zero third-party dependencies (stdlib only) · Apache-2.0 · local-first.
Modern agent setups grow sideways fast. One week you have a coding assistant; the next it can call MCP servers, run local tools, delegate to other agents, touch files, hit the network, and mutate repos. The useful part is the same as the dangerous part: agents are valuable because they reach capabilities outside the model.
Most governance proposals aim at the wrong unit — they try to intercept every host-agent action. That gets brittle: each agent has its own hook surface, payload format, sandbox story, and escape hatch. You end up building a universal agent police force and still miss the real boundary: the external capability being invoked.
Phylact flips the control plane. Capture capabilities into a roster; make every invoke pass through one fail-closed, policy-backed, audit-emitting gate. If a request is outside the capability's allowed scope, it never reaches the backend. If it's allowed, the chain records the decision before execution. The result isn't "trust the agent" — it's "trust only these capabilities, through this path, under this policy, with this proof trail."
PHYLACT_PY=python3 bash scripts/demo.shWhat it does — a filesystem MCP capability, captured and gated:
phylact init # ~/.phylact: policy, machine-id, chain
phylact capture mcp.fs --kind mcp \
--upstream "python examples/mock_mcp.py" --tool write_file
phylact gate mcp.fs --tier unstable # candidate -> sealed
phylact promote mcp.fs # sealed -> commandable (now invokable)
# a safe write — ALLOWED, forwarded to the real server, and chained
phylact invoke mcp.fs --tool write_file --args '{"path":"/tmp/notes.txt","content":"hi"}'
# a write to ~/.ssh — DENIED before the server ever sees it
phylact invoke mcp.fs --tool write_file --args '{"path":"~/.ssh/authorized_keys","content":"x"}'
# ⛔ Phylact denied this capability action: Credential and shell-init files cannot be touched.
# rule: deny-credential-path-write
# proof (chain): d21fbf83730848b3…The punchline isn't just that the write was blocked — it's that the denial is provable:
phylact chain tail mcp.fs # the deny event, hash-linked to the prior event
phylact verify mcp.fs # recomputes the chain; edit one byte and it fails at that seqA captured MCP capability tried to write ~/.ssh; Phylact blocked it at the capability
boundary; the refusal is visible, hash-linked, and independently verifiable.
The roster records what capabilities exist and their state: captured → gated → promoted → retired/drifted. A capability isn't commandable just because it exists — it must pass a gate (contract + tier) and an explicit promote.
The kernel is the enforcement spine. Each invoke becomes a canonical action (mcp.call,
file.write, http.request, file.recursive_delete, … — a closed set). Unknown actions
default to deny. Deny rules win before allow rules. Missing or invalid policy means
deny-all. Argument shapes corroborate the action type, so a write-shaped call named read_file
is still treated as a write.
The chain is the proof layer. Every capture, gate, promote, invoke, drift, retire, and
denial becomes canonical JSON, hash-linked per capability, stored as append-only JSONL.
verify walks the log, recomputes each hash, and checks sequence continuity. Secret-shaped
arguments are hashed before they ever land in an audit payload.
For MCP, enforcement is honest because the proxy is in the wire: one-shot invoke gates the
call boundary, but filesystem/network side effects are only truly enforceable when the
capability is reached through phylact serve mcp — which is why the flagship demo uses the
proxy path. The same capability invoked from Claude Code, Codex, or Hermes lands in one
chain, with the driver recorded per event — proving Phylact governs the capability, not the
agent wearing it.
Phylact was built FDE-style: start from a user pain, reduce it to a crisp system boundary,
harden the boundary adversarially, ship the smallest credible demo. The architecture came out
of a six-dimension ultracode specification pass (CLI · kernel · hash chain · MCP proxy ·
agent hooks · the roster seam), each dimension reviewed as if it were trying to fail open.
That review caught 18 blocking issues before implementation — spoofable driver identity, policy-parser risk, fabricated sign-off fields, hash-canonicalization drift, MCP schema injection, raw-endpoint bypass, default-deny bootstrapping, dedup under-counting, SQLite contention, proxy id correlation, protected-path symlink escapes, and more. The fixes changed the product: YAML → JSON (stdlib-only, no parser risk); universal host-agent interception cut; MCP made day one because the proxy is a real boundary; one canonical encoder for both storage and hashing; denials emitted before forwarding; scope-widening policy fields rejected; sensitive arguments redacted before audit.
Clean-room Python, zero runtime dependencies (sqlite3, hashlib, json, argparse,
subprocess, shlex, fcntl). The roster layer is reused surgically; the governance kernel
is rebuilt around fail-closed evaluation and verifiable audit.
v0.1, in active development. Lineage: the capability layer began as an internal project
("Geto") and its governance kernel draws on the clean-roomed Chitin execution kernel. See
docs/ for the design and the kernel essence.
Apache-2.0. See LICENSE and NOTICE.