@cairnkeep/cli 1.0.2
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/AGENTS.md +45 -0
- package/CONTRIBUTING.md +49 -0
- package/LICENSE +201 -0
- package/README.md +149 -0
- package/SECURITY.md +37 -0
- package/bin/cairn +73 -0
- package/claude/agents/code-reviewer.md +174 -0
- package/claude/agents/security-investigator.md +112 -0
- package/claude/agents/security-target-selector.md +90 -0
- package/claude/agents/security-validator.md +97 -0
- package/claude/agents/wiki-ingester.md +108 -0
- package/claude/agents/wiki-lint-auditor.md +94 -0
- package/claude/agents/wiki-query-analyst.md +84 -0
- package/claude/commands/context-explore.md +40 -0
- package/claude/commands/graphify.md +150 -0
- package/claude/commands/memory-review.md +85 -0
- package/claude/commands/memory-sync.md +71 -0
- package/claude/commands/recall.md +32 -0
- package/claude/commands/remember.md +43 -0
- package/claude/commands/repo-review.md +191 -0
- package/claude/commands/security-audit.md +174 -0
- package/claude/commands/wiki-ingest.md +112 -0
- package/claude/commands/wiki-lint.md +86 -0
- package/claude/commands/wiki-query.md +92 -0
- package/claude/hooks/context-explore-pretask.sh +93 -0
- package/claude/hooks/memory-capture.sh +59 -0
- package/claude/hooks/memory-recall.sh +84 -0
- package/claude/hooks/memory-wakeup.sh +45 -0
- package/docs/building-an-overlay.md +117 -0
- package/docs/domain-knowledge.md +86 -0
- package/docs/git-providers.md +36 -0
- package/docs/operating.md +366 -0
- package/mcp-memory-server/dist/embeddings.js +122 -0
- package/mcp-memory-server/dist/explore-cache.js +97 -0
- package/mcp-memory-server/dist/index.js +1256 -0
- package/mcp-memory-server/package.json +36 -0
- package/opencode/agents/code-reviewer.md +173 -0
- package/opencode/agents/security-investigator.md +111 -0
- package/opencode/agents/security-target-selector.md +89 -0
- package/opencode/agents/security-validator.md +96 -0
- package/opencode/agents/wiki-ingester.md +107 -0
- package/opencode/agents/wiki-lint-auditor.md +93 -0
- package/opencode/agents/wiki-query-analyst.md +83 -0
- package/opencode/command/code-review.md +199 -0
- package/opencode/command/context-explore.md +42 -0
- package/opencode/command/graphify.md +153 -0
- package/opencode/command/memory-review.md +44 -0
- package/opencode/command/memory-sync.md +94 -0
- package/opencode/command/recall.md +38 -0
- package/opencode/command/remember.md +46 -0
- package/opencode/command/security-audit.md +80 -0
- package/opencode/command/wiki-ingest.md +55 -0
- package/opencode/command/wiki-lint.md +51 -0
- package/opencode/command/wiki-query.md +50 -0
- package/opencode/plugins/memory-capture.ts +188 -0
- package/opencode/plugins/memory-recall.ts +132 -0
- package/opencode/plugins/memory-wakeup.ts +102 -0
- package/opencode/templates/security-finding-register.yaml.template +51 -0
- package/opencode/templates/security-issue.md.template +43 -0
- package/opencode/templates/security-policy.md.template +29 -0
- package/opencode/templates/security-report.md.template +43 -0
- package/opencode/templates/wiki-contradictions.md.template +31 -0
- package/opencode/templates/wiki-index.md.template +40 -0
- package/opencode/templates/wiki-lint-report.md.template +38 -0
- package/opencode/templates/wiki-log.md.template +11 -0
- package/opencode/templates/wiki-policy.md.template +47 -0
- package/opencode/templates/wiki-query-answer.md.template +26 -0
- package/opencode/templates/wiki-source-summary.md.template +33 -0
- package/opencode/workflows/memory-review-workflow.md +66 -0
- package/opencode/workflows/security-audit-workflow.md +197 -0
- package/opencode/workflows/wiki-ingest-workflow.md +149 -0
- package/opencode/workflows/wiki-lint-workflow.md +128 -0
- package/opencode/workflows/wiki-query-workflow.md +122 -0
- package/package.json +56 -0
- package/scripts/bootstrap.sh +99 -0
- package/scripts/doctor.sh +91 -0
- package/scripts/install-audit-timer.sh +68 -0
- package/scripts/lib/assert-tool-event.mjs +50 -0
- package/scripts/memory-store.sh +71 -0
- package/scripts/memory-wiki-audit.sh +156 -0
- package/scripts/sync-claude-assets.sh +182 -0
- package/scripts/sync-opencode-explore-assets.sh +187 -0
- package/scripts/sync-opencode-graphify-assets.sh +152 -0
- package/scripts/sync-opencode-memory-assets.sh +160 -0
- package/scripts/sync-opencode-plugin-assets.sh +163 -0
- package/scripts/sync-opencode-security-assets.sh +195 -0
- package/scripts/sync-opencode-wiki-assets.sh +250 -0
- package/scripts/test-audit-timer.sh +29 -0
- package/scripts/test-bootstrap-untracked.sh +41 -0
- package/scripts/test-cli-dispatch.sh +21 -0
- package/scripts/test-doctor.sh +32 -0
- package/scripts/test-launcher-hooks.sh +66 -0
- package/scripts/test-memory-store.sh +44 -0
- package/scripts/test-remember-recall-assertions.sh +70 -0
- package/scripts/transcript-to-text.mjs +53 -0
- package/scripts/verify-docs-parity.sh +112 -0
- package/scripts/verify-explore-maturation.sh +288 -0
- package/scripts/verify-fastcontext-reliability.sh +624 -0
- package/scripts/verify-no-private-references.sh +145 -0
- package/scripts/verify-opencode-live-parity.sh +864 -0
- package/scripts/verify-routing-seam.sh +169 -0
- package/scripts/verify-token-savings-ab.sh +557 -0
- package/templates/PROJECT-INSTRUCTIONS.md.template +42 -0
- package/templates/alignment-gap-register.yaml.template +56 -0
- package/templates/alignment-policy.md.template +28 -0
- package/templates/alignment-pr-template.md.template +18 -0
- package/templates/alignment-report.md.template +56 -0
- package/templates/env.example.template +25 -0
- package/templates/graph-policy.md.template +37 -0
- package/templates/graphs-gitignore.template +3 -0
- package/templates/memory-wiki-audit.service.template +6 -0
- package/templates/memory-wiki-audit.timer.template +9 -0
- package/templates/memory.json.template +4 -0
- package/templates/planning-config.json.template +6 -0
- package/templates/project-brief.md.template +40 -0
- package/templates/security-finding-register.yaml.template +51 -0
- package/templates/security-issue.md.template +43 -0
- package/templates/security-policy.md.template +29 -0
- package/templates/security-report.md.template +43 -0
- package/templates/start-claude.sh.template +46 -0
- package/templates/start-opencode.sh.template +41 -0
- package/templates/structured-change-canvas.md.template +63 -0
- package/templates/wiki-contradictions.md.template +31 -0
- package/templates/wiki-index.md.template +40 -0
- package/templates/wiki-lint-report.md.template +38 -0
- package/templates/wiki-log.md.template +11 -0
- package/templates/wiki-policy.md.template +47 -0
- package/templates/wiki-query-answer.md.template +26 -0
- package/templates/wiki-source-summary.md.template +33 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Routing seam real-binary proof (RT-01/RT-02, Phase 10 D-06 verify-by-
|
|
5
|
+
# execution — this repo's bar, above docs-only per D-10).
|
|
6
|
+
#
|
|
7
|
+
# Starts the REAL (non-mocked) token_miser binary in the background and polls
|
|
8
|
+
# its GET /health endpoint until it answers, then asserts the response body
|
|
9
|
+
# contains "status":"ok". This proves the routing seam's TARGET is a real,
|
|
10
|
+
# live binary that the route_check MCP tool (Phase 10 Plan 01) can reach.
|
|
11
|
+
#
|
|
12
|
+
# It does NOT prove a tier decision: /health never calls Router::classify,
|
|
13
|
+
# so a 200 here is liveness proof, not evidence that routing itself worked
|
|
14
|
+
# (RESEARCH.md Pitfall 4). The optional --full mode attempts one real
|
|
15
|
+
# /v1/chat/completions round-trip as a stretch goal — it needs a live tier
|
|
16
|
+
# backend absent on this machine, so it is never the required minimum
|
|
17
|
+
# (D-06/D-07 defer live routing) and must itself fail loud with a message
|
|
18
|
+
# (never a silent skip) when no backend is reachable.
|
|
19
|
+
#
|
|
20
|
+
# Mirrors scripts/verify-fastcontext-reliability.sh and
|
|
21
|
+
# scripts/verify-token-savings-ab.sh's staged, env-driven, loopback-safe,
|
|
22
|
+
# fail-loud-never-silent harness discipline. Every host-specific value
|
|
23
|
+
# (the binary path) comes from the ambient shell at runtime and is never
|
|
24
|
+
# hardcoded or echoed beyond a presence indicator (DEC-no-private-references).
|
|
25
|
+
#
|
|
26
|
+
# Pitfall 1 (RESEARCH.md): never probe token_miser with --help/--version —
|
|
27
|
+
# the binary's only CLI dispatch is the `explore` subcommand; every other
|
|
28
|
+
# invocation (no args, --help, garbage) falls through to starting the full
|
|
29
|
+
# Axum proxy server on 0.0.0.0:8080 and blocks forever. This script starts
|
|
30
|
+
# the binary for real (background + trap kill) instead of probing it.
|
|
31
|
+
|
|
32
|
+
usage() {
|
|
33
|
+
cat <<'EOF'
|
|
34
|
+
Usage: verify-routing-seam.sh
|
|
35
|
+
verify-routing-seam.sh --full
|
|
36
|
+
verify-routing-seam.sh -h|--help
|
|
37
|
+
|
|
38
|
+
Starts the real token_miser binary and proves it answers GET /health with
|
|
39
|
+
"status":"ok" (D-06 verify-by-execution). This is the required, default
|
|
40
|
+
mode: health-only, no chat traffic.
|
|
41
|
+
|
|
42
|
+
Options:
|
|
43
|
+
(default)
|
|
44
|
+
Health-only: start the real binary, poll GET /health with a bounded
|
|
45
|
+
retry loop (never a fixed sleep — startup includes gh/claude
|
|
46
|
+
model-discovery probes), assert "status":"ok", kill the process on
|
|
47
|
+
exit. Proves the seam's target is real and reachable — not a tier
|
|
48
|
+
decision (Pitfall 4).
|
|
49
|
+
--full
|
|
50
|
+
Health-only proof, plus an optional stretch: one real POST to
|
|
51
|
+
/v1/chat/completions. Skips with an explicit message (does not fail
|
|
52
|
+
the health-only proof) when no live tier backend is reachable — this
|
|
53
|
+
is never the required minimum (D-06/D-07).
|
|
54
|
+
-h, --help
|
|
55
|
+
Show this help text.
|
|
56
|
+
|
|
57
|
+
Environment:
|
|
58
|
+
CAIRN_ROUTE_BINARY Absolute path to the token_miser binary. Defaults to
|
|
59
|
+
$HOME/PARA/Projects/token-miser/target/release/token_miser.
|
|
60
|
+
Never echoed — only a presence indicator is logged.
|
|
61
|
+
EOF
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
CAIRN_ROUTE_BINARY="${CAIRN_ROUTE_BINARY:-$HOME/PARA/Projects/token-miser/target/release/token_miser}"
|
|
65
|
+
HEALTH_URL="http://127.0.0.1:8080/health"
|
|
66
|
+
|
|
67
|
+
# Script-global (not `local` to run_health_proof): the EXIT trap fires after
|
|
68
|
+
# the function returns, so it must read pid from a scope that outlives it —
|
|
69
|
+
# a `local pid` here would be unbound under `set -u` by the time trap runs.
|
|
70
|
+
ROUTE_PID=""
|
|
71
|
+
|
|
72
|
+
# log_binary_presence(): logs only whether CAIRN_ROUTE_BINARY was overridden
|
|
73
|
+
# from the default — never the resolved path value (mirrors
|
|
74
|
+
# log_endpoint_presence() in verify-fastcontext-reliability.sh, T-10-06).
|
|
75
|
+
log_binary_presence() {
|
|
76
|
+
local default="$HOME/PARA/Projects/token-miser/target/release/token_miser"
|
|
77
|
+
local overridden="no"
|
|
78
|
+
[[ "$CAIRN_ROUTE_BINARY" != "$default" ]] && overridden="yes"
|
|
79
|
+
echo "[env] CAIRN_ROUTE_BINARY overridden from default: $overridden" >&2
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
# run_health_proof(): starts the real binary in the background, polls
|
|
83
|
+
# GET /health, asserts "status":"ok", and guarantees teardown via trap.
|
|
84
|
+
# Exits nonzero (fails loud) if the binary is absent — never a silent pass.
|
|
85
|
+
run_health_proof() {
|
|
86
|
+
if [[ ! -x "$CAIRN_ROUTE_BINARY" ]]; then
|
|
87
|
+
echo "FATAL: token_miser binary not found or not executable at the resolved CAIRN_ROUTE_BINARY path — real proof cannot run (D-06). Set CAIRN_ROUTE_BINARY or build the binary." >&2
|
|
88
|
+
return 1
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
"$CAIRN_ROUTE_BINARY" &
|
|
92
|
+
ROUTE_PID=$!
|
|
93
|
+
trap 'kill "$ROUTE_PID" 2>/dev/null || true' EXIT
|
|
94
|
+
|
|
95
|
+
local attempt
|
|
96
|
+
local reached="no"
|
|
97
|
+
for attempt in $(seq 1 20); do
|
|
98
|
+
if curl -sf -m 2 "$HEALTH_URL" >/dev/null 2>&1; then
|
|
99
|
+
reached="yes"
|
|
100
|
+
break
|
|
101
|
+
fi
|
|
102
|
+
sleep 0.5
|
|
103
|
+
done
|
|
104
|
+
|
|
105
|
+
if [[ "$reached" != "yes" ]]; then
|
|
106
|
+
echo "FATAL: token_miser started (pid=$ROUTE_PID) but /health never became reachable within the poll budget" >&2
|
|
107
|
+
return 1
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
local body
|
|
111
|
+
body=$(curl -sf -m 2 "$HEALTH_URL")
|
|
112
|
+
if ! grep -q '"status":"ok"' <<<"$body"; then
|
|
113
|
+
echo "FATAL: /health responded but body did not contain \"status\":\"ok\" (got: $body)" >&2
|
|
114
|
+
return 1
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
echo "[health] OK: real token_miser binary answered GET /health with status ok (D-06 liveness proof; not a tier decision — Pitfall 4)"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
# run_full_stretch(): optional --full addendum. Attempts one real POST to
|
|
121
|
+
# /v1/chat/completions against the already-running proxy from
|
|
122
|
+
# run_health_proof(). Skips with an explicit message (exit 0, not a
|
|
123
|
+
# failure of the required health-only proof) when no tier backend answers.
|
|
124
|
+
run_full_stretch() {
|
|
125
|
+
echo "[full] attempting optional /v1/chat/completions round-trip (stretch, D-06/D-07 defer live routing)..." >&2
|
|
126
|
+
|
|
127
|
+
local response
|
|
128
|
+
if ! response=$(curl -sf -m 5 -X POST "http://127.0.0.1:8080/v1/chat/completions" \
|
|
129
|
+
-H 'Content-Type: application/json' \
|
|
130
|
+
-d '{"messages":[{"role":"user","content":"ping"}]}' 2>&1); then
|
|
131
|
+
echo "[full] SKIPPED: no live tier backend reachable for a real chat round-trip — this is an optional stretch, not the required minimum (D-06/D-07)." >&2
|
|
132
|
+
return 0
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
echo "[full] OK: received a response from /v1/chat/completions (not further validated — the health-only proof above is the required minimum): $response"
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
main() {
|
|
139
|
+
local full=0
|
|
140
|
+
|
|
141
|
+
while [[ $# -gt 0 ]]; do
|
|
142
|
+
case "$1" in
|
|
143
|
+
--full)
|
|
144
|
+
full=1
|
|
145
|
+
shift
|
|
146
|
+
;;
|
|
147
|
+
-h|--help)
|
|
148
|
+
usage
|
|
149
|
+
exit 0
|
|
150
|
+
;;
|
|
151
|
+
*)
|
|
152
|
+
usage >&2
|
|
153
|
+
exit 2
|
|
154
|
+
;;
|
|
155
|
+
esac
|
|
156
|
+
done
|
|
157
|
+
|
|
158
|
+
log_binary_presence
|
|
159
|
+
|
|
160
|
+
if ! run_health_proof; then
|
|
161
|
+
exit 1
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
if [[ "$full" -eq 1 ]]; then
|
|
165
|
+
run_full_stretch
|
|
166
|
+
fi
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
main "$@"
|