@saasontools/strauss-kb 0.1.14 → 0.1.16

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/ARCHITECTURE.md CHANGED
@@ -93,8 +93,26 @@ interface admits a tree-sitter replacement.
93
93
  Repository identity is normalised and compared, not parsed: an invented format
94
94
  would reject correct values from unseen hosts.
95
95
 
96
- Not one anchored file found under a default root is a wrong root, so its
97
- findings are dropped.
96
+ ## Remote over local checkout
97
+
98
+ An anchor naming another repository resolves against that repository's remote,
99
+ through a bare cache under `~/.strauss/repo-cache`. A checkout is one person's
100
+ view — stale, dirty, or absent — so a hash from it is evidence about that
101
+ machine, not the code.
102
+
103
+ The rejected design was multi-root: `--repo-root name=path` per repository,
104
+ root discovery, a `.strauss/kb-roots.json` map, a `repo-not-mapped` finding. It
105
+ makes the answer depend on the reader's disk — one machine verifies, another
106
+ reports drift — and needs configuring before a base can check itself. Git
107
+ already knows how to reach a remote.
108
+
109
+ A pinned `ref` is checked at that commit and the default branch compared on top
110
+ of it: was the record ever true, and does it still hold.
111
+
112
+ `repo` and `ref` come out of a `.md` file the reader did not write, so both are
113
+ validated against a shape before any `git` runs: an argv array stops the shell
114
+ but not git's own option parsing, where `--upload-pack=<cmd>` as a rev and
115
+ `ext::sh -c <cmd>` as a URL are each an execution primitive.
98
116
 
99
117
  ## Cross-worktree log safety
100
118
 
package/README.md CHANGED
@@ -208,13 +208,13 @@ An anchor names where a record attaches in the code: a `file`, optionally a
208
208
  `symbol` — symbolic, because a line number written mid-change is wrong by the
209
209
  end of it. Five optional fields extend it:
210
210
 
211
- | Field | Meaning |
212
- | ------------- | ---------------------------------------------------------------------------------------------------------------- |
213
- | `hash` | `sha256:<hex>` over the anchored text, algorithm-prefixed. |
214
- | `lines` | Line count the hash covered. |
215
- | `resolved_at` | When the anchor last resolved. |
216
- | `repo` | Which repository — remote URL or short name. Absent means this base's own repository. |
217
- | `ref` | Git rev the evidence was taken at. Recorded but unused until [SAA-709](https://linear.app/saason/issue/SAA-709). |
211
+ | Field | Meaning |
212
+ | ------------- | ------------------------------------------------------------------------------------- |
213
+ | `hash` | `sha256:<hex>` over the anchored text, algorithm-prefixed. |
214
+ | `lines` | Line count the hash covered. |
215
+ | `resolved_at` | When the anchor last resolved. |
216
+ | `repo` | Which repository — remote URL or short name. Absent means this base's own repository. |
217
+ | `ref` | Git rev the evidence was taken at. |
218
218
 
219
219
  `hash`, `lines`, and `resolved_at` are **measured** — a resolution pass stamps
220
220
  them; `repo` and `ref` are **author-owned identity** and a resolution pass
@@ -229,25 +229,35 @@ counterpart: it checks the anchored code against the working tree
229
229
  - **drifted** — hash changed. Baseline kept unless `--rebaseline`.
230
230
  - **unresolved** — not comparable, with a reason. A finding, not an error.
231
231
 
232
- An anchor naming another `repo` is skipped: never read, stamped, or counted.
232
+ An anchor naming another `repo` is read from that repository's **remote**,
233
+ through a bare cache under `~/.strauss/repo-cache` — a local checkout is one
234
+ person's possibly stale view of the same file. With a `ref` it has three
235
+ states: `matches-ref`, `drifted-from-ref`, and `drifted-on-default`.
236
+ `--offline` reads the cache and never fetches. Only `https`, `ssh`, and `git`
237
+ remotes are fetched, and a `repo` or `ref` git could read as an option is a
238
+ finding, not a command.
233
239
 
234
240
  An anchor must not read outside the repository it describes, checked lexically
235
241
  and again on the real path after symlinks.
236
242
 
237
243
  Exit code is non-zero on **drifted**, or on **unresolved** for an anchor that
238
- carries a hash; unstamped and foreign anchors never fail.
244
+ carries a hash; unstamped anchors and unreachable remotes never fail.
239
245
 
240
- A fully clean run — every checkable anchor `match`, none stamped this run —
246
+ A fully clean run — every anchor checked and `match`, none stamped this run —
241
247
  appends a `verified[]` event.
242
248
 
243
249
  Symbol resolution is a v1 heuristic; ties and unclosed blocks return
244
250
  `unresolved`.
245
251
 
246
252
  Drift also surfaces on read: `kb_load` and `kb_query` attach a
247
- `{ kind: "drifted" }` warning, and `kb_doctor` lists every drifted anchor
248
- base-wide all three take `--repo-root`. With no `--repo-root` given, a run
249
- that finds not one anchored file drops the finding as a wrong root; an explicit
250
- `--repo-root` is taken at its word.
253
+ `{ kind: "drifted" }` warning or `{ kind: "unchecked" }` for a foreign anchor
254
+ they could not read from the cache, because they never fetch — and `kb_doctor`
255
+ lists both base-wide, per repository. All three take `--repo-root`. With no
256
+ `--repo-root` given, a run that finds not one anchored file drops the finding as
257
+ a wrong root; an explicit `--repo-root` is taken at its word.
258
+
259
+ Remote resolution in full:
260
+ [specification](https://saasontools.github.io/strauss-agent-tools/specification#anchors-in-another-repository).
251
261
 
252
262
  Details: [specification](https://saasontools.github.io/strauss-agent-tools/specification).
253
263
 
@@ -398,8 +408,8 @@ Worked flows:
398
408
 
399
409
  **Placement is cache economics.** `load`'s output belongs in the stable
400
410
  prefix — system prompt or first turn; `query` and `pack` results belong at
401
- the tail. `digest` is the base's content stamp: a change-notification hook
402
- and `kb_stamp` (SAA-719) compare it to detect change, not the model. A
411
+ the tail. `digest` is the base's content stamp: `kb_stamp` and the opt-in
412
+ reload hook compare it to detect change, not the model. A
403
413
  prompt cache matches a byte-for-byte prefix, so one volatile result ahead of
404
414
  a stable load prices the base at full rate thereafter. Mechanism and digest
405
415
  caveats: <https://saasontools.github.io/strauss-agent-tools/mcp-reference>.
@@ -407,9 +417,9 @@ caveats: <https://saasontools.github.io/strauss-agent-tools/mcp-reference>.
407
417
  ## Health
408
418
 
409
419
  `doctor` sweeps a base read-only for `expired`, `expiring`, `unverified`,
410
- `aging`, `orphaned`, `broken-supersession`, `superseded-but-cited`, and
411
- `drifted`. All eight groups are reported even when empty; `--strict` gates on
412
- expiry alone, not on drift. Pass `--repo-root PATH` when the base does not sit
420
+ `aging`, `orphaned`, `broken-supersession`, `superseded-but-cited`, `drifted`,
421
+ and `unchecked`. All nine groups are reported even when empty; `--strict` gates
422
+ on expiry alone, not on drift. Pass `--repo-root PATH` when the base does not sit
413
423
  inside the tree it describes.
414
424
  Windows and judgments:
415
425
  [cli-reference](https://saasontools.github.io/strauss-agent-tools/cli-reference).
@@ -441,6 +451,11 @@ carry no numbers:
441
451
  }
442
452
  ```
443
453
 
454
+ A pinned base can also change mid-session — a `git pull`, a sub-agent's write.
455
+ `strauss-kb stamp` reports each pinned base's content digest. Comparing it for
456
+ you is opt-in, see the
457
+ [plugin README](../../plugins/strauss-kb/README.md#opt-in-workspace-hooks).
458
+
444
459
  `sync-instructions <file>` keeps that block between
445
460
  `<!-- strauss-kb:begin/end -->` sentinels in AGENTS.md or CLAUDE.md; it is
446
461
  idempotent, and covers runtimes without a reliable post-compaction hook.
@@ -448,15 +463,16 @@ idempotent, and covers runtimes without a reliable post-compaction hook.
448
463
  What each runtime gets (configs in the
449
464
  [plugin's adapters](../../plugins/strauss-kb/adapters/)):
450
465
 
451
- | Layer | Claude Code | Codex CLI | Antigravity CLI |
452
- | ------------------------- | ------------------ | ------------------------------------------- | -------------------------- |
453
- | MCP tool descriptions | ✓ | ✓ | ✓ |
454
- | Session-start injection | SessionStart hook | SessionStart hook | PreInvocation, per turn |
455
- | Post-compact re-injection | ✓ `compact` source | ✓ client-side; instruction-only when hosted | moot — injected every turn |
456
- | File-read blocking | opt-in PreToolUse | (shell is the side door) | opt-in PreToolUse, JSON |
457
- | Manual-edit validation | opt-in PostToolUse | ✗ | |
458
- | Generated-file edit guard | opt-in PreToolUse | ✗ | ✗ |
459
- | Instruction file | CLAUDE.md | AGENTS.md | AGENTS.md + rules/ |
466
+ | Layer | Claude Code | Codex CLI | Antigravity CLI |
467
+ | ------------------------- | -------------------------------- | ------------------------------------------- | -------------------------- |
468
+ | MCP tool descriptions | ✓ | ✓ | ✓ |
469
+ | Session-start injection | SessionStart hook | SessionStart hook | PreInvocation, per turn |
470
+ | Post-compact re-injection | ✓ `compact` source | ✓ client-side; instruction-only when hosted | moot — injected every turn |
471
+ | Reload after a pull | opt-in PostToolUse, SubagentStop | opt-in PostToolUse on `shell` | moot injected every turn |
472
+ | File-read blocking | opt-in PreToolUse | ✗ (shell is the side door) | opt-in PreToolUse, JSON |
473
+ | Manual-edit validation | opt-in PostToolUse | ✗ | ✗ |
474
+ | Generated-file edit guard | opt-in PreToolUse | | ✗ |
475
+ | Instruction file | CLAUDE.md | AGENTS.md | AGENTS.md + rules/ |
460
476
 
461
477
  Never read record files directly — read through the tools; a raw read bypasses
462
478
  standing, and a superseded record reads exactly like a current one. Enforce it