generated from coulomb/repo-seed
Implement local runtime persistence and policy gates
This commit is contained in:
113
docs/policy-audit.md
Normal file
113
docs/policy-audit.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Policy And Audit
|
||||
|
||||
`phase-memory` keeps policy enforcement adapter-based. The local runtime
|
||||
defines deterministic operation points, review records, audit envelopes, and
|
||||
redaction behavior without becoming an identity or authorization platform.
|
||||
|
||||
## Operation Points
|
||||
|
||||
Canonical operation names live in `phase_memory.policy.MemoryOperation`.
|
||||
|
||||
Current operation points include:
|
||||
|
||||
- `profile.import`
|
||||
- `graph.import`
|
||||
- `node.read`
|
||||
- `event.read`
|
||||
- `profile.plan`
|
||||
- `graph.lifecycle.plan`
|
||||
- `graph.activation.plan`
|
||||
- `package.compile`
|
||||
- `lifecycle.apply`
|
||||
- `memory.stabilize`
|
||||
- `memory.compact`
|
||||
- `memory.refresh`
|
||||
- `memory.delete_request`
|
||||
- `memory.archive`
|
||||
- `graph.export`
|
||||
- `store.repair.diagnostics`
|
||||
|
||||
Runtime operations call the configured `PolicyGateway` before emitting an
|
||||
envelope. The default local adapter is allow-all and exists only for
|
||||
dependency-light tests and local development.
|
||||
|
||||
## Review Records
|
||||
|
||||
Review-required lifecycle actions fail closed unless a caller provides an
|
||||
approved review record or the legacy local `approval_marker` shorthand.
|
||||
|
||||
Review records capture:
|
||||
|
||||
- review id
|
||||
- reviewed action id
|
||||
- reviewer
|
||||
- approval or rejection
|
||||
- timestamp
|
||||
- reason
|
||||
- obligations
|
||||
- source digests
|
||||
|
||||
The reviewed action id is deterministic:
|
||||
|
||||
```text
|
||||
action:<digest-of-lifecycle-action>
|
||||
```
|
||||
|
||||
This lets the runtime reject a review record that was issued for a different
|
||||
planned action.
|
||||
|
||||
## Activation Policy
|
||||
|
||||
Activation planning can receive a local policy context:
|
||||
|
||||
```python
|
||||
runtime.plan_activation(
|
||||
graph,
|
||||
max_items=4,
|
||||
max_tokens=80,
|
||||
policy_context={
|
||||
"required_labels": ["project-local"],
|
||||
"denied_labels": ["restricted"],
|
||||
"trust_zone": "local",
|
||||
"secrets_allowed": False,
|
||||
"approved_reauthorizations": [],
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
Nodes denied by policy are omitted before selection. The runtime returns
|
||||
diagnostics with code `activation_policy_denied` and a deterministic redacted
|
||||
record where policy-sensitive fields and text are replaced with `[REDACTED]`.
|
||||
|
||||
## Audit Envelope
|
||||
|
||||
Audit events use schema `phase_memory.audit.event.v1` and include:
|
||||
|
||||
- operation id
|
||||
- operation kind
|
||||
- subject id
|
||||
- profile id
|
||||
- graph id
|
||||
- policy decision
|
||||
- dry-run flag
|
||||
- planned action id
|
||||
- actor label
|
||||
- timestamp
|
||||
- source reference
|
||||
|
||||
The local audit sinks record these events either in memory or as append-only
|
||||
JSONL. External audit systems should implement the `AuditSink` port.
|
||||
|
||||
## Boundaries
|
||||
|
||||
This repository does not own:
|
||||
|
||||
- user identity
|
||||
- enterprise policy languages
|
||||
- remote policy decision points
|
||||
- long-term audit retention
|
||||
- legal hold or compliance workflows
|
||||
|
||||
Those belong behind adapters. `phase-memory` owns the memory-native points
|
||||
where policy, review, redaction, and audit decisions must be requested and
|
||||
explained.
|
||||
Reference in New Issue
Block a user