plan-auditor 2.1.0__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/.gitignore +10 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/CHANGELOG.md +24 -5
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/PKG-INFO +1 -1
- plan_auditor-2.2.0/docs/deployment-isolation.md +59 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/docs/threat-model.md +42 -24
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/pyproject.toml +2 -1
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/scripts/audit_check.py +722 -232
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/scripts/integrity.py +2 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/scripts/plan_graph.py +29 -20
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/__init__.py +3 -1
- plan_auditor-2.2.0/supervisor/agents_hardening.py +382 -0
- plan_auditor-2.2.0/supervisor/audit_session.py +140 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/cli.py +100 -20
- plan_auditor-2.2.0/supervisor/config.py +217 -0
- plan_auditor-2.2.0/supervisor/contracts.py +76 -0
- plan_auditor-2.2.0/supervisor/control_plane.py +88 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/daemon.py +64 -4
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/evidence.py +132 -79
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/integrity.py +16 -3
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/lifecycle.py +3 -1
- plan_auditor-2.2.0/supervisor/lock_hardening.py +144 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/orchestrator.py +50 -3
- plan_auditor-2.2.0/supervisor/plans.py +107 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/policies.py +72 -7
- plan_auditor-2.2.0/supervisor/request_contract.py +367 -0
- plan_auditor-2.2.0/supervisor/seal_migration.py +157 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/sealing.py +145 -44
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/workspace.py +22 -7
- plan_auditor-2.2.0/tests/request_fixture.py +47 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_agent_registry_chain.py +4 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_audit_check.py +1 -1
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_cli.py +4 -2
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_daemon.py +43 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_dependency_graph.py +7 -4
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_extra_layers.py +4 -2
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_full_contract_hardening.py +2 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_hooks.py +2 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_integration_hardening.py +5 -1
- plan_auditor-2.2.0/tests/test_registry_lock_partial.py +40 -0
- plan_auditor-2.2.0/tests/test_request_contract_hardening.py +108 -0
- plan_auditor-2.2.0/tests/test_root_cause_fixes_v220.py +336 -0
- plan_auditor-2.2.0/tests/test_runtime_root_hardening.py +275 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/wheel_cli_smoke.py +60 -0
- plan_auditor-2.1.0/supervisor/agents_hardening.py +0 -138
- plan_auditor-2.1.0/supervisor/config.py +0 -146
- plan_auditor-2.1.0/supervisor/contracts.py +0 -49
- plan_auditor-2.1.0/supervisor/plans.py +0 -87
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/CONTRIBUTING.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/LICENSE +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/README.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/SKILL.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/docs/architecture.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/docs/dependency-graph.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/docs/integrations.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/examples/fib/.plan-auditor/plan.json +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/examples/fib/fib.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/examples/fib/test_fib.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/hooks/README.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/references/plan-format.md +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/scripts/__init__.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/scripts/stop_gate.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/adversarial.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/agents.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/coverage.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/events.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/gate.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/goals.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/plan_verifier.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/priority.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/requirements.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/supervisor/watchdog.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_adversarial.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_agents_gate.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_authenticated_integrity.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_core_layers.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_events.py +0 -0
- {plan_auditor-2.1.0 → plan_auditor-2.2.0}/tests/test_failure_injection.py +0 -0
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
__pycache__/
|
|
2
2
|
*.pyc
|
|
3
3
|
.pytest_cache/
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
*.egg-info/
|
|
4
7
|
.plan-auditor/evidence.jsonl
|
|
8
|
+
.plan-auditor/evidence.head.json
|
|
9
|
+
.plan-auditor/evidence.write.lock
|
|
10
|
+
.plan-auditor/audit.freeze.lock
|
|
11
|
+
.plan-auditor/request.json
|
|
12
|
+
.plan-auditor/activation.json
|
|
13
|
+
.plan-auditor/integrity.json
|
|
5
14
|
.plan-auditor/*.tmp
|
|
6
15
|
.plan-auditor/archive/
|
|
7
16
|
.plan-auditor/snapshots/
|
|
8
17
|
.plan-auditor/seal.json
|
|
18
|
+
.plan-auditor/seals/
|
|
9
19
|
.plan-auditor/supervisor-runtime.json
|
|
10
20
|
.plan-auditor/supervisor-assessment.json
|
|
11
21
|
.plan-auditor/supervisor.stop
|
|
@@ -1,15 +1,34 @@
|
|
|
1
|
+
## Unreleased
|
|
2
|
+
|
|
3
|
+
- None yet.
|
|
4
|
+
|
|
1
5
|
# Changelog
|
|
2
6
|
|
|
7
|
+
## v2.2.0 — 2026-09-05
|
|
8
|
+
|
|
9
|
+
- **Physical control-plane confinement:** existing `.plan-auditor`, plan, seal, request/activation and policy path components are inspected with `lstat`; symlinked parents/leaves cannot redefine the workspace trust root.
|
|
10
|
+
- **Policy read confinement:** `load_config` authorizes only symlink-free workspace policy directories before policy loading; a resolved external symlink target is rejected before its files are read.
|
|
11
|
+
- **Sealed scope freeze:** automatic monotonic strengthening remains available for extra deterministic checks/prerequisites, but new steps, requirements, tools, coverage assignments or declared outputs now require a new host-approved request generation.
|
|
12
|
+
- **Safe v3→v4 migration:** `plan-auditor-migrate-seal` provides a representation-only migration path for exact full-contract v3 seals. It requires authoritative request alignment and refuses any plan-scope change.
|
|
13
|
+
- **Seal self-consistency:** v3/v4 seals validate their contract hash and criteria count on load/save before being trusted or authenticated.
|
|
14
|
+
- **Streaming evidence verification:** JSONL verification, hashing and HMAC migration retain one record/chunk at a time instead of reading complete evidence/archive files into RAM.
|
|
15
|
+
- **PID-aware registry locking:** registry transaction locks carry PID + random token; live owners are never evicted because of age alone, and stale cleanup requires a provably dead PID plus unchanged lock identity.
|
|
16
|
+
- **Activation semantics:** a lone `.plan-auditor/supervisor.json`, log or cache no longer makes a plans-free workspace look like an activated failed task; request/seal/evidence/plan/integrity/registry state still prevents deletion from degrading to `NO_PLAN`.
|
|
17
|
+
- **Single audit freeze implementation:** the unused `workspace.audit.lock` implementation was removed; `audit.freeze.lock`/`final_audit_session` remains the sole workspace final-audit freeze path.
|
|
18
|
+
- **Version identity:** source/package version advances to `2.2.0`, preventing post-v2.1.0 hardening from producing a different wheel under the already-published `2.1.0` version.
|
|
19
|
+
- **Trust-boundary documentation:** deliberate same-OS-user interference is explicitly treated as an OS isolation problem; separate account/container/VM deployment is required when that attacker is in scope.
|
|
20
|
+
- **Regression coverage:** new tests cover plan/policy symlink escapes, scope expansion, config-only activation, PID-aware registry locks, streaming evidence verification and exact legacy-seal migration.
|
|
21
|
+
|
|
3
22
|
## v2.1.0 — 2026-09-05
|
|
4
23
|
|
|
5
24
|
- **Aggregate multi-plan completion:** the integrated supervisor now enumerates the default plan and every safe `.plan-auditor/plans/<name>.json` plan. Global PASS requires every active plan to PASS; a passing default plan cannot hide an unfinished named plan, and a named-only workspace is no longer misclassified as `NO_PLAN`.
|
|
6
25
|
- **Explicit requirement coverage:** Supervisor Mode requires explicit requirements and deterministic `covers` links from steps. Every `must`/`should` requirement must be covered; omitted user requirements, unknown coverage IDs and duplicate requirement contracts block plan approval/PASS.
|
|
7
|
-
- **Full-contract format-v3 seals:** seals
|
|
8
|
-
- **Authenticated seals:** external-key HMAC integrity
|
|
26
|
+
- **Full-contract format-v3 seals:** seals bind task, requirements, required tools, step identity/order/title, requirement coverage, dependencies, required outputs, output contracts/checks, step checks, and the supervisor profile/mode/tier/policy fingerprint. Existing criteria may only be strengthened.
|
|
27
|
+
- **Authenticated seals:** external-key HMAC integrity authenticates plan seals in addition to evidence, checkpoints, registry state and the integrity marker. Seal tampering or missing/wrong key material fails closed after integrity initialization.
|
|
9
28
|
- **Configuration/policy downgrade prevention:** malformed supervisor configuration and configured policy files are explicit blocking errors. Profile/mode/tier and policy-file fingerprint are part of the sealed environment contract, so a post-seal downgrade is detected.
|
|
10
29
|
- **Evidence concurrency and rotation continuity:** evidence append/rotation uses a cross-process exclusive lock, active evidence links the latest archive tail, and failed-attempt limits are counted across archived plus active evidence instead of resetting after rotation.
|
|
11
|
-
- **Complete evidence verification:** `plan-auditor evidence verify`
|
|
12
|
-
- **Safe plan addressing:** named plan IDs are validated as safe basenames and cannot
|
|
30
|
+
- **Complete evidence verification:** `plan-auditor evidence verify` checks both active evidence and anchored archives.
|
|
31
|
+
- **Safe plan addressing:** named plan IDs are validated as safe basenames and cannot use lexical `..` traversal outside `.plan-auditor/plans`.
|
|
13
32
|
- **Canonical multi-agent ownership:** agent IDs are safe basenames and ownership paths are canonical workspace-relative paths before conflict comparison, preventing alternate spellings from evading `parallel-strict` overlap detection.
|
|
14
33
|
- **Transactional full-scope rollback:** default snapshots carry a manifest with file type, mode and hash; rollback restores that state and removes files introduced after the snapshot. Explicit snapshot lists remain intentionally scoped.
|
|
15
34
|
- **Stronger fresh-audit fingerprint:** workspace fingerprints include directories, file type and mode/executable bits in addition to contents and symlink targets.
|
|
@@ -20,7 +39,7 @@
|
|
|
20
39
|
- **Three-platform packaging and release gates:** real wheels are built and installed in clean virtual environments on Ubuntu, Windows and macOS. Smoke tests exercise multi-plan discovery, DAG/output dependencies, requirement coverage, full-contract seals, external-key HMAC, integrated audit, doctor, and evidence/integrity CLI paths. PyPI publishing waits for the same three-platform wheel preflight.
|
|
21
40
|
- **Versioning:** development version advanced to `2.1.0` so the hardened source cannot be confused with the already-published `2.0.2` artifact.
|
|
22
41
|
- **Regression hardening:** dedicated failure-injection tests cover named-plan bypasses, seal-contract weakening, environment downgrade, HMAC seal tampering, invalid config/policies, path traversal, evidence races/rotation/retry history, active-log tampering, rollback cleanup, executable-bit fingerprint changes, canonical agent conflicts, missing tools and bounded verifier output.
|
|
23
|
-
- **Observational final audit:** a full audit
|
|
42
|
+
- **Observational final audit:** a full audit fails if a verifier mutates product workspace content, type, or mode. Verification must prove pre-existing implementation state rather than creating the claimed result during the audit itself.
|
|
24
43
|
|
|
25
44
|
## v2.0.2 — 2026-09-05
|
|
26
45
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: plan-auditor
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: Independent multi-layer verification supervisor for AI coding agents
|
|
5
5
|
Project-URL: Homepage, https://github.com/Furox-Art/plan-auditor
|
|
6
6
|
Project-URL: Repository, https://github.com/Furox-Art/plan-auditor
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Deployment isolation for a deliberately malicious agent
|
|
2
|
+
|
|
3
|
+
Plan Auditor's normal mode assumes the AI agent may be wrong or overconfident but
|
|
4
|
+
does not have an OS security boundary from the deterministic supervisor. If the
|
|
5
|
+
agent process itself is deliberately malicious, a same-user Python lock/HMAC
|
|
6
|
+
setup is not a sufficient root of trust: the process can ignore cooperative lock
|
|
7
|
+
files and may be able to read same-user key material.
|
|
8
|
+
|
|
9
|
+
## Required boundary
|
|
10
|
+
|
|
11
|
+
For that threat model, run the verifier under a different OS/container identity:
|
|
12
|
+
|
|
13
|
+
1. **Supervisor identity** owns the external HMAC key and Plan Auditor control
|
|
14
|
+
state. The agent identity must not be able to read the key.
|
|
15
|
+
2. **Agent identity** gets only the repository/product write permissions needed
|
|
16
|
+
for implementation. It must not be able to modify the supervisor executable,
|
|
17
|
+
key file, service configuration or host approval source.
|
|
18
|
+
3. The supervisor receives read access to product state plus the narrowly scoped
|
|
19
|
+
writes required for `.plan-auditor` evidence/seals/registry.
|
|
20
|
+
4. Host request activation is performed by the trusted/user side, not by the
|
|
21
|
+
untrusted agent identity.
|
|
22
|
+
5. The final audit runs after cooperating agent processes are quiescent. For a
|
|
23
|
+
hostile agent, the OS/container boundary—not `audit.freeze.lock`—prevents
|
|
24
|
+
concurrent mutation of trusted control state.
|
|
25
|
+
|
|
26
|
+
## Linux example boundary
|
|
27
|
+
|
|
28
|
+
A typical layout uses two users, for example `pa-agent` and `pa-supervisor`.
|
|
29
|
+
Keep the HMAC key in a file readable only by `pa-supervisor` and start the
|
|
30
|
+
supervisor service with:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
PLAN_AUDITOR_HMAC_KEY_FILE=/var/lib/plan-auditor/keys/project.key
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The key file should not be inside the workspace. Use normal filesystem ACLs,
|
|
37
|
+
service sandboxing or a container mount policy so `pa-agent` cannot read it.
|
|
38
|
+
|
|
39
|
+
## Container/VM boundary
|
|
40
|
+
|
|
41
|
+
For stronger isolation, place the deterministic supervisor in a separate
|
|
42
|
+
container/VM. Mount product state read-only for the final audit when practical,
|
|
43
|
+
and mount only the Plan Auditor control-state directory writable by the
|
|
44
|
+
supervisor. Do not share the HMAC secret with the agent container.
|
|
45
|
+
|
|
46
|
+
## Windows boundary
|
|
47
|
+
|
|
48
|
+
Use a distinct Windows account/service identity for the supervisor and ACL the
|
|
49
|
+
key file so the agent account cannot read it. The same principle applies: a
|
|
50
|
+
process running under the same account is not considered isolated merely because
|
|
51
|
+
it is a different PID.
|
|
52
|
+
|
|
53
|
+
## What this changes
|
|
54
|
+
|
|
55
|
+
This deployment boundary upgrades the external-HMAC/freeze controls from
|
|
56
|
+
workspace tamper detection to a meaningful adversarial boundary. Without it, the
|
|
57
|
+
project intentionally makes the narrower claim documented in `threat-model.md`:
|
|
58
|
+
it detects buggy/overconfident agent behavior and workspace tampering within the
|
|
59
|
+
stated same-user trust assumptions; it is not a kernel sandbox.
|
|
@@ -13,8 +13,9 @@ normal installation both processes may run as the same OS user. Plan Auditor is
|
|
|
13
13
|
|
|
14
14
|
For the normal “buggy/overconfident agent” threat model, deterministic evidence,
|
|
15
15
|
full-contract sealing, requirement coverage and fail-closed aggregation are the
|
|
16
|
-
main controls.
|
|
17
|
-
|
|
16
|
+
main controls. A deliberately malicious process with the same OS credentials is a
|
|
17
|
+
different trust boundary: use a separate OS account/container/VM and keep the HMAC
|
|
18
|
+
key inaccessible to the untrusted account when that adversary is in scope.
|
|
18
19
|
|
|
19
20
|
## Trust model
|
|
20
21
|
|
|
@@ -25,7 +26,7 @@ deliberately malicious process with the same credentials.
|
|
|
25
26
|
| Repository/product files | untrusted until checked |
|
|
26
27
|
| Plan requirements and verification contract | trusted only after full-contract seal |
|
|
27
28
|
| Verification commands/build scripts | executable code; results are evidence, not inherently trustworthy semantics |
|
|
28
|
-
| User configuration/policies | trusted intent, but syntax
|
|
29
|
+
| User configuration/policies | trusted intent, but syntax and physical path confinement are validated fail-closed |
|
|
29
30
|
| External HMAC key | trusted only while inaccessible to an untrusted forger |
|
|
30
31
|
|
|
31
32
|
## Main failure/attack classes
|
|
@@ -35,13 +36,14 @@ deliberately malicious process with the same credentials.
|
|
|
35
36
|
3. AI skips a prerequisite or consumes an unverified intermediate result.
|
|
36
37
|
4. AI marks a step `verified` without real evidence.
|
|
37
38
|
5. AI weakens checks/dependencies/coverage after approval.
|
|
38
|
-
6.
|
|
39
|
-
7.
|
|
40
|
-
8.
|
|
41
|
-
9.
|
|
42
|
-
10.
|
|
43
|
-
11.
|
|
44
|
-
12.
|
|
39
|
+
6. AI expands approved scope by adding steps/requirements/tools/outputs after sealing.
|
|
40
|
+
7. A named plan is left unfinished while a default plan passes.
|
|
41
|
+
8. Evidence is edited, truncated, reordered, raced under concurrent writers, or made pathologically large.
|
|
42
|
+
9. A verification command is unsafe or produces pathological output.
|
|
43
|
+
10. Configuration/policies are malformed, symlinked outside workspace, or downgraded after sealing.
|
|
44
|
+
11. Multi-agent file ownership uses alternate path spellings or stale-lock eviction to evade coordination.
|
|
45
|
+
12. Package behavior differs across Linux/Windows/macOS.
|
|
46
|
+
13. A malicious same-user process directly interferes with supervisor state/key material.
|
|
45
47
|
|
|
46
48
|
## Controls
|
|
47
49
|
|
|
@@ -51,14 +53,19 @@ deliberately malicious process with the same credentials.
|
|
|
51
53
|
| Hidden named plan | Integrated gate enumerates default + every safe named plan; global PASS requires ALL active plans PASS |
|
|
52
54
|
| Skipped prerequisite | DAG validation, topological full audit, `depends_on`, concrete `outputs` and `requires_outputs` rechecks |
|
|
53
55
|
| Fake `status=verified` | Status alone is never fresh-audit proof; final gate matches current checks/graph/output evidence and workspace fingerprint |
|
|
54
|
-
| Criteria weakening | Format-
|
|
55
|
-
|
|
|
56
|
+
| Criteria weakening | Format-v4 seal binds task, requirements, tools, step identity/order/title, coverage, effective DAG, outputs, verification checks and supervisor/request environment |
|
|
57
|
+
| Scope expansion | Existing sealed step/requirement/tool/coverage/output scope is frozen; only proof-strengthening checks/prerequisites may be added automatically |
|
|
58
|
+
| Legacy seal migration | `plan-auditor-migrate-seal` migrates only an exact v3 contract after authoritative-request alignment; migration cannot reseal changed scope |
|
|
59
|
+
| Config/policy downgrade | Seal binds profile/mode/tier/runtime limits/policy/request fingerprints; malformed config/policy files are blocking errors |
|
|
60
|
+
| Control-plane symlink escape | Existing `.plan-auditor`, plan, seal, request and policy path components are checked with `lstat`; symlinked control-plane roots/leaves are rejected before read/write |
|
|
56
61
|
| Command injection | Structured `argv` preferred; shell disabled by default; `shell:true` is explicit opt-in and cannot combine with `argv` |
|
|
57
|
-
| Path traversal | Workspace paths are
|
|
62
|
+
| Path traversal | Workspace paths are physically confined; named plan IDs and agent IDs are safe basenames |
|
|
58
63
|
| Agent path aliases | Ownership paths are canonical workspace-relative paths before conflict comparison |
|
|
64
|
+
| Registry lock theft | Registry write locks carry PID + random token; live writers are never evicted by age alone and stale removal requires a provably dead PID plus unchanged lock identity |
|
|
59
65
|
| Evidence concurrent writes | Cross-process evidence write lock serializes append/rotation |
|
|
66
|
+
| Evidence memory exhaustion | Evidence chain verification, hashing and HMAC migration stream records/files rather than loading whole JSONL files into RAM |
|
|
60
67
|
| Evidence history rewrite | SHA-256 `prev` chain spans rotations; active log links latest archive tail |
|
|
61
|
-
| Tail truncation / forged state | Optional external-key HMAC signs records, heads/checkpoints, registry state, integrity marker and plan seals |
|
|
68
|
+
| Tail truncation / forged state | Optional external-key HMAC signs records, heads/checkpoints, registry state, integrity marker, request activation and plan seals |
|
|
62
69
|
| Retry-cap reset by rotation | Failed attempts are counted across archived and active evidence |
|
|
63
70
|
| Rollback leftovers | Full-workspace snapshots contain a manifest; rollback restores state and prunes introduced files within full scope |
|
|
64
71
|
| File-mode drift | Workspace fingerprint includes type and POSIX mode as well as content/symlink target |
|
|
@@ -93,9 +100,18 @@ plan-auditor integrity init .
|
|
|
93
100
|
plan-auditor audit .
|
|
94
101
|
```
|
|
95
102
|
|
|
103
|
+
For an old full-contract v3 workspace, perform the representation-only migration
|
|
104
|
+
before the final v4 audit:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
plan-auditor-migrate-seal .
|
|
108
|
+
plan-auditor audit .
|
|
109
|
+
```
|
|
110
|
+
|
|
96
111
|
Initialization validates existing hash chains before authenticating them, signs
|
|
97
|
-
all active plan seals, evidence/archive records and checkpoints,
|
|
98
|
-
records/head. The signed integrity marker is written
|
|
112
|
+
all active plan seals, evidence/archive records and checkpoints, request/activation
|
|
113
|
+
metadata, and agent-registry records/head. The signed integrity marker is written
|
|
114
|
+
last.
|
|
99
115
|
|
|
100
116
|
Once initialized, missing/wrong key material, HMAC mismatch, seal tampering, tail
|
|
101
117
|
truncation or marker loss fails closed.
|
|
@@ -104,9 +120,13 @@ truncation or marker loss fails closed.
|
|
|
104
120
|
|
|
105
121
|
HMAC protects against workspace-only rewriting **only while the attacker cannot
|
|
106
122
|
obtain the key**. A same-user process that can read the environment/key file can
|
|
107
|
-
compute valid HMACs
|
|
108
|
-
|
|
109
|
-
|
|
123
|
+
compute valid HMACs and can ignore cooperative freeze files. No Python lock can
|
|
124
|
+
create a security boundary against a process with the same OS credentials.
|
|
125
|
+
|
|
126
|
+
When deliberate same-user interference is in scope, the root control is deployment
|
|
127
|
+
isolation: run the deterministic supervisor under a distinct OS identity or in a
|
|
128
|
+
separate container/VM, give the untrusted agent write access only to the intended
|
|
129
|
+
workspace/product surface, and expose the HMAC key only to the supervisor identity.
|
|
110
130
|
|
|
111
131
|
## Fail-closed terminology
|
|
112
132
|
|
|
@@ -114,9 +134,7 @@ The project does not claim “unbreakable”, “immutable”, or “perfectly s
|
|
|
114
134
|
uses these narrower guarantees:
|
|
115
135
|
|
|
116
136
|
- **deterministic evidence** — real reproducible checks rather than agent prose,
|
|
117
|
-
- **full-contract seal** — approved criteria cannot be weakened without detection,
|
|
118
|
-
- **tamper-evident/authenticated state** — modifications are detected within the
|
|
119
|
-
stated key/trust boundary,
|
|
137
|
+
- **full-contract seal** — approved criteria and scope cannot be weakened/expanded without detection/host approval,
|
|
138
|
+
- **tamper-evident/authenticated state** — modifications are detected within the stated key/trust boundary,
|
|
120
139
|
- **aggregate multi-plan gate** — all active plans participate in completion,
|
|
121
|
-
- **fail-closed** — invalid/unknown critical state resolves to FAIL/UNKNOWN rather
|
|
122
|
-
than PASS.
|
|
140
|
+
- **fail-closed** — invalid/unknown critical state resolves to FAIL/UNKNOWN rather than PASS.
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "plan-auditor"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.2.0"
|
|
8
8
|
description = "Independent multi-layer verification supervisor for AI coding agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -26,6 +26,7 @@ dependencies = []
|
|
|
26
26
|
|
|
27
27
|
[project.scripts]
|
|
28
28
|
plan-auditor = "supervisor.cli:entrypoint"
|
|
29
|
+
plan-auditor-migrate-seal = "supervisor.seal_migration:main"
|
|
29
30
|
|
|
30
31
|
[project.urls]
|
|
31
32
|
Homepage = "https://github.com/Furox-Art/plan-auditor"
|