generated from coulomb/repo-seed
Implement local runtime persistence and policy gates
This commit is contained in:
@@ -146,6 +146,49 @@ The slice should emit plans first, not mutate durable memory by surprise.
|
||||
Durable writes, external adapters, live LLM extraction, vector retrieval, and
|
||||
service deployment can follow once the plan model is stable.
|
||||
|
||||
## Local Runtime Facade
|
||||
|
||||
The second implementation slice adds a local facade, `PhaseMemoryRuntime`, over
|
||||
the deterministic core. The facade is not a service runner. It is the small
|
||||
application surface that adjacent tools can call before a service deployment
|
||||
exists.
|
||||
|
||||
Runtime operations currently include:
|
||||
|
||||
- profile import
|
||||
- graph import
|
||||
- profile execution planning
|
||||
- graph lifecycle planning
|
||||
- graph activation planning
|
||||
- package compilation handoff through `ContextPackageCompiler`
|
||||
|
||||
Each operation returns a JSON-serializable envelope with:
|
||||
|
||||
- `schema_version`
|
||||
- `operation_id`
|
||||
- `operation`
|
||||
- `dry_run`
|
||||
- `valid`
|
||||
- `subject`
|
||||
- `source`
|
||||
- `policy_decision`
|
||||
- `audit_receipt`
|
||||
- `diagnostics`
|
||||
- `data`
|
||||
|
||||
The local CLI exposes the same facade for fixtures and developer workflows:
|
||||
|
||||
```bash
|
||||
phase-memory profile plan profile.json
|
||||
phase-memory graph lifecycle graph.json --stale-after-days 7 --delete-after-days 30
|
||||
phase-memory graph activate graph.json --max-items 3 --max-tokens 60
|
||||
```
|
||||
|
||||
The default implementation uses in-memory stores, an allow-all local policy
|
||||
gateway, a recording audit sink, and a noop context-package compiler. These are
|
||||
test and integration adapters, not a claim that durable persistence, policy, or
|
||||
package internals belong in this repository.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Should `phase-memory` depend directly on `markitect-tool` for validation, or
|
||||
|
||||
91
docs/local-persistence.md
Normal file
91
docs/local-persistence.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# Local Persistence
|
||||
|
||||
`phase-memory` can run against a versioned local file workspace. This is a
|
||||
developer and integration adapter, not a production graph database.
|
||||
|
||||
## Layout
|
||||
|
||||
```text
|
||||
memory-store/
|
||||
phase-memory.json
|
||||
profiles/
|
||||
<profile-id>.json
|
||||
nodes/
|
||||
<node-id>.json
|
||||
edges/
|
||||
<edge-id>.json
|
||||
paths/
|
||||
<path-id>.json
|
||||
activations/
|
||||
events.jsonl
|
||||
audit.jsonl
|
||||
```
|
||||
|
||||
The root `phase-memory.json` declares:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": "phase_memory.local_store.v1"
|
||||
}
|
||||
```
|
||||
|
||||
Profiles, nodes, edges, and paths are stored as deterministic JSON files.
|
||||
Events and audit records are append-only JSONL files. The current local runtime
|
||||
does not compact, delete, or rewrite append-only logs.
|
||||
|
||||
## CLI
|
||||
|
||||
Import local fixtures:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m phase_memory.cli store import \
|
||||
--store .phase-memory-local \
|
||||
--profile tests/fixtures/memory-profile.json \
|
||||
--graph tests/fixtures/memory-graph.json
|
||||
```
|
||||
|
||||
Export a Markitect-compatible graph envelope:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m phase_memory.cli store export \
|
||||
--store .phase-memory-local \
|
||||
--graph-id local-dev
|
||||
```
|
||||
|
||||
Inspect repair diagnostics:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m phase_memory.cli store repair \
|
||||
--store .phase-memory-local
|
||||
```
|
||||
|
||||
Repair diagnostics report malformed JSONL event lines, unknown event schema
|
||||
versions, missing edge endpoints, and path records that reference events not
|
||||
present in the event log.
|
||||
|
||||
## Paths
|
||||
|
||||
Conversational paths are structured records, not transcript blobs. A path can
|
||||
record:
|
||||
|
||||
- `path_id`
|
||||
- `parent_path_id`
|
||||
- ordered `event_ids`
|
||||
- active, merged, abandoned, or compacted state
|
||||
- merge target
|
||||
- abandoned reason
|
||||
- compacted summary id
|
||||
|
||||
Helper functions in `phase_memory.paths` create, branch, merge, abandon, and
|
||||
compact paths while also producing structured path events for the fluid memory
|
||||
event log.
|
||||
|
||||
## Review-Gated Apply
|
||||
|
||||
Lifecycle planning remains dry-run by default. The runtime exposes an optional
|
||||
`apply_lifecycle_actions` operation for local stores. Actions marked
|
||||
`requires_review` are denied unless the caller provides an explicit
|
||||
`approval_marker`.
|
||||
|
||||
This keeps the local adapter useful for development while preserving the
|
||||
project rule that durable memory changes must be inspectable and deliberate.
|
||||
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