procheiron 0.1.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.
Files changed (107) hide show
  1. procheiron-0.1.0/.gitignore +7 -0
  2. procheiron-0.1.0/CODE_OF_CONDUCT.md +8 -0
  3. procheiron-0.1.0/CONTRIBUTING.md +30 -0
  4. procheiron-0.1.0/LICENSE +21 -0
  5. procheiron-0.1.0/PKG-INFO +114 -0
  6. procheiron-0.1.0/README.md +85 -0
  7. procheiron-0.1.0/conformance/generic-vault/.procheiron/config.yaml +29 -0
  8. procheiron-0.1.0/conformance/generic-vault/.procheiron/lib/procheiron_lock.py +47 -0
  9. procheiron-0.1.0/conformance/generic-vault/.procheiron/lib/procheiron_paths.py +60 -0
  10. procheiron-0.1.0/conformance/generic-vault/.procheiron/lib/procheiron_patterns.py +87 -0
  11. procheiron-0.1.0/conformance/generic-vault/.procheiron/lib/procheiron_resolve.py +191 -0
  12. procheiron-0.1.0/conformance/generic-vault/.procheiron/lib/procheiron_schema.py +248 -0
  13. procheiron-0.1.0/conformance/generic-vault/.procheiron/policy/policy_data.json +133 -0
  14. procheiron-0.1.0/conformance/generic-vault/.procheiron/policy/procheiron.rego +144 -0
  15. procheiron-0.1.0/conformance/generic-vault/.procheiron/policy/procheiron_policy.py +162 -0
  16. procheiron-0.1.0/conformance/generic-vault/.procheiron/policy/procheiron_test.rego +85 -0
  17. procheiron-0.1.0/conformance/generic-vault/.procheiron/profiles/meridian/lint.json +44 -0
  18. procheiron-0.1.0/conformance/generic-vault/.procheiron/profiles/meridian/profile.md +98 -0
  19. procheiron-0.1.0/conformance/generic-vault/.procheiron/profiles/meridian/retrieval.md +85 -0
  20. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/adapter_manifest.schema.json +27 -0
  21. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/audit_event.schema.json +71 -0
  22. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/config.schema.json +46 -0
  23. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/manifest.schema.json +40 -0
  24. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/memory_record.schema.json +135 -0
  25. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/profile_lint.schema.json +34 -0
  26. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/required_tokens.json +32 -0
  27. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/severity_map.json +53 -0
  28. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/source_record.schema.json +47 -0
  29. procheiron-0.1.0/conformance/generic-vault/.procheiron/schemas/supersession.schema.json +34 -0
  30. procheiron-0.1.0/conformance/generic-vault/.procheiron/validators/validate_procheiron2.py +723 -0
  31. procheiron-0.1.0/conformance/generic-vault/console/ACTIVE_PROJECTS.md +42 -0
  32. procheiron-0.1.0/conformance/generic-vault/console/AGENT_BOOT.md +128 -0
  33. procheiron-0.1.0/conformance/generic-vault/console/AGENT_REGISTRY.md +52 -0
  34. procheiron-0.1.0/conformance/generic-vault/console/BLOCKERS.md +46 -0
  35. procheiron-0.1.0/conformance/generic-vault/console/DECISIONS.md +62 -0
  36. procheiron-0.1.0/conformance/generic-vault/console/PRECEDENCE.md +87 -0
  37. procheiron-0.1.0/conformance/generic-vault/console/PROCHEIRON.md +62 -0
  38. procheiron-0.1.0/conformance/generic-vault/console/RETRIEVAL_POLICY.md +107 -0
  39. procheiron-0.1.0/conformance/generic-vault/console/SELF_ACTION_POLICY.md +415 -0
  40. procheiron-0.1.0/conformance/generic-vault/console/SOURCE_OF_TRUTH.md +54 -0
  41. procheiron-0.1.0/conformance/generic-vault/knowledge/wiki/DESIGN_PRINCIPLES.md +30 -0
  42. procheiron-0.1.0/conformance/generic-vault/memory/README.md +60 -0
  43. procheiron-0.1.0/conformance/generic-vault/memory/SCHEMA.md +117 -0
  44. procheiron-0.1.0/conformance/generic-vault/memory/VALIDATION.md +33 -0
  45. procheiron-0.1.0/conformance/generic-vault/memory/index/audit.jsonl +8 -0
  46. procheiron-0.1.0/conformance/generic-vault/memory/index/memories.jsonl +8 -0
  47. procheiron-0.1.0/conformance/generic-vault/memory/index/supersessions.jsonl +1 -0
  48. procheiron-0.1.0/conformance/generic-vault/runtime/state/STATE.json +10 -0
  49. procheiron-0.1.0/conformance/generic-vault/sources/MATERIAL_STANDARDS.md +65 -0
  50. procheiron-0.1.0/conformance/generic-vault/studio/STUDIO_GOVERNANCE.md +28 -0
  51. procheiron-0.1.0/conformance/manifest.json +27 -0
  52. procheiron-0.1.0/conformance/minimal-vault/.procheiron/config.yaml +6 -0
  53. procheiron-0.1.0/conformance/minimal-vault/console/CONSOLE.md +79 -0
  54. procheiron-0.1.0/conformance/minimal-vault/memory/SCHEMA.md +82 -0
  55. procheiron-0.1.0/conformance/minimal-vault/memory/index/audit.jsonl +4 -0
  56. procheiron-0.1.0/conformance/minimal-vault/memory/index/memories.jsonl +4 -0
  57. procheiron-0.1.0/conformance/minimal-vault/memory_promote.py +477 -0
  58. procheiron-0.1.0/conformance/minimal-vault/memory_propose.py +271 -0
  59. procheiron-0.1.0/conformance/minimal-vault/procheiron_schema.py +248 -0
  60. procheiron-0.1.0/conformance/minimal-vault/schemas/memory_record.schema.json +135 -0
  61. procheiron-0.1.0/conformance/minimal-vault/validate_minimal.py +170 -0
  62. procheiron-0.1.0/conformance/run_conformance.py +203 -0
  63. procheiron-0.1.0/examples/minimal-adopter/CONSOLE.md +79 -0
  64. procheiron-0.1.0/examples/minimal-adopter/README.md +103 -0
  65. procheiron-0.1.0/examples/minimal-adopter/SCHEMA.md +82 -0
  66. procheiron-0.1.0/examples/minimal-adopter/memory_promote.py +477 -0
  67. procheiron-0.1.0/examples/minimal-adopter/memory_propose.py +271 -0
  68. procheiron-0.1.0/examples/minimal-adopter/procheiron_schema.py +248 -0
  69. procheiron-0.1.0/examples/minimal-adopter/schemas/memory_record.schema.json +135 -0
  70. procheiron-0.1.0/examples/minimal-adopter/validate_minimal.py +170 -0
  71. procheiron-0.1.0/init/PORTING_GUIDE.md +258 -0
  72. procheiron-0.1.0/init/procheiron_init.py +326 -0
  73. procheiron-0.1.0/pyproject.toml +18 -0
  74. procheiron-0.1.0/spec/README.md +27 -0
  75. procheiron-0.1.0/spec/boundary.md +52 -0
  76. procheiron-0.1.0/spec/conformance.md +191 -0
  77. procheiron-0.1.0/spec/control-plane.md +115 -0
  78. procheiron-0.1.0/spec/governance.md +133 -0
  79. procheiron-0.1.0/spec/memory-commons.md +122 -0
  80. procheiron-0.1.0/src/procheiron/__init__.py +3 -0
  81. procheiron-0.1.0/src/procheiron/cli.py +158 -0
  82. procheiron-0.1.0/src/procheiron/data/adopter/memory_promote.py +477 -0
  83. procheiron-0.1.0/src/procheiron/data/adopter/memory_propose.py +271 -0
  84. procheiron-0.1.0/src/procheiron/data/adopter/procheiron_schema.py +248 -0
  85. procheiron-0.1.0/src/procheiron/data/adopter/schemas/memory_record.schema.json +135 -0
  86. procheiron-0.1.0/src/procheiron/data/adopter/validate_minimal.py +170 -0
  87. procheiron-0.1.0/src/procheiron/data/policy/policy_data.json +133 -0
  88. procheiron-0.1.0/src/procheiron/data/policy/procheiron.rego +144 -0
  89. procheiron-0.1.0/src/procheiron/data/policy/procheiron_test.rego +85 -0
  90. procheiron-0.1.0/src/procheiron/data/schemas/adapter_manifest.schema.json +27 -0
  91. procheiron-0.1.0/src/procheiron/data/schemas/audit_event.schema.json +71 -0
  92. procheiron-0.1.0/src/procheiron/data/schemas/config.schema.json +46 -0
  93. procheiron-0.1.0/src/procheiron/data/schemas/manifest.schema.json +40 -0
  94. procheiron-0.1.0/src/procheiron/data/schemas/memory_record.schema.json +135 -0
  95. procheiron-0.1.0/src/procheiron/data/schemas/profile_lint.schema.json +34 -0
  96. procheiron-0.1.0/src/procheiron/data/schemas/required_tokens.json +32 -0
  97. procheiron-0.1.0/src/procheiron/data/schemas/severity_map.json +53 -0
  98. procheiron-0.1.0/src/procheiron/data/schemas/source_record.schema.json +47 -0
  99. procheiron-0.1.0/src/procheiron/data/schemas/supersession.schema.json +34 -0
  100. procheiron-0.1.0/src/procheiron/init.py +325 -0
  101. procheiron-0.1.0/src/procheiron/lock.py +47 -0
  102. procheiron-0.1.0/src/procheiron/paths.py +60 -0
  103. procheiron-0.1.0/src/procheiron/patterns.py +87 -0
  104. procheiron-0.1.0/src/procheiron/policy.py +162 -0
  105. procheiron-0.1.0/src/procheiron/resolve.py +191 -0
  106. procheiron-0.1.0/src/procheiron/schema.py +248 -0
  107. procheiron-0.1.0/src/procheiron/validate.py +729 -0
@@ -0,0 +1,7 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.bak
4
+ .procheiron/locks/
5
+ .procheiron/backups/
6
+ *.log
7
+ .DS_Store
@@ -0,0 +1,8 @@
1
+ # Code of Conduct
2
+
3
+ This project follows the [Contributor Covenant](https://www.contributor-covenant.org/) v2.1.
4
+
5
+ Be respectful, assume good faith, and focus on the work. Harassment or abusive behavior is not tolerated.
6
+ Report concerns by opening a confidential issue or contacting the maintainers.
7
+
8
+ The full Contributor Covenant text applies; see https://www.contributor-covenant.org/version/2/1/code_of_conduct/.
@@ -0,0 +1,30 @@
1
+ # Contributing to Procheiron
2
+
3
+ Procheiron is a spec + reference implementation for governed agent memory. Contributions are welcome,
4
+ with one rule that comes from the project's own subject matter: **claims trail proofs.**
5
+
6
+ ## Ground rules
7
+
8
+ 1. **Every behavioral claim must be backed by the conformance suite.** If you change governance behavior,
9
+ add or update a fixture in `conformance/` and make `run_conformance.py` green. A PR that changes
10
+ behavior without a fixture will be asked for one.
11
+ 2. **Zero runtime dependencies.** Anything a deployment runs at runtime must be standard-library Python.
12
+ Dev/CI-only tools (jsonschema, opa) are fine but must never be required to run the validator, init, or
13
+ the minimal adopter.
14
+ 3. **No secrets, ever.** No real credentials, tokens, identities, or private deployment content in any
15
+ fixture, example, or test. Secret-*shaped* strings used to test detection must be generated at runtime,
16
+ not committed (see `run_conformance.py`).
17
+ 4. **Portable Core, specific Profile.** Keep deployment-specific detail (paths, identities, ladder/gate
18
+ tables, executor bindings) in profiles/examples — not in the normative spec. See `spec/boundary.md`.
19
+ 5. **Number honestly.** This is v0.1. v1.0 is earned only when a second *real* deployment passes
20
+ conformance — not by a fixture pass, a single deployment, or authority approval alone.
21
+
22
+ ## How to propose a change
23
+
24
+ - Open an issue describing the behavior and why.
25
+ - For spec changes, edit `spec/` and update `conformance.md` (the MUST-list) together.
26
+ - Run `python3 conformance/run_conformance.py` and include the output in your PR.
27
+
28
+ ## What's most wanted right now
29
+
30
+ See the Roadmap in `README.md` — the standalone, `--root`-relative MCP server is the top item.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Procheiron contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.4
2
+ Name: procheiron
3
+ Version: 0.1.0
4
+ Summary: Governance and provenance layer for agent memory.
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 Procheiron contributors
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+ License-File: LICENSE
27
+ Requires-Python: >=3.9
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Procheiron
31
+
32
+ **A governance and provenance layer for agent memory.** Not a memory engine — the trust layer that
33
+ sits on top of one.
34
+
35
+ Memory engines (supermemory, mempalace, agentmemory, a vector DB, or plain files) answer *"what does my
36
+ agent remember?"* Procheiron answers a different question: **"can a *different* agent trust this memory,
37
+ and prove who wrote it, who reviewed it, and who authorized it?"** It is built for the case a single-agent
38
+ memory store ignores — **multiple agents sharing one governed source of truth.**
39
+
40
+ Status: **v0.1 draft, pre-release.** Conformance passes at fixture level (a second, fully fictional
41
+ deployment validates against the same Core). Honest scope discipline: nothing here claims more than the
42
+ conformance suite proves.
43
+
44
+ ## Why this exists
45
+
46
+ Give an agent keys and it will use them. Give several agents a shared memory and, without governance, any
47
+ one of them can write a "fact" the others will trust — no record of who, no independent review, no way to
48
+ supersede it cleanly. Procheiron makes the trustworthy path the easy one:
49
+
50
+ - **Provenance-first lifecycle** — every memory is `draft → candidate → validated → active → superseded`.
51
+ An `active` (trusted) record requires independent review by an actor that is *not* its author.
52
+ - **Authority, not vibes** — who may promote, review, or authorize is policy, checked by a validator and a
53
+ policy engine, not a prompt asking nicely.
54
+ - **Provable, replayable** — a conformance suite checks that a deployment obeys the spec; a fictional
55
+ reference deployment (`conformance/generic-vault/`) proves the same Core governs a vault it has never
56
+ seen.
57
+
58
+ ## What's in this repo
59
+
60
+ | Path | What it is |
61
+ |---|---|
62
+ | `spec/` | The v0.1 specification: `governance.md`, `memory-commons.md`, `control-plane.md`, the normative `conformance.md` MUST-list, and the Core/Profile `boundary.md`. |
63
+ | `conformance/` | `run_conformance.py` + fixtures. `generic-vault/` is a complete fictional deployment ("Meridian Atelier"); `minimal-vault/` is the 5-file minimal adopter. Run it to prove conformance. |
64
+ | `examples/minimal-adopter/` | The smallest compliant deployment — a memory commons with provenance + independent review, no heavyweight governance ladder. |
65
+ | `init/` | `procheiron_init.py` scaffolds a new deployment; `PORTING_GUIDE.md` is the step-by-step. |
66
+
67
+ ## Quick start
68
+
69
+ ```bash
70
+ # Install (zero runtime dependencies — stdlib-only Python):
71
+ pipx install procheiron # or: pip install procheiron
72
+
73
+ # Scaffold a governed memory commons and validate it:
74
+ procheiron init ./my-commons
75
+ procheiron validate ./my-commons
76
+ ```
77
+
78
+ From a source checkout (no install required):
79
+
80
+ ```bash
81
+ # Prove the spec holds against the bundled fixtures:
82
+ python3 conformance/run_conformance.py
83
+
84
+ # Scaffold via the init script directly:
85
+ python3 init/procheiron_init.py --root ./my-commons
86
+ ```
87
+
88
+ ## Design choices worth knowing
89
+
90
+ - **Zero runtime dependencies.** Every tool a live deployment runs is standard-library Python. (`jsonschema`,
91
+ `opa` etc. are used only for development/CI cross-checks, never required at runtime.) Adopt it without
92
+ taking on a dependency tree.
93
+ - **Bring your own memory engine.** Procheiron governs records and their lifecycle; it does **not** do
94
+ embeddings or retrieval and never will (that is the engine's job). Point it at any store.
95
+ - **Core vs Profile.** The spec is portable Core. Deployment-specific bindings (identities, paths, a git
96
+ preservation executor, a full L0–L9 authority ladder) live in a *profile* — see `boundary.md`.
97
+
98
+ ## Not in scope (by design)
99
+
100
+ No vector/retrieval engine. No recall benchmarks — that is the memory engine's axis, not ours. No claim of
101
+ "production-replicable" until a second *real* deployment passes conformance (fixture-level proof is what
102
+ exists today, and the README says exactly that).
103
+
104
+ ## Roadmap (next, post first-deployment feedback)
105
+
106
+ 1. **Standalone MCP server** — `memory.search/get/propose/promote` + `boot_context`, the "any agent has the
107
+ context on hand" integration. (A working version exists but is currently coupled to its origin
108
+ deployment's layout; the port to a `--root`-relative standalone server is the top item.)
109
+ 2. ~~PyPI / `pipx` packaging and a one-command `procheiron init`.~~ **Shipped in v0.1** — `pip install procheiron`, `procheiron init`, `procheiron validate`.
110
+ 3. A reference integration: Procheiron governing a third-party memory engine end to end.
111
+
112
+ ## License
113
+
114
+ MIT — see `LICENSE`.
@@ -0,0 +1,85 @@
1
+ # Procheiron
2
+
3
+ **A governance and provenance layer for agent memory.** Not a memory engine — the trust layer that
4
+ sits on top of one.
5
+
6
+ Memory engines (supermemory, mempalace, agentmemory, a vector DB, or plain files) answer *"what does my
7
+ agent remember?"* Procheiron answers a different question: **"can a *different* agent trust this memory,
8
+ and prove who wrote it, who reviewed it, and who authorized it?"** It is built for the case a single-agent
9
+ memory store ignores — **multiple agents sharing one governed source of truth.**
10
+
11
+ Status: **v0.1 draft, pre-release.** Conformance passes at fixture level (a second, fully fictional
12
+ deployment validates against the same Core). Honest scope discipline: nothing here claims more than the
13
+ conformance suite proves.
14
+
15
+ ## Why this exists
16
+
17
+ Give an agent keys and it will use them. Give several agents a shared memory and, without governance, any
18
+ one of them can write a "fact" the others will trust — no record of who, no independent review, no way to
19
+ supersede it cleanly. Procheiron makes the trustworthy path the easy one:
20
+
21
+ - **Provenance-first lifecycle** — every memory is `draft → candidate → validated → active → superseded`.
22
+ An `active` (trusted) record requires independent review by an actor that is *not* its author.
23
+ - **Authority, not vibes** — who may promote, review, or authorize is policy, checked by a validator and a
24
+ policy engine, not a prompt asking nicely.
25
+ - **Provable, replayable** — a conformance suite checks that a deployment obeys the spec; a fictional
26
+ reference deployment (`conformance/generic-vault/`) proves the same Core governs a vault it has never
27
+ seen.
28
+
29
+ ## What's in this repo
30
+
31
+ | Path | What it is |
32
+ |---|---|
33
+ | `spec/` | The v0.1 specification: `governance.md`, `memory-commons.md`, `control-plane.md`, the normative `conformance.md` MUST-list, and the Core/Profile `boundary.md`. |
34
+ | `conformance/` | `run_conformance.py` + fixtures. `generic-vault/` is a complete fictional deployment ("Meridian Atelier"); `minimal-vault/` is the 5-file minimal adopter. Run it to prove conformance. |
35
+ | `examples/minimal-adopter/` | The smallest compliant deployment — a memory commons with provenance + independent review, no heavyweight governance ladder. |
36
+ | `init/` | `procheiron_init.py` scaffolds a new deployment; `PORTING_GUIDE.md` is the step-by-step. |
37
+
38
+ ## Quick start
39
+
40
+ ```bash
41
+ # Install (zero runtime dependencies — stdlib-only Python):
42
+ pipx install procheiron # or: pip install procheiron
43
+
44
+ # Scaffold a governed memory commons and validate it:
45
+ procheiron init ./my-commons
46
+ procheiron validate ./my-commons
47
+ ```
48
+
49
+ From a source checkout (no install required):
50
+
51
+ ```bash
52
+ # Prove the spec holds against the bundled fixtures:
53
+ python3 conformance/run_conformance.py
54
+
55
+ # Scaffold via the init script directly:
56
+ python3 init/procheiron_init.py --root ./my-commons
57
+ ```
58
+
59
+ ## Design choices worth knowing
60
+
61
+ - **Zero runtime dependencies.** Every tool a live deployment runs is standard-library Python. (`jsonschema`,
62
+ `opa` etc. are used only for development/CI cross-checks, never required at runtime.) Adopt it without
63
+ taking on a dependency tree.
64
+ - **Bring your own memory engine.** Procheiron governs records and their lifecycle; it does **not** do
65
+ embeddings or retrieval and never will (that is the engine's job). Point it at any store.
66
+ - **Core vs Profile.** The spec is portable Core. Deployment-specific bindings (identities, paths, a git
67
+ preservation executor, a full L0–L9 authority ladder) live in a *profile* — see `boundary.md`.
68
+
69
+ ## Not in scope (by design)
70
+
71
+ No vector/retrieval engine. No recall benchmarks — that is the memory engine's axis, not ours. No claim of
72
+ "production-replicable" until a second *real* deployment passes conformance (fixture-level proof is what
73
+ exists today, and the README says exactly that).
74
+
75
+ ## Roadmap (next, post first-deployment feedback)
76
+
77
+ 1. **Standalone MCP server** — `memory.search/get/propose/promote` + `boot_context`, the "any agent has the
78
+ context on hand" integration. (A working version exists but is currently coupled to its origin
79
+ deployment's layout; the port to a `--root`-relative standalone server is the top item.)
80
+ 2. ~~PyPI / `pipx` packaging and a one-command `procheiron init`.~~ **Shipped in v0.1** — `pip install procheiron`, `procheiron init`, `procheiron validate`.
81
+ 3. A reference integration: Procheiron governing a third-party memory engine end to end.
82
+
83
+ ## License
84
+
85
+ MIT — see `LICENSE`.
@@ -0,0 +1,29 @@
1
+ version: 0.1
2
+ profile: meridian
3
+ root: .
4
+ paths:
5
+ console: console
6
+ memory: memory
7
+ sources: sources
8
+ wiki: knowledge
9
+ outputs: outputs
10
+ adapters: adapters
11
+ legacy_governance: studio
12
+ workspace: workspace
13
+ runtime_root: runtime/procheiron
14
+ runtime_state: runtime/state/STATE.json
15
+ scripts: scripts
16
+ policy_defaults:
17
+ local_first: true
18
+ human_visible: true
19
+ raw_sources_immutable: true
20
+ derived_memory_rebuildable: true
21
+ provenance_required: true
22
+ temporal_by_default: true
23
+ no_runtime_lock_in: true
24
+ no_external_actions_by_default: true
25
+ no_hooks_phase_1_2: true
26
+ no_cron_changes_phase_1_2: true
27
+ no_package_installs_phase_1_2: true
28
+ agents_may_propose_not_promote: true
29
+ secrets_allowed: false
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env python3
2
+ """Single-writer advisory lock for the Procheiron memory indexes (roadmap 3.6).
3
+
4
+ STAGED ARTIFACT — installs to .procheiron/lib/procheiron_lock.py under the
5
+ Phase-3 adoption authorization, shared by memory_promote.py and memory_propose.py
6
+ so there is one lock implementation, no drift. Stdlib-only.
7
+
8
+ Discipline: O_CREAT|O_EXCL create (no auto-steal), age-surfaced contention,
9
+ unlink on exit (including SystemExit). Extracted verbatim-in-behavior from the
10
+ Lock already living in the live memory_promote.py.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import datetime as dt
15
+ import os
16
+ from pathlib import Path
17
+ from typing import Any
18
+
19
+
20
+ class LockHeld(SystemExit):
21
+ """Raised (as SystemExit, so a CLI exits cleanly) when the lock is held."""
22
+
23
+
24
+ class Lock:
25
+ def __init__(self, root: Path) -> None:
26
+ lock_dir = Path(root) / ".procheiron" / "locks"
27
+ lock_dir.mkdir(parents=True, exist_ok=True)
28
+ self.path = lock_dir / "memory_index.lock"
29
+
30
+ def __enter__(self) -> "Lock":
31
+ try:
32
+ fd = os.open(str(self.path), os.O_CREAT | os.O_EXCL | os.O_WRONLY)
33
+ except FileExistsError:
34
+ age = dt.datetime.now().timestamp() - self.path.stat().st_mtime
35
+ raise LockHeld(
36
+ f"memory index lock held ({self.path}, {int(age)}s old); "
37
+ "retry or remove a stale lock manually"
38
+ )
39
+ os.write(fd, f"{os.getpid()} {dt.datetime.now(dt.timezone.utc).isoformat()}\n".encode())
40
+ os.close(fd)
41
+ return self
42
+
43
+ def __exit__(self, *_exc: Any) -> None:
44
+ try:
45
+ self.path.unlink()
46
+ except FileNotFoundError:
47
+ pass
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env python3
2
+ """Source-path normalization for Procheiron memory records.
3
+
4
+ Converts machine-absolute provenance paths into self-describing, portable
5
+ forms so records survive a deployment move (the data-plane weld from the
6
+ 2026-06-10/11 audits):
7
+
8
+ - a path under the deployment root becomes root-relative
9
+ - a path under any absolute `paths.<key>` from config.yaml becomes
10
+ `{paths.<key>}/<rest>` (longest prefix wins)
11
+ - any other absolute path is returned unchanged and reported by the caller
12
+
13
+ Used by memory_propose.py (normalize at write time) and migrate_records.py
14
+ (repair existing records). Stdlib-only.
15
+ """
16
+ from __future__ import annotations
17
+
18
+ import os
19
+ from pathlib import Path
20
+ from typing import Any, Optional, Tuple
21
+
22
+
23
+ def normalize_source_path(cfg: Any, raw: str) -> Tuple[str, bool]:
24
+ """Return (normalized_path, changed). Non-absolute input passes through."""
25
+ if not raw or not raw.startswith('/'):
26
+ return raw, False
27
+ # Collapse `..`/`.` segments BEFORE prefix matching so a path like
28
+ # `/v/memory/../secret/x` does not falsely tokenize under {paths.memory}
29
+ # (review finding L-4). normpath is lexical only — it never touches disk
30
+ # or resolves symlinks, so it cannot leak filesystem state.
31
+ raw = os.path.normpath(raw)
32
+ candidate = Path(raw)
33
+ best_key: Optional[str] = None
34
+ best_len = -1
35
+ for key, value in cfg.paths.items():
36
+ base = Path(str(value))
37
+ if not base.is_absolute():
38
+ continue
39
+ try:
40
+ rest = candidate.relative_to(base)
41
+ except ValueError:
42
+ continue
43
+ if len(str(base)) > best_len:
44
+ best_key, best_len = key, len(str(base))
45
+ best_rest = rest
46
+ root = Path(str(cfg.root))
47
+ try:
48
+ root_rest = candidate.relative_to(root)
49
+ root_len = len(str(root))
50
+ except ValueError:
51
+ root_rest, root_len = None, -1
52
+
53
+ if root_rest is not None and root_len >= best_len:
54
+ return root_rest.as_posix(), True
55
+ if best_key is not None:
56
+ rest_str = best_rest.as_posix()
57
+ if rest_str == '.':
58
+ return '{paths.%s}' % best_key, True
59
+ return '{paths.%s}/%s' % (best_key, rest_str), True
60
+ return raw, False
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env python3
2
+ """Shared Procheiron secret-pattern registry.
3
+
4
+ Single source of truth for secret detection across the validator
5
+ (validate_procheiron2.py), the candidate-append helper (memory_propose.py),
6
+ and the promotion gate (memory_promote.py). Reunified 2026-06-11 per the
7
+ A-to-Z audit finding that the v2 validator had regressed to 3 patterns
8
+ (AKIA dropped) while memory_propose carried 11 unshared.
9
+
10
+ Stdlib-only. Importing this module must never require third-party packages.
11
+ """
12
+ from __future__ import annotations
13
+
14
+ import re
15
+ import unicodedata
16
+ from typing import List, Tuple
17
+
18
+ # (label, compiled pattern). Labels are stable identifiers used in reports.
19
+ SECRET_PATTERNS: List[Tuple[str, "re.Pattern[str]"]] = [
20
+ ("openai_style_key", re.compile(r"\bsk-[A-Za-z0-9_\-]{16,}\b")),
21
+ ("stripe_key", re.compile(r"\bsk_(live|test)_[A-Za-z0-9]{16,}\b")),
22
+ ("github_token", re.compile(r"\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{20,}\b")),
23
+ ("github_fine_grained", re.compile(r"\bgithub_pat_[A-Za-z0-9_]{20,}\b")),
24
+ ("google_api_key", re.compile(r"\bAIza[0-9A-Za-z_\-]{30,}\b")),
25
+ ("slack_token", re.compile(r"\bxox[baprs]-[A-Za-z0-9\-]{10,}\b")),
26
+ ("aws_access_key_id", re.compile(r"\bAKIA[0-9A-Z]{16}\b")),
27
+ ("jwt", re.compile(r"\beyJ[A-Za-z0-9_\-]{10,}\.[A-Za-z0-9_\-]{10,}\.")),
28
+ ("bearer_token", re.compile(r"(?i)\bbearer\s+[A-Za-z0-9\-_\.=]{16,}")),
29
+ (
30
+ "credential_assignment",
31
+ re.compile(r"(?i)[\"']?(password|passwd|api[_-]?key|secret|token)[\"']?\s*[:=]\s*[\"']?\S{12,}"),
32
+ ),
33
+ ("private_key_block", re.compile(r"-----BEGIN [A-Z ]*PRIVATE KEY-----")),
34
+ ]
35
+
36
+
37
+ _ZERO_WIDTH = {"​", "‌", "‍", "⁠", ""}
38
+
39
+
40
+ def normalize_for_scan(text: str) -> str:
41
+ """NFKC-normalize and strip zero-width/format chars before secret scanning.
42
+
43
+ Defeats the common evasions: a zero-width space inside a key, a fullwidth
44
+ colon in `password:`, an NBSP in a token. Without this, the regexes run on
45
+ the raw bytes and a single invisible character hides a live credential
46
+ (review finding L-1). We strip Unicode Cf (format) chars and the explicit
47
+ zero-width set, then NFKC-fold width/compatibility variants.
48
+ """
49
+ if not text:
50
+ return ""
51
+ out = []
52
+ for ch in text:
53
+ if ch in _ZERO_WIDTH:
54
+ continue
55
+ if unicodedata.category(ch) == "Cf":
56
+ continue
57
+ out.append(ch)
58
+ return unicodedata.normalize("NFKC", "".join(out))
59
+
60
+
61
+ def scan_text(text: str) -> List[Tuple[int, str]]:
62
+ """Return (line_number, label) findings for every secret-pattern hit.
63
+
64
+ Each line is scanned both raw and normalized, so an evaded credential is
65
+ still caught while line numbers stay meaningful.
66
+ """
67
+ findings: List[Tuple[int, str]] = []
68
+ for lineno, line in enumerate(text.splitlines(), 1):
69
+ norm = normalize_for_scan(line)
70
+ for label, pattern in SECRET_PATTERNS:
71
+ if pattern.search(line) or (norm != line and pattern.search(norm)):
72
+ findings.append((lineno, label))
73
+ return findings
74
+
75
+
76
+ def first_match_label(text: str) -> str | None:
77
+ """Return the label of the first matching pattern, or None.
78
+
79
+ Scans both the raw and normalized forms so zero-width / homoglyph evasions
80
+ do not slip a live secret past the guard.
81
+ """
82
+ raw = text or ""
83
+ norm = normalize_for_scan(raw)
84
+ for label, pattern in SECRET_PATTERNS:
85
+ if pattern.search(raw) or (norm != raw and pattern.search(norm)):
86
+ return label
87
+ return None