knodin 0.8.3 → 0.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +7 -1
  2. package/dist/bin/cli.js +489 -78
  3. package/dist/src/agent-events.js +128 -0
  4. package/dist/src/agent-hooks.js +156 -0
  5. package/dist/src/cli-model.js +42 -1
  6. package/dist/src/engine/candidate-database.js +167 -0
  7. package/dist/src/engine/embeddings.js +8 -5
  8. package/dist/src/engine/index.js +930 -262
  9. package/dist/src/engine/prune.js +8 -0
  10. package/dist/src/file-metrics.js +153 -0
  11. package/dist/src/output-telemetry.js +8 -3
  12. package/dist/src/repair-lease.js +8 -5
  13. package/dist/src/response-budget.js +2 -1
  14. package/dist/src/session-telemetry.js +163 -0
  15. package/dist/src/shared-index/artifact.js +65 -0
  16. package/dist/src/shared-index/cache.js +267 -0
  17. package/dist/src/shared-index/compatibility.js +70 -0
  18. package/dist/src/shared-index/config.js +224 -0
  19. package/dist/src/shared-index/contract.js +117 -0
  20. package/dist/src/shared-index/manifest.js +71 -0
  21. package/dist/src/shared-index/opportunistic.js +37 -0
  22. package/dist/src/shared-index/overlay.js +98 -0
  23. package/dist/src/shared-index/provenance.js +149 -0
  24. package/dist/src/shared-index/publisher.js +198 -0
  25. package/dist/src/shared-index/restore.js +209 -0
  26. package/dist/src/shared-index/s3-client.js +124 -0
  27. package/dist/src/shared-index/schemas.js +86 -0
  28. package/dist/src/shared-index/selection.js +111 -0
  29. package/dist/src/tools/knodin-tools.js +70 -3
  30. package/docs/CLI.md +56 -0
  31. package/docs/INSTALLATION.md +11 -0
  32. package/docs/MCP.md +12 -0
  33. package/docs/SHARED-INDEX-CONTRACT.md +132 -0
  34. package/docs/TELEMETRY.md +19 -1
  35. package/docs/releases/0.8.4.md +22 -0
  36. package/docs/releases/0.8.5.md +25 -0
  37. package/package.json +12 -3
  38. package/roadmap/competitive-roadmap.md +20 -0
  39. package/schemas/shared-index-branch-pointer-v1.schema.json +66 -0
  40. package/schemas/shared-index-config-v1.schema.json +97 -0
  41. package/schemas/shared-index-manifest-v1.schema.json +104 -0
  42. package/schemas/shared-index-provenance-v1.schema.json +100 -0
package/docs/CLI.md CHANGED
@@ -6,6 +6,27 @@ options, numeric parsing, unknown-option rejection, and root or command help.
6
6
  `bin/cli.ts` dispatches the validated invocation to the existing product
7
7
  handlers so JSON output contracts and established commands remain compatible.
8
8
 
9
+ ## Shared indexes
10
+
11
+ `knodin shared status` reports reviewed configuration, active graph provenance,
12
+ the last bounded restore outcome, cache state, and freshness strategy without
13
+ network access. Add `--probe` only for an explicit S3 credential/object check.
14
+
15
+ `knodin shared pull` discovers signed branch pointers, selects the nearest
16
+ locally proven ancestor, downloads or reuses an immutable digest-addressed
17
+ artifact, reconciles the current checkout in a candidate database, deep-audits,
18
+ and atomically promotes it. `--json` returns one result; `--jsonl` also streams
19
+ lossless phase records. A failed pull leaves the previous graph usable.
20
+
21
+ `knodin shared configure` writes the reviewed `.knodin/shared-index.yaml` trust
22
+ configuration from explicit repository, S3, branch, and public-key options. It
23
+ never reads or writes AWS credentials. `--disable` prevents automatic S3 access
24
+ without deleting local graph or cache state.
25
+
26
+ Index Hub publishers run `knodin index --clean` followed by
27
+ `knodin shared publisher-metadata --json`; the latter stamps and emits the exact
28
+ compatibility fingerprint used by clients.
29
+
9
30
  Run `knodin --help` for the root command inventory or append `--help` to any
10
31
  declared command path, for example:
11
32
 
@@ -32,6 +53,23 @@ example repository existence, mutually exclusive configuration modes, and
32
53
  graph-query target rules), but syntax cannot reach a handler unless the shared
33
54
  declarative model accepts it first.
34
55
 
56
+ Optional Claude lifecycle integration is explicit and user-global:
57
+
58
+ ```bash
59
+ knodin agent-hooks install --client claude --dry-run
60
+ knodin agent-hooks install --client claude
61
+ knodin agent-hooks status --client claude
62
+ knodin agent-hooks uninstall --client claude
63
+ ```
64
+
65
+ Installation atomically merges knodin-owned `SessionStart`, turn, tool, and
66
+ session-end handlers into the user's Claude settings. It preserves unrelated
67
+ settings and hooks, including aidev-track, and uninstall removes only exact
68
+ knodin entries. SessionStart emits at most 600 tokens, 8 KiB, and 12 bounded
69
+ orientation items. Hooks fail open and no-op outside initialized repositories.
70
+ The internal `agent-event` command is machine-facing and consumes bounded JSON
71
+ from stdin; it is not a general event-ingestion API.
72
+
35
73
  `knodin query resource_reachability --limit 100` runs cached, on-demand static
36
74
  TS/JS source-to-sink analysis. It covers literal `process.env` and
37
75
  `fs.readFileSync` reads reaching `console.log`, `fetch`, or `db.query` through
@@ -42,6 +80,24 @@ dynamic names, reflection, computed aliases, and unsupported languages are
42
80
  reported rather than guessed. This is a static heuristic, not runtime reachability
43
81
  or an exploitability verdict.
44
82
 
83
+ `knodin query file_metrics [--base <ref>] [--test-scope all|test|production]
84
+ --format json` emits the versioned `schemas/file-metrics-v1.schema.json`
85
+ contract. Each source file carries lexical line, import, route, and effect
86
+ counts. With `--base`, knodin resolves the local merge-base and reads both trees
87
+ directly from Git object storage; it does not check out or build a second graph.
88
+ Added and removed files have null deltas, preventing consumers from mistaking
89
+ either for an architectural improvement or regression. Output contains paths
90
+ and integer counts only and supplies measurements, not thresholds or a verdict.
91
+
92
+ ```bash
93
+ knodin query file_metrics --base origin/main --test-scope production --format json > metrics.json
94
+ jq -e '[.files[] | select(.status == "changed") | .delta | to_entries[] | select(.value > 0)] | length == 0' metrics.json
95
+ ```
96
+
97
+ An invalid ref or unresolvable merge-base fails non-zero. Binary and invalid
98
+ UTF-8 files are skipped rather than reported as zero. The query is graph
99
+ independent, so damaged graph state cannot become a misleading empty result.
100
+
45
101
  For support evidence, `knodin diagnostics enable|status|preview|archive|inspect|clear|disable`
46
102
  manages an explicit local failure journal and redacted gzip JSON bundles.
47
103
  Collection does not upload data. See `docs/DIAGNOSTICS.md` for retention,
@@ -205,6 +205,17 @@ idempotent. Local fixtures use zero hosted spend, no credentials, and no source
205
205
  egress. Diagnostic archives remain governed by the privacy-safe preview and
206
206
  archive contract in [`DIAGNOSTICS.md`](DIAGNOSTICS.md).
207
207
 
208
+ Claude users may explicitly install one user-global lifecycle adapter after
209
+ previewing its settings merge:
210
+
211
+ ```bash
212
+ knodin agent-hooks install --client claude --dry-run
213
+ knodin agent-hooks install --client claude
214
+ ```
215
+
216
+ This is independent of `knodin init` and telemetry persistence. Remove only
217
+ knodin-owned entries with `knodin agent-hooks uninstall --client claude`.
218
+
208
219
  Upgrade with the manager that owns the executable:
209
220
 
210
221
  ```bash
package/docs/MCP.md CHANGED
@@ -4,11 +4,23 @@ knodin exposes exactly one MCP tool named `knodin`. Capabilities such as
4
4
  context, explain, review, search, docs, doctor, repositories, and systems are
5
5
  operations of that gateway, not separate top-level tools.
6
6
 
7
+ Shared-index support also stays inside that one gateway. Status, context,
8
+ query, explain, review, map, and search responses include a bounded
9
+ `sharedIndex` provenance object. `source: "shared-snapshot"` identifies origin;
10
+ the independent freshness envelope says whether completed reconciliation and
11
+ deep audit still match the checkout. AWS credentials, raw S3 exceptions, and
12
+ source path lists are never returned.
13
+
7
14
  Use `operation: "query", pattern: "resource_reachability"` for the same bounded,
8
15
  cached, repo-wide TS/JS analysis as the CLI. It requires no symbol and retains
9
16
  the gateway's freshness refusal and response budgets; returned paths remain
10
17
  source-evidenced static heuristics with explicit coverage and omissions.
11
18
 
19
+ Use `operation: "query", pattern: "file_metrics"`, optional `base`, and
20
+ `testScope` for graph-independent, Git-backed file measurements. The versioned
21
+ `fileMetrics` envelope contains paths and integer counts only—no source snippets,
22
+ thresholds, or policy verdict.
23
+
12
24
  Use `operation: "evidence"` for deterministic `locate`, `outline`, `evidence`,
13
25
  and `expand` source delivery with a verified complete-file hash handshake and
14
26
  recoverable hard-budget continuations. See `docs/PROGRESSIVE-EVIDENCE.md`.
@@ -0,0 +1,132 @@
1
+ # Shared-index contract v1
2
+
3
+ This document freezes the wire and trust contract shared by the Knodin client
4
+ and an Index Hub publisher. The normative machine schemas are:
5
+
6
+ - `schemas/shared-index-config-v1.schema.json`
7
+ - `schemas/shared-index-branch-pointer-v1.schema.json`
8
+ - `schemas/shared-index-manifest-v1.schema.json`
9
+ - `schemas/shared-index-provenance-v1.schema.json`
10
+
11
+ The cross-implementation fixtures are in
12
+ `src/__tests__/fixtures/shared-index-contract-v1.json`. Producers and consumers
13
+ must validate the same fixtures before claiming v1 compatibility.
14
+
15
+ ## Trust and identity
16
+
17
+ The reviewed `.knodin/shared-index.yaml` public key is the only trust root. A
18
+ pointer, manifest, signature, object metadata, or S3 response cannot replace
19
+ it. Configuration contains no credentials, role provisioning, endpoint
20
+ override, portal data, Terraform data, or GitHub App data. `enabled: false`
21
+ forbids automatic S3 access.
22
+
23
+ Repository identity is canonicalized by removing an optional `https://` or
24
+ `ssh://git@` transport prefix from a remote identity, removing one trailing
25
+ dot from the host, lower-casing host/owner/name with the `en-US` locale,
26
+ removing one `.git` suffix from the name, and NFC-normalizing every component.
27
+ All three canonical components are compared. The S3 namespace is:
28
+
29
+ `v1/<encoded-host>/<encoded-owner>/<encoded-repo>/`
30
+
31
+ Each component and branch is encoded independently as UTF-8 RFC 3986 percent
32
+ encoding with uppercase hex. `/`, spaces, Unicode, and `%` are therefore data,
33
+ not separators. Branch patterns are either an exact Git ref name or a single
34
+ terminal `/*` prefix pattern; matching is Unicode code-point exact after NFC
35
+ normalization. A branch pointer never overrides local commit or ancestry truth.
36
+
37
+ ## Signed bytes
38
+
39
+ Manifest JSON uses RFC 8785 JSON Canonicalization Scheme bytes: UTF-8, sorted
40
+ object keys, no insignificant whitespace, and no trailing newline. The
41
+ signature covers those raw manifest bytes, not a pre-hashed digest supplied by
42
+ the caller. The algorithm is RSA-PSS with SHA-256, MGF1-SHA-256, and an exact
43
+ 32-byte salt. Public keys are PEM-encoded X.509 SubjectPublicKeyInfo. The
44
+ `publicKeySha256` value is lower-case hex SHA-256 over its DER SPKI bytes.
45
+
46
+ The pointer is untrusted discovery metadata. Before signature verification the
47
+ client bounds and validates it, checks registration/repository identity,
48
+ confines `manifestKey` beneath the canonical immutable prefix, downloads the
49
+ manifest, and matches SHA-256 over the exact downloaded canonical bytes.
50
+ The detached signature key is the manifest key with terminal `manifest.json`
51
+ replaced by `manifest.sig`. Immutable snapshots use exactly
52
+ `snapshots/<commit>/<inputFingerprint>/`; the graph key is exactly
53
+ `graph.sqlite.zst` in that directory. Alternate filenames and nested paths are
54
+ rejected even when they remain inside the repository prefix.
55
+
56
+ ## Compatibility
57
+
58
+ V1 requires exact equality for database schema version, model ID and digest,
59
+ parser bundle digest, index configuration digest, and prune-policy digest. The
60
+ client's Knodin major version must equal the manifest major version and the
61
+ client minor version must be greater than or equal to the manifest minor
62
+ version. Pre-release versions are compatible only when the complete Knodin
63
+ version is equal. Patch-version differences alone are compatible.
64
+
65
+ `knodin shared publisher-metadata --json` is the single publisher/client
66
+ implementation of these values. It also stamps `sharedIndexInputFingerprint`
67
+ into the checkpointed publisher database so restore can bind SQLite metadata
68
+ back to the signed manifest. In v1:
69
+
70
+ - `modelDigest` hashes a canonical descriptor containing model ID, the pinned
71
+ immutable model revision, 384 dimensions, and the installed Transformers.js
72
+ version.
73
+ - `parserBundleDigest` hashes parser policy version 1 and the installed
74
+ `web-tree-sitter`, `tree-sitter-wasms`, and `web-tree-sitter-sfapex`
75
+ versions.
76
+ - `indexConfigDigest` hashes index-policy version 1, database schema, and
77
+ embedding dimensions.
78
+ - `prunePolicyDigest` hashes prune-policy version 1, the sorted ignored
79
+ directory set, and the `.claude/worktrees` pattern.
80
+
81
+ Any represented behavior change must increment its policy descriptor version.
82
+ Publishers must not duplicate this logic in shell.
83
+
84
+ ## Bounds
85
+
86
+ Limits include every byte received, not merely parsed content:
87
+
88
+ | Object | Maximum bytes |
89
+ | --- | ---: |
90
+ | Branch pointer | 64 KiB |
91
+ | Manifest | 256 KiB |
92
+ | Detached signature | 16 KiB |
93
+ | Compressed graph | 8 GiB |
94
+ | Decompressed graph | 32 GiB |
95
+
96
+ Compressed and decompressed sizes and SHA-256 digests must match the manifest
97
+ exactly. The limits are ceilings; a deployment may configure stricter local
98
+ bounds. Unknown schema versions and unknown fields fail closed. No failure
99
+ before audited candidate promotion may modify the active graph.
100
+
101
+ ## Discovery, cache, and restore
102
+
103
+ Discovery never fetches Git history. Exact local HEAD is preferred; otherwise
104
+ only the nearest commit proven by the existing local object database to be an
105
+ ancestor is usable. In shallow clones an unprovable commit is rejected, while
106
+ an exact HEAD remains usable.
107
+
108
+ Verified compressed artifacts are cached privately under
109
+ `~/.knodin/shared-index-cache/v1/sha256/<compressedSha256>/graph.sqlite.zst`.
110
+ The cache uses per-digest cross-process locks and leases, verifies size and
111
+ digest before atomic installation, and never evicts a leased object. Every
112
+ worktree gets a distinct writable candidate database. Decompression enforces
113
+ the signed output size and digest, rejects trailing compressed data, validates
114
+ the SQLite header and internal commit/schema/fingerprint, reconciles final Git
115
+ and filesystem truth, deep-audits, and only then promotes.
116
+
117
+ ## Operator surfaces
118
+
119
+ - `knodin shared status` is network-free. `--probe` is the explicit S3/auth
120
+ check.
121
+ - `knodin shared pull` performs an explicit restore; `--jsonl` retains every
122
+ phase event.
123
+ - `knodin shared configure` writes only `.knodin/shared-index.yaml` and never
124
+ accepts or stores AWS credentials. `--disable` preserves the graph and cache.
125
+ - `knodin shared publisher-metadata --json` emits and stamps the frozen
126
+ compatibility metadata after watcher-free clean indexing.
127
+
128
+ The single MCP gateway includes `sharedIndex` provenance in status, context,
129
+ query, explain, review, map, and search responses before response budgeting.
130
+ Snapshot provenance and freshness are separate claims. Failed attempts are
131
+ recorded separately and never replace the provenance or bytes of the active
132
+ graph.
package/docs/TELEMETRY.md CHANGED
@@ -25,13 +25,31 @@ knodin telemetry export
25
25
  knodin telemetry clear
26
26
  ```
27
27
 
28
+ Claude adoption evidence is an independent repository-local opt-in:
29
+
30
+ ```text
31
+ knodin telemetry enable
32
+ knodin telemetry disable
33
+ ```
34
+
35
+ When enabled and the optional Claude hooks are installed, knodin records HMAC'd
36
+ session identity, lifecycle event kind, turn boundaries, coarse tool category,
37
+ supported knodin operation, freshness, context delivery, cache state, and
38
+ latency. It never persists prompts, transcript paths, source, raw tool input or
39
+ output, shell command text, usernames, or absolute paths. Disable stops new
40
+ session events without deleting retained history; `clear` removes both
41
+ operation and session event stores.
42
+
28
43
  `--retention-days 1..3650` changes the read/persistence window. `--input` and
29
44
  `--output` accept only repository-contained, non-symlink paths. `clear` is the
30
45
  only command that deletes the private JSONL file; report and export never do.
31
46
 
32
47
  The default report is `.knodin/telemetry-report.html`. It includes summary,
33
48
  operation, time-series, private repository, indexing-cost, latency, freshness,
34
- and fidelity views with light/dark styling. The default machine-readable export
49
+ fidelity, session adoption, evidence-before-edit, and observed fallback-traversal
50
+ views with light/dark styling. Ordinary hooks cannot establish why a follow-up
51
+ occurred, so corrective round trips and task success remain unavailable unless
52
+ supplied by a controlled outcome replay. The default machine-readable export
35
53
  is `.knodin/telemetry-export.json` and labels measured, modeled, and unknown
36
54
  baselines explicitly. Neither artifact needs a daemon, hosted service,
37
55
  authentication, or source egress.
@@ -0,0 +1,22 @@
1
+ # knodin 0.8.4
2
+
3
+ This release adds optional, bounded coding-session orientation and local
4
+ adoption evidence while preserving knodin's freshness and privacy boundaries.
5
+
6
+ - Adds an explicit, idempotent Claude hook installer for compact SessionStart
7
+ context. Injection is limited to 600 tokens, 8 KiB, and 12 items, reports its
8
+ bounds, rejects stale cached evidence, and fails open outside initialized
9
+ repositories.
10
+ - Adds opt-in, repository-local session telemetry and an adoption dashboard for
11
+ delivered context, successful graph-evidence operations, fallback traversal,
12
+ and evidence-before-edit observations.
13
+ - Persists only coarse allowlisted metadata and locally keyed session hashes;
14
+ prompts, source, raw tool input, commands, paths, and unhashed session IDs are
15
+ not retained.
16
+ - Keeps corrective round trips explicitly unavailable because ordinary hook
17
+ events cannot establish why an agent made a follow-up call or prove a causal
18
+ productivity improvement.
19
+ - Adds C102's preregistered paired-evaluation design so future outcome claims
20
+ require replay evidence rather than being inferred from adoption counters.
21
+
22
+ This remains an ordinary 0.x release, not a dogfood-only build and not GA.
@@ -0,0 +1,25 @@
1
+ # knodin 0.8.5
2
+
3
+ This release adds a versioned, fail-closed shared-index contract and safer
4
+ large-repository lifecycle operations while preserving local-only defaults and
5
+ the limitations recorded in the competitive roadmap.
6
+
7
+ - Adds strict repository configuration, discovery-pointer, immutable-manifest,
8
+ signature, compatibility, and provenance contracts shared by publishers and
9
+ clients.
10
+ - Adds native AWS default-credential-chain support, bounded S3 retrieval and
11
+ caching, verified decompression, snapshot selection, and recoverable restore.
12
+ - Adds watcher-free candidate database creation, deep audit, reconciliation,
13
+ atomic promotion, rollback, and interrupted-promotion recovery.
14
+ - Adds shared-index configuration, status, restore, and publisher operations to
15
+ the CLI and compact MCP gateway, plus a guarded publishing workflow.
16
+ - Adds `file_metrics` with arbitrary Git-ref comparison for source-derived
17
+ architectural ratchets without a checked-in numeric baseline.
18
+ - Hardens timing-sensitive structural-routing and behavioral-contract replay
19
+ under instrumented host load without weakening assertions or interactive
20
+ hang limits.
21
+
22
+ Shared indexes remain explicitly opt-in. Reviewed repository configuration is
23
+ the trust root, snapshots cannot replace it, and incompatible or ambiguous
24
+ evidence fails closed. This remains an ordinary 0.x release, not GA or a claim
25
+ of certified trusted distribution.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "knodin",
3
- "version": "0.8.3",
3
+ "version": "0.8.5",
4
4
  "description": "knodin — source-evidenced local code intelligence with known bounds. Stable identity, fresh evidence, truthful budgets, and recoverable bounded views.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -42,6 +42,7 @@
42
42
  "docs/REPOSITORIES-AND-WORKTREES.md",
43
43
  "docs/RELEASE-0.3-EVIDENCE.md",
44
44
  "docs/SIGNED-UPDATES.md",
45
+ "docs/SHARED-INDEX-CONTRACT.md",
45
46
  "docs/releases/0.3.0.md",
46
47
  "docs/releases/0.4.0.md",
47
48
  "docs/releases/0.4.1.md",
@@ -59,6 +60,8 @@
59
60
  "docs/releases/0.8.0.md",
60
61
  "docs/releases/0.8.2.md",
61
62
  "docs/releases/0.8.3.md",
63
+ "docs/releases/0.8.4.md",
64
+ "docs/releases/0.8.5.md",
62
65
  "docs/assets/knodin-favicon.svg",
63
66
  "docs/SYSTEMS-AND-RELATIONSHIPS.md",
64
67
  "docs/TELEMETRY.md",
@@ -67,6 +70,10 @@
67
70
  "roadmap/competitive-roadmap.md",
68
71
  "schemas/release-attestation-v1.schema.json",
69
72
  "schemas/support-bundle-v2.schema.json",
73
+ "schemas/shared-index-config-v1.schema.json",
74
+ "schemas/shared-index-branch-pointer-v1.schema.json",
75
+ "schemas/shared-index-manifest-v1.schema.json",
76
+ "schemas/shared-index-provenance-v1.schema.json",
70
77
  "*.wasm"
71
78
  ],
72
79
  "engines": {
@@ -137,14 +144,16 @@
137
144
  "lint:fix": "biome check --write ."
138
145
  },
139
146
  "dependencies": {
140
- "@huggingface/transformers": "^4.2.0",
147
+ "@aws-sdk/client-s3": "3.1106.0",
148
+ "@huggingface/transformers": "4.2.0",
141
149
  "@modelcontextprotocol/sdk": "^1.30.0",
150
+ "@smithy/node-http-handler": "4.9.13",
142
151
  "chokidar": "^5.0.0",
143
152
  "commander": "15.0.0",
144
153
  "gpt-tokenizer": "3.4.0",
145
154
  "ora": "9.4.1",
146
155
  "re2-wasm": "1.0.2",
147
- "tree-sitter-wasms": "^0.1.13",
156
+ "tree-sitter-wasms": "0.1.13",
148
157
  "web-tree-sitter": "0.20.8",
149
158
  "web-tree-sitter-sfapex": "2.4.1",
150
159
  "yaml": "2.9.0",
@@ -137,6 +137,7 @@ new items or strengthen existing ones; they do not reopen the archived roadmap.
137
137
  | C99 | P1 | implemented | Resolve bounded TypeScript dependency-injection wiring | C2, C3, C24, C95 |
138
138
  | C100 | P1 | implemented | Prove bounded Salesforce Flow-to-Apex paths | C2, C3, C20, C23, C95, C96 |
139
139
  | C101 | P1 | implemented | Strengthen contract-led positioning | C95, C97, C98, C99, C100 |
140
+ | C102 | P1 | implemented — opt-in observational evidence only | Add bounded Claude session context and adoption evidence | C3, C16, C61, C93, C95 |
140
141
 
141
142
  ### C98 — Bounded source-to-sink resource reachability
142
143
 
@@ -192,6 +193,25 @@ new items or strengthen existing ones; they do not reopen the archived roadmap.
192
193
  commits normally form one reasonably sized shared PR; assistants do not
193
194
  auto-open per-item PRs, and unrelated changes are not bundled for size.
194
195
 
196
+ ### C102 — Bounded Claude session context and adoption evidence
197
+
198
+ - Status: implemented — opt-in observational evidence only
199
+ - Priority: P1
200
+ - DependsOn: C3, C16, C61, C93, C95
201
+ - Evidence: `src/agent-hooks.ts`, `src/agent-events.ts`,
202
+ `src/session-telemetry.ts`, focused unit/CLI tests, and
203
+ `benchmarks/evaluations/c102-session-adoption/README.md`.
204
+ - Implementation: an explicit user-global Claude hook installer atomically
205
+ preserves unrelated settings and supports status, dry-run, and targeted
206
+ uninstall. SessionStart injects cached, freshness-aware orientation under
207
+ 600 tokens, 8 KiB, and 12 items. Separate repository-local telemetry opt-in
208
+ records private lifecycle categories and extends the existing local report.
209
+ - Bounds: ordinary hooks prove neither task success nor why a follow-up turn
210
+ occurred. The dashboard labels corrective round trips unavailable, stores no
211
+ prompt/source/command/transcript/tool-output bodies, and authorizes no
212
+ productivity or superiority claim. Claude is the only supported client for
213
+ this adapter; the event model remains client-neutral for later evaluation.
214
+
195
215
  ## Roadmap completion contract
196
216
 
197
217
  This section is the control plane for completing this roadmap with a persistent
@@ -0,0 +1,66 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://knodin.dev/schemas/shared-index-branch-pointer-v1.schema.json",
4
+ "title": "Knodin shared-index branch discovery pointer v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "registrationId",
10
+ "repository",
11
+ "branch",
12
+ "commit",
13
+ "inputFingerprint",
14
+ "manifestKey",
15
+ "manifestSha256",
16
+ "updatedAt"
17
+ ],
18
+ "properties": {
19
+ "schemaVersion": { "const": 1 },
20
+ "registrationId": { "$ref": "#/$defs/registrationId" },
21
+ "repository": { "$ref": "#/$defs/repository" },
22
+ "branch": { "type": "string", "minLength": 1, "maxLength": 1024 },
23
+ "commit": { "$ref": "#/$defs/gitObject" },
24
+ "inputFingerprint": { "$ref": "#/$defs/sha256" },
25
+ "manifestKey": {
26
+ "type": "string",
27
+ "minLength": 1,
28
+ "maxLength": 2048,
29
+ "pattern": "^v1/[^/]+/[^/]+/[^/]+/snapshots/[a-f0-9]{40,64}/[a-f0-9]{64}/manifest\\.json$"
30
+ },
31
+ "manifestSha256": { "$ref": "#/$defs/sha256" },
32
+ "updatedAt": {
33
+ "type": "string",
34
+ "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d{1,9})?Z$"
35
+ }
36
+ },
37
+ "$defs": {
38
+ "registrationId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{0,127}$" },
39
+ "sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
40
+ "gitObject": { "type": "string", "pattern": "^[a-f0-9]{40,64}$" },
41
+ "repository": {
42
+ "type": "object",
43
+ "additionalProperties": false,
44
+ "required": ["host", "owner", "name"],
45
+ "properties": {
46
+ "host": {
47
+ "type": "string",
48
+ "pattern": "^(?!.*\\.\\.)(?!.*(?:^|\\.)-)(?!.*-(?:\\.|$))[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?$",
49
+ "maxLength": 253
50
+ },
51
+ "owner": {
52
+ "type": "string",
53
+ "minLength": 1,
54
+ "maxLength": 255,
55
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,253}[a-z0-9])?$"
56
+ },
57
+ "name": {
58
+ "type": "string",
59
+ "minLength": 1,
60
+ "maxLength": 255,
61
+ "pattern": "^[a-z0-9](?:[a-z0-9._-]{0,253}[a-z0-9])?$"
62
+ }
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,97 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://knodin.dev/schemas/shared-index-config-v1.schema.json",
4
+ "title": "Knodin shared-index repository configuration v1",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "enabled",
10
+ "registrationId",
11
+ "aws",
12
+ "repository",
13
+ "branches",
14
+ "signing"
15
+ ],
16
+ "properties": {
17
+ "schemaVersion": { "const": 1 },
18
+ "enabled": { "type": "boolean" },
19
+ "registrationId": { "$ref": "#/$defs/registrationId" },
20
+ "aws": {
21
+ "type": "object",
22
+ "additionalProperties": false,
23
+ "required": ["region", "bucket"],
24
+ "properties": {
25
+ "region": {
26
+ "type": "string",
27
+ "pattern": "^[a-z]{2}(?:-gov)?-[a-z]+-\\d$",
28
+ "maxLength": 32
29
+ },
30
+ "bucket": {
31
+ "type": "string",
32
+ "pattern": "^(?!xn--)(?!.*\\.\\.)(?!.*\\.-)(?!.*-\\.)(?!\\d{1,3}(?:\\.\\d{1,3}){3}$)[a-z0-9][a-z0-9.-]{1,61}[a-z0-9]$"
33
+ }
34
+ }
35
+ },
36
+ "repository": { "$ref": "#/$defs/repository" },
37
+ "branches": {
38
+ "type": "array",
39
+ "minItems": 1,
40
+ "maxItems": 64,
41
+ "uniqueItems": true,
42
+ "items": {
43
+ "type": "string",
44
+ "minLength": 1,
45
+ "maxLength": 255,
46
+ "pattern": "^(?!/)(?!.*//)(?!.*\\.\\.)(?!.*@\\{)(?!.*[~^:?\\[\\\\])[^*]+(?:/\\*)?$"
47
+ }
48
+ },
49
+ "signing": {
50
+ "type": "object",
51
+ "additionalProperties": false,
52
+ "required": ["algorithm", "keyId", "publicKeySha256", "publicKeyPem"],
53
+ "properties": {
54
+ "algorithm": { "const": "RSASSA_PSS_SHA_256" },
55
+ "keyId": {
56
+ "type": "string",
57
+ "maxLength": 2048,
58
+ "pattern": "^(?:arn:(?:aws|aws-us-gov|aws-cn):kms:[a-z0-9-]+:\\d{12}:(?:key/[A-Za-z0-9-]+|alias/[A-Za-z0-9/_+=,.@-]+)|alias/[A-Za-z0-9/_+=,.@-]+)$"
59
+ },
60
+ "publicKeySha256": { "$ref": "#/$defs/sha256" },
61
+ "publicKeyPem": {
62
+ "type": "string",
63
+ "pattern": "^-----BEGIN PUBLIC KEY-----\\n(?:[A-Za-z0-9+/=]+\\n)+-----END PUBLIC KEY-----\\n?$",
64
+ "maxLength": 16384
65
+ }
66
+ }
67
+ }
68
+ },
69
+ "$defs": {
70
+ "registrationId": { "type": "string", "pattern": "^[a-z0-9][a-z0-9._-]{0,127}$" },
71
+ "sha256": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
72
+ "repository": {
73
+ "type": "object",
74
+ "additionalProperties": false,
75
+ "required": ["host", "owner", "name"],
76
+ "properties": {
77
+ "host": {
78
+ "type": "string",
79
+ "pattern": "^(?!.*\\.\\.)(?!.*(?:^|\\.)-)(?!.*-(?:\\.|$))[a-z0-9](?:[a-z0-9.-]{0,251}[a-z0-9])?$",
80
+ "maxLength": 253
81
+ },
82
+ "owner": {
83
+ "type": "string",
84
+ "minLength": 1,
85
+ "maxLength": 255,
86
+ "pattern": "^[a-z0-9](?:[a-z0-9-]{0,253}[a-z0-9])?$"
87
+ },
88
+ "name": {
89
+ "type": "string",
90
+ "minLength": 1,
91
+ "maxLength": 255,
92
+ "pattern": "^[a-z0-9](?:[a-z0-9._-]{0,253}[a-z0-9])?$"
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }