mishkan-harness 0.1.0
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/LICENSE +21 -0
- package/README.md +205 -0
- package/bin/mishkan.js +221 -0
- package/docs/design/MISHKAN_agent_aliases.md +140 -0
- package/docs/design/MISHKAN_decisions.md +172 -0
- package/docs/design/MISHKAN_harness_design.md +820 -0
- package/docs/design/MISHKAN_ontology.md +87 -0
- package/docs/design/MISHKAN_token_optimisation.md +181 -0
- package/docs/engineer/README.md +37 -0
- package/docs/engineer/profile.example.md +79 -0
- package/docs/usage/01-installation.md +178 -0
- package/docs/usage/02-project-init.md +151 -0
- package/docs/usage/03-orchestration.md +218 -0
- package/docs/usage/04-memory-layer.md +201 -0
- package/docs/usage/05-selective-ingest.md +177 -0
- package/docs/usage/06-llm-providers.md +195 -0
- package/docs/usage/07-troubleshooting.md +316 -0
- package/docs/usage/08-glossary.md +154 -0
- package/docs/usage/09-workflows.md +123 -0
- package/docs/usage/README.md +77 -0
- package/package.json +43 -0
- package/payload/install/settings.hooks.json +47 -0
- package/payload/mishkan/AGENT_SPEC.md +154 -0
- package/payload/mishkan/agents/ahikam.md +58 -0
- package/payload/mishkan/agents/aholiab.md +68 -0
- package/payload/mishkan/agents/asaph.md +73 -0
- package/payload/mishkan/agents/baruch.md +88 -0
- package/payload/mishkan/agents/benaiah.md +76 -0
- package/payload/mishkan/agents/bezalel.md +83 -0
- package/payload/mishkan/agents/caleb.md +74 -0
- package/payload/mishkan/agents/deborah.md +63 -0
- package/payload/mishkan/agents/elasah.md +58 -0
- package/payload/mishkan/agents/eliashib.md +68 -0
- package/payload/mishkan/agents/ezra.md +69 -0
- package/payload/mishkan/agents/hanun.md +64 -0
- package/payload/mishkan/agents/hiram.md +68 -0
- package/payload/mishkan/agents/hizkiah.md +76 -0
- package/payload/mishkan/agents/huldah.md +59 -0
- package/payload/mishkan/agents/huram.md +66 -0
- package/payload/mishkan/agents/hushai.md +59 -0
- package/payload/mishkan/agents/igal.md +58 -0
- package/payload/mishkan/agents/ira.md +86 -0
- package/payload/mishkan/agents/jahaziel.md +71 -0
- package/payload/mishkan/agents/jakin.md +66 -0
- package/payload/mishkan/agents/jehonathan.md +62 -0
- package/payload/mishkan/agents/jehoshaphat.md +68 -0
- package/payload/mishkan/agents/joab.md +71 -0
- package/payload/mishkan/agents/joah.md +62 -0
- package/payload/mishkan/agents/maaseiah.md +61 -0
- package/payload/mishkan/agents/meremoth.md +65 -0
- package/payload/mishkan/agents/meshullam.md +67 -0
- package/payload/mishkan/agents/nathan.md +70 -0
- package/payload/mishkan/agents/nehemiah.md +93 -0
- package/payload/mishkan/agents/obed.md +60 -0
- package/payload/mishkan/agents/oholiab.md +67 -0
- package/payload/mishkan/agents/palal.md +63 -0
- package/payload/mishkan/agents/phinehas.md +73 -0
- package/payload/mishkan/agents/rehum.md +60 -0
- package/payload/mishkan/agents/salma.md +69 -0
- package/payload/mishkan/agents/seraiah.md +73 -0
- package/payload/mishkan/agents/shallum.md +66 -0
- package/payload/mishkan/agents/shaphan.md +64 -0
- package/payload/mishkan/agents/shemaiah.md +67 -0
- package/payload/mishkan/agents/shevna.md +58 -0
- package/payload/mishkan/agents/uriah.md +70 -0
- package/payload/mishkan/agents/zaccur.md +58 -0
- package/payload/mishkan/agents/zadok.md +67 -0
- package/payload/mishkan/agents/zerubbabel.md +69 -0
- package/payload/mishkan/cognee/.env.curated.example +61 -0
- package/payload/mishkan/cognee/.env.example +165 -0
- package/payload/mishkan/cognee/Dockerfile +50 -0
- package/payload/mishkan/cognee/README.md +129 -0
- package/payload/mishkan/cognee/docker-compose.curated-ui.yml +61 -0
- package/payload/mishkan/cognee/docker-compose.curated.yml +85 -0
- package/payload/mishkan/cognee/docker-compose.hardening.yml +16 -0
- package/payload/mishkan/cognee/docker-compose.selfhosted.yml +114 -0
- package/payload/mishkan/cognee/docker-compose.ui.yml +70 -0
- package/payload/mishkan/cognee/docker-compose.yml +71 -0
- package/payload/mishkan/cognee/ingest-curated.py +92 -0
- package/payload/mishkan/commands/dep-audit.md +24 -0
- package/payload/mishkan/commands/mishkan-init.md +25 -0
- package/payload/mishkan/commands/mishkan-resume.md +21 -0
- package/payload/mishkan/commands/promote.md +19 -0
- package/payload/mishkan/commands/sefer-pull.md +19 -0
- package/payload/mishkan/commands/sprint-close.md +21 -0
- package/payload/mishkan/config/curated-library.yaml +113 -0
- package/payload/mishkan/config/improvement-queries.md +29 -0
- package/payload/mishkan/config/model-routing.yaml +87 -0
- package/payload/mishkan/config/projects.yaml +38 -0
- package/payload/mishkan/evals/baruch/README.md +93 -0
- package/payload/mishkan/evals/baruch/fixtures/invalid/bad-outcome-enum.json +15 -0
- package/payload/mishkan/evals/baruch/fixtures/invalid/bad-sprint-pattern.json +15 -0
- package/payload/mishkan/evals/baruch/fixtures/invalid/bad-trigger-enum.json +15 -0
- package/payload/mishkan/evals/baruch/fixtures/invalid/malformed-json.json +7 -0
- package/payload/mishkan/evals/baruch/fixtures/invalid/missing-required-field.json +14 -0
- package/payload/mishkan/evals/baruch/fixtures/valid/blocked-vendor.json +15 -0
- package/payload/mishkan/evals/baruch/fixtures/valid/curated-shortcircuit.json +15 -0
- package/payload/mishkan/evals/baruch/fixtures/valid/partial-no-write.json +14 -0
- package/payload/mishkan/evals/baruch/fixtures/valid/resolved-cross-harness.json +15 -0
- package/payload/mishkan/evals/baruch/golden_case/expected.yaml +35 -0
- package/payload/mishkan/evals/baruch/golden_case/input.yaml +47 -0
- package/payload/mishkan/evals/baruch/golden_case/produced.json +15 -0
- package/payload/mishkan/evals/baruch/run.sh +129 -0
- package/payload/mishkan/hooks/model-route.py +96 -0
- package/payload/mishkan/hooks/post-tool-observe.sh +45 -0
- package/payload/mishkan/hooks/pre-tool-security.sh +150 -0
- package/payload/mishkan/hooks/session-start.sh +20 -0
- package/payload/mishkan/hooks/stop-reporter.sh +29 -0
- package/payload/mishkan/ontology.md +87 -0
- package/payload/mishkan/rules/backend/yasad.md +23 -0
- package/payload/mishkan/rules/common/dependencies.md +53 -0
- package/payload/mishkan/rules/common/quality.md +16 -0
- package/payload/mishkan/rules/common/security.md +20 -0
- package/payload/mishkan/rules/documentation/sefer.md +19 -0
- package/payload/mishkan/rules/frontend/panim.md +21 -0
- package/payload/mishkan/rules/infrastructure/migdal.md +22 -0
- package/payload/mishkan/scripts/dependency-audit.sh +171 -0
- package/payload/mishkan/scripts/ensure-curated-box.sh +66 -0
- package/payload/mishkan/scripts/mishkan-ingest.sh +92 -0
- package/payload/mishkan/scripts/observability-aggregate.sh +57 -0
- package/payload/mishkan/scripts/seed-curated-library.sh +62 -0
- package/payload/mishkan/scripts/sync-profile.sh +65 -0
- package/payload/mishkan/scripts/validate-research-log.sh +108 -0
- package/payload/mishkan/skills/asaph-a11y-seo-craft/SKILL.md +289 -0
- package/payload/mishkan/skills/baruch-research-reporting-craft/SKILL.md +460 -0
- package/payload/mishkan/skills/benaiah-devsecops-craft/SKILL.md +329 -0
- package/payload/mishkan/skills/bezalel-cto-craft/SKILL.md +391 -0
- package/payload/mishkan/skills/caleb-web-research-craft/SKILL.md +306 -0
- package/payload/mishkan/skills/cognee-promote/SKILL.md +40 -0
- package/payload/mishkan/skills/cognee-quickstart/SKILL.md +66 -0
- package/payload/mishkan/skills/context-compress/SKILL.md +36 -0
- package/payload/mishkan/skills/deborah-ux-craft/SKILL.md +295 -0
- package/payload/mishkan/skills/dependency-audit/SKILL.md +59 -0
- package/payload/mishkan/skills/dependency-vetting/SKILL.md +59 -0
- package/payload/mishkan/skills/documentation-craft/SKILL.md +468 -0
- package/payload/mishkan/skills/ezra-research-formulation-craft/SKILL.md +319 -0
- package/payload/mishkan/skills/hanun-observability-craft/SKILL.md +312 -0
- package/payload/mishkan/skills/hiram-ui-craft/SKILL.md +334 -0
- package/payload/mishkan/skills/hizkiah-implementation-craft/SKILL.md +701 -0
- package/payload/mishkan/skills/hushai-security-advisor-craft/SKILL.md +282 -0
- package/payload/mishkan/skills/ira-code-security-craft/SKILL.md +553 -0
- package/payload/mishkan/skills/jakin-intent-clarification-craft/SKILL.md +299 -0
- package/payload/mishkan/skills/jehonathan-publication-craft/SKILL.md +262 -0
- package/payload/mishkan/skills/joab-app-security-craft/SKILL.md +266 -0
- package/payload/mishkan/skills/meremoth-devops-craft/SKILL.md +298 -0
- package/payload/mishkan/skills/meshullam-infra-design-craft/SKILL.md +302 -0
- package/payload/mishkan/skills/mishkan-ingest/SKILL.md +65 -0
- package/payload/mishkan/skills/mishkan-init/SKILL.md +65 -0
- package/payload/mishkan/skills/nathan-architecture-craft/SKILL.md +547 -0
- package/payload/mishkan/skills/nehemiah-pm-craft/SKILL.md +484 -0
- package/payload/mishkan/skills/obed-asset-pipeline-craft/SKILL.md +286 -0
- package/payload/mishkan/skills/oholiab-design-system-craft/SKILL.md +334 -0
- package/payload/mishkan/skills/palal-systems-craft/SKILL.md +281 -0
- package/payload/mishkan/skills/qa-evaluation-craft/SKILL.md +406 -0
- package/payload/mishkan/skills/rehum-sre-advisor-craft/SKILL.md +228 -0
- package/payload/mishkan/skills/reporter-discipline-craft/SKILL.md +351 -0
- package/payload/mishkan/skills/research-pipeline/SKILL.md +55 -0
- package/payload/mishkan/skills/salma-frontend-implementation-craft/SKILL.md +369 -0
- package/payload/mishkan/skills/sefer-pull/SKILL.md +37 -0
- package/payload/mishkan/skills/shallum-database-craft/SKILL.md +347 -0
- package/payload/mishkan/skills/shaphan-summarisation-craft/SKILL.md +271 -0
- package/payload/mishkan/skills/shemaiah-evaluation-craft/SKILL.md +342 -0
- package/payload/mishkan/skills/sprint-report/SKILL.md +28 -0
- package/payload/mishkan/skills/team-lead-craft/SKILL.md +457 -0
- package/payload/mishkan/skills/zadok-contract-craft/SKILL.md +520 -0
- package/payload/mishkan/templates/case-node.schema.json +22 -0
- package/payload/mishkan/templates/mcp.json +22 -0
- package/payload/mishkan/templates/observability-log.schema.json +24 -0
- package/payload/mishkan/templates/project-CLAUDE.md +47 -0
- package/payload/mishkan/templates/research-log.schema.json +40 -0
- package/payload/mishkan/templates/settings.json +12 -0
- package/payload/mishkan/templates/settings.local.json +6 -0
- package/payload/mishkan/templates/sprint-state.schema.json +47 -0
- package/payload/mishkan/templates/team-report.schema.json +50 -0
- package/payload/mishkan/templates/user-CLAUDE.md +62 -0
- package/payload/mishkan/workflows/README.md +88 -0
- package/payload/mishkan/workflows/mishkan-architecture-panel.js +156 -0
- package/payload/mishkan/workflows/mishkan-codebase-audit.js +188 -0
- package/payload/mishkan/workflows/mishkan-deep-research.js +251 -0
- package/payload/mishkan/workflows/mishkan-init.js +156 -0
- package/payload/mishkan/workflows/mishkan-migration-wave.js +180 -0
- package/payload/mishkan/workflows/mishkan-release-readiness.js +163 -0
- package/payload/mishkan/workflows/mishkan-sprint-close.js +112 -0
- package/payload/user/CLAUDE.md +62 -0
- package/payload/user/rules/engineer-standards.md +66 -0
- package/payload/user/rules/y4nn-standards.md +167 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MISHKAN — idempotently ensure the CURATED box (global singleton) is up + seeded.
|
|
3
|
+
# Called by /mishkan-init. The curated box is shared across ALL projects, so this
|
|
4
|
+
# NEVER recreates or reseeds an already-running, already-populated box — it only
|
|
5
|
+
# fills what's missing. Safe to run repeatedly.
|
|
6
|
+
#
|
|
7
|
+
# Does: ensure .env.curated exists (generated from the example, reusing the work
|
|
8
|
+
# stack's LLM key + a fresh Neo4j password) -> ensure curated_db -> bring the box
|
|
9
|
+
# up if down -> seed only if the curated graph is empty. See decision D-007.
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
COGNEE_DIR="${HOME}/.claude/mishkan/cognee"
|
|
13
|
+
cd "$COGNEE_DIR" || { echo "cognee dir not found: $COGNEE_DIR" >&2; exit 1; }
|
|
14
|
+
|
|
15
|
+
# 0. work stack owns the shared network + Ollama + Postgres — it must be up first.
|
|
16
|
+
if ! docker ps --format '{{.Names}}' | grep -qx mishkan-cognee-pg; then
|
|
17
|
+
echo "work stack not running — bring it up first (docker-compose.yml), then re-run." >&2
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# 1. ensure .env.curated (SOPS-manage the real file; this is the bootstrap fallback).
|
|
22
|
+
if [ ! -f .env.curated ]; then
|
|
23
|
+
[ -f .env.curated.example ] || { echo ".env.curated.example missing" >&2; exit 1; }
|
|
24
|
+
echo "generating .env.curated (reusing work LLM key; fresh local passwords)..."
|
|
25
|
+
LLMKEY="$(grep '^LLM_API_KEY=' .env | cut -d= -f2-)"
|
|
26
|
+
PGPW="$(grep '^DB_PASSWORD=' .env | cut -d= -f2-)"
|
|
27
|
+
umask 077
|
|
28
|
+
sed -e "s|^LLM_API_KEY=.*|LLM_API_KEY=${LLMKEY}|" \
|
|
29
|
+
-e "s|^GRAPH_DATABASE_PASSWORD=.*|GRAPH_DATABASE_PASSWORD=$(openssl rand -hex 16)|" \
|
|
30
|
+
-e "s|^DB_PASSWORD=.*|DB_PASSWORD=${PGPW}|" \
|
|
31
|
+
-e "s|^DEFAULT_USER_PASSWORD=.*|DEFAULT_USER_PASSWORD=$(openssl rand -hex 20)|" \
|
|
32
|
+
.env.curated.example > .env.curated
|
|
33
|
+
chmod 600 .env.curated
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# 2. ensure the isolated curated_db in the shared Postgres.
|
|
37
|
+
if ! docker exec mishkan-cognee-pg psql -U cognee -d cognee_db -tAc \
|
|
38
|
+
"SELECT 1 FROM pg_database WHERE datname='curated_db'" | grep -q 1; then
|
|
39
|
+
docker exec mishkan-cognee-pg psql -U cognee -d cognee_db -c \
|
|
40
|
+
"CREATE DATABASE curated_db OWNER cognee;"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# 3. bring the curated box up if it's not already running.
|
|
44
|
+
if ! docker ps --format '{{.Names}}' | grep -qx mishkan-curated-mcp; then
|
|
45
|
+
docker compose --env-file .env.curated -f docker-compose.curated.yml up -d
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# 4. wait for curated-mcp health (bounded).
|
|
49
|
+
echo "waiting for mishkan-curated-mcp..."
|
|
50
|
+
for _ in $(seq 1 40); do
|
|
51
|
+
[ "$(docker inspect -f '{{.State.Health.Status}}' mishkan-curated-mcp 2>/dev/null)" = "healthy" ] && break
|
|
52
|
+
sleep 5
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
# 5. seed ONLY if the curated graph is empty (never reseed a populated singleton).
|
|
56
|
+
N4PW="$(grep '^GRAPH_DATABASE_PASSWORD=' .env.curated | cut -d= -f2-)"
|
|
57
|
+
COUNT="$(docker exec mishkan-curated-neo4j cypher-shell -u neo4j -p "$N4PW" --format plain \
|
|
58
|
+
"MATCH (n:CuratedResource) RETURN count(n);" 2>/dev/null | tail -1 | tr -dc '0-9')"
|
|
59
|
+
if [ "${COUNT:-0}" = "0" ]; then
|
|
60
|
+
echo "curated graph empty — seeding..."
|
|
61
|
+
"${HOME}/.claude/mishkan/scripts/seed-curated-library.sh"
|
|
62
|
+
else
|
|
63
|
+
echo "curated library already populated (${COUNT} nodes) — leaving as-is."
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
echo "curated box ready on :${CURATED_MCP_PORT:-7730}"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MISHKAN — selectively ingest docs into the project's work cognee store.
|
|
3
|
+
# Default: nothing enters memory unless tagged (`mishkan: ingest` frontmatter)
|
|
4
|
+
# or explicitly listed — preventing PII bleed and oversized-doc errors.
|
|
5
|
+
# Runs cognee.add -> cognify -> memify (extraction + enrichment).
|
|
6
|
+
#
|
|
7
|
+
# mishkan-ingest.sh --tagged-only # walk ./docs/ for tagged
|
|
8
|
+
# mishkan-ingest.sh docs/SECURITY.md docs/ROADMAP.md
|
|
9
|
+
# mishkan-ingest.sh --dataset=research docs/research.md
|
|
10
|
+
set -euo pipefail
|
|
11
|
+
|
|
12
|
+
TAGGED_ONLY=false
|
|
13
|
+
DATASET="$(basename "$PWD")"
|
|
14
|
+
PATHS=()
|
|
15
|
+
CONTAINER="${COGNEE_CONTAINER:-mishkan-cognee-mcp}"
|
|
16
|
+
|
|
17
|
+
while [ $# -gt 0 ]; do
|
|
18
|
+
case "$1" in
|
|
19
|
+
--tagged-only) TAGGED_ONLY=true; shift ;;
|
|
20
|
+
--dataset=*) DATASET="${1#--dataset=}"; shift ;;
|
|
21
|
+
-h|--help) sed -n '2,12p' "$0"; exit 0 ;;
|
|
22
|
+
*) PATHS+=("$1"); shift ;;
|
|
23
|
+
esac
|
|
24
|
+
done
|
|
25
|
+
|
|
26
|
+
[ ${#PATHS[@]} -eq 0 ] && PATHS=("./docs")
|
|
27
|
+
|
|
28
|
+
docker ps --format '{{.Names}}' | grep -qx "$CONTAINER" \
|
|
29
|
+
|| { echo "work cognee container '$CONTAINER' is not running" >&2; exit 1; }
|
|
30
|
+
|
|
31
|
+
# Collect candidate files (md only).
|
|
32
|
+
FILES=()
|
|
33
|
+
for p in "${PATHS[@]}"; do
|
|
34
|
+
if [ -d "$p" ]; then
|
|
35
|
+
while IFS= read -r f; do FILES+=("$f"); done < <(find "$p" -type f -name "*.md")
|
|
36
|
+
elif [ -f "$p" ]; then
|
|
37
|
+
FILES+=("$p")
|
|
38
|
+
else
|
|
39
|
+
echo "warn: skipping (not found): $p" >&2
|
|
40
|
+
fi
|
|
41
|
+
done
|
|
42
|
+
|
|
43
|
+
# Filter to tagged docs if requested. A doc is tagged when its YAML frontmatter
|
|
44
|
+
# (the block between the first two `---` lines) contains `mishkan: ingest`.
|
|
45
|
+
if $TAGGED_ONLY; then
|
|
46
|
+
KEPT=()
|
|
47
|
+
for f in "${FILES[@]}"; do
|
|
48
|
+
if awk '
|
|
49
|
+
BEGIN{infm=0;ok=0}
|
|
50
|
+
NR==1 && $0=="---"{infm=1;next}
|
|
51
|
+
infm && $0=="---"{exit}
|
|
52
|
+
infm && /^[[:space:]]*mishkan:[[:space:]]*ingest[[:space:]]*$/{ok=1;exit}
|
|
53
|
+
NR>50 && !infm{exit}
|
|
54
|
+
END{exit !ok}
|
|
55
|
+
' "$f"; then KEPT+=("$f"); fi
|
|
56
|
+
done
|
|
57
|
+
FILES=("${KEPT[@]}")
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
if [ ${#FILES[@]} -eq 0 ]; then
|
|
61
|
+
echo "no docs selected (tagged_only=$TAGGED_ONLY, paths='${PATHS[*]}')"
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
echo "ingesting ${#FILES[@]} file(s) into dataset '${DATASET}':"
|
|
66
|
+
printf ' %s\n' "${FILES[@]}"
|
|
67
|
+
|
|
68
|
+
# Stage files into the container, then run add -> cognify -> memify.
|
|
69
|
+
docker exec "$CONTAINER" sh -c 'rm -rf /home/cognee/ingest_buf && mkdir -p /home/cognee/ingest_buf'
|
|
70
|
+
for f in "${FILES[@]}"; do
|
|
71
|
+
docker cp "$f" "${CONTAINER}:/home/cognee/ingest_buf/$(basename "$f")"
|
|
72
|
+
done
|
|
73
|
+
|
|
74
|
+
PY_SCRIPT="$(mktemp)"
|
|
75
|
+
cat > "$PY_SCRIPT" <<'PY'
|
|
76
|
+
import asyncio, glob, sys, cognee
|
|
77
|
+
DATASET = sys.argv[1]
|
|
78
|
+
FILES = sorted(glob.glob("/home/cognee/ingest_buf/*"))
|
|
79
|
+
async def m():
|
|
80
|
+
if not FILES:
|
|
81
|
+
print(">> no files"); return
|
|
82
|
+
await cognee.add(FILES, dataset_name=DATASET)
|
|
83
|
+
print(f">> added {len(FILES)} file(s) -> {DATASET}", flush=True)
|
|
84
|
+
await cognee.cognify(datasets=[DATASET])
|
|
85
|
+
print(">> cognified", flush=True)
|
|
86
|
+
await cognee.memify(dataset=DATASET)
|
|
87
|
+
print(">> memified", flush=True)
|
|
88
|
+
asyncio.run(m())
|
|
89
|
+
PY
|
|
90
|
+
docker cp "$PY_SCRIPT" "${CONTAINER}:/home/cognee/_mishkan_ingest.py"
|
|
91
|
+
rm -f "$PY_SCRIPT"
|
|
92
|
+
docker exec -i -w /app/cognee-mcp "$CONTAINER" uv run python -u /home/cognee/_mishkan_ingest.py "$DATASET"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MISHKAN — observability aggregation.
|
|
3
|
+
# Reads logs/*.jsonl (raw PostToolUse events), computes per-tool and per-outcome
|
|
4
|
+
# counts plus per-session activity, and writes a summary the improvement layer
|
|
5
|
+
# reads. Triggered by /sprint-close.
|
|
6
|
+
#
|
|
7
|
+
# Raw events carry tool/outcome/session/timestamp; agent/team/sprint/token fields
|
|
8
|
+
# are enriched here where derivable and left null otherwise (hook payload limit).
|
|
9
|
+
set -euo pipefail
|
|
10
|
+
|
|
11
|
+
MISHKAN="${HOME}/.claude/mishkan"
|
|
12
|
+
LOG_DIR="${MISHKAN}/logs"
|
|
13
|
+
TS="$(date -u +%Y%m%dT%H%M%SZ)"
|
|
14
|
+
OUT="${LOG_DIR}/aggregate-${TS}.json"
|
|
15
|
+
|
|
16
|
+
command -v python3 >/dev/null 2>&1 || { echo "python3 required" >&2; exit 1; }
|
|
17
|
+
mkdir -p "$LOG_DIR"
|
|
18
|
+
|
|
19
|
+
python3 - "$LOG_DIR" "$OUT" <<'PY'
|
|
20
|
+
import sys, json, glob, os
|
|
21
|
+
from collections import Counter, defaultdict
|
|
22
|
+
log_dir, out_path = sys.argv[1], sys.argv[2]
|
|
23
|
+
tool_counts = Counter()
|
|
24
|
+
outcome_counts = Counter()
|
|
25
|
+
per_session = defaultdict(int)
|
|
26
|
+
total = 0
|
|
27
|
+
for f in glob.glob(os.path.join(log_dir, "*.jsonl")):
|
|
28
|
+
if os.path.basename(f).startswith(("aggregate-", "milestones")):
|
|
29
|
+
continue
|
|
30
|
+
for line in open(f):
|
|
31
|
+
line = line.strip()
|
|
32
|
+
if not line:
|
|
33
|
+
continue
|
|
34
|
+
try:
|
|
35
|
+
e = json.loads(line)
|
|
36
|
+
except json.JSONDecodeError:
|
|
37
|
+
continue
|
|
38
|
+
total += 1
|
|
39
|
+
for t in e.get("tool_calls", []):
|
|
40
|
+
tool_counts[t] += 1
|
|
41
|
+
outcome_counts[e.get("outcome", "unknown")] += 1
|
|
42
|
+
per_session[e.get("session", "unknown")] += 1
|
|
43
|
+
summary = {
|
|
44
|
+
"generated": os.path.basename(out_path),
|
|
45
|
+
"total_events": total,
|
|
46
|
+
"tool_calls": dict(tool_counts.most_common()),
|
|
47
|
+
"outcomes": dict(outcome_counts),
|
|
48
|
+
"sessions": dict(per_session),
|
|
49
|
+
"note": "agent/team/sprint/token enrichment pending Cognee-side join; raw hook payload lacks them.",
|
|
50
|
+
}
|
|
51
|
+
json.dump(summary, open(out_path, "w"), indent=2)
|
|
52
|
+
print(f"aggregated {total} events -> {out_path}")
|
|
53
|
+
print("top tools:", dict(tool_counts.most_common(5)))
|
|
54
|
+
PY
|
|
55
|
+
|
|
56
|
+
echo "Summary written. Push to Cognee as Sprint/Agent metric nodes once the"
|
|
57
|
+
echo "container is up (see config/improvement-queries.md for the queries it feeds)."
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MISHKAN — seed the curated library into Cognee.
|
|
3
|
+
# Reads config/curated-library.yaml, emits a JSONL of CuratedResource entries,
|
|
4
|
+
# then ingests them as typed Team + CuratedResource nodes via the structured
|
|
5
|
+
# low-level pipeline (ingest-curated.py) run INSIDE the cognee-mcp container.
|
|
6
|
+
# No LLM extraction — embeddings only (use local Ollama embeddings to avoid
|
|
7
|
+
# cloud rate walls on bulk ingest).
|
|
8
|
+
#
|
|
9
|
+
# One-time bootstrap. The ingest PRUNES the graph first for a clean, reproducible
|
|
10
|
+
# seed — run before real session knowledge accumulates.
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
MISHKAN="${HOME}/.claude/mishkan"
|
|
14
|
+
LIB="${MISHKAN}/config/curated-library.yaml"
|
|
15
|
+
OUT="${MISHKAN}/cognee/curated-resources.jsonl"
|
|
16
|
+
INGEST="${MISHKAN}/cognee/ingest-curated.py"
|
|
17
|
+
CONTAINER="${COGNEE_CONTAINER:-mishkan-curated-mcp}"
|
|
18
|
+
CTR_JSONL="/home/cognee/curated-resources.jsonl"
|
|
19
|
+
CTR_INGEST="/home/cognee/ingest-curated.py"
|
|
20
|
+
|
|
21
|
+
command -v python3 >/dev/null 2>&1 || { echo "python3 required" >&2; exit 1; }
|
|
22
|
+
[ -f "$LIB" ] || { echo "curated library not found: $LIB" >&2; exit 1; }
|
|
23
|
+
mkdir -p "${MISHKAN}/cognee"
|
|
24
|
+
|
|
25
|
+
# Convert YAML → JSONL of CuratedResource nodes (ontology type=CuratedResource).
|
|
26
|
+
python3 - "$LIB" "$OUT" <<'PY'
|
|
27
|
+
import sys, json
|
|
28
|
+
try:
|
|
29
|
+
import yaml
|
|
30
|
+
except ImportError:
|
|
31
|
+
sys.exit("pyyaml required: pip install pyyaml")
|
|
32
|
+
lib_path, out_path = sys.argv[1], sys.argv[2]
|
|
33
|
+
data = yaml.safe_load(open(lib_path))
|
|
34
|
+
n = 0
|
|
35
|
+
with open(out_path, "w") as f:
|
|
36
|
+
for team, items in (data or {}).items():
|
|
37
|
+
for it in items:
|
|
38
|
+
node = {
|
|
39
|
+
"type": "CuratedResource",
|
|
40
|
+
"team": team,
|
|
41
|
+
"name": it["name"],
|
|
42
|
+
"url": it["url"],
|
|
43
|
+
"problem_class": it.get("problem_class", ""),
|
|
44
|
+
"source_tier": "curated",
|
|
45
|
+
}
|
|
46
|
+
f.write(json.dumps(node) + "\n")
|
|
47
|
+
n += 1
|
|
48
|
+
print(f"wrote {n} CuratedResource nodes -> {out_path}")
|
|
49
|
+
PY
|
|
50
|
+
|
|
51
|
+
# Ingest into Cognee via the structured low-level pipeline inside the container.
|
|
52
|
+
if docker ps --format '{{.Names}}' 2>/dev/null | grep -qx "${CONTAINER}"; then
|
|
53
|
+
echo "Ingesting into ${CONTAINER} (structured Team + CuratedResource nodes)..."
|
|
54
|
+
[ -f "$INGEST" ] || { echo "ingest script missing: $INGEST" >&2; exit 1; }
|
|
55
|
+
docker cp "$OUT" "${CONTAINER}:${CTR_JSONL}"
|
|
56
|
+
docker cp "$INGEST" "${CONTAINER}:${CTR_INGEST}"
|
|
57
|
+
docker exec -i -w /app/cognee-mcp "${CONTAINER}" uv run python -u "${CTR_INGEST}"
|
|
58
|
+
echo "Seed complete. Verify: MATCH (r:CuratedResource) RETURN r.team, count(*);"
|
|
59
|
+
else
|
|
60
|
+
echo "Cognee container '${CONTAINER}' not running. JSONL is ready at ${OUT};"
|
|
61
|
+
echo "bring the stack up and re-run this script (or set COGNEE_CONTAINER)."
|
|
62
|
+
fi
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# MISHKAN — profile propagation (mechanical layer).
|
|
3
|
+
# Copies the canonical engineer profile to the runtime path every reference uses,
|
|
4
|
+
# and audits the harness for references + drift. The semantic re-derivation of
|
|
5
|
+
# digests drawn from the profile is Seraiah's job, not this script's.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# sync-profile.sh # copy canonical -> runtime, then report references
|
|
9
|
+
# sync-profile.sh --check # report references + drift only (no copy)
|
|
10
|
+
#
|
|
11
|
+
# Canonical source resolution:
|
|
12
|
+
# 1. $MISHKAN_PROFILE_SRC if set
|
|
13
|
+
# 2. <repo>/docs/engineer/profile.md (when run from a MISHKAN checkout)
|
|
14
|
+
# 3. the existing runtime copy (treated as source if no repo canonical found)
|
|
15
|
+
set -uo pipefail
|
|
16
|
+
|
|
17
|
+
MISHKAN="${HOME}/.claude/mishkan"
|
|
18
|
+
RUNTIME="${MISHKAN}/profile.md"
|
|
19
|
+
CHECK_ONLY=0
|
|
20
|
+
[ "${1:-}" = "--check" ] && CHECK_ONLY=1
|
|
21
|
+
|
|
22
|
+
resolve_src() {
|
|
23
|
+
if [ -n "${MISHKAN_PROFILE_SRC:-}" ] && [ -f "$MISHKAN_PROFILE_SRC" ]; then
|
|
24
|
+
echo "$MISHKAN_PROFILE_SRC"; return
|
|
25
|
+
fi
|
|
26
|
+
# walk up from cwd looking for docs/engineer/profile.md
|
|
27
|
+
local d; d="$(pwd)"
|
|
28
|
+
while [ "$d" != "/" ]; do
|
|
29
|
+
[ -f "$d/docs/engineer/profile.md" ] && { echo "$d/docs/engineer/profile.md"; return; }
|
|
30
|
+
d="$(dirname "$d")"
|
|
31
|
+
done
|
|
32
|
+
[ -f "$RUNTIME" ] && { echo "$RUNTIME"; return; }
|
|
33
|
+
echo ""; return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
SRC="$(resolve_src)"
|
|
37
|
+
if [ -z "$SRC" ]; then
|
|
38
|
+
echo "sync-profile: no canonical profile found (set MISHKAN_PROFILE_SRC or run from a MISHKAN checkout)." >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if [ "$CHECK_ONLY" -eq 0 ]; then
|
|
43
|
+
if [ "$SRC" != "$RUNTIME" ]; then
|
|
44
|
+
mkdir -p "$MISHKAN"
|
|
45
|
+
cp "$SRC" "$RUNTIME"
|
|
46
|
+
echo "synced: $SRC -> $RUNTIME"
|
|
47
|
+
else
|
|
48
|
+
echo "canonical == runtime ($RUNTIME); nothing to copy."
|
|
49
|
+
fi
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
echo "--- references to the engineer profile across the harness ---"
|
|
53
|
+
# Files that reference the runtime path (exclude this script and the runtime file itself).
|
|
54
|
+
grep -rl "profile.md" "$MISHKAN" "${HOME}/.claude/CLAUDE.md" --exclude=sync-profile.sh 2>/dev/null \
|
|
55
|
+
| grep -v "/profile.md$" | sed "s#${HOME}#~#g" || echo " (no path references found)"
|
|
56
|
+
|
|
57
|
+
# Stale check excludes this script (its grep pattern contains the legacy string by design).
|
|
58
|
+
STALE="$(grep -rl "Y4NN_profile" "$MISHKAN" "${HOME}/.claude/CLAUDE.md" --exclude=sync-profile.sh 2>/dev/null || true)"
|
|
59
|
+
if [ -n "$STALE" ]; then
|
|
60
|
+
echo "--- DRIFT: stale 'Y4NN_profile' references (should be 'profile.md') ---"
|
|
61
|
+
echo "$STALE" | sed "s#${HOME}#~#g"
|
|
62
|
+
echo ">> Ask Seraiah to update these and re-derive any digests."
|
|
63
|
+
else
|
|
64
|
+
echo "no stale references. (Semantic digests in CLAUDE.md are Seraiah's to re-derive if the profile changed materially.)"
|
|
65
|
+
fi
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# validate-research-log.sh — enforce the research-log.schema.json contract.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# validate-research-log.sh <path-to-research-log.json>
|
|
6
|
+
#
|
|
7
|
+
# Exit codes:
|
|
8
|
+
# 0 → valid
|
|
9
|
+
# 1 → invalid (schema violation or missing required field)
|
|
10
|
+
# 2 → environment problem (jq/ajv missing, schema not found, file unreadable)
|
|
11
|
+
#
|
|
12
|
+
# Why this exists: Baruch is the terminal stage of the research pipeline. Its
|
|
13
|
+
# output is the durable record of every research run. A free-text reporter
|
|
14
|
+
# eventually drifts — a schema-validated one cannot. This script is the
|
|
15
|
+
# enforcement layer around payload/mishkan/templates/research-log.schema.json.
|
|
16
|
+
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
LOG_PATH="${1:-}"
|
|
20
|
+
if [[ -z "$LOG_PATH" ]]; then
|
|
21
|
+
echo "usage: $(basename "$0") <path-to-research-log.json>" >&2
|
|
22
|
+
exit 2
|
|
23
|
+
fi
|
|
24
|
+
if [[ ! -r "$LOG_PATH" ]]; then
|
|
25
|
+
echo "error: cannot read $LOG_PATH" >&2
|
|
26
|
+
exit 2
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
SCHEMA_CANDIDATES=(
|
|
30
|
+
"${MISHKAN_HOME:-$HOME/.claude/mishkan}/templates/research-log.schema.json"
|
|
31
|
+
"$(dirname "$0")/../templates/research-log.schema.json"
|
|
32
|
+
)
|
|
33
|
+
SCHEMA_PATH=""
|
|
34
|
+
for c in "${SCHEMA_CANDIDATES[@]}"; do
|
|
35
|
+
if [[ -r "$c" ]]; then SCHEMA_PATH="$c"; break; fi
|
|
36
|
+
done
|
|
37
|
+
if [[ -z "$SCHEMA_PATH" ]]; then
|
|
38
|
+
echo "error: research-log.schema.json not found in any known location" >&2
|
|
39
|
+
printf ' searched: %s\n' "${SCHEMA_CANDIDATES[@]}" >&2
|
|
40
|
+
exit 2
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Layer 1 — JSON well-formedness (fast, always available).
|
|
44
|
+
if ! command -v jq >/dev/null 2>&1; then
|
|
45
|
+
echo "error: jq is required" >&2
|
|
46
|
+
exit 2
|
|
47
|
+
fi
|
|
48
|
+
if ! jq -e . "$LOG_PATH" >/dev/null 2>&1; then
|
|
49
|
+
echo "invalid: $LOG_PATH is not valid JSON" >&2
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Layer 2 — Required-field check (works without ajv; mirrors schema 'required').
|
|
54
|
+
REQUIRED=(agent team sprint trigger query_intent tools_invoked
|
|
55
|
+
research_output_summary applied_to_task outcome
|
|
56
|
+
knowledge_graph_write curated_library_match)
|
|
57
|
+
missing=()
|
|
58
|
+
for f in "${REQUIRED[@]}"; do
|
|
59
|
+
if ! jq -e --arg k "$f" 'has($k)' "$LOG_PATH" >/dev/null 2>&1; then
|
|
60
|
+
missing+=("$f")
|
|
61
|
+
fi
|
|
62
|
+
done
|
|
63
|
+
if (( ${#missing[@]} > 0 )); then
|
|
64
|
+
echo "invalid: missing required fields: ${missing[*]}" >&2
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Enum checks (cheap, semantic).
|
|
69
|
+
trigger=$(jq -r '.trigger' "$LOG_PATH")
|
|
70
|
+
case "$trigger" in
|
|
71
|
+
faced_problem|requested) ;;
|
|
72
|
+
*) echo "invalid: trigger must be one of faced_problem|requested (got '$trigger')" >&2; exit 1 ;;
|
|
73
|
+
esac
|
|
74
|
+
|
|
75
|
+
outcome=$(jq -r '.outcome' "$LOG_PATH")
|
|
76
|
+
case "$outcome" in
|
|
77
|
+
resolved|partial|blocked) ;;
|
|
78
|
+
*) echo "invalid: outcome must be one of resolved|partial|blocked (got '$outcome')" >&2; exit 1 ;;
|
|
79
|
+
esac
|
|
80
|
+
|
|
81
|
+
sprint=$(jq -r '.sprint' "$LOG_PATH")
|
|
82
|
+
if [[ ! "$sprint" =~ ^S[0-9]+$ ]]; then
|
|
83
|
+
echo "invalid: sprint must match ^S[0-9]+\$ (got '$sprint')" >&2
|
|
84
|
+
exit 1
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Layer 3 — Full JSON Schema validation when ajv is available.
|
|
88
|
+
# This catches additionalProperties, type mismatches, and format violations
|
|
89
|
+
# that the layer-2 fast checks do not.
|
|
90
|
+
if command -v ajv >/dev/null 2>&1; then
|
|
91
|
+
if ! ajv validate -s "$SCHEMA_PATH" -d "$LOG_PATH" --strict=false >/dev/null 2>&1; then
|
|
92
|
+
echo "invalid: schema validation failed (ajv):" >&2
|
|
93
|
+
ajv validate -s "$SCHEMA_PATH" -d "$LOG_PATH" --strict=false >&2 || true
|
|
94
|
+
exit 1
|
|
95
|
+
fi
|
|
96
|
+
elif command -v check-jsonschema >/dev/null 2>&1; then
|
|
97
|
+
if ! check-jsonschema --schemafile "$SCHEMA_PATH" "$LOG_PATH" >/dev/null 2>&1; then
|
|
98
|
+
echo "invalid: schema validation failed (check-jsonschema):" >&2
|
|
99
|
+
check-jsonschema --schemafile "$SCHEMA_PATH" "$LOG_PATH" >&2 || true
|
|
100
|
+
exit 1
|
|
101
|
+
fi
|
|
102
|
+
else
|
|
103
|
+
# No JSON-Schema validator available; layers 1+2 still ran.
|
|
104
|
+
echo "warn: ajv/check-jsonschema not installed; ran fast checks only" >&2
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
echo "valid: $LOG_PATH"
|
|
108
|
+
exit 0
|