@saasontools/strauss-kb 0.1.11 → 0.1.12

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/README.md CHANGED
@@ -534,6 +534,14 @@ fact; a missing replacement is `broken-chain` with no head — the case that nee
534
534
  the most care, because returning the stale record unmarked looks exactly like
535
535
  success.
536
536
 
537
+ **Placement is cache economics.** `load`'s output belongs in the stable
538
+ prefix — system prompt or first turn; `query` and `pack` results belong at
539
+ the tail. `digest` is the base's content stamp: a change-notification hook
540
+ and `kb_stamp` (SAA-719) compare it to detect change, not the model. A
541
+ prompt cache matches a byte-for-byte prefix, so one volatile result ahead of
542
+ a stable load prices the base at full rate thereafter. Mechanism and digest
543
+ caveats: <https://saasontools.github.io/strauss-agent-tools/mcp-reference>.
544
+
537
545
  ## Health
538
546
 
539
547
  `doctor` sweeps a whole base and reports what has decayed. It is read-only —
@@ -2562,7 +2562,7 @@ var loadCommand = define({
2562
2562
  name: "load",
2563
2563
  tool: "kb_load",
2564
2564
  usage: "load [type] [--budget N | --all] [--repo-root PATH]",
2565
- description: "Loads the whole knowledge base at once, each record with its standing. Superseded records arrive as stubs (name, replacement, date); rejected and open records arrive whole. Refuses past the token budget rather than truncating \u2014 call kb_catalog, then kb_pack on the record that matters, or narrow with `type`; kb_query for a lookup by wording. `all` bypasses the budget.",
2565
+ description: "Loads the whole knowledge base at once, each record with its standing. Superseded records arrive as stubs; rejected and open records arrive whole. Refuses past the token budget \u2014 call kb_catalog, kb_pack on it; `all` bypasses the budget. Never read record files directly. Cache-stable; `digest` is the base's content stamp \u2014 hooks use it to tell you when to reload.",
2566
2566
  input: z14.object({
2567
2567
  bundlePath,
2568
2568
  type: z14.enum(KB_RECORD_TYPES).optional(),
@@ -2805,7 +2805,7 @@ var queryCommand = define({
2805
2805
  name: "query",
2806
2806
  tool: "kb_query",
2807
2807
  usage: "query <text...> [--repo-root PATH]",
2808
- description: "Search and return each match with its standing. Results are flagged, never filtered: a superseded record comes back alongside whatever replaced it, and a rejected one is marked as something explicitly not adopted. This is the lookup-by-wording rung, and the narrowest of the three: use it when you know roughly what the record says. The decision rule around it \u2014 while the base fits kb_load's token budget, kb_load it whole, because on this package's measurements a reader holding the whole base answered eight of nine questions whose wording appears in no record where embedding search answered four; once kb_load refuses, kb_catalog for one line per record and then kb_pack on the record the work centres on; and kb_query when the question is a point lookup rather than a neighbourhood. A query cannot tell you that nothing was decided \u2014 it returns its nearest hit whatever the distance \u2014 so reach for kb_catalog when the question is what exists. Never read record files directly: this tool (with kb_load, kb_catalog, kb_pack and kb_trace) is the only supported way to read a base; a file read bypasses supersession resolution and returns replaced records as if current.",
2808
+ description: "Search; every hit carries its standing. Flagged, never filtered: a superseded hit returns with its replacement, a rejected one is marked. Prefer kb_load when the base fits its budget \u2014 a full read beats search. Results are volatile: place them at the tail, not the cached prefix. Never read record files directly.",
2809
2809
  input: z20.object({
2810
2810
  bundlePath,
2811
2811
  text: z20.string().optional(),
@@ -3642,6 +3642,7 @@ ${answer}
3642
3642
  const records = adjudicated.filter((hit) => hit.standing !== "superseded");
3643
3643
  const superseded = adjudicated.filter((hit) => hit.standing === "superseded").map(stub);
3644
3644
  const approxTokens2 = records.reduce((total, hit) => total + estimateTokens(hit.record), 0) + superseded.reduce((total, entry) => total + estimateStubTokens(entry), 0);
3645
+ const bundleDigestValue = bundleDigest(records, superseded);
3645
3646
  if (!options.all && approxTokens2 > budgetTokens) {
3646
3647
  return {
3647
3648
  loaded: false,
@@ -3652,7 +3653,8 @@ ${answer}
3652
3653
  approxTokens: approxTokens2,
3653
3654
  budgetTokens,
3654
3655
  type: options.type
3655
- })
3656
+ }),
3657
+ digest: bundleDigestValue
3656
3658
  };
3657
3659
  }
3658
3660
  return {
@@ -3661,7 +3663,8 @@ ${answer}
3661
3663
  tokensLoaded: approxTokens2,
3662
3664
  budgetTokens: options.all ? null : budgetTokens,
3663
3665
  records,
3664
- superseded
3666
+ superseded,
3667
+ digest: bundleDigestValue
3665
3668
  };
3666
3669
  }
3667
3670
  /** How a position was arrived at, as a timeline. See `trace.ts`. */
@@ -3978,6 +3981,22 @@ function normalizeActor(id) {
3978
3981
  function digest(contents) {
3979
3982
  return createHash2("sha256").update(contents).digest("hex");
3980
3983
  }
3984
+ function bundleDigest(records, superseded) {
3985
+ const entries = [
3986
+ ...records.map(
3987
+ (hit) => `${hit.record.conceptId}:current:${digest(
3988
+ stringifyMarkdownWithFrontmatter(
3989
+ hit.record.body,
3990
+ hit.record.frontmatter
3991
+ )
3992
+ )}`
3993
+ ),
3994
+ ...superseded.map(
3995
+ (entry) => `${entry.conceptId}:superseded:${digest(JSON.stringify(entry))}`
3996
+ )
3997
+ ].sort();
3998
+ return digest(entries.join("\n"));
3999
+ }
3981
4000
 
3982
4001
  // src/pack.ts
3983
4002
  var DEFAULT_PACK_HOPS = 2;
@@ -4064,7 +4083,7 @@ function typeRank(record) {
4064
4083
  }
4065
4084
 
4066
4085
  // src/version.ts
4067
- var VERSION = true ? "0.1.11" : "0.0.0-dev";
4086
+ var VERSION = true ? "0.1.12" : "0.0.0-dev";
4068
4087
 
4069
4088
  export {
4070
4089
  kbSourceSchema,
@@ -4166,4 +4185,4 @@ export {
4166
4185
  KbStore,
4167
4186
  VERSION
4168
4187
  };
4169
- //# sourceMappingURL=chunk-OVRQCQ6P.js.map
4188
+ //# sourceMappingURL=chunk-33ZCBEUV.js.map