@saasontools/strauss-kb 0.1.11 → 0.1.13

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
@@ -64,6 +64,21 @@ rewritten to remove; enforcing a vocabulary would make them a closed enum, which
64
64
  or do not, where a tag can be wrong forever. If narrowing ever matters, measure
65
65
  tag narrowing against vector recall on a real base rather than adding both.
66
66
 
67
+ ## Typed links
68
+
69
+ Supersession is not a rel. It is a lifecycle, and
70
+ `strauss_supersedes`/`strauss_superseded_by` already carry it in both
71
+ directions; a rel would be a second spelling free to disagree with them.
72
+
73
+ The rel vocabulary is closed, but the read schema tolerates an unknown one.
74
+ Frontmatter strict enough to reject it would make the file fail to parse, and a
75
+ file that fails to parse is skipped by `list()` rather than reported — the
76
+ bundle would drop the record instead of naming it. Tolerant read, strict write:
77
+ `kb_write` refuses an unknown rel, `kb_validate` reports one as an error.
78
+
79
+ `kb_impact` reports a superseded or rejected record and stops there. A withdrawn
80
+ record's declared dependencies are not obligations anyone still owes.
81
+
67
82
  ## Rejected: a format that needs a parser
68
83
 
69
84
  This was broken twice. A hand-rolled frontmatter reader could not express nested
package/README.md CHANGED
@@ -155,6 +155,7 @@ OKF version defining the same name cannot collide:
155
155
  | `strauss_status` | `draft`, `proposed`, `accepted`, `open`, `resolved`, `rejected`, `superseded`. Parses with a default of `draft`. |
156
156
  | `strauss_supersedes` / `strauss_superseded_by` | Both directions of a supersession, written together. |
157
157
  | `strauss_anchors` | `{ file, symbol?, hash?, lines?, resolved_at? }` — where the record attaches in the code, and optionally what that code looked like when it did. See [Anchors and drift](#anchors-and-drift). |
158
+ | `strauss_links` | `{ target, rel }` — a typed causal edge, source → target. See [Links](#links). |
158
159
  | `strauss_assumption` | The claim has no source, said as a field rather than as a fake entry in `sources`. |
159
160
  | `strauss_answered` | Who resolved an open question, and when. |
160
161
  | `strauss_verify` | Checks that would confirm the record still holds. |
@@ -162,7 +163,8 @@ OKF version defining the same name cannot collide:
162
163
 
163
164
  Edges are markdown links in the body, as OKF specifies — untyped, with the kind
164
165
  conveyed by the surrounding prose. Broken links are legal: records are routinely
165
- written before the ones they point at exist.
166
+ written before the ones they point at exist. `strauss_links` adds a typed layer
167
+ over that, described below.
166
168
 
167
169
  Twelve record types differ only in what their body answers and where they start
168
170
  in the lifecycle — `fact`, `requirement`, `constraint`, `decision`,
@@ -197,6 +199,35 @@ A lock file. It closes the window and adds a stale-hold failure mode that is
197
199
  worse than the residue.
198
200
  ```
199
201
 
202
+ ## Links
203
+
204
+ `strauss_links` is a typed causal edge, `[{ target, rel }]` on the source
205
+ record, read source → target: `A depends_on B` means A needs B. The vocabulary
206
+ is closed: eight rels. The **dependant** — the end that breaks when the other
207
+ changes — is per-rel.
208
+
209
+ | `rel` | `A <rel> B` means | Dependant |
210
+ | ------------- | ---------------------------- | --------- |
211
+ | `depends_on` | A needs B to hold | A |
212
+ | `verified_by` | B confirms A | A |
213
+ | `satisfies` | A discharges B's requirement | A |
214
+ | `constrains` | A bounds what B may do | B |
215
+ | `informs` | A shaped B, not binding | B |
216
+ | `blocks` | B waits on A | B |
217
+ | `invalidates` | A makes B no longer hold | B |
218
+ | `related_to` | no dependence | — |
219
+
220
+ `kb_impact` (`strauss-kb impact <id>`): the transitive set of dependants, each
221
+ rel followed in its own direction, never `related_to`.
222
+
223
+ `kb_backlinks` (`strauss-kb backlinks <id>`): every inbound edge, one hop, any rel.
224
+
225
+ `kb_validate`: unknown rel or malformed target is an `error`, absent target a
226
+ `warning`. Only errors fail the exit code.
227
+
228
+ The [specification](https://saasontools.github.io/strauss-agent-tools/specification)
229
+ has the rest.
230
+
200
231
  ## Writes
201
232
 
202
233
  Records are staged to a sibling file and published atomically, so a concurrent
@@ -314,6 +345,9 @@ strauss-kb [--bundle PATH] <command> [args]
314
345
  The bounded neighbourhood around one record, every cut named.
315
346
  query <text...> [--repo-root PATH] Search; every match arrives flagged with its standing.
316
347
  trace <concept-id> [edges...] How a position was arrived at, as a timeline.
348
+ impact <concept-id> [--depth N] [--rels a,b]
349
+ What breaks if this changes: its dependants, transitively.
350
+ backlinks <concept-id> Who points at this record — one hop, every rel.
317
351
  list [type] Every record, optionally narrowed to one type.
318
352
  index The index, rebuilt if it disagrees with the records.
319
353
  log What touched what, and when.
@@ -342,7 +376,9 @@ worked; `--` ends flag parsing, for the verbs that end in free prose. Errors
342
376
  go to stderr and exit 1. `validate`, `anchor-resolve`, and `doctor --strict`
343
377
  are the commands whose exit code is not just "did it run": a check that
344
378
  reports a problem succeeded as a command and failed as a check, so each exits
345
- 1 with its findings on stdout.
379
+ 1 with its findings on stdout. Only `validate` findings with `severity: "error"`
380
+ do that — a base mid-write is full of links to records not written yet, so
381
+ warnings alone exit 0.
346
382
 
347
383
  A flag accepts either spelling — `--budget 4000` or `--budget=4000` — and a
348
384
  flag given no value is an error rather than a silent fallback to the default,
@@ -360,7 +396,7 @@ strauss-kb --bundle .strauss/kb write fact <<'JSON'
360
396
  JSON
361
397
 
362
398
  strauss-kb query cache key region
363
- strauss-kb validate || echo "problems above"
399
+ strauss-kb validate || echo "errors above" # warnings alone still exit 0
364
400
  ```
365
401
 
366
402
  ## MCP server
@@ -368,7 +404,8 @@ strauss-kb validate || echo "problems above"
368
404
  `strauss-kb-mcp` speaks stdio and takes no API key and no required environment.
369
405
  Every CLI verb is a tool: `kb_write`, `kb_write_decision`, `kb_no_decision`,
370
406
  `kb_status`, `kb_supersede`, `kb_answer`, `kb_verify`, `kb_anchor_resolve`,
371
- `kb_load`, `kb_catalog`, `kb_pack`, `kb_query`, `kb_trace`, `kb_list`,
407
+ `kb_load`, `kb_catalog`, `kb_pack`, `kb_query`, `kb_trace`, `kb_impact`,
408
+ `kb_backlinks`, `kb_list`,
372
409
  `kb_index`, `kb_log`, `kb_validate`, `kb_doctor`, `kb_schema`, `kb_types`,
373
410
  `kb_pin`, `kb_unpin`, `kb_pins`, `kb_context`. Most tools take a `bundlePath`;
374
411
  `kb_schema` and `kb_types` describe the format rather than any one base, and
@@ -534,6 +571,14 @@ fact; a missing replacement is `broken-chain` with no head — the case that nee
534
571
  the most care, because returning the stale record unmarked looks exactly like
535
572
  success.
536
573
 
574
+ **Placement is cache economics.** `load`'s output belongs in the stable
575
+ prefix — system prompt or first turn; `query` and `pack` results belong at
576
+ the tail. `digest` is the base's content stamp: a change-notification hook
577
+ and `kb_stamp` (SAA-719) compare it to detect change, not the model. A
578
+ prompt cache matches a byte-for-byte prefix, so one volatile result ahead of
579
+ a stable load prices the base at full rate thereafter. Mechanism and digest
580
+ caveats: <https://saasontools.github.io/strauss-agent-tools/mcp-reference>.
581
+
537
582
  ## Health
538
583
 
539
584
  `doctor` sweeps a whole base and reports what has decayed. It is read-only —
@@ -2,7 +2,7 @@ import {
2
2
  KB_COMMANDS,
3
3
  KbStore,
4
4
  VERSION
5
- } from "./chunk-OVRQCQ6P.js";
5
+ } from "./chunk-XALWG3EZ.js";
6
6
 
7
7
  // src/mcp.ts
8
8
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -46,4 +46,4 @@ export {
46
46
  createKbMcpServer,
47
47
  runKbMcpServer
48
48
  };
49
- //# sourceMappingURL=chunk-CWWXMD35.js.map
49
+ //# sourceMappingURL=chunk-WZODZNR6.js.map