mishkan-harness 0.2.0 → 0.2.4
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.
- package/README.md +108 -172
- package/bin/mishkan.js +677 -16
- package/docs/design/MISHKAN_decisions.md +450 -8
- package/docs/design/MISHKAN_harness_design.md +1 -33
- package/docs/design/MISHKAN_observability.md +13 -9
- package/docs/engineer/profile-readable.md +201 -0
- package/docs/engineer/profile.md +754 -0
- package/docs/research/graphify-token-saving-poc.md +108 -0
- package/docs/usage/09-workflows.md +74 -4
- package/docs/usage/10-observability.md +37 -13
- package/docs/usage/11-graphify.md +264 -0
- package/docs/usage/12-skill-discovery.md +294 -0
- package/docs/usage/README.md +5 -3
- package/package.json +1 -1
- package/payload/install/settings.hooks.json +24 -0
- package/payload/mishkan/AGENT_SPEC.md +25 -7
- package/payload/mishkan/agents/ahikam.md +4 -2
- package/payload/mishkan/agents/aholiab.md +4 -2
- package/payload/mishkan/agents/asaph.md +5 -2
- package/payload/mishkan/agents/baruch.md +19 -2
- package/payload/mishkan/agents/benaiah.md +4 -2
- package/payload/mishkan/agents/bezalel.md +4 -2
- package/payload/mishkan/agents/caleb.md +4 -2
- package/payload/mishkan/agents/deborah.md +4 -2
- package/payload/mishkan/agents/elasah.md +4 -2
- package/payload/mishkan/agents/eliashib.md +4 -2
- package/payload/mishkan/agents/ezra.md +4 -2
- package/payload/mishkan/agents/hanun.md +5 -2
- package/payload/mishkan/agents/hiram.md +5 -2
- package/payload/mishkan/agents/hizkiah.md +5 -2
- package/payload/mishkan/agents/huldah.md +4 -2
- package/payload/mishkan/agents/huram.md +4 -2
- package/payload/mishkan/agents/hushai.md +5 -2
- package/payload/mishkan/agents/igal.md +4 -2
- package/payload/mishkan/agents/ira.md +5 -2
- package/payload/mishkan/agents/jahaziel.md +5 -2
- package/payload/mishkan/agents/jakin.md +4 -2
- package/payload/mishkan/agents/jehonathan.md +5 -2
- package/payload/mishkan/agents/jehoshaphat.md +4 -2
- package/payload/mishkan/agents/joab.md +5 -2
- package/payload/mishkan/agents/joah.md +5 -2
- package/payload/mishkan/agents/maaseiah.md +4 -2
- package/payload/mishkan/agents/meremoth.md +5 -2
- package/payload/mishkan/agents/meshullam.md +5 -2
- package/payload/mishkan/agents/nathan.md +5 -2
- package/payload/mishkan/agents/nehemiah.md +4 -2
- package/payload/mishkan/agents/obed.md +4 -2
- package/payload/mishkan/agents/oholiab.md +5 -2
- package/payload/mishkan/agents/palal.md +5 -2
- package/payload/mishkan/agents/phinehas.md +4 -2
- package/payload/mishkan/agents/rehum.md +4 -2
- package/payload/mishkan/agents/salma.md +5 -2
- package/payload/mishkan/agents/seraiah.md +4 -2
- package/payload/mishkan/agents/shallum.md +5 -2
- package/payload/mishkan/agents/shaphan.md +4 -2
- package/payload/mishkan/agents/shemaiah.md +4 -2
- package/payload/mishkan/agents/shevna.md +5 -2
- package/payload/mishkan/agents/uriah.md +5 -2
- package/payload/mishkan/agents/zaccur.md +4 -2
- package/payload/mishkan/agents/zadok.md +5 -2
- package/payload/mishkan/agents/zerubbabel.md +4 -2
- package/payload/mishkan/commands/code-graph.md +35 -0
- package/payload/mishkan/commands/eval-baruch.md +57 -0
- package/payload/mishkan/commands/mishkan-org-reference.md +58 -0
- package/payload/mishkan/commands/mishkan-resume.md +19 -5
- package/payload/mishkan/commands/mishkan-skills-misses.md +47 -0
- package/payload/mishkan/commands/mishkan-skills-reindex.md +33 -0
- package/payload/mishkan/commands/skills.md +35 -0
- package/payload/mishkan/commands/sprint-close.md +3 -1
- package/payload/mishkan/hooks/pre-tool-knowledge-route.sh +231 -0
- package/payload/mishkan/hooks/pre-tool-task-skill-route.sh +122 -0
- package/payload/mishkan/hooks/session-start-skill-index.sh +35 -0
- package/payload/mishkan/observability/schema.json +1 -1
- package/payload/mishkan/observability/watch/src/mishkan_watch/__main__.py +84 -2
- package/payload/mishkan/observability/watch/src/mishkan_watch/app.py +64 -3
- package/payload/mishkan/observability/watch/src/mishkan_watch/org_data.py +79 -0
- package/payload/mishkan/observability/watch/src/mishkan_watch/skills_data.py +267 -0
- package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/agents.py +33 -1
- package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/knowledge.py +118 -9
- package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/live.py +102 -2
- package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/org.py +139 -0
- package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/skills.py +187 -0
- package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/usage.py +377 -0
- package/payload/mishkan/observability/watch/src/mishkan_watch/tabs/workflows.py +199 -27
- package/payload/mishkan/observability/watch/src/mishkan_watch/theme.tcss +78 -4
- package/payload/mishkan/observability/watchd/src/mishkan_watchd/__main__.py +36 -6
- package/payload/mishkan/observability/watchd/src/mishkan_watchd/sources/bus_tail.py +16 -3
- package/payload/mishkan/observability/watchd/src/mishkan_watchd/sources/graphify_tail.py +220 -0
- package/payload/mishkan/observability/watchd/src/mishkan_watchd/sources/worktree_poll.py +13 -2
- package/payload/mishkan/observability/watchd/src/mishkan_watchd/state.py +157 -3
- package/payload/mishkan/observability/watchd/tests/test_state.py +6 -2
- package/payload/mishkan/org/org.json +141 -0
- package/payload/mishkan/scripts/pre-commit-eval-gate.sh +50 -0
- package/payload/mishkan/scripts/skill-discovery-indexer.py +462 -0
- package/payload/mishkan/scripts/skill-discovery-misses.py +173 -0
- package/payload/mishkan/scripts/skill-discovery-router.py +457 -0
- package/payload/mishkan/scripts/skill-discovery-smoke.sh +156 -0
- package/payload/mishkan/skills/graphify-query-craft/SKILL.md +162 -0
- package/payload/mishkan/skills/mishkan-init/SKILL.md +15 -0
- package/payload/mishkan/skills/skill-discovery/SKILL.md +120 -0
- package/payload/mishkan/templates/case-node.schema.json +1 -0
- package/payload/mishkan/templates/observability-log.schema.json +1 -0
- package/payload/mishkan/workflows/README.md +78 -13
- package/payload/mishkan/workflows/chosheb-feature-ship.js +75 -0
- package/payload/mishkan/workflows/migdal-dr-drill.js +94 -0
- package/payload/mishkan/workflows/migdal-infra-change.js +67 -0
- package/payload/mishkan/workflows/mishkan-blast-radius.js +144 -0
- package/payload/mishkan/workflows/mishkan-init.js +58 -0
- package/payload/mishkan/workflows/mishkan-knowledge-gap-discovery.js +121 -0
- package/payload/mishkan/workflows/mishkan-standards-rollout.js +153 -0
- package/payload/mishkan/workflows/mishmar-security-gate.js +83 -0
- package/payload/mishkan/workflows/panim-ds-rollout.js +83 -0
- package/payload/mishkan/workflows/sefer-release-notes.js +85 -0
- package/payload/mishkan/workflows/yasad-data-migration-wave.js +78 -0
- package/payload/mishkan/workflows/yasad-schema-evolution.js +76 -0
- package/payload/mishkan/templates/user-CLAUDE.md +0 -62
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# 12 — Skill discovery
|
|
2
|
+
|
|
3
|
+
> Goal: surface the right installed skills for the current task without
|
|
4
|
+
> bloating context. Universal indexer + 3-mechanism router + 3-bucket
|
|
5
|
+
> output. Advisory — the model decides what to load. Decision: see
|
|
6
|
+
> [D-011](../design/MISHKAN_decisions.md#d-011--universal-skill-discovery-layer-added-2026-06-07).
|
|
7
|
+
|
|
8
|
+
## Why this exists
|
|
9
|
+
|
|
10
|
+
The harness ships 40+ MISHKAN craft skills, and the user surface adds
|
|
11
|
+
dozens more (`~/.claude/skills/`, plugin-bundled, project-local). Two
|
|
12
|
+
failure modes compete: silent reinvention (work that a skill already
|
|
13
|
+
encodes), and context bloat (loading too many skills "just in case"). The
|
|
14
|
+
discovery layer collapses that tension into a single advisory pass.
|
|
15
|
+
|
|
16
|
+
## What gets installed
|
|
17
|
+
|
|
18
|
+
| Component | Path | Role |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Indexer | `~/.claude/mishkan/scripts/skill-discovery-indexer.py` | Scans every skill root, writes `index.json` |
|
|
21
|
+
| Router | `~/.claude/mishkan/scripts/skill-discovery-router.py` | Reads index, scores skills for a task, emits 3 buckets |
|
|
22
|
+
| Skill | `~/.claude/mishkan/skills/skill-discovery/` | Tells the main session how to invoke + interpret |
|
|
23
|
+
| `/skills` | `~/.claude/commands/skills.md` | Run the router on the current task |
|
|
24
|
+
| `/mishkan-skills-reindex` | `~/.claude/commands/mishkan-skills-reindex.md` | Manual full rebuild |
|
|
25
|
+
|
|
26
|
+
Output lands at `~/.claude/mishkan/skill-discovery/`:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
index.json — universal index, one entry per indexed skill
|
|
30
|
+
misses.jsonl — every empty-result routing (tuning signal)
|
|
31
|
+
indexer-errors.jsonl — per-skill indexer failures
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Roots scanned (precedence order)
|
|
35
|
+
|
|
36
|
+
The indexer scans these roots **in order**. First hit on a name wins;
|
|
37
|
+
shadowed entries are recorded in `meta.collisions`, not silently dropped:
|
|
38
|
+
|
|
39
|
+
1. `~/.claude/mishkan/skills/` — `origin = mishkan`
|
|
40
|
+
2. `~/.claude/skills/` — `origin = user`
|
|
41
|
+
3. `~/.claude/plugins/*/skills/` — `origin = plugin`
|
|
42
|
+
4. `<repo>/.claude/skills/` — `origin = project`
|
|
43
|
+
|
|
44
|
+
## Indexer commands
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Full rescan (install/update default)
|
|
48
|
+
python3 ~/.claude/mishkan/scripts/skill-discovery-indexer.py --rebuild
|
|
49
|
+
|
|
50
|
+
# Cheap session-boot sweep (rebuilds only if mtime is newer than last_scan)
|
|
51
|
+
python3 ~/.claude/mishkan/scripts/skill-discovery-indexer.py --stat-only
|
|
52
|
+
|
|
53
|
+
# Manual rebuild (records manual=True in meta)
|
|
54
|
+
python3 ~/.claude/mishkan/scripts/skill-discovery-indexer.py --manual
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Router usage
|
|
58
|
+
|
|
59
|
+
The router accepts a task description on `--task` or on stdin, and emits a
|
|
60
|
+
3-bucket JSON to stdout:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
python3 ~/.claude/mishkan/scripts/skill-discovery-router.py \
|
|
64
|
+
--task "Refactor the auth module to use JWT with refresh tokens" \
|
|
65
|
+
--relevant-categories security,backend
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Output shape (abbreviated):
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"task_summary": "...",
|
|
73
|
+
"must_load": [
|
|
74
|
+
{ "name": "auth-implementation-patterns", "score": 7.2, "origin": "user",
|
|
75
|
+
"category": "security", "trust": "third-party (user); ..." }
|
|
76
|
+
],
|
|
77
|
+
"should_consider": [ ... ],
|
|
78
|
+
"adjacent": [ ... ],
|
|
79
|
+
"total_returned": 6,
|
|
80
|
+
"warnings": [],
|
|
81
|
+
"stale_rebuild_needed": false
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## The 3 buckets — semantics
|
|
86
|
+
|
|
87
|
+
| Bucket | Cap | When it fires | What the model does |
|
|
88
|
+
|---|---|---|---|
|
|
89
|
+
| `must_load` | ≤ 3 | Score ≥ `threshold_high` (default 4.0) and strong trigger match | Load these into context as the directly-relevant skills. |
|
|
90
|
+
| `should_consider` | ≤ 5 | Mid-band (≥ `threshold_mid`, < `threshold_high`) | Skim description; load if the work clearly intersects. |
|
|
91
|
+
| `adjacent` | ≤ 5 | Low score, same category | Awareness only; mention if helpful; do not load. |
|
|
92
|
+
|
|
93
|
+
**Hard cap:** 13 total. **Bias rule:** prefer enriching `should_consider`
|
|
94
|
+
over padding `must_load` when scores are close — the cost of loading a
|
|
95
|
+
wrong skill is higher than the cost of skipping a marginal one.
|
|
96
|
+
|
|
97
|
+
## Trust asymmetry
|
|
98
|
+
|
|
99
|
+
Every entry carries an `origin` field. Non-`mishkan` entries (origin =
|
|
100
|
+
`user`, `plugin`, or `project`) carry a `trust` warning in the router
|
|
101
|
+
output and **must not be auto-loaded for stateful operations** — the
|
|
102
|
+
y4nn-standards §5 boundary (git push, SSH to prod, docker exec on prod,
|
|
103
|
+
sudo, schema migration, log forensics). For generative work, third-party
|
|
104
|
+
skills are fine to load once you've read the description.
|
|
105
|
+
|
|
106
|
+
## Refresh triggers
|
|
107
|
+
|
|
108
|
+
| Trigger | Mode | Notes |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| Install / update | `--rebuild` | Full rescan; runs once at install time |
|
|
111
|
+
| Session boot | `--stat-only` | mtime sweep vs `meta.last_scan`; rebuilds only on change |
|
|
112
|
+
| Manual | `--manual` (or `/mishkan-skills-reindex`) | Sets `meta.manual = true` |
|
|
113
|
+
| Stale entry at routing time | router drops + warns | `stale_rebuild_needed: true` in output |
|
|
114
|
+
|
|
115
|
+
## Failure modes — fail-open
|
|
116
|
+
|
|
117
|
+
Everywhere:
|
|
118
|
+
|
|
119
|
+
- Indexer error on a single skill → that skill is skipped, error recorded
|
|
120
|
+
to `indexer-errors.jsonl`, index still writes.
|
|
121
|
+
- Router error → empty buckets, miss recorded to `misses.jsonl`, exit 0.
|
|
122
|
+
- Index missing/unreadable → router returns `stale_rebuild_needed: true`.
|
|
123
|
+
|
|
124
|
+
The discovery layer never blocks a session. If it fails, the only impact
|
|
125
|
+
is that you don't get the advisory pass — you fall back to memory and
|
|
126
|
+
explicit naming, which is exactly how the harness worked before D-011.
|
|
127
|
+
|
|
128
|
+
## Phase 1 scope
|
|
129
|
+
|
|
130
|
+
Wired in two places only:
|
|
131
|
+
|
|
132
|
+
1. `/skills` slash command — invoke the router on demand.
|
|
133
|
+
2. `mishkan-init` workflow — `SkillRouter` phase runs early; result is
|
|
134
|
+
folded into Bezalel's signoff context as advisory.
|
|
135
|
+
|
|
136
|
+
Other workflows route through their existing craft skills unchanged.
|
|
137
|
+
|
|
138
|
+
## Phase 2 — automatic discovery
|
|
139
|
+
|
|
140
|
+
Phase 2 turns "the router exists" into "agents auto-discover skills
|
|
141
|
+
without being asked." Three injection mechanisms ship; the `mishkan-init`
|
|
142
|
+
canary above stays in place — Phase 2 adds auto-routing as the dominant
|
|
143
|
+
path everywhere else. All three are fail-open and never block.
|
|
144
|
+
|
|
145
|
+
### Mechanism 1 — install-time rebuild
|
|
146
|
+
|
|
147
|
+
The npm installer runs the indexer in `--rebuild` mode at the end of
|
|
148
|
+
phase 1, so `~/.claude/mishkan/skill-discovery/index.json` is seeded
|
|
149
|
+
before any session boots. A missing `python3` or an indexer error logs a
|
|
150
|
+
warning and the install continues; recover with
|
|
151
|
+
`/mishkan-skills-reindex`.
|
|
152
|
+
|
|
153
|
+
### Mechanism 2 — SessionStart drift check
|
|
154
|
+
|
|
155
|
+
`hooks/session-start-skill-index.sh` runs on every session boot and
|
|
156
|
+
calls the indexer in `--stat-only` mode. It compares each indexed
|
|
157
|
+
SKILL.md mtime against `meta.last_scan` and rebuilds only on drift.
|
|
158
|
+
|
|
159
|
+
| Property | Value |
|
|
160
|
+
|---|---|
|
|
161
|
+
| Hook event | `SessionStart` (matcher `""`) |
|
|
162
|
+
| p95 budget | 200 ms |
|
|
163
|
+
| Worst case | full rebuild — bounded by skill file count |
|
|
164
|
+
| Failure mode | exit 0 silently; router surfaces `index_missing_or_unreadable` on next call |
|
|
165
|
+
|
|
166
|
+
### Mechanism 3 — PreToolUse auto-injection on `Task` / `Agent`
|
|
167
|
+
|
|
168
|
+
`hooks/pre-tool-task-skill-route.sh` is the load-bearing piece. It:
|
|
169
|
+
|
|
170
|
+
1. Fires only on `Task` and `Agent` tool calls (matcher `Task|Agent`,
|
|
171
|
+
sharing the same matcher block as `model-route.py`).
|
|
172
|
+
2. Reads the Claude Code hook stdin payload, extracts
|
|
173
|
+
`tool_input.prompt`, and trims to 4 KB.
|
|
174
|
+
3. Runs the router with `--format injection --max-injection-tokens 600`.
|
|
175
|
+
4. Returns the resulting compact markdown block via the documented
|
|
176
|
+
PreToolUse field `hookSpecificOutput.additionalContext` — Claude
|
|
177
|
+
prepends it to the subagent's prompt.
|
|
178
|
+
5. Skips injection entirely when the buckets are empty (no
|
|
179
|
+
"no skills found" noise).
|
|
180
|
+
6. Emits a `hook_fire` observability event for every fire (decision =
|
|
181
|
+
`allow` with injection, `ok` without).
|
|
182
|
+
|
|
183
|
+
Hard caps:
|
|
184
|
+
|
|
185
|
+
- ≤ 3 `must_load` + ≤ 3 `should_consider` entries (Phase 1's `adjacent`
|
|
186
|
+
bucket is dropped at injection time).
|
|
187
|
+
- ≤ 600 tokens of prepended markdown (router enforces by trimming
|
|
188
|
+
`should_consider` tail-first).
|
|
189
|
+
- Trust marker preserved: non-`mishkan` entries are suffixed with
|
|
190
|
+
`(community)` in the rendered block.
|
|
191
|
+
|
|
192
|
+
| Property | Value |
|
|
193
|
+
|---|---|
|
|
194
|
+
| Hook event | `PreToolUse` (matcher `Task\|Agent`) |
|
|
195
|
+
| p95 budget | 100 ms |
|
|
196
|
+
| Hard timeout | 1.5 s (kills a wedged interpreter; still exits 0) |
|
|
197
|
+
| Failure mode | no output, exit 0; Task call proceeds without advisory |
|
|
198
|
+
|
|
199
|
+
### Injection block shape
|
|
200
|
+
|
|
201
|
+
```
|
|
202
|
+
## Discovered skills (advisory)
|
|
203
|
+
|
|
204
|
+
**Load now (high relevance):**
|
|
205
|
+
- <name>: <one-line description>
|
|
206
|
+
- <name>: <one-line description>
|
|
207
|
+
|
|
208
|
+
**Consider:**
|
|
209
|
+
- <name>: <one-line description>
|
|
210
|
+
|
|
211
|
+
These skills were surfaced by the harness's skill-discovery router. Loading is your call.
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Disabling a mechanism per-session
|
|
215
|
+
|
|
216
|
+
Each mechanism is wired into `~/.claude/settings.json` after install. To
|
|
217
|
+
silence one without uninstalling the harness, edit
|
|
218
|
+
`settings.json` and remove the matching `hooks` entry:
|
|
219
|
+
|
|
220
|
+
| Mechanism | Match in settings.json |
|
|
221
|
+
|---|---|
|
|
222
|
+
| Install-time rebuild | (one-shot at install; nothing to disable runtime) |
|
|
223
|
+
| SessionStart drift check | `SessionStart` → command ending in `session-start-skill-index.sh` |
|
|
224
|
+
| PreToolUse Task injection | `PreToolUse` matcher `Task\|Agent` → command ending in `pre-tool-task-skill-route.sh` |
|
|
225
|
+
|
|
226
|
+
Project-local override: drop a `.claude/settings.local.json` in the
|
|
227
|
+
project with the same `hooks` event but an empty `hooks` array; Claude
|
|
228
|
+
Code merges project settings over user-level ones.
|
|
229
|
+
|
|
230
|
+
### Misses telemetry — surfacing the signal
|
|
231
|
+
|
|
232
|
+
Every empty-bucket routing lands in `misses.jsonl`. Aggregate it with:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
python3 ~/.claude/mishkan/scripts/skill-discovery-misses.py --top 10
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
or the slash command `/mishkan-skills-misses`. The report clusters
|
|
239
|
+
recurring task patterns by sorted-keyword signature, breaks down by
|
|
240
|
+
reason (`no_match_above_threshold`, `index_missing_or_unreadable`,
|
|
241
|
+
`router_exception:*`, …), and dates the observation window.
|
|
242
|
+
|
|
243
|
+
Use it at sprint close to drive the **threshold-tuning process**:
|
|
244
|
+
|
|
245
|
+
1. Recurring pattern with count ≥ 5 and a clearly-applicable skill? Edit
|
|
246
|
+
the skill's `description` to include the pattern's keywords.
|
|
247
|
+
Description tuning is free; do it before threshold tuning.
|
|
248
|
+
2. If patterns still miss after description tuning *and* scores cluster
|
|
249
|
+
just under `must_load`, lower `--threshold-high` from 4.0 to 3.5
|
|
250
|
+
(one 0.5 step, one sprint at a time).
|
|
251
|
+
3. If `must_load` over-fires on marginal skills, raise `--threshold-high`
|
|
252
|
+
to 4.5.
|
|
253
|
+
4. `router_exception:*` reasons are bugs — escalate to Bezalel, never
|
|
254
|
+
tune around them.
|
|
255
|
+
|
|
256
|
+
## Troubleshooting
|
|
257
|
+
|
|
258
|
+
**`index_missing_or_unreadable` warning.**
|
|
259
|
+
Run `/mishkan-skills-reindex`. If that fails, inspect
|
|
260
|
+
`~/.claude/mishkan/skill-discovery/indexer-errors.jsonl`.
|
|
261
|
+
|
|
262
|
+
**Buckets all empty for a query that obviously matches a skill.**
|
|
263
|
+
The miss is already logged. Two likely causes:
|
|
264
|
+
- The skill's `description` does not contain the keywords the task used.
|
|
265
|
+
Tune the description; do not lower the threshold.
|
|
266
|
+
- The skill's frontmatter is malformed and the indexer skipped it. Check
|
|
267
|
+
`indexer-errors.jsonl`.
|
|
268
|
+
|
|
269
|
+
**A skill I expect to win the bucket is being shadowed by a duplicate
|
|
270
|
+
name in another root.**
|
|
271
|
+
Inspect `index.json.meta.collisions`. Precedence is
|
|
272
|
+
mishkan → user → plugin → project. Rename one of the duplicates.
|
|
273
|
+
|
|
274
|
+
**Indexer keeps rebuilding on every session boot.**
|
|
275
|
+
Something is touching a `SKILL.md` mtime. Check the
|
|
276
|
+
`meta.last_scan` value in `index.json` and compare to file mtimes under
|
|
277
|
+
the four roots; the offender is whatever has the newest mtime that
|
|
278
|
+
shouldn't.
|
|
279
|
+
|
|
280
|
+
## Tuning the thresholds
|
|
281
|
+
|
|
282
|
+
Defaults: `threshold_high = 4.0`, `threshold_mid = 1.5`. Both are
|
|
283
|
+
guesses from Phase 1 scaffolding. Don't tune them until the miss log
|
|
284
|
+
shows a stable distribution of scores around the cutoffs across at least
|
|
285
|
+
2 sprints — premature tuning chases noise.
|
|
286
|
+
|
|
287
|
+
Per-invocation overrides:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
python3 ~/.claude/mishkan/scripts/skill-discovery-router.py \
|
|
291
|
+
--task "..." \
|
|
292
|
+
--threshold-high 5.0 \
|
|
293
|
+
--threshold-mid 2.0
|
|
294
|
+
```
|
package/docs/usage/README.md
CHANGED
|
@@ -46,8 +46,10 @@ You ──talk──▶ MAIN SESSION = leadership (Nehemiah/Bezalel via CLAUDE
|
|
|
46
46
|
| 06 | [LLM provider profiles](./06-llm-providers.md) | Gemini/NVIDIA/Ollama/OpenAI/Anthropic, rate vs daily caps |
|
|
47
47
|
| 07 | [Troubleshooting](./07-troubleshooting.md) | Real gotchas + fixes from the build |
|
|
48
48
|
| 08 | [Glossary](./08-glossary.md) | 45-agent roster (alias → role → team), key terms |
|
|
49
|
-
| 09 | [Dynamic Workflows](./09-workflows.md) |
|
|
50
|
-
| 10 | [Observability](./10-observability.md) | Cross-session daemon + Textual TUI (
|
|
49
|
+
| 09 | [Dynamic Workflows](./09-workflows.md) | 10 org-level + 8 team-level workflows, ADR D-010 portfolio discipline |
|
|
50
|
+
| 10 | [Observability](./10-observability.md) | Cross-session daemon + Textual TUI; 8 tabs (Live · Agents · Workflows · Knowledge · Activity · Org-Ref · Usage · Skills), project filter (`p`) |
|
|
51
|
+
| 11 | [Graphify](./11-graphify.md) | Code-structure graph; queries at ~1.8k tokens (88.1× reduction, POC-verified); D-008 + D-009 |
|
|
52
|
+
| 12 | [Skill discovery](./12-skill-discovery.md) | Universal indexer + 3-bucket router across MISHKAN, user, plugin, and project skills; D-011 |
|
|
51
53
|
|
|
52
54
|
## Where to start
|
|
53
55
|
|
|
@@ -60,7 +62,7 @@ You ──talk──▶ MAIN SESSION = leadership (Nehemiah/Bezalel via CLAUDE
|
|
|
60
62
|
## Authoritative references this documentation builds on
|
|
61
63
|
|
|
62
64
|
- [`docs/design/MISHKAN_harness_design.md`](../design/MISHKAN_harness_design.md) — the 5-layer architecture and rationale.
|
|
63
|
-
- [`docs/design/MISHKAN_decisions.md`](../design/MISHKAN_decisions.md) — D-001…D-
|
|
65
|
+
- [`docs/design/MISHKAN_decisions.md`](../design/MISHKAN_decisions.md) — D-001…D-011 with rationale.
|
|
64
66
|
- [`docs/design/MISHKAN_agent_aliases.md`](../design/MISHKAN_agent_aliases.md) — the biblical roster.
|
|
65
67
|
- [`docs/design/MISHKAN_ontology.md`](../design/MISHKAN_ontology.md) — cognee entity + relationship types.
|
|
66
68
|
- [`docs/design/MISHKAN_token_optimisation.md`](../design/MISHKAN_token_optimisation.md) — context economy.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mishkan-harness",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "MISHKAN — a personal advanced SWE R&D harness for Claude Code: 45 biblically-named agents across six teams, deterministic rules + hooks, a shared research pipeline, dependency/supply-chain vetting, and a Cognee-backed knowledge graph. Installs into ~/.claude.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
{
|
|
18
18
|
"type": "command",
|
|
19
19
|
"command": "python3 {{MISHKAN}}/hooks/model-route.py"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"type": "command",
|
|
23
|
+
"command": "bash {{MISHKAN}}/hooks/pre-tool-task-skill-route.sh"
|
|
20
24
|
}
|
|
21
25
|
]
|
|
22
26
|
},
|
|
@@ -28,6 +32,15 @@
|
|
|
28
32
|
"command": "bash {{MISHKAN}}/hooks/pre-tool-trace.sh"
|
|
29
33
|
}
|
|
30
34
|
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"matcher": "Read|Grep",
|
|
38
|
+
"hooks": [
|
|
39
|
+
{
|
|
40
|
+
"type": "command",
|
|
41
|
+
"command": "bash {{MISHKAN}}/hooks/pre-tool-knowledge-route.sh"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
31
44
|
}
|
|
32
45
|
],
|
|
33
46
|
"PostToolUse": [
|
|
@@ -41,6 +54,17 @@
|
|
|
41
54
|
]
|
|
42
55
|
}
|
|
43
56
|
],
|
|
57
|
+
"SessionStart": [
|
|
58
|
+
{
|
|
59
|
+
"matcher": "",
|
|
60
|
+
"hooks": [
|
|
61
|
+
{
|
|
62
|
+
"type": "command",
|
|
63
|
+
"command": "bash {{MISHKAN}}/hooks/session-start-skill-index.sh"
|
|
64
|
+
}
|
|
65
|
+
]
|
|
66
|
+
}
|
|
67
|
+
],
|
|
44
68
|
"Stop": [
|
|
45
69
|
{
|
|
46
70
|
"matcher": "",
|
|
@@ -62,8 +62,10 @@ Optional and NOT used by MISHKAN by default: `skills`, `disallowedTools`,
|
|
|
62
62
|
|
|
63
63
|
## Dynamic Context Injection Point
|
|
64
64
|
|
|
65
|
-
<!--
|
|
66
|
-
|
|
65
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
66
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
67
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
68
|
+
parent session context, not injected here. -->
|
|
67
69
|
```
|
|
68
70
|
|
|
69
71
|
## 3. The Prompt Defense Baseline (verbatim, every agent)
|
|
@@ -110,13 +112,29 @@ Every agent file ends with:
|
|
|
110
112
|
|
|
111
113
|
## Dynamic Context Injection Point
|
|
112
114
|
|
|
113
|
-
<!--
|
|
114
|
-
|
|
115
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
116
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
117
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
118
|
+
parent session context, not injected here. -->
|
|
115
119
|
```
|
|
116
120
|
|
|
117
|
-
This is
|
|
118
|
-
|
|
119
|
-
|
|
121
|
+
This is a **boundary marker, not a runtime hook**. Nothing in MISHKAN
|
|
122
|
+
parses it at load time or splices content at the position. Its job is
|
|
123
|
+
twofold:
|
|
124
|
+
|
|
125
|
+
- **Author discipline.** Everything above the marker must stay byte-
|
|
126
|
+
identical between calls so Anthropic's prompt cache fires on the
|
|
127
|
+
static prefix. Putting a date, a counter, or any volatile value above
|
|
128
|
+
the marker breaks cacheability for that whole prefix on the next call.
|
|
129
|
+
- **Reader orientation.** A human reading the file sees exactly where
|
|
130
|
+
the cacheable role ends and where project-variable context starts.
|
|
131
|
+
|
|
132
|
+
Project sprint state from `./CLAUDE.md` does land in the agent's effective
|
|
133
|
+
context — but via Claude Code's normal session loading (parent session
|
|
134
|
+
context propagates to spawned subagents), not by injection at this
|
|
135
|
+
marker. The section title is kept for backwards compatibility and
|
|
136
|
+
because it correctly names the boundary; the comment inside has been
|
|
137
|
+
updated to match reality.
|
|
120
138
|
|
|
121
139
|
## 6. Body length policy
|
|
122
140
|
|
|
@@ -54,5 +54,7 @@ No `/plan` (collect-only role).
|
|
|
54
54
|
|
|
55
55
|
## Dynamic Context Injection Point
|
|
56
56
|
|
|
57
|
-
<!--
|
|
58
|
-
|
|
57
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
58
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
59
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
60
|
+
parent session context, not injected here. -->
|
|
@@ -64,5 +64,7 @@ Approval gate via `/plan`.
|
|
|
64
64
|
|
|
65
65
|
## Dynamic Context Injection Point
|
|
66
66
|
|
|
67
|
-
<!--
|
|
68
|
-
|
|
67
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
68
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
69
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
70
|
+
parent session context, not injected here. -->
|
|
@@ -53,6 +53,7 @@ finding:
|
|
|
53
53
|
## Skills (invoke on demand)
|
|
54
54
|
|
|
55
55
|
- `asaph-a11y-seo-craft` — semantic-first + cite-the-SC + remediation boundary
|
|
56
|
+
- `graphify-query-craft` — query the project code-structure graph (~1.8k tokens vs ~80k+ grep+Read) before reading source for any structural question (who calls X, what depends on Y, where is the entry point). Per D-009 amended scope: all code-touching dev agents.
|
|
56
57
|
- `accessibility-compliance` — WCAG 2.2 implementation
|
|
57
58
|
- `wcag-audit-patterns` — running a WCAG audit
|
|
58
59
|
- `screen-reader-testing` — AT testing
|
|
@@ -69,5 +70,7 @@ WCAG 2.2 AA minimum.
|
|
|
69
70
|
|
|
70
71
|
## Dynamic Context Injection Point
|
|
71
72
|
|
|
72
|
-
<!--
|
|
73
|
-
|
|
73
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
74
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
75
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
76
|
+
parent session context, not injected here. -->
|
|
@@ -80,9 +80,26 @@ Stateful operations hard stop. Sequence before implementation. Diagnose
|
|
|
80
80
|
before fix. Durable solutions only. No scope expansion. No fabricated
|
|
81
81
|
facts. English for all output.
|
|
82
82
|
|
|
83
|
+
## Contract eval
|
|
84
|
+
|
|
85
|
+
Output schema and golden-case semantic invariants exercised by
|
|
86
|
+
`payload/mishkan/evals/baruch/`. Not LLM-live — schema + jq assertions
|
|
87
|
+
on a frozen golden output. Run BEFORE any change to:
|
|
88
|
+
|
|
89
|
+
- `payload/mishkan/templates/research-log.schema.json`
|
|
90
|
+
- `payload/mishkan/scripts/validate-research-log.sh`
|
|
91
|
+
- This file
|
|
92
|
+
- The Baruch craft skill
|
|
93
|
+
|
|
94
|
+
Invoke via `/eval-baruch` or `bash payload/mishkan/evals/baruch/run.sh`.
|
|
95
|
+
CI workflow `.github/workflows/eval-baruch.yml` runs it on every PR
|
|
96
|
+
touching one of those paths.
|
|
97
|
+
|
|
83
98
|
---
|
|
84
99
|
|
|
85
100
|
## Dynamic Context Injection Point
|
|
86
101
|
|
|
87
|
-
<!--
|
|
88
|
-
|
|
102
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
103
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
104
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
105
|
+
parent session context, not injected here. -->
|
|
@@ -72,5 +72,7 @@ Two root causes on non-trivial failures.
|
|
|
72
72
|
|
|
73
73
|
## Dynamic Context Injection Point
|
|
74
74
|
|
|
75
|
-
<!--
|
|
76
|
-
|
|
75
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
76
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
77
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
78
|
+
parent session context, not injected here. -->
|
|
@@ -79,5 +79,7 @@ Approval gate on consequential decisions via `/plan`.
|
|
|
79
79
|
|
|
80
80
|
## Dynamic Context Injection Point
|
|
81
81
|
|
|
82
|
-
<!--
|
|
83
|
-
|
|
82
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
83
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
84
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
85
|
+
parent session context, not injected here. -->
|
|
@@ -70,5 +70,7 @@ facts. English for all output.
|
|
|
70
70
|
|
|
71
71
|
## Dynamic Context Injection Point
|
|
72
72
|
|
|
73
|
-
<!--
|
|
74
|
-
|
|
73
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
74
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
75
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
76
|
+
parent session context, not injected here. -->
|
|
@@ -59,5 +59,7 @@ No fabricated research — cite the heuristic or study.
|
|
|
59
59
|
|
|
60
60
|
## Dynamic Context Injection Point
|
|
61
61
|
|
|
62
|
-
<!--
|
|
63
|
-
|
|
62
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
63
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
64
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
65
|
+
parent session context, not injected here. -->
|
|
@@ -54,5 +54,7 @@ No `/plan` (collect-only role).
|
|
|
54
54
|
|
|
55
55
|
## Dynamic Context Injection Point
|
|
56
56
|
|
|
57
|
-
<!--
|
|
58
|
-
|
|
57
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
58
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
59
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
60
|
+
parent session context, not injected here. -->
|
|
@@ -64,5 +64,7 @@ No `:latest` tags. SOPS for secrets. Hardening overlay on recreate. Approval gat
|
|
|
64
64
|
|
|
65
65
|
## Dynamic Context Injection Point
|
|
66
66
|
|
|
67
|
-
<!--
|
|
68
|
-
|
|
67
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
68
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
69
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
70
|
+
parent session context, not injected here. -->
|
|
@@ -65,5 +65,7 @@ facts. English for all output.
|
|
|
65
65
|
|
|
66
66
|
## Dynamic Context Injection Point
|
|
67
67
|
|
|
68
|
-
<!--
|
|
69
|
-
|
|
68
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
69
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
70
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
71
|
+
parent session context, not injected here. -->
|
|
@@ -43,6 +43,7 @@ operational glue.
|
|
|
43
43
|
## Skills (invoke on demand)
|
|
44
44
|
|
|
45
45
|
- `hanun-observability-craft` — three signals + hardening overlay always reapplied + structured logs
|
|
46
|
+
- `graphify-query-craft` — query the project code-structure graph (~1.8k tokens vs ~80k+ grep+Read) before reading source for any structural question (who calls X, what depends on Y, where is the entry point). Per D-009 amended scope: all code-touching dev agents.
|
|
46
47
|
- `prometheus-configuration` — metrics plumbing
|
|
47
48
|
- `grafana-dashboards` — dashboard work
|
|
48
49
|
- `secrets-management` — secret-handling operations
|
|
@@ -60,5 +61,7 @@ Hardening overlay on every recreate. SOPS for secrets.
|
|
|
60
61
|
|
|
61
62
|
## Dynamic Context Injection Point
|
|
62
63
|
|
|
63
|
-
<!--
|
|
64
|
-
|
|
64
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
65
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
66
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
67
|
+
parent session context, not injected here. -->
|
|
@@ -45,6 +45,7 @@ component contracts, or shared visual primitives).
|
|
|
45
45
|
## Skills (invoke on demand)
|
|
46
46
|
|
|
47
47
|
- `hiram-ui-craft` — UI design + prototype handoff discipline (the depth lives here)
|
|
48
|
+
- `graphify-query-craft` — query the project code-structure graph (~1.8k tokens vs ~80k+ grep+Read) before reading source for any structural question (who calls X, what depends on Y, where is the entry point). Per D-009 amended scope: all code-touching dev agents.
|
|
48
49
|
- `frontend-design` — production-grade UI work
|
|
49
50
|
- `design-system-patterns` — tokens, theming, component patterns
|
|
50
51
|
- `visual-design-foundations` — typography, hierarchy, layout
|
|
@@ -64,5 +65,7 @@ WCAG 2.2 AA on interactive components.
|
|
|
64
65
|
|
|
65
66
|
## Dynamic Context Injection Point
|
|
66
67
|
|
|
67
|
-
<!--
|
|
68
|
-
|
|
68
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
69
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
70
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
71
|
+
parent session context, not injected here. -->
|
|
@@ -51,6 +51,7 @@ when a task touches more than one component.
|
|
|
51
51
|
## Skills (invoke on demand)
|
|
52
52
|
|
|
53
53
|
- `hizkiah-implementation-craft` — any backend implementation against
|
|
54
|
+
- `graphify-query-craft` — query the project code-structure graph (~1.8k tokens vs ~80k+ grep+Read) before reading source for any structural question (who calls X, what depends on Y, where is the entry point). Per D-009 amended scope: all code-touching dev agents.
|
|
54
55
|
a fixed contract (principles-first, with Python/FastAPI, TypeScript/Hono,
|
|
55
56
|
and PHP/Laravel examples — the depth lives in this skill, not here)
|
|
56
57
|
- `fastapi-templates` — FastAPI implementation (when the stack is Python)
|
|
@@ -72,5 +73,7 @@ OpenAPI contract before endpoint.
|
|
|
72
73
|
|
|
73
74
|
## Dynamic Context Injection Point
|
|
74
75
|
|
|
75
|
-
<!--
|
|
76
|
-
|
|
76
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
77
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
78
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
79
|
+
parent session context, not injected here. -->
|
|
@@ -55,5 +55,7 @@ No `/plan` (collect-only role).
|
|
|
55
55
|
|
|
56
56
|
## Dynamic Context Injection Point
|
|
57
57
|
|
|
58
|
-
<!--
|
|
59
|
-
|
|
58
|
+
<!-- Cacheable prefix boundary. Everything above this line must stay
|
|
59
|
+
byte-identical between calls for prompt caching to fire. Project
|
|
60
|
+
sprint state from ./CLAUDE.md is loaded by Claude Code into the
|
|
61
|
+
parent session context, not injected here. -->
|