mishkan-harness 0.2.5 → 0.2.7

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 (145) hide show
  1. package/README.md +49 -11
  2. package/bin/mishkan.js +562 -79
  3. package/docs/design/MISHKAN_decisions.md +398 -8
  4. package/docs/design/MISHKAN_observability.md +8 -8
  5. package/docs/engineer/profile-readable.md +201 -0
  6. package/docs/engineer/profile.md +754 -0
  7. package/docs/usage/01-installation.md +22 -8
  8. package/docs/usage/02-project-init.md +30 -13
  9. package/docs/usage/03-orchestration.md +46 -7
  10. package/docs/usage/04-memory-layer.md +135 -69
  11. package/docs/usage/06-llm-providers.md +2 -1
  12. package/docs/usage/07-troubleshooting.md +23 -0
  13. package/docs/usage/08-glossary.md +12 -3
  14. package/docs/usage/09-workflows.md +15 -3
  15. package/docs/usage/10-observability.md +3 -3
  16. package/docs/usage/11-graphify.md +38 -18
  17. package/docs/usage/12-cli.md +87 -0
  18. package/docs/usage/12-skill-discovery.md +11 -0
  19. package/docs/usage/README.md +35 -19
  20. package/package.json +1 -1
  21. package/payload/mishkan/AGENT_SPEC.md +3 -1
  22. package/payload/mishkan/agents/ahikam.md +3 -1
  23. package/payload/mishkan/agents/aholiab.md +3 -1
  24. package/payload/mishkan/agents/asaph.md +3 -1
  25. package/payload/mishkan/agents/baruch.md +8 -1
  26. package/payload/mishkan/agents/benaiah.md +3 -1
  27. package/payload/mishkan/agents/bezalel.md +3 -1
  28. package/payload/mishkan/agents/caleb.md +3 -1
  29. package/payload/mishkan/agents/deborah.md +3 -1
  30. package/payload/mishkan/agents/elasah.md +3 -1
  31. package/payload/mishkan/agents/eliashib.md +3 -1
  32. package/payload/mishkan/agents/ezra.md +3 -1
  33. package/payload/mishkan/agents/hanun.md +3 -1
  34. package/payload/mishkan/agents/hiram.md +3 -1
  35. package/payload/mishkan/agents/hizkiah.md +3 -1
  36. package/payload/mishkan/agents/huldah.md +3 -1
  37. package/payload/mishkan/agents/huram.md +3 -1
  38. package/payload/mishkan/agents/hushai.md +3 -1
  39. package/payload/mishkan/agents/igal.md +3 -1
  40. package/payload/mishkan/agents/ira.md +3 -1
  41. package/payload/mishkan/agents/jahaziel.md +3 -1
  42. package/payload/mishkan/agents/jakin.md +3 -1
  43. package/payload/mishkan/agents/jehonathan.md +3 -1
  44. package/payload/mishkan/agents/jehoshaphat.md +3 -1
  45. package/payload/mishkan/agents/joab.md +3 -1
  46. package/payload/mishkan/agents/joah.md +3 -1
  47. package/payload/mishkan/agents/maaseiah.md +3 -1
  48. package/payload/mishkan/agents/meremoth.md +3 -1
  49. package/payload/mishkan/agents/meshullam.md +3 -1
  50. package/payload/mishkan/agents/nathan.md +3 -1
  51. package/payload/mishkan/agents/nehemiah.md +3 -1
  52. package/payload/mishkan/agents/obed.md +3 -1
  53. package/payload/mishkan/agents/oholiab.md +3 -1
  54. package/payload/mishkan/agents/palal.md +3 -1
  55. package/payload/mishkan/agents/phinehas.md +3 -1
  56. package/payload/mishkan/agents/rehum.md +3 -1
  57. package/payload/mishkan/agents/salma.md +3 -1
  58. package/payload/mishkan/agents/seraiah.md +3 -1
  59. package/payload/mishkan/agents/shallum.md +3 -1
  60. package/payload/mishkan/agents/shaphan.md +3 -1
  61. package/payload/mishkan/agents/shemaiah.md +6 -1
  62. package/payload/mishkan/agents/shevna.md +3 -1
  63. package/payload/mishkan/agents/uriah.md +3 -1
  64. package/payload/mishkan/agents/zaccur.md +3 -1
  65. package/payload/mishkan/agents/zadok.md +3 -1
  66. package/payload/mishkan/agents/zerubbabel.md +3 -1
  67. package/payload/mishkan/cognee/.env.example +11 -0
  68. package/payload/mishkan/cognee/Dockerfile +20 -0
  69. package/payload/mishkan/cognee/README.md +34 -14
  70. package/payload/mishkan/cognee/docker-compose.curated.yml +33 -6
  71. package/payload/mishkan/cognee/docker-compose.selfhosted.yml +35 -5
  72. package/payload/mishkan/cognee/docker-compose.work.yml +191 -0
  73. package/payload/mishkan/cognee/docker-compose.yml +18 -3
  74. package/payload/mishkan/cognee/patches/cognee-mcp-core-align.py +72 -0
  75. package/payload/mishkan/cognee/patches/cognee-mcp-recall-user.py +82 -0
  76. package/payload/mishkan/cognee/promote-curated.py +77 -0
  77. package/payload/mishkan/cognee/prune-store.py +23 -0
  78. package/payload/mishkan/commands/mishkan-init.md +4 -1
  79. package/payload/mishkan/commands/mishkan-org-reference.md +2 -2
  80. package/payload/mishkan/config/curated-library.yaml +1 -0
  81. package/payload/mishkan/config/model-routing.yaml +23 -14
  82. package/payload/mishkan/evals/baruch/fixtures/invalid/bad-curated-candidate.json +22 -0
  83. package/payload/mishkan/evals/baruch/fixtures/valid/resolved-curated-candidate.json +23 -0
  84. package/payload/mishkan/hooks/model-route.py +14 -1
  85. package/payload/mishkan/hooks/post-tool-observe.sh +55 -7
  86. package/payload/mishkan/hooks/pre-tool-trace.sh +40 -6
  87. package/payload/mishkan/observability/README.md +15 -12
  88. package/payload/mishkan/observability/schema.json +18 -1
  89. package/payload/mishkan/observability/usage_parser.py +1 -0
  90. package/payload/mishkan/observability/watch/pyproject.toml +1 -1
  91. package/payload/mishkan/observability/watch/src/mishkan_watch/__init__.py +1 -1
  92. package/payload/mishkan/observability/watch/src/mishkan_watch/__main__.py +78 -21
  93. package/payload/mishkan/observability/watch/src/mishkan_watch/app.py +56 -3
  94. package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/agents.py +29 -7
  95. package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/knowledge.py +83 -8
  96. package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/live.py +42 -13
  97. package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/usage.py +10 -3
  98. package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/workflows.py +47 -7
  99. package/payload/mishkan/observability/watchd/pyproject.toml +1 -1
  100. package/payload/mishkan/observability/watchd/src/mishkan_watchd/__init__.py +1 -1
  101. package/payload/mishkan/observability/watchd/src/mishkan_watchd/__main__.py +87 -11
  102. package/payload/mishkan/observability/watchd/src/mishkan_watchd/server.py +126 -9
  103. package/payload/mishkan/observability/watchd/src/mishkan_watchd/sources/cognee_poll.py +136 -49
  104. package/payload/mishkan/observability/watchd/src/mishkan_watchd/sources/graphify_tail.py +38 -64
  105. package/payload/mishkan/observability/watchd/src/mishkan_watchd/state.py +222 -34
  106. package/payload/mishkan/observability/watchd/tests/test_state.py +502 -4
  107. package/payload/mishkan/ontology.md +8 -1
  108. package/payload/mishkan/ontology.ttl +188 -0
  109. package/payload/mishkan/scripts/ensure-work-store.sh +230 -0
  110. package/payload/mishkan/scripts/mishkan-ingest.sh +53 -3
  111. package/payload/mishkan/scripts/promote-curated.sh +77 -0
  112. package/payload/mishkan/scripts/reset-knowledge-data.sh +70 -0
  113. package/payload/mishkan/scripts/validate-research-log.sh +27 -0
  114. package/payload/mishkan/skills/baruch-research-reporting-craft/SKILL.md +42 -8
  115. package/payload/mishkan/skills/cognee-promote/SKILL.md +13 -0
  116. package/payload/mishkan/skills/cognee-quickstart/SKILL.md +7 -1
  117. package/payload/mishkan/skills/ezra-research-formulation-craft/SKILL.md +9 -0
  118. package/payload/mishkan/skills/mishkan-ingest/SKILL.md +22 -0
  119. package/payload/mishkan/skills/mishkan-init/SKILL.md +31 -19
  120. package/payload/mishkan/skills/shemaiah-evaluation-craft/SKILL.md +33 -5
  121. package/payload/mishkan/skills/team-lead-craft/SKILL.md +66 -0
  122. package/payload/mishkan/templates/mcp.json +7 -2
  123. package/payload/mishkan/templates/observability-log.schema.json +1 -1
  124. package/payload/mishkan/templates/research-log.schema.json +15 -1
  125. package/payload/mishkan/workflows/README.md +19 -13
  126. package/payload/mishkan/workflows/chosheb-feature-ship.js +63 -18
  127. package/payload/mishkan/workflows/migdal-dr-drill.js +4 -0
  128. package/payload/mishkan/workflows/migdal-infra-change.js +48 -7
  129. package/payload/mishkan/workflows/mishkan-architecture-panel.js +4 -0
  130. package/payload/mishkan/workflows/mishkan-blast-radius.js +4 -0
  131. package/payload/mishkan/workflows/mishkan-codebase-audit.js +4 -0
  132. package/payload/mishkan/workflows/mishkan-deep-research.js +4 -0
  133. package/payload/mishkan/workflows/mishkan-init.js +4 -0
  134. package/payload/mishkan/workflows/mishkan-knowledge-gap-discovery.js +4 -0
  135. package/payload/mishkan/workflows/mishkan-migration-wave.js +4 -0
  136. package/payload/mishkan/workflows/mishkan-release-readiness.js +4 -0
  137. package/payload/mishkan/workflows/mishkan-sprint-close.js +4 -0
  138. package/payload/mishkan/workflows/mishkan-standards-rollout.js +4 -0
  139. package/payload/mishkan/workflows/mishmar-security-gate.js +45 -6
  140. package/payload/mishkan/workflows/panim-ds-rollout.js +4 -0
  141. package/payload/mishkan/workflows/panim-feature-ship.js +132 -0
  142. package/payload/mishkan/workflows/sefer-release-notes.js +4 -0
  143. package/payload/mishkan/workflows/yasad-data-migration-wave.js +4 -0
  144. package/payload/mishkan/workflows/yasad-feature-ship.js +130 -0
  145. package/payload/mishkan/workflows/yasad-schema-evolution.js +4 -0
@@ -35,14 +35,19 @@ runtime selection — for no benefit given the target. Removing it simplifies th
35
35
  build materially.
36
36
 
37
37
  **Implications:**
38
- - Three tiers only: Opus, Sonnet, Haiku.
38
+ - Tier *values* the hook accepts: Fable, Opus, Sonnet, Haiku — but **Fable is
39
+ dormant** (0 agents) since its 2026-06-12 suspension (amendment below). Live
40
+ distribution is Opus 9 · Sonnet 22 · Haiku 14.
41
+ - **Fable (0 — dormant):** briefly the producing specialists of Mishmar + Migdal
42
+ (2026-06-11 amendment), reverted to Sonnet on 2026-06-12 (suspension amendment).
43
+ The value stays valid so the tier can be re-enabled if access is restored.
39
44
  - **Opus (9):** Nehemiah, Bezalel, all Team Leads, Jehonathan.
40
- - **Sonnet (22):** every agent that **writes code/config into the codebase**
41
- (precision matters on Y4NN's code) + senior specialists + research
42
- clarify/formulate/research. Includes all implementation specialists
43
- Hizkiah, Salma, Hiram, Obed, Asaph, Palal, Meremoth, Hanun — plus Nathan,
44
- Zadok, Shallum, Ira, Benaiah, Joab, Hushai, Oholiab, Meshullam, Seraiah,
45
- Joah, Jakin, Ezra, Caleb.
45
+ - **Sonnet (22):** every agent that **writes code/config into the
46
+ codebase** (precision matters on Y4NN's code) + senior specialists + research
47
+ clarify/formulate/research. Includes implementation specialists Hizkiah,
48
+ Salma, Hiram, Obed, Asaph, Palal, Meremoth, Hanun — plus Nathan, Zadok,
49
+ Shallum, Ira, Benaiah, Joab, Hushai, Oholiab, Meshullam, Seraiah, Joah,
50
+ Jakin, Ezra, Caleb.
46
51
  - **Haiku (14):** agents that do **not** write code — QA (Uriah, Jahaziel),
47
52
  all Team Reporters, pure advisors (Deborah, Rehum), Sefer team-layer docs
48
53
  (Shevna), research summarise/evaluate/report (Shaphan, Shemaiah, Baruch).
@@ -50,6 +55,42 @@ build materially.
50
55
  **Amendment 2026-05-27:** original split put implementation specialists on
51
56
  Haiku for cost. Revised on Y4NN's preference — Sonnet writes his code more
52
57
  precisely. Haiku retained only where no code is written (evaluate/collect/advise).
58
+
59
+ **Amendment 2026-06-11 (four-tier — Fable 5 for Migdal + Mishmar specialists):**
60
+ the eight producing specialists of the infrastructure (Migdal) and security
61
+ (Mishmar) teams move from Sonnet to **Fable 5** (`claude-fable-5`). Fable 5 is
62
+ positioned for complex, long-horizon work — threat modelling, infra topology,
63
+ hardening — which is exactly these agents' load. Note the selector here is
64
+ **reasoning load, not code-writing**: that is why Hushai (a security *advisor* that
65
+ writes no code) qualifies for Fable on the strength of its analysis depth, whereas
66
+ the Sonnet tier's selector is *code-writing precision on Y4NN's code* and the Haiku
67
+ tier's is *no reasoning or code at all* (collect/evaluate/advise-lite). The two
68
+ "advisor" agents split on exactly this axis — Hushai (reasoning-heavy security
69
+ counsel) → Fable; Rehum (health/SRE advice-lite) → Haiku. Scope is deliberate: team
70
+ **leads** (Phinehas, Eliashib) stay Opus (orchestration/judgement), and the
71
+ **reporters** (Maaseiah, Zaccur) stay Haiku (collect only). This amends "three tiers
72
+ only" to four; the "Claude Code models only" decision is unchanged (Fable 5 is a
73
+ Claude model). Cost: Fable 5 is **$10 / $50 per MTok** — above Opus-tier — and is
74
+ covered by plan limits until **2026-06-22**, then usage credits (an accepted cost).
75
+ Verified before rollout: `fable` is a valid bare subagent alias resolving to
76
+ `claude-fable-5` (confirmed against the API-recorded model field in a subagent
77
+ transcript). The `model-route.py` hook's `VALID` set, the `observability-log` schema
78
+ `model_tier` enum, and the `usage_parser.py` price table were extended for the new
79
+ tier in the same change.
80
+
81
+ **Amendment 2026-06-12 (Fable suspended — reverted to Sonnet):** less than a day
82
+ after the four-tier amendment landed, Anthropic disabled Claude Fable 5 (and Mythos 5)
83
+ for **all customers** under a US export-control directive
84
+ (anthropic.com/news/fable-mythos-access, 2026-06-12 17:21 ET) — `claude-fable-5` now
85
+ hard-errors on spawn (verified: a subagent routed to it returns "model … may not
86
+ exist or you may not have access", 0 tokens). The eight Migdal+Mishmar specialists are
87
+ therefore **reverted to Sonnet** (frontmatter + `model-routing.yaml`), restoring the
88
+ pre-amendment distribution (Opus 9 · Sonnet 22 · Haiku 14). The four-tier **mechanism
89
+ is kept dormant** — `fable` stays in the hook's `VALID` set, the telemetry enum, and
90
+ the price table — so re-enabling is a one-line routing change if Anthropic restores
91
+ access ("working to restore access as soon as possible"). This episode is the concrete
92
+ motivation for D-017 (user-editable dynamic tier routing): model availability can
93
+ change abruptly, and routing should adapt without a code change + reinstall.
53
94
  - Tier declared per-agent in frontmatter `model:` field.
54
95
  - Overridable centrally via `~/.claude/mishkan/config/model-routing.yaml`.
55
96
  - Cost discipline lives entirely in tier assignment + prompt caching +
@@ -167,6 +208,8 @@ small extra Neo4j. The curated library is small and regenerable
167
208
  bulk seeding bursts embedding calls and cloud free-tier embeddings 429
168
209
  (RESOURCE_EXHAUSTED).
169
210
 
211
+ *(Superseded on the work-store axis by D-012: per-project physical isolation. The `cognee` MCP alias now points to a per-project Ladybug store, not port `:7777`. Port `:7777` is repurposed as `cognee-memory`, holding only `claude_code_memory`.)*
212
+
170
213
  ## D-008 — Three-layer memory epistemology: structure / project semantics / curated cross-project (added 2026-06-05)
171
214
 
172
215
  **Decision:** MISHKAN's knowledge surface is split into **three physically
@@ -356,6 +399,8 @@ introduced to protect.
356
399
  (curated vs work split) by adding a third epistemic layer on the same
357
400
  discipline.
358
401
 
402
+ *(The "Cognee work (`:7777`)" row in the table above describes the model as of D-008. Superseded on the work-store axis by D-012: the `cognee` MCP alias now points to a per-project Ladybug store on its own port; `:7777` is repurposed as `cognee-memory`, session memory only.)*
403
+
359
404
  ## D-009 — Graph-first PreToolUse gate for the five code-writing specialists (added 2026-06-05)
360
405
 
361
406
  **Decision:** introduce a MISHKAN PreToolUse hook — `pre-tool-knowledge-route.py` —
@@ -612,7 +657,7 @@ worth reaching for.
612
657
  `mishkan-blast-radius`, `mishkan-knowledge-gap-discovery`,
613
658
  `mishkan-standards-rollout`. Adding an 11th forces a retirement vote.
614
659
  - **4 team-level workflows per team.** Current shipped count varies by team
615
- (Chosheb 1, Panim 1, Yasad 2, Mishmar 1, Migdal 2, Sefer 1). Spare slots
660
+ (Chosheb 1, Panim 2, Yasad 3, Mishmar 1, Migdal 2, Sefer 1). Spare slots
616
661
  per team are deliberately left open — candidates compete for them at
617
662
  PM+CTO review, not on a team lead's word.
618
663
 
@@ -717,6 +762,52 @@ upcoming-use justification.
717
762
  candidate; a determined push can word-paint around it. Mitigation: the
718
763
  CTO half of the gate has explicit authority to reject on shape.
719
764
 
765
+ ### Amendment (2026-06-10) — loop-until-QA-passes feature-ship workflows
766
+
767
+ **Trigger.** The engineer observed that the designed Lead → Specialist → QA
768
+ collaboration was not enforced in practice — the main session dispatched
769
+ specialists directly and self-graded, bypassing the chain, with no loop driving
770
+ work to a QA-clean state. The remedy is two-layer: a cross-cutting discipline in
771
+ `team-lead-craft` §6.1 (all six teams), and a deterministic, unskippable workflow
772
+ form where stakes justify it.
773
+
774
+ **Portfolio change (PM + CTO joint brief).**
775
+
776
+ - **Two NEW team workflows:** `yasad-feature-ship`, `panim-feature-ship`.
777
+ - **Three AMENDED workflows** gain a bounded retry loop in place (no new slot):
778
+ `chosheb-feature-ship` (loop-until-ready), `mishmar-security-gate` and
779
+ `migdal-infra-change` (conservative — one remediation-proposal cycle then
780
+ escalate). Sefer is covered by the discipline layer only (no product to gate —
781
+ a workflow there would be anti-pattern #4).
782
+
783
+ **Brief, per the proposal format.**
784
+
785
+ - *Problem.* The chain is bypassable; QA convergence is not enforced.
786
+ - *Fan-out shape.* `route → implement → parallel orthogonal QA panel →
787
+ loop-until-zero-blockers (cap 3; 1–2 conservative for security/infra) →
788
+ escalate`. ≥6 agents across panel × cycles.
789
+ - *Termination predicate.* Zero `blocker`-severity findings (keys off the
790
+ existing structured QA verdicts — Uriah/Jahaziel agent contracts and the
791
+ existing workflow `{ready}`/`{decision}`/`{safe}` fields; no new contract).
792
+ - *Expected fire-count.* High — once per shipped feature on the active team;
793
+ comfortably clears the ≥10/quarter bar.
794
+ - *Anti-pattern self-check.* #1 cleared (termination predicate + parallel panel,
795
+ not a linear skill); #2 cleared (no nesting); #3 cleared (panels are
796
+ orthogonal — contract/tests/data; a11y/DS/QA; the panel excludes the
797
+ implementer so no lens self-reviews); #4 cleared (synthesis is a QA-clean
798
+ artifact or a structured escalation).
799
+
800
+ **Caps after this amendment.** Team-level total 8 → 10. Per-team: Yasad 3/4,
801
+ Panim 2/4; Chosheb/Mishmar/Migdal/Sefer unchanged (amendments use no new slot).
802
+ All within the 4/team cap.
803
+
804
+ **Loop-until-X is no longer single-use.** This supersedes the earlier framing
805
+ (`workflows/README.md`) that `knowledge-gap-discovery` was the only legitimate
806
+ loop-until-X. Bounded QA-convergence is now a sanctioned second case; the bound
807
+ (hard cycle cap + mandatory escalation, never silent settle) is what keeps it
808
+ inside the discipline. Security and infra loops are deliberately conservative:
809
+ no stateful op runs inside the loop (asymmetric delegation, rules §5).
810
+
720
811
  **Supersedes / amends:** none. Codifies the discipline implicit in D-002
721
812
  (Claude Code models only — capability discipline) and D-007 (separate stores
722
813
  — epistemic discipline) onto the orchestration layer.
@@ -1011,4 +1102,303 @@ savings carry through to those workflows.
1011
1102
 
1012
1103
  ---
1013
1104
 
1105
+ ## D-012 — Per-project isolation of the cognee work store (added 2026-06-10)
1106
+
1107
+ **Status:** adopted (per-project physical isolation); engine **resolved** to
1108
+ embedded Ladybug (Benaiah-vetted, see below); the provisioning migration is a
1109
+ follow-on plan. Co-owned by Bezalel (CTO) + Phinehas (security).
1110
+
1111
+ **Decision:** each project gets its **own physically-separate cognee work store**,
1112
+ instead of all projects sharing the single work box on `:7777`. Isolation is by
1113
+ **topology** (separate process + separate data), never by cognee's `datasets=`
1114
+ filter. This extends D-007's physical-separation principle from *curated vs work*
1115
+ to *project vs project* within work. The curated store (`:7730`) is unchanged —
1116
+ one corpus, no projects to isolate from each other.
1117
+
1118
+ **Why (the assumption that broke):** D-007 separated curated from work but assumed
1119
+ `datasets=` would scope projects *within* the work store. It does not. Verified
1120
+ against cognee v1.1.0 source + issue #1023: with `ENABLE_BACKEND_ACCESS_CONTROL=
1121
+ false` (required because cognee's access control is Neo4j-incompatible), the
1122
+ `datasets=` filter is **advisory only** — search runs against the whole graph.
1123
+ cognee's only real isolation is a physical per-dataset DB created in access-control
1124
+ mode, and Neo4j is not a supported backend for it. A `datasets=["wisemoney"]`
1125
+ query returned aiobi-mail content **including a live Gemini API key** — a
1126
+ cross-tenant confidentiality failure (Phinehas: CRITICAL), not a latent weakness.
1127
+
1128
+ **Engine (resolved — Benaiah dependency vet against cognee v1.1.0):** **embedded
1129
+ Ladybug.** `GRAPH_DATABASE_PROVIDER=ladybug` is cognee's *default* at v1.1.0 —
1130
+ `ladybug==0.16.0` is a core (non-optional) dependency with a fully-implemented
1131
+ adapter (`infrastructure/databases/graph/get_graph_engine.py`; the `kuzu` token
1132
+ aliases to the same `LadybugAdapter`). Each project = **one cognee-mcp container
1133
+ (the already-patched `mishkan/cognee-mcp` image) on its own port + own volume, with
1134
+ `GRAPH_DATABASE_PROVIDER=ladybug` and a per-project `GRAPH_FILE_PATH`** → physical
1135
+ isolation by container + volume + on-disk graph file, no Neo4j (embedded), no N×4g
1136
+ memory floor, no reliance on the failed `datasets=` filter. The Neo4j-per-project
1137
+ fallback is **not needed**.
1138
+
1139
+ *Implementation note — container, not stdio (2026-06-10).* Bezalel proposed
1140
+ evaluating a host **stdio** cognee-mcp (zero container) as the default. Evaluated and
1141
+ rejected: the recall fix (`cognee-mcp-recall-user.py` + `cognee-mcp-core-align.py`)
1142
+ lives only in the **built Docker image**, so a host checkout (`_src/cognee`, unpatched
1143
+ + core not version-aligned) would reintroduce the recall bug and require maintaining
1144
+ the patches in two places. The container path reuses the image where recall is
1145
+ *proven* working — physical isolation is identical (separate container + volume), the
1146
+ only loss vs stdio is one lightweight container per active project (no Neo4j, so far
1147
+ cheaper than today's shared Neo4j-backed store). Revisit stdio if/when cognee-mcp
1148
+ ships the #2855 fix upstream and the patches can be dropped. Supply-chain:
1149
+ Ladybug is a credible MIT fork of the Apple-archived Kuzu (founder ex-FB/Google),
1150
+ actively maintained (v0.17.1, Jun 2026), no known CVEs, version-pinned — acceptable
1151
+ for an embedded local store with no network exposure; **re-vet at 12 months** (watch
1152
+ items: ~8-month-old fork, PyPI `ladybug` namespace recently reclaimed from an
1153
+ unrelated tools suite).
1154
+
1155
+ **Provisioning:** lazy, per project at `/mishkan-init` — `ensure-work-store.sh`
1156
+ brings up the project's own Ladybug container and prints its port, substituted into
1157
+ the rendered `.mcp.json`. **Three aliases per project** (the alias is the doorway;
1158
+ the backend behind each differs):
1159
+ - **`cognee`** → this project's own Ladybug store — isolated project knowledge.
1160
+ - **`cognee-memory`** → a single **shared** session-memory store: the **kept** Neo4j
1161
+ box on `:7777`, holding **`claude_code_memory`** only. Per-client session memory
1162
+ is one continuous thing across all work and is **not re-derivable** from docs, so
1163
+ it stays a shared pillar rather than fragmenting per project. (Session memory is
1164
+ cross-project by nature; it must be kept scrubbed of project secrets/PII.)
1165
+ *Mechanism (verified, cognee v1.1.0):* two distinct layers — the **session
1166
+ conversational cache** (env `CACHING`) and the **`claude_code_memory` graph
1167
+ dataset** (env `COGNEE_MCP_AGENT_SCOPED`). Per-project stores set `CACHING=false`
1168
+ so the session cache accumulates only in `cognee-memory`; `CACHING=false` disables
1169
+ only that cache (not embedding/LLM/query caching, recall/cognify unaffected). The
1170
+ permanent `claude_code_memory` dataset is independent of `CACHING` — it is kept
1171
+ central by routing `remember()`/memory writes to the `cognee-memory` alias.
1172
+ - **`cognee-curated`** → the shared reference library (`:7730`, D-007).
1173
+
1174
+ Isolation rides on the per-project `cognee` instance; the dataset name becomes
1175
+ cosmetic. The old shared Neo4j *work* graph (project data) is **discarded** — it is
1176
+ re-derivable from tagged docs — but the **box itself is kept and repurposed** as
1177
+ `cognee-memory`; `claude_code_memory` is never pruned (D-007). So the migration
1178
+ does not delete the Neo4j box, it narrows its job to session memory.
1179
+
1180
+ **Security posture (Phinehas, gating):** the boundary must be physical and
1181
+ verifiable by topology; an application-layer filter whose enforcement just failed
1182
+ (#1023) is rejected *as the boundary* (acceptable only as defense-in-depth on top).
1183
+ **Interim controls, mandatory until per-project stores land:** the shared `:7777`
1184
+ is a **single trust domain** — no secrets, no PII; ingest opt-in + scrubbed only;
1185
+ a loud advisory-only warning at the boundary; and the already-leaked Gemini key is
1186
+ **revoked (engineer) then purged from the graph (engineer-run, Mishmar-specified)**.
1187
+
1188
+ **Alternatives considered:**
1189
+ 1. *Re-enable access control on Neo4j.* Rejected — `multi_user_support_possible()`
1190
+ raises `EnvironmentError` for Neo4j; needs a backend migration first.
1191
+ 2. *Neo4j Enterprise multi-DB (one DB per project).* Rejected as primary — standing
1192
+ license liability for a single-engineer harness; still N cognee-mcp instances;
1193
+ one Neo4j process still spans tenants. Last-resort fallback only.
1194
+ 3. *Wrapper-side post-filter on the shared graph.* Rejected — no reliable per-node
1195
+ dataset tag to filter on; a non-durable workaround (rule 3).
1196
+
1197
+ **Consequences.** *Positive:* per-project confidentiality by construction, no
1198
+ reliance on cognee's filter, bounded per-project cost (embedded ≈ free; fallback ≈
1199
+ one small Neo4j). *Negative:* loses the work-store Neo4j browser (static-HTML
1200
+ `visualize_graph` export is the fallback); existing work graphs are re-ingested
1201
+ against the new backend (cheap, idempotent via `mishkan-ingest`); a dependency on
1202
+ Ladybug's maintenance health (Benaiah-vetted; Kuzu is archived).
1203
+
1204
+ **Supersedes / amends:** extends **D-007** (physical store separation) to a
1205
+ per-project axis within work — D-007 stands unchanged. Touches **D-008**'s Cognee
1206
+ work store. The provisioning migration (`mishkan-init` rework, per-project store
1207
+ creation, re-ingest) is a follow-on `/plan` routed to Migdal, gated on the engine
1208
+ vet + Y4NN ratification.
1209
+
1210
+ ---
1211
+
1212
+ ## D-013 — Attach the MISHKAN ontology to ingested documentation (added 2026-06-11)
1213
+
1214
+ **Status:** accepted · **Drivers:** Y4NN · **Authors:** drafted by the harness, ratify with Nathan + Bezalel.
1215
+
1216
+ **Context.** `mishkan-ingest` ran `cognee.cognify(datasets=[…])` with **no ontology** — the live
1217
+ log says *"No ontology file provided. No owl ontology will be attached to the graph. [OntologyAdapter]"*,
1218
+ and ingested nodes carry `ontology_valid: false`. The harness already defines a schema in
1219
+ `payload/mishkan/ontology.md` (14 entity types, 16 edges, `blast_radius`), but it was a **markdown
1220
+ convention for agent-authored nodes** (`cognee-promote`, `context-compress`, Baruch) — never a
1221
+ machine ontology fed to cognify. So ingested documentation was graphed by unconstrained LLM
1222
+ extraction, with no link to the MISHKAN type system.
1223
+
1224
+ **Decision.** Ship a machine ontology and attach it at every `mishkan-ingest` cognify.
1225
+ - `payload/mishkan/ontology.ttl` — **Turtle/OWL**, the 1:1 machine mirror of `ontology.md` (14
1226
+ `owl:Class`, 16 `owl:ObjectProperty` with `rdfs:domain`/`range` via `owl:unionOf`, `blast_radius`
1227
+ as `owl:DatatypeProperty`). Turtle over RDF/XML for reviewability; hand-authored because the schema
1228
+ is "locked v1." `ontology.md` stays the canonical human source; `ontology.ttl` is its machine form.
1229
+ - cognee v1.1.0 reads the ontology from the **environment** (Pydantic `OntologyEnvConfig`), **not** a
1230
+ cognify kwarg (verified live — the kwarg lands in `**kwargs` and is silently ignored).
1231
+ `docker-compose.work.yml` sets `ONTOLOGY_RESOLVER=rdflib` · `MATCHING_STRATEGY=fuzzy` (already the
1232
+ defaults) · `ONTOLOGY_FILE_PATH=/home/cognee/ontology.ttl`; `ensure-work-store.sh` stages the ttl to
1233
+ that path at provision (idempotent). **Fail-open:** missing file → cognee warns, ingests
1234
+ ontology-free. So the ontology applies to *every* cognify in the work store, not just `mishkan-ingest`.
1235
+ - ONE shared ontology for all projects (the MISHKAN schema is global), even though work stores are
1236
+ per-project (D-012).
1237
+
1238
+ **Caveat (sets expectations).** cognee's resolver marks `ontology_valid=true` and adds parent/object-
1239
+ property edges **only where the LLM-extracted entity *type names* match ontology class names**. The
1240
+ default `KnowledgeGraph` extraction assigns free-form types; it will not emit `Decision` /
1241
+ `ResearchOutput` / `Incident` unless steered. So this pass gives **validation + enrichment of matches**,
1242
+ not full retyping of prose into MISHKAN classes. Forcing the taxonomy (custom prompt / graph_model)
1243
+ is a **Phase 2**, opened only if Phase-1 `ontology_valid` coverage proves too thin.
1244
+
1245
+ **Alternatives considered.** (1) *markdown→ttl generator* — rejected for now: a locked v1 schema does
1246
+ not justify the build step (revisit if it starts churning). (2) *RDF/XML* — rejected: far less
1247
+ reviewable than Turtle for a hand-authored, versioned artifact.
1248
+
1249
+ **Consequences.** *Positive:* ingested docs are linked to the type system where they match; the
1250
+ `CuratedResource`/`CaseNode`/etc. classes become real, queryable types; sets up the D-014 research→
1251
+ curated feed. *Negative:* a second artifact (`ontology.ttl`) to keep in sync with `ontology.md`
1252
+ (guarded by a label-coverage check); ontology benefit is partial until Phase-2 extraction steering.
1253
+
1254
+ **Refs:** extends **D-008** (knowledge surfaces) and rides on **D-012** (per-project store). Mechanism
1255
+ confirmed against the installed cognee v1.1.0 source (`modules/ontology/ontology_env_config.py` +
1256
+ `get_ontology_resolver_from_env`): env-config only, requires resolver `rdflib` + strategy `fuzzy` +
1257
+ a file path (resolver/strategy already default to those values). Out of scope: agent-write paths
1258
+ (already convention-bound); the **curated** store (its nodes are pre-typed by the structured seed —
1259
+ `add_data_points`, no cognify extraction — so no ontology needed there); back-filling existing graphs.
1260
+
1261
+ ---
1262
+
1263
+ ## D-015 — Unified semantic `mishkan` control surface for the knowledge stack (added 2026-06-11)
1264
+
1265
+ **Status:** accepted · **Drivers:** Y4NN · **Authors:** drafted by the harness, ratify with Bezalel.
1266
+
1267
+ **Context.** The engineer drove every stateful cognee op by hand across scattered compose files and
1268
+ scripts (a 3-file `docker compose` incantation, `ensure-work-store.sh`, manual `docker rm -f`/`volume
1269
+ rm`, `ensure-curated-box.sh`, ad-hoc `docker ps`). High friction, high recall load. Two robustness gaps
1270
+ also surfaced this session: a docker rename/orphan race (fixed, `a9cf950`) and a TUI daemon-probe that
1271
+ mis-read a *wedged* `watchd` as healthy.
1272
+
1273
+ **Decision.** Extend the `mishkan` CLI into one control surface, governed by a strict naming rule and
1274
+ the asymmetric-delegation boundary (D-005).
1275
+
1276
+ - **Naming rule (semantic, object-first):** a command must name *what it operates on*.
1277
+ - **Bare verb IFF the object is the tool itself** — `mishkan install | uninstall | status`. (Not
1278
+ `harness install`: the npm pkg is `mishkan-harness`, so `npx mishkan-harness harness install`
1279
+ doubles "harness".)
1280
+ - **`mishkan <object> <verb>` for every subsystem** — `knowledge configure|ingest`,
1281
+ `knowledge-stack up|down|restart|status`, `project-work-store [<slug>] up|down|reset`,
1282
+ `code-graph status|open|scan`, `observability install|open`, `org show`. Descriptive compound
1283
+ objects (`knowledge-stack`, `project-work-store`) are preferred over brevity — a bare `start`
1284
+ ("start *what*?") or a topology noun the user must decode (`stack`/`memory`/`foundation`) are both
1285
+ rejected. `knowledge-stack` = infra lifecycle (`up`); `project-work-store` = data lifecycle (`reset`).
1286
+ - **Rule-5 boundary (the crux):** the CLI **executes** because the *human* invokes it — D-005 forbids
1287
+ *agents* running stateful ops, and they still can't (the bin is never in an agent tool set); the TUI
1288
+ still can't either (it only *surfaces* the command, never runs it). Destructive ops (`stop`, `reset`)
1289
+ gate on a confirm.
1290
+ - **Guided bring-up, not a thin wrapper:** `knowledge-stack up` preflights config (docker present,
1291
+ `.env`, `COGNEE_MCP_REF`) and, on a gap, prints the exact fix and stops — never a cryptic docker
1292
+ error. `project-work-store up` warns if the stack is down. `/mishkan-init` composes the two:
1293
+ `knowledge-stack up` (ensure infra, confirm-if-down) + `project-work-store up` (this project).
1294
+ - **TUI hardening:** `_probe_socket` now reads the daemon's on-connect `{"type":"snapshot"}` frame and
1295
+ validates it, so a *wedged* watchd is replaced rather than adopted (client-side only).
1296
+
1297
+ **Alternatives considered.** (1) bare `start`/`stop` — rejected (object-less). (2) `stack`/`memory`
1298
+ nouns — rejected (require decoding internal topology). (3) start/stop *buttons* in the TUI — rejected,
1299
+ moves stateful control into a tool (breaks D-005). (4) the CLI re-implementing the scripts — rejected;
1300
+ it *wraps* them so the scripts stay the single source of truth.
1301
+
1302
+ **Consequences.** *Positive:* one low-recall surface; preflight/guide kills cryptic failures; the TUI
1303
+ points at the fix without executing it; daemon self-heals on wedge. *Negative:* renames published
1304
+ commands (`configure-knowledge`→`knowledge configure`, `observability`→`observability install`,
1305
+ `org`→`org show`) — old flat names kept as hidden working aliases so nothing breaks mid-migration; help,
1306
+ install sign-off, docs/usage, README, and the org-reference command updated in the same pass.
1307
+
1308
+ **Refs:** rides on D-005 (asymmetric delegation), D-008 (knowledge surfaces), D-012 (per-project store).
1309
+
1310
+ ---
1311
+
1312
+ ## D-016 — Engineer-gated promotion of research findings into the curated library (added 2026-06-11)
1313
+
1314
+ **Context.** The curated library (`cognee-curated`, :7730) is the org-wide reference surface (D-007),
1315
+ but it was **seed-only**: `ingest-curated.py` *prunes then writes*, so it cannot grow additively without
1316
+ wiping curated. The research pipeline writes `ResearchOutput`/`CaseNode` to the per-project **work** store
1317
+ (D-012), never curated; and **no agent has a curated-write tool** — curated is read-only at the agent layer
1318
+ by design. So a reusable resource Caleb finds (a vendor doc, a spec, a primary reference) dies in one
1319
+ project. The ontology already ships `CuratedResource` + `CuratedLibraryHit` for exactly this growth — only
1320
+ the wire was missing.
1321
+
1322
+ **Decision.** Add an **engineer-gated** path to grow curated, additive and deduped, with the human as the
1323
+ library's editor:
1324
+ 1. **Shemaiah** (evaluate) emits a structured `curated_promotion_candidate` (name, url, problem_class,
1325
+ team, source_tier, why) **only when** `verdict=resolved` + `confidence≥medium` +
1326
+ `curated_library_agreement=not_covered` + real cross-project reuse. It nominates; it writes nothing.
1327
+ 2. **Baruch** (report) copies the candidate into the research-log **and** appends it to an engineer queue
1328
+ `~/.claude/mishkan/curated-candidates.jsonl`. Baruch has `Write` but still **no** curated-write tool —
1329
+ the boundary holds. The research-log schema is `additionalProperties:false`, so the new optional field
1330
+ was added to **both** `templates/research-log.schema.json` and `scripts/validate-research-log.sh`
1331
+ (with a bash-layer shape check so a malformed candidate fails without ajv).
1332
+ 3. **The engineer** runs `mishkan knowledge curate` — it lists pending candidates, asks per candidate, and
1333
+ on approval runs `scripts/promote-curated.sh` → `cognee/promote-curated.py`: an **additive** write
1334
+ (`CuratedResource` DataPoint + `add_data_points`, **no prune**), deduped by url against the seed manifest
1335
+ and a promoted ledger, via `docker exec` into `mishkan-curated-mcp`. Stateful — the human runs it, never
1336
+ an agent, never automatic.
1337
+ 4. **Telemetry.** Ezra's curated short-circuit records the matched resource (a `CuratedLibraryHit` signal),
1338
+ so a promoted resource's usefulness is measurable and dead weight is auditable.
1339
+
1340
+ **Why engineer-gated, not auto.** Auto-promotion was rejected: the curated surface is shared across every
1341
+ project, so an unvetted write pollutes it for all, and (per D-012) research output can carry PII/secrets —
1342
+ a human scrub before a shared write is the safety boundary. Phinehas reviews PII/secret-scrub on a
1343
+ candidate; Bezalel ratifies the additive-write design; Nathan authored the ADR.
1344
+
1345
+ **Consequences.** *Positive:* curated grows from real work without a re-seed; the prune-based seed stays
1346
+ intact for bootstrap; the agent-layer read-only boundary is preserved end-to-end; dedup keeps the library
1347
+ clean; the hit signal makes promotions falsifiable. *Negative:* one more human-gated step (the engineer
1348
+ must run `mishkan knowledge curate`); the dedup ledger assumes these scripts own curated writes (a manual
1349
+ out-of-band write to curated would not be in the ledger — documented boundary).
1350
+
1351
+ **Out of scope:** auto-promotion (rejected); the seed (`ensure-curated-box.sh` / `seed-curated-library.sh`
1352
+ unchanged); work-store promotion (`cognee-promote` work tiers unchanged); any agent curated-write tool
1353
+ (stays read-only).
1354
+
1355
+ **Refs:** rides on D-005 (asymmetric delegation — the write is the engineer's hands), D-007 (curated
1356
+ library), D-008 (knowledge surfaces), D-012 (per-project store / PII boundary), D-013 (ontology types
1357
+ `CuratedResource` + `CuratedLibraryHit`), D-015 (the `mishkan knowledge curate` control surface).
1358
+
1359
+ ---
1360
+
1361
+ ## D-017 — User-editable model-tier routing via a preserved overlay (added 2026-06-13)
1362
+
1363
+ **Context.** D-002 made `model-routing.yaml` the central tier map and the `model-route.py` hook reads it
1364
+ live, so a tier change takes effect on the next delegation with no reinstall. But two gaps made re-tiering
1365
+ impractical for the engineer: (1) it is developer-facing YAML with no friendly surface, and (2)
1366
+ `mishkan install` overwrites `model-routing.yaml` (it sits inside the `copyDir(payload/mishkan,…)` tree),
1367
+ so a hand edit is clobbered on the next update. The Fable suspension (D-002 amendment 2026-06-12) made
1368
+ this urgent: a tier can vanish overnight, and the engineer needs to adapt routing — for availability,
1369
+ cost, or preference — without editing source and reinstalling.
1370
+
1371
+ **Decision.** Add a `mishkan model` control surface backed by a **preserved overlay file**:
1372
+ - **`model-routing.local.yaml`** holds the engineer's per-agent overrides. The hook reads the shipped
1373
+ default, then overlays local (local wins per-agent); fail-open is preserved (absent or malformed
1374
+ overlay → behaves exactly as the single-file routing). The installer **places it once and preserves
1375
+ it** — and because `copyDir` ships no such file and never deletes destination extras, a refresh can
1376
+ never clobber it (the same place-once philosophy as `engineer-standards.md`). This is an **overlay**,
1377
+ not a preserve-the-whole-file scheme: the shipped default keeps flowing on every update (new agents,
1378
+ baseline changes), while the engineer's deltas persist on top — no drift.
1379
+ - **`mishkan model show | set <agent|team|all> <tier> | reset [target]`** edits ONLY the overlay — never
1380
+ the shipped default, never the 45 frontmatter files. `team` expands via `org/org.json` (the same source
1381
+ as `mishkan org show`). `set` validates the tier and, for a **dormant** tier (`fable`, currently
1382
+ suspended), warns and confirms. `show` flags any agent routed to a dormant tier.
1383
+
1384
+ **Why overlay over preserve-the-file (Bezalel ratified).** Preserving a user-edited `model-routing.yaml`
1385
+ would freeze it: future baseline changes (the Fable revert, a new agent, a re-tier) would never reach an
1386
+ engineer who once edited it — the installed-runtime-vs-source drift trap. The overlay keeps the two
1387
+ concerns separate: harness owns the default, engineer owns the deltas.
1388
+
1389
+ **Consequences.** *Positive:* routing is now the engineer's to change at will, instantly (hook reads live)
1390
+ and durably (survives updates); responds to abrupt availability changes without a code change; no
1391
+ 45-frontmatter churn. *Negative:* two files now express routing (default + overlay) — mitigated by
1392
+ `mishkan model show` rendering the effective merge; an overlay entry set equal to the default is harmless
1393
+ redundancy.
1394
+
1395
+ **Out of scope:** named profiles (`thrifty`/`max`) — `set`/`reset` cover edit-by-intent; profiles are a
1396
+ thin future follow-up over the same overlay. No auto-detection of model availability (the dormant warning
1397
+ is static). Agent frontmatter `model:` stays the shipped fallback used only if the hook is absent.
1398
+
1399
+ **Refs:** rides on D-002 (the tier model + the routing hook), D-005 (the CLI is human-run), D-015 (the
1400
+ semantic `mishkan <object> <verb>` surface this extends with `model`).
1401
+
1402
+ ---
1403
+
1014
1404
  *Decisions locked May 2026. Revisit only with a dated amendment below.*
@@ -583,14 +583,14 @@ empty state dim-centered.
583
583
  ║ ○1 Live ○2 Agents ○3 Workflows ●4 Knowledge ○5 Activity 2 sessions 12:03 ║
584
584
  ╠══ COGNEE STORES ═══════════════════════════════════════════════════════════════════════╣
585
585
  ║ ║
586
- ║ ╭─ work :7777 ────────────────╮ ╭─ curated :7730 ──────────────╮
587
- ║ │ ● UP · 02h14m │ │ ● UP · 43h12m │
588
- ║ │ │ │ │
589
- ║ │ 1,247 nodes │ │ 96 nodes │
590
- ║ │ ▁▁▂▃▃▅▆█ +12 last 5min │ │ ▁▁▁▁▂▂▃▃ +0 last 30min │
591
- ║ │ last ingest 12:02:14 │ │ last seed 2026-05-29 │
592
- ║ │ embeddings: gemini 3072d │ │ embeddings: ollama 768d │
593
- ╰─────────────────────────────╯ ╰──────────────────────────────╯
586
+ ║ ╭─ cognee-memory :7777 ──────────╮ ╭─ curated :7730 ──────────────╮
587
+ ║ │ ● UP · 02h14m │ │ ● UP · 43h12m │
588
+ ║ │ session memory only │ │ │
589
+ ║ │ 1,247 nodes │ │ 96 nodes │
590
+ ║ │ ▁▁▂▃▃▅▆█ +12 last 5min │ │ ▁▁▁▁▂▂▃▃ +0 last 30min │
591
+ ║ │ last ingest 12:02:14 │ │ last seed 2026-05-29 │
592
+ ║ │ embeddings: gemini 3072d │ │ embeddings: ollama 768d │
593
+ ╰───────────────────────────────╯ ╰──────────────────────────────╯
594
594
  ║ ║
595
595
  ╠══ RECENT OPS ═════════════════════════════════════════════════════════════════════════╣
596
596
  ║ time store op query / path ms Δnodes ║