@cairnkeep/cli 2.3.0 → 2.4.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/CHANGELOG.md +78 -0
- package/README.md +221 -6
- package/bin/cairn +43 -2
- package/claude/capability-contract/hooks/capability-command-finish.sh +81 -0
- package/claude/capability-contract/hooks/capability-command-start.sh +76 -0
- package/claude/hooks/compaction-capture.sh +34 -0
- package/claude/hooks/memory-capture.sh +47 -5
- package/claude/hooks/memory-wakeup.sh +55 -2
- package/docs/building-an-overlay.md +1 -1
- package/docs/design/meta-agent.md +439 -0
- package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
- package/docs/learning/lessons/L01-safe-trial.md +3 -3
- package/docs/learning/lessons/L02-installation.md +2 -2
- package/docs/learning/lessons/L03-first-project.md +1 -1
- package/docs/operating.md +531 -4
- package/docs/privacy-and-data-flow.md +417 -0
- package/docs/storage.md +252 -0
- package/examples/eval/README.md +42 -0
- package/examples/eval/adapter.json +12 -0
- package/examples/eval/bundled-fake.json +1 -0
- package/examples/eval/task-set.json +1 -0
- package/mcp-memory-server/dist/artifact-cli.js +184 -0
- package/mcp-memory-server/dist/artifact-schema.js +218 -0
- package/mcp-memory-server/dist/artifact-store.js +812 -0
- package/mcp-memory-server/dist/capability-adapter.js +286 -0
- package/mcp-memory-server/dist/capability-cli.js +361 -0
- package/mcp-memory-server/dist/capability-config.js +310 -0
- package/mcp-memory-server/dist/capability-harness.js +496 -0
- package/mcp-memory-server/dist/capability-registry.js +123 -0
- package/mcp-memory-server/dist/capability-schema.js +65 -0
- package/mcp-memory-server/dist/capability-store.js +431 -0
- package/mcp-memory-server/dist/compaction-normalize.js +267 -0
- package/mcp-memory-server/dist/eval-cli.js +523 -0
- package/mcp-memory-server/dist/eval-plan.js +346 -0
- package/mcp-memory-server/dist/eval-process.js +273 -0
- package/mcp-memory-server/dist/eval-report.js +609 -0
- package/mcp-memory-server/dist/eval-runner.js +827 -0
- package/mcp-memory-server/dist/eval-schema.js +368 -0
- package/mcp-memory-server/dist/eval-statistics.js +161 -0
- package/mcp-memory-server/dist/eval-workspace.js +313 -0
- package/mcp-memory-server/dist/failure-signature.js +141 -0
- package/mcp-memory-server/dist/index.js +600 -55
- package/mcp-memory-server/dist/node-cli.js +84 -0
- package/mcp-memory-server/dist/node-schema.js +170 -0
- package/mcp-memory-server/dist/node-store.js +455 -0
- package/mcp-memory-server/dist/note-cli.js +235 -0
- package/mcp-memory-server/dist/note-distiller.js +177 -0
- package/mcp-memory-server/dist/note-enrichment.js +93 -0
- package/mcp-memory-server/dist/note-schema.js +4 -0
- package/mcp-memory-server/dist/note-store.js +985 -0
- package/mcp-memory-server/dist/trajectory-cli.js +141 -0
- package/mcp-memory-server/dist/trajectory-normalize.js +448 -0
- package/mcp-memory-server/dist/trajectory-redaction.js +155 -0
- package/mcp-memory-server/dist/trajectory-schema.js +73 -0
- package/mcp-memory-server/dist/trajectory-store.js +339 -0
- package/mcp-memory-server/package.json +24 -2
- package/mcp-memory-server/scripts/fixtures/compaction-claude-code-2.1.219.json +9 -0
- package/mcp-memory-server/scripts/fixtures/compaction-claude-code-2.1.220.json +9 -0
- package/mcp-memory-server/scripts/fixtures/compaction-opencode-1.17.20-event.json +6 -0
- package/mcp-memory-server/scripts/fixtures/compaction-opencode-1.17.20-messages.json +119 -0
- package/mcp-memory-server/scripts/fixtures/compaction-unknown-version.json +17 -0
- package/opencode/capability-contract/plugins/capability-command.ts +319 -0
- package/opencode/command/graphify.md +25 -14
- package/opencode/plugins/memory-capture.ts +76 -10
- package/opencode/plugins/memory-wakeup.ts +58 -6
- package/package.json +9 -4
- package/pi/extensions/cairnkeep-trajectory.ts +55 -0
- package/schemas/artifact.schema.json +133 -0
- package/schemas/capability-callback.schema.json +68 -0
- package/schemas/capability-contract.schema.json +126 -0
- package/schemas/eval-adapter.schema.json +43 -0
- package/schemas/eval-protocol.schema.json +114 -0
- package/schemas/eval-report.schema.json +423 -0
- package/schemas/eval-task-set.schema.json +114 -0
- package/schemas/memory-node.schema.json +90 -0
- package/schemas/note.schema.json +112 -0
- package/schemas/trajectory-redaction.schema.json +25 -0
- package/schemas/trajectory.schema.json +82 -0
- package/scripts/bootstrap.sh +4 -0
- package/scripts/completion.sh +119 -5
- package/scripts/doctor.sh +284 -0
- package/scripts/fake-eval-adapter.mjs +120 -0
- package/scripts/fixtures/capability-harness-contracts.json +408 -0
- package/scripts/install-audit-timer.sh +3 -1
- package/scripts/lib/capability-opencode-plugin-harness.mjs +291 -0
- package/scripts/lib/trajectory-opencode-plugin-harness.mjs +25 -0
- package/scripts/lib/trajectory-pi-extension-harness.mjs +42 -0
- package/scripts/memory-wiki-audit.sh +49 -0
- package/scripts/smoke-bash32.sh +9 -0
- package/scripts/sync-claude-assets.sh +99 -6
- package/scripts/sync-opencode-graphify-assets.sh +24 -3
- package/scripts/sync-opencode-plugin-assets.sh +31 -5
- package/scripts/sync-opencode-security-assets.sh +24 -3
- package/scripts/sync-opencode-wiki-assets.sh +24 -3
- package/scripts/sync-pi-assets.sh +72 -0
- package/scripts/test-audit-timer.sh +98 -0
- package/scripts/test-bootstrap-untracked.sh +48 -0
- package/scripts/test-cli-dispatch.sh +41 -2
- package/scripts/test-compaction-hooks.sh +495 -0
- package/scripts/test-completion.sh +77 -0
- package/scripts/test-doctor.sh +348 -1
- package/scripts/test-eval-cli.sh +175 -0
- package/scripts/test-launcher-hooks.sh +602 -3
- package/scripts/test-notes-cli.sh +114 -0
- package/scripts/test-package-install.sh +251 -0
- package/scripts/test-phase16-node-lifecycle.sh +50 -0
- package/scripts/test-phase17-artifact-lifecycle.sh +370 -0
- package/scripts/test-phase18-capability-lifecycle.sh +504 -0
- package/scripts/test-phase18-harness-boundary.sh +1060 -0
- package/scripts/test-phase19-eval-lifecycle.sh +1015 -0
- package/scripts/test-trajectory-cli.sh +87 -0
- package/scripts/test-trajectory-hooks.sh +142 -0
- package/scripts/test-uninstall.sh +231 -5
- package/scripts/uninstall.sh +37 -5
- package/scripts/verify-dependency-security.mjs +121 -0
- package/scripts/verify-docs-parity.sh +527 -1
- package/scripts/verify-phase18-runtime-evidence.mjs +895 -0
- package/scripts/verify-phase19-runtime-evidence.mjs +947 -0
- package/templates/capabilities.json.template +7 -0
- package/templates/env.example.template +51 -0
- package/templates/memory-wiki-audit.service.template +1 -1
- package/templates/start-claude.sh.template +36 -0
- package/templates/start-opencode.sh.template +47 -5
- package/templates/start-pi.sh.template +30 -0
- package/templates/trajectory-redaction.json.template +4 -0
|
@@ -14,15 +14,31 @@
|
|
|
14
14
|
set -euo pipefail
|
|
15
15
|
|
|
16
16
|
repo="$(pwd)"
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
trajectory_enabled=0
|
|
19
|
+
case "${CAIRN_TRAJECTORY_CAPTURE:-}" in
|
|
20
|
+
1|true|TRUE|yes|YES|on|ON) trajectory_enabled=1 ;;
|
|
21
|
+
esac
|
|
22
|
+
|
|
23
|
+
# Preserve the original disabled path: outside a bootstrapped repository the
|
|
24
|
+
# hook exits before reading stdin or starting a process.
|
|
25
|
+
if [ "$trajectory_enabled" -eq 0 ]; then
|
|
26
|
+
[ -f "$repo/.agentfs/project.db" ] || exit 0
|
|
27
|
+
fi
|
|
18
28
|
|
|
19
29
|
INFRA_ROOT="@@INFRA_ROOT@@"
|
|
20
30
|
SERVER_ENTRY="$INFRA_ROOT/mcp-memory-server/dist/index.js"
|
|
31
|
+
TRAJECTORY_ENTRY="$INFRA_ROOT/mcp-memory-server/dist/trajectory-cli.js"
|
|
21
32
|
TEXT_HELPER="$INFRA_ROOT/scripts/transcript-to-text.mjs"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
[
|
|
33
|
+
|
|
34
|
+
# Keep every pre-existing no-model guard ahead of stdin parsing when trajectory
|
|
35
|
+
# capture is disabled.
|
|
36
|
+
if [ "$trajectory_enabled" -eq 0 ]; then
|
|
37
|
+
[ -f "$SERVER_ENTRY" ] || exit 0
|
|
38
|
+
[ -z "${CAIRN_LLM_API_KEY:-}" ] && exit 0
|
|
39
|
+
EXTRACT_MODEL="${CAIRN_LLM_EXTRACTION_MODEL:-}"
|
|
40
|
+
[ -z "$EXTRACT_MODEL" ] && exit 0
|
|
41
|
+
fi
|
|
26
42
|
|
|
27
43
|
# Read hook JSON from stdin; pull transcript_path (fail-open if absent/malformed).
|
|
28
44
|
input="$(cat)"
|
|
@@ -32,6 +48,32 @@ try:
|
|
|
32
48
|
except Exception: print("")' 2>/dev/null || true)"
|
|
33
49
|
[ -n "$transcript_path" ] && [ -f "$transcript_path" ] || exit 0
|
|
34
50
|
|
|
51
|
+
# Trajectory capture is local, model-free and independently bounded. The
|
|
52
|
+
# watchdog exists only on the opt-in path and cannot fail the SessionEnd hook.
|
|
53
|
+
if [ "$trajectory_enabled" -eq 1 ] && [ -f "$TRAJECTORY_ENTRY" ]; then
|
|
54
|
+
node "$TRAJECTORY_ENTRY" capture-claude "$transcript_path" "$repo" >/dev/null 2>&1 &
|
|
55
|
+
trajectory_pid=$!
|
|
56
|
+
(
|
|
57
|
+
sleep 3
|
|
58
|
+
kill -KILL "$trajectory_pid" >/dev/null 2>&1 || true
|
|
59
|
+
) &
|
|
60
|
+
trajectory_watchdog_pid=$!
|
|
61
|
+
wait "$trajectory_pid" >/dev/null 2>&1 || true
|
|
62
|
+
kill "$trajectory_watchdog_pid" >/dev/null 2>&1 || true
|
|
63
|
+
wait "$trajectory_watchdog_pid" >/dev/null 2>&1 || true
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Durable-memory extraction remains independently gated by the pre-existing
|
|
67
|
+
# project/model requirements. The disabled path passed these checks before
|
|
68
|
+
# stdin parsing above; the enabled path reaches them only after local capture.
|
|
69
|
+
if [ "$trajectory_enabled" -eq 1 ]; then
|
|
70
|
+
[ -f "$repo/.agentfs/project.db" ] || exit 0
|
|
71
|
+
[ -f "$SERVER_ENTRY" ] || exit 0
|
|
72
|
+
[ -z "${CAIRN_LLM_API_KEY:-}" ] && exit 0
|
|
73
|
+
EXTRACT_MODEL="${CAIRN_LLM_EXTRACTION_MODEL:-}"
|
|
74
|
+
[ -z "$EXTRACT_MODEL" ] && exit 0
|
|
75
|
+
fi
|
|
76
|
+
|
|
35
77
|
# Convert transcript JSONL → readable text, then extract candidates.
|
|
36
78
|
text="$(node "$TEXT_HELPER" "$transcript_path" 2>/dev/null || true)"
|
|
37
79
|
[ -n "$text" ] || exit 0
|
|
@@ -6,7 +6,33 @@
|
|
|
6
6
|
set -euo pipefail
|
|
7
7
|
|
|
8
8
|
repo="$(pwd)"
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
compaction_enabled=0
|
|
11
|
+
case "${CAIRN_COMPACTION_CAPTURE:-}" in
|
|
12
|
+
1|true|TRUE|yes|YES|on|ON) compaction_enabled=1 ;;
|
|
13
|
+
esac
|
|
14
|
+
|
|
15
|
+
if [ "$compaction_enabled" -eq 0 ]; then
|
|
16
|
+
[ -f "$repo/.agentfs/project.db" ] || [ -f "$repo/.planning/wiki/index.md" ] || exit 0
|
|
17
|
+
else
|
|
18
|
+
[ -f "$repo/.agentfs/project.db" ] || [ -f "$repo/.planning/wiki/index.md" ] \
|
|
19
|
+
|| [ -f "$repo/.agentfs/artifacts.db" ] || exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
session_ref=""
|
|
23
|
+
if [ "$compaction_enabled" -eq 1 ]; then
|
|
24
|
+
input="$(cat)"
|
|
25
|
+
session_id="$(printf '%s' "$input" | python3 -c 'import json,re,sys
|
|
26
|
+
try:
|
|
27
|
+
value=json.load(sys.stdin)
|
|
28
|
+
session_id=value.get("session_id", "")
|
|
29
|
+
source=value.get("source", "")
|
|
30
|
+
safe=lambda item: isinstance(item, str) and re.fullmatch(r"[A-Za-z0-9._:/-]{1,160}", item)
|
|
31
|
+
print(session_id if safe(session_id) and (source == "" or safe(source)) else "")
|
|
32
|
+
except Exception:
|
|
33
|
+
print("")' 2>/dev/null || true)"
|
|
34
|
+
[ -n "$session_id" ] && session_ref="claude-code:$session_id"
|
|
35
|
+
fi
|
|
10
36
|
|
|
11
37
|
if [ -f "$repo/.agentfs/project.db" ]; then
|
|
12
38
|
echo "## Project memory (AgentFS)"
|
|
@@ -24,7 +50,7 @@ fi
|
|
|
24
50
|
# entries cannot both be correct and must be resolved before dependent work.
|
|
25
51
|
contradictions="$repo/.planning/wiki/CONTRADICTIONS.md"
|
|
26
52
|
if [ -f "$contradictions" ]; then
|
|
27
|
-
open_hard="$(awk '/<!-- wiki:contradictions:open:start -->/{f=1;next} /<!-- wiki:contradictions:open:end -->/{f=0} f' "$contradictions" | grep -iE 'severity:[[:space:]]*hard')"
|
|
53
|
+
open_hard="$(awk '/<!-- wiki:contradictions:open:start -->/{f=1;next} /<!-- wiki:contradictions:open:end -->/{f=0} f' "$contradictions" | grep -iE 'severity:[[:space:]]*hard' || true)"
|
|
28
54
|
if [ -n "$open_hard" ]; then
|
|
29
55
|
echo
|
|
30
56
|
echo "## Open HARD contradictions — resolve before dependent work"
|
|
@@ -43,3 +69,30 @@ if [ -d "$repo/.planning/memory-staging" ]; then
|
|
|
43
69
|
echo "Run /memory-review to accept (→ AgentFS) or discard these before doing other work."
|
|
44
70
|
fi
|
|
45
71
|
fi
|
|
72
|
+
|
|
73
|
+
if [ "$compaction_enabled" -eq 1 ]; then
|
|
74
|
+
artifact_entry="@@INFRA_ROOT@@/mcp-memory-server/dist/artifact-cli.js"
|
|
75
|
+
if [ -f "$artifact_entry" ]; then
|
|
76
|
+
recovery_file="${TMPDIR:-/tmp}/cairn-compaction-recovery.$$"
|
|
77
|
+
if [ -n "$session_ref" ]; then
|
|
78
|
+
node "$artifact_entry" recover "$repo" --session-ref "$session_ref" >"$recovery_file" 2>/dev/null &
|
|
79
|
+
else
|
|
80
|
+
node "$artifact_entry" recover "$repo" >"$recovery_file" 2>/dev/null &
|
|
81
|
+
fi
|
|
82
|
+
recovery_pid=$!
|
|
83
|
+
(
|
|
84
|
+
sleep 3
|
|
85
|
+
kill -KILL "$recovery_pid" >/dev/null 2>&1 || true
|
|
86
|
+
) &
|
|
87
|
+
recovery_watchdog_pid=$!
|
|
88
|
+
wait "$recovery_pid" >/dev/null 2>&1 || true
|
|
89
|
+
kill "$recovery_watchdog_pid" >/dev/null 2>&1 || true
|
|
90
|
+
wait "$recovery_watchdog_pid" >/dev/null 2>&1 || true
|
|
91
|
+
if [ -s "$recovery_file" ]; then
|
|
92
|
+
echo
|
|
93
|
+
grep -qF "## Compaction recovery" "$recovery_file" || echo "## Compaction recovery"
|
|
94
|
+
cat "$recovery_file"
|
|
95
|
+
fi
|
|
96
|
+
rm -f "$recovery_file"
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
@@ -33,7 +33,7 @@ by `cairn bootstrap`) run three optional hooks, each a no-op when absent:
|
|
|
33
33
|
| Seam | When | Use it for |
|
|
34
34
|
|---|---|---|
|
|
35
35
|
| `.ai/pre-launch.sh` | sourced after `.env`, before launch | export a provider base URL / credentials, refresh a token, run a connectivity check, or **abort** the launch by returning non-zero |
|
|
36
|
-
| `CAIRN_EXTRA_SETTINGS` | read just before launch | path to a settings file layered onto the harness (`--settings` for Claude Code,
|
|
36
|
+
| `CAIRN_EXTRA_SETTINGS` | read just before launch | path to a settings file layered onto the harness (`--settings` for Claude Code, `OPENCODE_CONFIG` for OpenCode); process env still wins, so an inline value beats the file |
|
|
37
37
|
| `.ai/post-exit.sh` | sourced after the harness exits | teardown; `CAIRN_EXIT_STATUS` holds the exit code |
|
|
38
38
|
|
|
39
39
|
**Typical overlay launcher** — a corporate wrapper needs a non-default provider
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
# Meta-agent design contract
|
|
2
|
+
|
|
3
|
+
> **Design-only status.** Phase 20 ships this Markdown file only. It ships no
|
|
4
|
+
> executable schema, compiler, generator, controller, adapter change,
|
|
5
|
+
> configuration surface, command-line interface, or runtime default. Phase 18
|
|
6
|
+
> capability state and Phase 19 evaluation behavior described below are current
|
|
7
|
+
> facts. Every meta-agent control, artifact, state, and action described as a
|
|
8
|
+
> requirement is future work that requires separate approval.
|
|
9
|
+
|
|
10
|
+
## Status and normative language
|
|
11
|
+
|
|
12
|
+
This document specifies a future, bounded build-test-improve configuration
|
|
13
|
+
loop. It does not accept input and is not an executable interface. In future
|
|
14
|
+
requirements, **MUST**, **MUST NOT**, **REQUIRED**, and **SHALL** are normative;
|
|
15
|
+
**SHOULD** and **MAY** describe constrained choices. Statements explicitly
|
|
16
|
+
labelled current describe accepted Phase 18 or Phase 19 behavior rather than
|
|
17
|
+
new behavior.
|
|
18
|
+
|
|
19
|
+
Every block labelled **Illustrative only** is fictional, secret-free, and
|
|
20
|
+
non-normative. Such a block is not a shipped schema and is not accepted CLI
|
|
21
|
+
input. It provides no default, compatibility promise, or implementation
|
|
22
|
+
authority.
|
|
23
|
+
|
|
24
|
+
## Paper concept and Cairnkeep boundary
|
|
25
|
+
|
|
26
|
+
The paper's build-test-improve concept motivates a future bounded configuration
|
|
27
|
+
loop, but does not redefine Cairnkeep's ownership. Cairnkeep may eventually
|
|
28
|
+
compile an operator objective into a reviewable form, propose bounded candidate
|
|
29
|
+
artifacts, coordinate approved measurement, and prepare a reversible proposal.
|
|
30
|
+
It must not own a harness inference loop. Existing repository contracts remain
|
|
31
|
+
the authority over external design inspiration.
|
|
32
|
+
|
|
33
|
+
Natural-language objectives are untrusted proposal data. They never authorize
|
|
34
|
+
repository reads, writes, commands, network use, evaluation, or application.
|
|
35
|
+
Only a future compiler and deterministic validator may produce the strict,
|
|
36
|
+
versioned form that an operator can review, reject, or confirm. Confirmation of
|
|
37
|
+
that form grants no evaluation or apply authority.
|
|
38
|
+
|
|
39
|
+
## Natural-language specification → strict form
|
|
40
|
+
|
|
41
|
+
The future form is the only reviewable control representation. Its validator
|
|
42
|
+
MUST reject unknown fields and MUST NOT infer, repair, or model-author any
|
|
43
|
+
safety-critical value. A natural-language objective remains attached as
|
|
44
|
+
untrusted provenance, not executable policy.
|
|
45
|
+
|
|
46
|
+
### Required configuration fields and fail-closed rules
|
|
47
|
+
|
|
48
|
+
| Required field group | Required future content | Deterministic invalidation rule |
|
|
49
|
+
|---|---|---|
|
|
50
|
+
| Schema and specification identity | Supported schema version, unique specification ID, canonical form digest, and untrusted objective reference | Reject absent or duplicate identity, unknown fields, unsupported versions, or a digest that does not match canonical form bytes. |
|
|
51
|
+
| Repository scope and immutable revisions | One or more declared repository roots, each bound to an exact immutable revision | Reject an empty root set, unresolved or non-immutable revisions, duplicate aliases, or a root whose real path cannot be established. |
|
|
52
|
+
| Path policy | Canonical `allowed_paths` and `denied_paths`, with deny precedence and a declared symlink policy | Reject absolute or non-canonical entries, traversal, symlink escape, out-of-root resolution, overlap with ambiguous ownership, or any target denied after canonicalization. |
|
|
53
|
+
| Per-run execution limits | Finite positive elapsed-time and output-byte limits for every command and adapter run | Reject missing, zero, negative, non-finite, unsafe, or unbounded resources; do not assign compatibility defaults. |
|
|
54
|
+
| Search and campaign ceilings | Finite maximum candidates, iterations, total wall time, reported token budget, reported cost budget with currency, consecutive invalid candidates, and consecutive non-improving candidates | Reject every omitted or non-finite ceiling, incompatible cost units, or a bound that cannot be accounted from retained evidence. Exhaustion is terminal. |
|
|
55
|
+
| Safety policy | Explicit network, write, command, privacy, and hard-regression rules, including non-compensable gates | Reject omissions, ambiguous verbs, undeclared egress, ambient command authority, or a policy that lets metric gain compensate for a hard failure. |
|
|
56
|
+
| Capability baseline and candidate | All eight canonical IDs in canonical order, each with complete before/after enabled state and matching before/after configuration digests | Reject missing, extra, reordered, or duplicate IDs; partial deltas; unavailable status; or any state/digest mismatch. A Phase 18 digest is provenance, not approval. |
|
|
57
|
+
| Task-set separation | Separate committed exploration and held-out confirmation task-set references, each with immutable source revision and task-set digest | Reject reuse, overlap, mutable references, unresolved revisions, digest mismatch, or any path by which held-out results become generator feedback. |
|
|
58
|
+
| Evaluation identity and schedule | Operator-owned adapter/config IDs, exact adapter-config digest, repetitions, deterministic seeds and order, verifier identity, isolated workspace policy, and execution limits | Reject resolved secret or endpoint values, implicit ordering, incomplete schedules, mutable verifier inputs, or an adapter/config identity that changes after approval. |
|
|
59
|
+
| Selection policy | Primary metric, direction, minimum improvement rule, regression guards, minimum eligible pairs, interval/confidence rule, repeated-comparison policy, and sufficient evidence scope | Reject missing denominators, undefined direction, unusable interval rules, absent regression gates, or any policy able to reinterpret missing evidence as success. |
|
|
60
|
+
| Mutable surfaces | Exact allowed harness-owned prompt files and typed capability fields, with pre-image identities and digests | Reject a target outside repository/path policy, a non-harness-owned prompt file, free-form configuration, or a target not present in the approved candidate artifact. |
|
|
61
|
+
| Human authority | Explicit human approval policy for form confirmation, evaluation, apply, rollback, rejection, and cancellation | Reject combined or delegated gates, automatic application, ambiguous approvers, or a form that removes unconditional cancellation and rollback authority. |
|
|
62
|
+
|
|
63
|
+
The exact Phase 18 capability IDs, in canonical order, are:
|
|
64
|
+
|
|
65
|
+
1. `memory.write`
|
|
66
|
+
2. `memory.search`
|
|
67
|
+
3. `notes.distill`
|
|
68
|
+
4. `wiki`
|
|
69
|
+
5. `graph`
|
|
70
|
+
6. `security.audit`
|
|
71
|
+
7. `route.check`
|
|
72
|
+
8. `context.explore`
|
|
73
|
+
|
|
74
|
+
The current `resolveCapabilityStatus()` result supplies an effective ordered
|
|
75
|
+
snapshot and `configuration_digest`. Neither the status nor its digest is a
|
|
76
|
+
meta-agent candidate, signature, approval, or authorization.
|
|
77
|
+
|
|
78
|
+
### Admission is fail closed
|
|
79
|
+
|
|
80
|
+
The future validator MUST reject every safety-critical omission, unknown field,
|
|
81
|
+
unsupported version, unresolved revision, non-finite resource, path traversal,
|
|
82
|
+
symlink escape, and out-of-root path. It MUST also reject stale or mismatched
|
|
83
|
+
digests and any value that would require an inferred default. Invalid input
|
|
84
|
+
cannot be made valid by prose interpretation, candidate output, prior runs, or
|
|
85
|
+
operator environment discovery.
|
|
86
|
+
|
|
87
|
+
Forms, proposals, and reports may carry only bounded, value-free identifiers
|
|
88
|
+
for operator-owned secret or adapter configuration. They MUST NOT contain
|
|
89
|
+
credentials, resolved secrets, endpoint values, provider defaults, complete
|
|
90
|
+
environment snapshots, or captured environment values. A reference says which
|
|
91
|
+
operator-owned configuration is expected; it never resolves or copies it.
|
|
92
|
+
|
|
93
|
+
### Illustrative only — fictional strict form
|
|
94
|
+
|
|
95
|
+
The following is secret-free and non-normative. It is not a shipped schema and
|
|
96
|
+
is not accepted CLI input. Angle-bracketed values are fictional review labels,
|
|
97
|
+
not normative numeric defaults or accepted syntax.
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
specification: sample-improvement-study
|
|
101
|
+
schema: future-version
|
|
102
|
+
repositories:
|
|
103
|
+
- root_ref: repo-alpha
|
|
104
|
+
immutable_revision: revision-alpha
|
|
105
|
+
scope:
|
|
106
|
+
allowed_paths: [harness-owned/prompts]
|
|
107
|
+
denied_paths: [operator-settings]
|
|
108
|
+
limits:
|
|
109
|
+
maximum candidates: <operator-declared finite count>
|
|
110
|
+
iterations: <operator-declared finite count>
|
|
111
|
+
total_wall_time: <operator-declared finite duration>
|
|
112
|
+
reported_token_budget: <operator-declared finite amount>
|
|
113
|
+
evaluation:
|
|
114
|
+
exploration_task_set: committed-set-alpha
|
|
115
|
+
held_out_task_set: committed-set-beta
|
|
116
|
+
adapter_config_ref: operator-config-alpha
|
|
117
|
+
capabilities:
|
|
118
|
+
before_and_after: [memory.write, memory.search, notes.distill, wiki,
|
|
119
|
+
graph, security.audit, route.check, context.explore]
|
|
120
|
+
human approval policy:
|
|
121
|
+
form: separate
|
|
122
|
+
evaluation: separate
|
|
123
|
+
apply: separate
|
|
124
|
+
rollback: always available
|
|
125
|
+
cancellation: always available
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Bounded candidate artifact
|
|
129
|
+
|
|
130
|
+
A future candidate generator may emit only an immutable, canonically digested
|
|
131
|
+
artifact within the confirmed form's mutable surfaces. It may include bounded
|
|
132
|
+
prompt diffs and a complete typed capability before/after snapshot. It cannot
|
|
133
|
+
execute inference, commands, evaluation, or writes; grant itself new scope;
|
|
134
|
+
change any task, verifier, metric, threshold, resource bound, safety rule,
|
|
135
|
+
approval rule, stopping policy, or evidence history; or consult held-out
|
|
136
|
+
confirmation results. Generation and execution are separate authorities.
|
|
137
|
+
|
|
138
|
+
## Ownership and authority
|
|
139
|
+
|
|
140
|
+
The operator retains every irreversible or cost-bearing authority. Cairnkeep's
|
|
141
|
+
future components may transform and validate bounded artifacts, but every
|
|
142
|
+
inference execution MUST cross the accepted Phase 19 coordinator into an
|
|
143
|
+
operator-configured external adapter. Candidate generation, comparison,
|
|
144
|
+
approval, application, confirmation policy, and rollback have no direct
|
|
145
|
+
inference edge.
|
|
146
|
+
|
|
147
|
+
```text
|
|
148
|
+
untrusted objective
|
|
149
|
+
-> future form compiler/validator -> human form confirmation
|
|
150
|
+
-> future bounded candidate artifact -> human evaluation approval
|
|
151
|
+
-> Phase 19 immutable schedule
|
|
152
|
+
-> operator-configured external adapter -> inference execution
|
|
153
|
+
-> independent verifier -> canonical Phase 19 report
|
|
154
|
+
-> future comparison -> reviewable patch proposal -> human apply approval
|
|
155
|
+
-> future backup/digest/atomic applier -> held-out confirmation approval
|
|
156
|
+
-> Phase 19 immutable held-out schedule
|
|
157
|
+
-> operator-configured external adapter -> inference execution
|
|
158
|
+
-> independent verifier -> canonical Phase 19 report
|
|
159
|
+
-> accept | inconclusive | no_eligible_candidate | rollback
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
There is no arrow from a Cairnkeep generator, selector, applier, or rollback
|
|
163
|
+
operation to inference. Phase 19 is the sole Cairnkeep execution and measurement
|
|
164
|
+
seam; the operator-configured external adapter remains the sole inference owner.
|
|
165
|
+
|
|
166
|
+
| Actor or component | May do | Must not do | Required authority |
|
|
167
|
+
|---|---|---|---|
|
|
168
|
+
| Operator | Confirm/reject form, approve/cancel evaluation, approve/reject application, accept confirmation, request rollback | Delegate mandatory gates to candidate output or ambient configuration | Separate, explicit decision at each gate |
|
|
169
|
+
| Future compiler/validator | Convert untrusted prose to a strict form; reject invalid fields | Execute prose, infer defaults, resolve secrets, or broaden scope | Form confirmation before admission |
|
|
170
|
+
| Future candidate generator | Produce bounded immutable artifacts within declared mutable surfaces | Execute inference/commands, mutate control policy, inspect held-out results, or write repositories | Confirmed form and remaining resource budget |
|
|
171
|
+
| Phase 18 capability contract | Resolve current ordered state and configuration digest | Select candidates, authorize changes, or represent arbitrary candidate overlays | Existing operator configuration |
|
|
172
|
+
| Phase 19 coordinator | Validate committed inputs, create isolated serial schedules, call the configured adapter, verify tasks, and persist canonical evidence | Own inference, generate candidates, choose a winner, apply a patch, or grant approval | Separate evaluation or confirmation approval |
|
|
173
|
+
| Operator-configured external adapter | Execute all inference under the approved bounded request and its operator-owned environment | Change tasks, verifier, policy, schedule, or repository state through this design | Operator configuration plus Phase 19 request |
|
|
174
|
+
| Future comparator | Apply the predeclared policy to canonical reports | Reclassify infrastructure errors, hide missingness, or relax thresholds after seeing results | Immutable form and validated reports |
|
|
175
|
+
| Future applier/rollback owner | Apply or exactly restore one approved proposal under digest guards | Infer intent, overwrite later edits, delete unrelated content, or invoke inference | Separate apply or rollback approval |
|
|
176
|
+
|
|
177
|
+
## Candidate evaluation through Phase 19
|
|
178
|
+
|
|
179
|
+
Candidate generation first produces an immutable candidate artifact and stops.
|
|
180
|
+
Deterministic validation and explicit evaluation approval are required before
|
|
181
|
+
Phase 19. The approved evaluation freezes committed task sets, exact source
|
|
182
|
+
revision, independent verifier, finite limits, repetitions, seeds and order,
|
|
183
|
+
adapter/config identity, and fresh isolated workspaces. The adapter alone runs
|
|
184
|
+
inference. Comparison reads canonical JSON; it never parses arbitrary adapter
|
|
185
|
+
diagnostics or model output.
|
|
186
|
+
|
|
187
|
+
### Current Phase 19 behavior versus missing future contract
|
|
188
|
+
|
|
189
|
+
| Concern | Current accepted Phase 18/19 behavior | Missing future contract; not shipped by Phase 20 |
|
|
190
|
+
|---|---|---|
|
|
191
|
+
| Capability identity | `expected_capability_digest` and `observed_capability_digest` bind the complete Phase 18 effective state. | Candidate-overlay identity and expected/observed candidate digests for arbitrary prompt/config candidates. |
|
|
192
|
+
| Adapter identity | `adapter_config_digest` binds the operator adapter configuration. | It is not a generated-candidate digest and grants no selection or apply authority. |
|
|
193
|
+
| Request surface | Phase 19 sends experiment/task identity, arm, repetition, pass, isolated paths, fixed input, limits, seed, expected capability digest, and output path. | Phase 19 has no arbitrary candidate overlay reference, injection contract, or expected candidate digest. |
|
|
194
|
+
| Result surface | Strict results may report bounded metrics, identities, references, and `observed_capability_digest`. | There is no observed candidate-overlay digest, and no candidate pass/approval field. |
|
|
195
|
+
| Ablation | `runCapabilityAblation()` compares an all-enabled baseline with exactly one disabled capability and requires four invocations per task/repetition: two passes in each of two arms. | It is not generic prompt search, arbitrary configuration injection, or a multi-capability candidate arm. |
|
|
196
|
+
| Scheduling | Deterministic, serial, immutable, paired schedules and fresh isolated workspaces are current. | Adaptive generation/selection and separate exploration/held-out campaign control are absent. |
|
|
197
|
+
| Report | Canonical reports preserve observations, aggregates, condition levels, eligible pairs, missingness, warnings, intervals, evidence scope, and provenance. | Reports do not choose winners, authorize application, or provide a proposal/rollback ledger. |
|
|
198
|
+
|
|
199
|
+
Exploration and held-out confirmation task sets MUST be separate, committed,
|
|
200
|
+
immutable, non-overlapping, and digest-bound. Exploration results may inform the
|
|
201
|
+
next bounded candidate within remaining limits. Held-out results MUST never
|
|
202
|
+
become generator feedback, even after rejection or rollback. A changed task,
|
|
203
|
+
verifier, metric, threshold, seed policy, bound, safety policy, or confirmation
|
|
204
|
+
set requires a new form and new approvals; it cannot be a candidate mutation.
|
|
205
|
+
|
|
206
|
+
The future comparator consumes Phase 19's exact terminal states: `completed`,
|
|
207
|
+
`verifier_failed`, `timeout`, `cancelled`, `adapter_error`, and
|
|
208
|
+
`invalid_result`; and pass states: `passed`, `failed`, and `unknown`. It also
|
|
209
|
+
consumes expected/observed capability digests, condition levels, eligible-pair
|
|
210
|
+
counts, missingness, warnings, intervals, and evidence scope. Infrastructure
|
|
211
|
+
states and unknown verification remain missing or ineligible evidence, never
|
|
212
|
+
candidate failures or passes. `offline-framework` evidence authorizes framework
|
|
213
|
+
mechanics only and cannot support product quality, efficiency, cost, latency,
|
|
214
|
+
significance, or causal claims.
|
|
215
|
+
|
|
216
|
+
## Proposal bundle, application, and rollback
|
|
217
|
+
|
|
218
|
+
A future proposal bundle is one canonically identified, reviewable unit. Any
|
|
219
|
+
failed element invalidates the whole proposal; partial acceptance or partial
|
|
220
|
+
application is forbidden.
|
|
221
|
+
|
|
222
|
+
| Required proposal bundle element | Content | Whole-proposal invalidation |
|
|
223
|
+
|---|---|---|
|
|
224
|
+
| Canonical identity | Proposal version/ID/digest; confirmed form digest; immutable source revision; baseline and candidate artifact digests | Unknown version, non-canonical bytes, duplicate ID, unresolved revision, or any digest mismatch |
|
|
225
|
+
| Evidence-bound rationale | Primary metric rule, regression guards, eligible-pair counts, interval result, evidence scope, warnings, missingness, and bounded references to exact Phase 19 reports/digests | Unsupported claim, copied arbitrary diagnostics, missing report, stale digest, inadequate scope, or rationale exceeding evidence |
|
|
226
|
+
| Prompt change | A unified diff limited to operator-declared harness-owned prompt files, with contained canonical paths, modes, and pre/post digests | Non-declared target, symlink/out-of-root path, denied path, binary ambiguity, missing pre-image, or diff/digest mismatch |
|
|
227
|
+
| Typed capability change | All eight before/after rows in canonical order and their Phase 18 before/after configuration digests | Partial delta, unknown/reordered ID, unavailable status, or state/digest mismatch |
|
|
228
|
+
| Safety findings | Results for every non-compensable network, write, command, privacy, and hard-regression gate | Missing, unknown, failed, or waived hard gate |
|
|
229
|
+
| Apply preconditions | Exact revision, root/path identities, pre-image bytes/digests/modes, proposal digest, and separate apply-approval record | Stale, missing, mismatched, out-of-scope, or subsequently changed precondition |
|
|
230
|
+
| Rollback instructions | Backup references, original bytes/modes/digests, applied post-image digests, created-file ownership, and manual-resolution conditions | Incomplete backup, ambiguous ownership, unguarded removal, or restoration not exact |
|
|
231
|
+
|
|
232
|
+
### Illustrative only — fictional proposal bundle
|
|
233
|
+
|
|
234
|
+
This fictional, secret-free, non-normative example is not a shipped schema and
|
|
235
|
+
is not accepted CLI input. It contains no credential, endpoint, provider
|
|
236
|
+
default, environment snapshot, or private identifier.
|
|
237
|
+
|
|
238
|
+
```text
|
|
239
|
+
proposal: sample-proposal-alpha
|
|
240
|
+
form_digest: digest-form-alpha
|
|
241
|
+
source_revision: revision-alpha
|
|
242
|
+
candidate_digest: digest-candidate-alpha
|
|
243
|
+
evidence:
|
|
244
|
+
exploration_report_ref: report-alpha
|
|
245
|
+
report_digest: digest-report-alpha
|
|
246
|
+
prompt_change:
|
|
247
|
+
target: harness-owned/prompts/review.md
|
|
248
|
+
unified_diff_ref: reviewed-diff-alpha
|
|
249
|
+
pre_image_digest: digest-before-alpha
|
|
250
|
+
post_image_digest: digest-after-alpha
|
|
251
|
+
capability_delta:
|
|
252
|
+
snapshot: complete-eight-row-before-and-after
|
|
253
|
+
before_digest: digest-capabilities-before
|
|
254
|
+
after_digest: digest-capabilities-after
|
|
255
|
+
application: separate-human-approval-required
|
|
256
|
+
rollback: exact-backup-and-post-image-guard-required
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Application is default-off and needs approval distinct from form confirmation
|
|
260
|
+
and evaluation approval. Immediately before any write, a future applier MUST
|
|
261
|
+
revalidate the exact revision, real contained roots, canonical allow/deny
|
|
262
|
+
policy, path ownership, symlink status, pre-image bytes/modes/digests, proposal
|
|
263
|
+
digest, and complete capability snapshots. It MUST finish exact backups of
|
|
264
|
+
every pre-image before the first write, then apply the whole proposal atomically
|
|
265
|
+
or leave the repository unchanged. A local audit record contains only bounded,
|
|
266
|
+
value-free identities, paths, modes, digests, outcomes, and backup references.
|
|
267
|
+
|
|
268
|
+
Any stale, missing, mismatched, unsafe, or out-of-scope precondition invalidates
|
|
269
|
+
the entire proposal. No automatic rebase, fuzzy patch, best-effort subset, or
|
|
270
|
+
model-authored repair is allowed.
|
|
271
|
+
|
|
272
|
+
Rollback also requires explicit operator authority. Restoration may proceed
|
|
273
|
+
only when each current file still matches the applied post-image digest. A
|
|
274
|
+
proposal-created file may be removed only when it is proposal-owned and remains
|
|
275
|
+
byte-for-byte unchanged. Missing or later-edited files require manual
|
|
276
|
+
resolution. Rollback MUST NOT delete or overwrite unrelated content,
|
|
277
|
+
subsequently edited user files, user settings, retained evidence, or another
|
|
278
|
+
proposal's assets. Backup-first exact-revert and atomic write behavior in the
|
|
279
|
+
current project lifecycle are precedents, not a generic applier delivered here.
|
|
280
|
+
|
|
281
|
+
## Bounded state machine and stopping policy
|
|
282
|
+
|
|
283
|
+
The future controller is a finite state machine. Every transition preserves the
|
|
284
|
+
confirmed form, immutable evidence history, and resource accounting. A
|
|
285
|
+
candidate cannot modify tasks, verifier, metrics, thresholds, bounds,
|
|
286
|
+
safety/approval/stopping policy, evidence scope rules, or prior evidence.
|
|
287
|
+
|
|
288
|
+
| State | Entry condition | Exit and outcome | Required evidence | Immutable while active |
|
|
289
|
+
|---|---|---|---|---|
|
|
290
|
+
| `specification` | Untrusted objective received | Reject/cancel, or submit strict form to `validation` | Objective reference only | No authority or inferred defaults |
|
|
291
|
+
| `validation` | Complete candidate form produced | Invalid → `rejection`; valid → human `approval`; cancel → `cancelled` | Canonical form, source/path/resource checks | Complete form and validation record |
|
|
292
|
+
| `candidate_proposal` | Confirmed form and remaining bounds | Invalid/non-improving ceiling → `exhausted`; valid artifact → `approval` | Candidate digest, scope checks, accounting | Control plane and evidence history |
|
|
293
|
+
| `approval` | A form, evaluation, patch, confirmation, or rollback action awaits a distinct decision | Approve to named next state; reject → `rejected`; cancel → `cancelled` | Exact object digest and authority type | Approval cannot cover another gate |
|
|
294
|
+
| `evaluation` | Explicit evaluation approval and validated Phase 19 plan | Complete → `comparison`; hard failure → `inconclusive` or `rejection`; cancel → `cancelled` | Canonical partial/final Phase 19 report | Schedule, task sets, source, adapter, verifier, seeds, limits |
|
|
295
|
+
| `comparison` | Canonical exploration report validated | Eligible → `patch_proposal`; insufficient evidence → `inconclusive` or `no_eligible_candidate`; budget remains → `candidate_proposal` | Terminal/pass states, digests, levels, pairs, missingness, warnings, intervals, scope | Selection and repeated-comparison policy |
|
|
296
|
+
| `patch_proposal` | Candidate passes exploration policy | Whole bundle valid → apply `approval`; invalid → `rejection` | Proposal identity, evidence, diff/delta, safety, preconditions, rollback | Proposal bytes and referenced evidence |
|
|
297
|
+
| `application` | Separate apply approval and immediate preflight passes | Atomic success → `confirmation`; preflight fail → `rejected`; ambiguous result → `manual_resolution` | Backups, pre/post digests, audit record | Approved proposal and backups |
|
|
298
|
+
| `confirmation` | Applied candidate and separately approved held-out schedule | Policy passes → `accepted`; inadequate evidence → `inconclusive`; regression/hard failure → `rollback` | One canonical held-out report, never generator feedback | Confirmation set and acceptance rules |
|
|
299
|
+
| `rollback` | Operator requests rollback or policy requires it | Exact restore → `rolled_back`; later edits/ambiguity → `manual_resolution`; cancel preserves state | Applied post-image checks and exact backups | No-clobber boundary and retained evidence |
|
|
300
|
+
| `rejection` | Invalid form/candidate/proposal, hard-gate failure, or explicit rejection | Terminal `rejected` | Value-free reason and retained evidence | All prior evidence |
|
|
301
|
+
| terminal | `accepted`, `inconclusive`, `no_eligible_candidate`, `rejected`, `cancelled`, `exhausted`, `rolled_back`, or `manual_resolution` reached | No automatic exit or restart | Final reason, resource totals, evidence/proposal references | Entire history |
|
|
302
|
+
|
|
303
|
+
### Stopping policy and selection conditions
|
|
304
|
+
|
|
305
|
+
| Condition | Required action/outcome |
|
|
306
|
+
|---|---|
|
|
307
|
+
| All hard gates pass; no regression guard fails; candidate/capability digests match; minimum eligible pairs are met; a usable interval satisfies the predeclared metric/direction/improvement rule; evidence scope is sufficient | Candidate may proceed from exploration to patch proposal; it is not yet accepted. |
|
|
308
|
+
| Exactly one separately approved held-out confirmation passes the same hard gates and predeclared acceptance policy | Stop as `accepted`. Further search requires a new form. |
|
|
309
|
+
| No candidate has adequate eligible pairs or compatible observations | Stop as `no_eligible_candidate`; never choose from absence. |
|
|
310
|
+
| Evidence exists but interval, missingness, warnings, scope, or improvement rule cannot establish eligibility | Stop as `inconclusive`; never relax policy post hoc. |
|
|
311
|
+
| Any non-compensable hard gate or safety/privacy regression fails | Stop evaluation/application; `rejected` or approved `rollback`. Metric gain cannot compensate. |
|
|
312
|
+
| Maximum candidates, iterations, total wall time, reported token budget, or reported cost budget is reached | Stop as `exhausted` before next admission. Missing token/cost reporting is not zero. |
|
|
313
|
+
| Consecutive invalid or non-improving candidate bound is reached | Stop as `exhausted`. |
|
|
314
|
+
| Human rejects form, evaluation, proposal, application, confirmation, or rollback | Stop as `rejected`, preserving evidence and current repository state. |
|
|
315
|
+
| Cancellation requested at any state | Stop admission, bound active Phase 19 cleanup, preserve partial evidence, and terminate as `cancelled`. |
|
|
316
|
+
| Rollback cannot safely restore because post-images changed or ownership is ambiguous | Stop as `manual_resolution`; do not overwrite or delete. |
|
|
317
|
+
|
|
318
|
+
Only an accepted held-out confirmation produces `accepted`. Exploration alone
|
|
319
|
+
cannot do so. Selection remains at least as conservative as Phase 19's report
|
|
320
|
+
semantics: missing intervals, small samples, intervals crossing the declared
|
|
321
|
+
no-effect boundary, incompatible semantics, unknown verifier outcomes, and
|
|
322
|
+
infrastructure failures cannot name a winner.
|
|
323
|
+
|
|
324
|
+
## Privacy and security invariants
|
|
325
|
+
|
|
326
|
+
These are requirements for any separately approved future implementation; Phase
|
|
327
|
+
20 does not implement the controls. Hard privacy and safety failures are
|
|
328
|
+
terminal and non-compensable. Artifacts remain local, bounded, value-minimized,
|
|
329
|
+
and bound to immutable source and evidence. No proposal or report may persist
|
|
330
|
+
prompts beyond the reviewed unified diff, model output, arbitrary diagnostics,
|
|
331
|
+
resolved credentials, endpoint values, or complete environment state.
|
|
332
|
+
|
|
333
|
+
| Threat pattern | Required future control | Failure disposition |
|
|
334
|
+
|---|---|---|
|
|
335
|
+
| Untrusted specification escalates policy or authority | Strict allow-listed versioned form, unknown-field rejection, no inferred defaults, separate human gates | Reject form before generation or execution |
|
|
336
|
+
| Path, symlink, or secret escape | Canonical real-root containment, deny precedence, no-follow checks, immediate preflight, value-free secret/config references | Reject whole form/proposal; write nothing |
|
|
337
|
+
| Adapter or candidate digest spoofing | Independently reconstruct exact form, candidate, adapter, Phase 18 state, and future overlay digests at each boundary | Observation/proposal is invalid, not a task failure |
|
|
338
|
+
| Confirmation-set overfitting | Separate committed exploration and held-out task sets; no overlap; held-out results never return to generator | Reject campaign or stop confirmation |
|
|
339
|
+
| Safety regression masked by metric gain | Non-compensable network/write/command/privacy and regression guards before metric selection | Reject or roll back regardless of metric |
|
|
340
|
+
| Resource exhaustion | Finite per-run, candidate, iteration, wall-time, reported-token/cost, invalid, and non-improvement ceilings with pre-admission accounting | Cancel active bounded work and stop as `exhausted` or `cancelled` |
|
|
341
|
+
| Apply/rollback time-of-check/time-of-use race or partial write | Immediate revision/path/pre-image revalidation, exact backups first, atomic all-or-nothing apply, post-image-guarded rollback | Leave unchanged, roll back exactly, or require `manual_resolution` |
|
|
342
|
+
| Proposal, report, or audit leakage | Strict bounded fields, local permissions, value-free diagnostics/IDs, reviewed diff only, report references instead of copied runtime content | Reject sensitive artifact and retain no partial copy |
|
|
343
|
+
| Infrastructure error fabricated as task outcome | Preserve Phase 19 terminal/pass separation, explicit missingness and partial reports, unknown verifier outcomes | `inconclusive` or ineligible; never fabricate pass/fail/winner |
|
|
344
|
+
|
|
345
|
+
## Prerequisites not delivered by Phases 14–19
|
|
346
|
+
|
|
347
|
+
Phases 14–19 already deliver structured local trajectories; asynchronous notes
|
|
348
|
+
and hindsight retrieval; typed memory nodes; compaction/artifact storage; the
|
|
349
|
+
eight capability IDs, toggles, digests, and value-free logs; committed strict
|
|
350
|
+
evaluation schemas; isolation and independent verification; two-pass and
|
|
351
|
+
one-off ablation execution; canonical reports, missingness, intervals,
|
|
352
|
+
cancellation; and `offline-framework` evidence. Those accepted substrates are
|
|
353
|
+
not backlog rows.
|
|
354
|
+
|
|
355
|
+
### Future implementation backlog — not delivered by Phase 20
|
|
356
|
+
|
|
357
|
+
Each row is future work requiring separate approval. The list is exactly nine
|
|
358
|
+
items; Phase 20 delivers none of them.
|
|
359
|
+
|
|
360
|
+
| # | Exact absent capability | Accepted substrate it may reuse | Delivery status |
|
|
361
|
+
|---|---|---|---|
|
|
362
|
+
| 1 | Natural-language-to-form compiler and validator | Strict versioning, canonical digests, and path validation patterns | Future work requiring separate approval; not delivered by Phase 20 |
|
|
363
|
+
| 2 | Bounded candidate generator | Phase 18 typed capability identities and retained evidence | Future work requiring separate approval; not delivered by Phase 20 |
|
|
364
|
+
| 3 | Candidate-config injection contract for external adapters | Phase 19 adapter seam and Phase 18 capability digests; Phase 19 currently has no arbitrary overlay identity or observed candidate digest and supports only exactly-one-capability-off ablation | Future work requiring separate approval; not delivered by Phase 20 |
|
|
365
|
+
| 4 | Scoped proposal/artifact schema | Existing strict versioned local artifacts and canonical reports | Future work requiring separate approval; not delivered by Phase 20 |
|
|
366
|
+
| 5 | Backup-first patch applier and rollback ledger | Existing backup-first uninstall/revert and atomic single-file write precedents | Future work requiring separate approval; not delivered by Phase 20 |
|
|
367
|
+
| 6 | Exploration and held-out committed task sets | Current committed task-set schema, exact revisions, and verifier | Future work requiring separate approval; not delivered by Phase 20 |
|
|
368
|
+
| 7 | Selection policy accounting for uncertainty and repeated comparisons | Phase 19 condition levels, paired estimates, missingness, warnings, and intervals | Future work requiring separate approval; not delivered by Phase 20 |
|
|
369
|
+
| 8 | Sufficient live baseline evidence | Validator-checked evidence scope and exact-source runtime provenance; existing offline evidence is framework-only | Future work requiring separate approval; not delivered by Phase 20 |
|
|
370
|
+
| 9 | Dedicated privacy/security threat review | Current local privacy, bounded storage, secret exclusion, and public hygiene guards | Future work requiring separate approval; not delivered by Phase 20 |
|
|
371
|
+
|
|
372
|
+
## Explicit exclusions
|
|
373
|
+
|
|
374
|
+
- No Cairnkeep orchestrator or unified orchestrator is designed or delivered.
|
|
375
|
+
- Cairnkeep does not own an inference loop; every inference execution remains
|
|
376
|
+
with an operator-configured external adapter reached through Phase 19.
|
|
377
|
+
- Architect-style in-loop compression is outside this design and Phase 20.
|
|
378
|
+
- Trace UI is outside this design and Phase 20.
|
|
379
|
+
- Eval UI is outside this design and Phase 20.
|
|
380
|
+
- Phase 20 implements no compiler, generator, selection controller, proposal
|
|
381
|
+
schema, patch applier, rollback ledger, candidate adapter-protocol change,
|
|
382
|
+
configuration schema, CLI surface, runtime default, or modification of Phase
|
|
383
|
+
18 or Phase 19 contracts.
|
|
384
|
+
- Phase 20 adds no symbol, command, flag, package, dependency, test source,
|
|
385
|
+
executable interface, release, publication, or automatic product claim.
|
|
386
|
+
|
|
387
|
+
All excluded implementation work requires a new plan, threat review, approval,
|
|
388
|
+
tests, and evidence. Naming a future contract here does not reserve a public
|
|
389
|
+
interface or represent it as delivered.
|
|
390
|
+
|
|
391
|
+
## Decision traceability
|
|
392
|
+
|
|
393
|
+
| ID | Document home | Normative trace |
|
|
394
|
+
|---|---|---|
|
|
395
|
+
| META-01 | Natural-language specification → strict form | Untrusted prose can become only a complete, versioned, fail-closed future form. |
|
|
396
|
+
| META-02 | Ownership; evaluation; proposal; state machine | Candidates are bounded, measured only through Phase 19/adapters, and separately approved for application. |
|
|
397
|
+
| META-03 | Prerequisites; explicit exclusions | Exactly nine prerequisites remain future work and prohibited ownership/UI/implementation is explicit. |
|
|
398
|
+
| D-01 | Natural-language specification → strict form | Natural language is untrusted proposal data, never executable control. |
|
|
399
|
+
| D-02 | Required configuration fields | Scope, revisions, paths, resources, safety, capabilities, tasks, evaluation, selection, mutation, and authority are required. |
|
|
400
|
+
| D-03 | Admission is fail closed | Omissions, unknowns, unsafe paths, unresolved revisions, non-finite resources, and inferred defaults invalidate. |
|
|
401
|
+
| D-04 | Admission; privacy invariants | Only value-free operator-owned references are allowed; secret/endpoint/environment values are forbidden. |
|
|
402
|
+
| D-05 | Status and normative language | The artifact is design-only; examples are non-normative; no schema or CLI ships. |
|
|
403
|
+
| D-06 | Ownership and authority | Phase 19 is the sole execution/measurement seam and the external adapter owns inference. |
|
|
404
|
+
| D-07 | Candidate evaluation | Source, tasks, verifier, adapter identity, schedule, limits, seeds, and digests are frozen and comparable. |
|
|
405
|
+
| D-08 | Candidate evaluation | Canonical terminal/pass states, condition levels, missingness, uncertainty, and evidence scope remain authoritative. |
|
|
406
|
+
| D-09 | Bounded candidate artifact; ownership | Candidate generation and adapter execution are separate authorities. |
|
|
407
|
+
| D-10 | Candidate evaluation | Exploration and held-out sets are separate; held-out results never become generator feedback. |
|
|
408
|
+
| D-11 | Candidate evaluation | `offline-framework` authorizes framework claims only. |
|
|
409
|
+
| D-12 | Proposal bundle | Canonical identity, rationale, reports, diffs/deltas, safety, preconditions, and rollback form one review unit. |
|
|
410
|
+
| D-13 | Proposal bundle | Unified prompt diffs are limited to operator-declared harness-owned files. |
|
|
411
|
+
| D-14 | Application and rollback | Apply is separately approved, immediately revalidated, backup-first, atomic, and locally audited. |
|
|
412
|
+
| D-15 | Proposal invalidation | Any stale, missing, mismatched, unsafe, or out-of-scope element invalidates the whole proposal. |
|
|
413
|
+
| D-16 | Application and rollback | Reject/apply/rollback are explicit and restoration cannot clobber unrelated or later-edited content. |
|
|
414
|
+
| D-17 | Bounded state machine | Every required state has entry, evidence, immutable fields, and an explicit exit/outcome. |
|
|
415
|
+
| D-18 | Selection and stopping | Hard gates are non-compensable and all resource/search ceilings are finite. |
|
|
416
|
+
| D-19 | Selection and stopping | Acceptance needs matching digests, no regression, adequate pairs, usable interval, sufficient scope, and held-out confirmation. |
|
|
417
|
+
| D-20 | Selection and stopping | Exhaustion, invalid/non-improving bounds, rejection, cancellation, hard failure, and confirmation all stop explicitly. |
|
|
418
|
+
| D-21 | Future backlog | Exactly nine missing prerequisites are enumerated once and separated from accepted Phase 14–19 substrate. |
|
|
419
|
+
| D-22 | Explicit exclusions | The backlog is not implementation and all ownership, compression, UI, runtime, schema, CLI, and adapter work remains excluded. |
|
|
420
|
+
|
|
421
|
+
## References
|
|
422
|
+
|
|
423
|
+
- [Phase 18 capability schema](../../mcp-memory-server/src/capability-schema.ts)
|
|
424
|
+
and [configuration resolver](../../mcp-memory-server/src/capability-config.ts)
|
|
425
|
+
are the current capability contract of record.
|
|
426
|
+
- [Phase 19 evaluation schema](../../mcp-memory-server/src/eval-schema.ts),
|
|
427
|
+
[plan validator](../../mcp-memory-server/src/eval-plan.ts),
|
|
428
|
+
[runner](../../mcp-memory-server/src/eval-runner.ts), and
|
|
429
|
+
[report owner](../../mcp-memory-server/src/eval-report.ts) are the current
|
|
430
|
+
evaluation contract of record.
|
|
431
|
+
- Published current contracts are the
|
|
432
|
+
[task-set schema](../../schemas/eval-task-set.schema.json),
|
|
433
|
+
[adapter schema](../../schemas/eval-adapter.schema.json), and
|
|
434
|
+
[report schema](../../schemas/eval-report.schema.json).
|
|
435
|
+
- [Operating](../operating.md), [privacy and data flow](../privacy-and-data-flow.md),
|
|
436
|
+
and [storage](../storage.md) define the current operator, privacy, and local
|
|
437
|
+
lifecycle boundaries.
|
|
438
|
+
- The paper's §2.3.4 and §2.4 are design inspiration only. Repository source,
|
|
439
|
+
accepted Phase 18/19 behavior, and published schemas remain authoritative.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
**Status:** Ready
|
|
4
4
|
**Track:** Quickstart
|
|
5
5
|
**Time:** 15 minutes
|
|
6
|
-
**Tested with:** Cairnkeep 2.
|
|
6
|
+
**Tested with:** Cairnkeep 2.4.0
|
|
7
7
|
|
|
8
8
|
## Outcome
|
|
9
9
|
|
|
@@ -26,7 +26,7 @@ ephemeral; the named course volume is persistent.
|
|
|
26
26
|
1. Pull the public image:
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
podman pull ghcr.io/cairnkeep/cairnkeep:2.
|
|
29
|
+
podman pull ghcr.io/cairnkeep/cairnkeep:2.4.0
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
2. Start the stdio server with a read-only root filesystem and no Linux
|
|
@@ -38,7 +38,7 @@ ephemeral; the named course volume is persistent.
|
|
|
38
38
|
--read-only --cap-drop=all --security-opt=no-new-privileges \
|
|
39
39
|
--tmpfs=/tmp:rw,noexec,nosuid,size=64m,mode=1777 \
|
|
40
40
|
--volume cairnkeep-course-data:/data:Z,U \
|
|
41
|
-
ghcr.io/cairnkeep/cairnkeep:2.
|
|
41
|
+
ghcr.io/cairnkeep/cairnkeep:2.4.0 stdio
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
3. The process waits quietly for MCP input. Press `Ctrl-C` after confirming it
|