@ggui-ai/mcp-server-handlers 0.25.0 → 0.26.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.
Files changed (101) hide show
  1. package/README.md +2 -2
  2. package/dist/credits/index.d.ts +2 -2
  3. package/dist/credits/index.d.ts.map +1 -1
  4. package/dist/credits/index.js +1 -1
  5. package/dist/credits/list-credit-transactions.d.ts +21 -7
  6. package/dist/credits/list-credit-transactions.d.ts.map +1 -1
  7. package/dist/credits/list-credit-transactions.js +12 -2
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/ops-blueprint/cache-mirror.d.ts +41 -0
  12. package/dist/ops-blueprint/cache-mirror.d.ts.map +1 -0
  13. package/dist/ops-blueprint/cache-mirror.js +19 -0
  14. package/dist/ops-blueprint/delete.d.ts +18 -0
  15. package/dist/ops-blueprint/delete.d.ts.map +1 -1
  16. package/dist/ops-blueprint/delete.js +21 -2
  17. package/dist/ops-blueprint/errors.d.ts +11 -0
  18. package/dist/ops-blueprint/errors.d.ts.map +1 -1
  19. package/dist/ops-blueprint/errors.js +14 -0
  20. package/dist/ops-blueprint/generate.d.ts +1 -3
  21. package/dist/ops-blueprint/generate.d.ts.map +1 -1
  22. package/dist/ops-blueprint/generate.js +47 -58
  23. package/dist/ops-blueprint/list.d.ts.map +1 -1
  24. package/dist/ops-blueprint/list.js +1 -2
  25. package/dist/ops-blueprint/register.d.ts +17 -6
  26. package/dist/ops-blueprint/register.d.ts.map +1 -1
  27. package/dist/ops-blueprint/register.js +77 -45
  28. package/dist/ops-blueprint/update.d.ts +3 -2
  29. package/dist/ops-blueprint/update.d.ts.map +1 -1
  30. package/dist/ops-blueprint/update.js +4 -3
  31. package/dist/renders/blueprint-coverage.d.ts +23 -4
  32. package/dist/renders/blueprint-coverage.d.ts.map +1 -1
  33. package/dist/renders/blueprint-coverage.js +45 -5
  34. package/dist/renders/blueprint-durability.d.ts.map +1 -1
  35. package/dist/renders/blueprint-durability.js +5 -0
  36. package/dist/renders/blueprint-matcher.d.ts +28 -0
  37. package/dist/renders/blueprint-matcher.d.ts.map +1 -1
  38. package/dist/renders/blueprint-matcher.js +39 -7
  39. package/dist/renders/blueprint-registry.d.ts +52 -1
  40. package/dist/renders/blueprint-registry.d.ts.map +1 -1
  41. package/dist/renders/blueprint-registry.js +137 -10
  42. package/dist/renders/build-seed-pool.d.ts.map +1 -1
  43. package/dist/renders/build-seed-pool.js +6 -0
  44. package/dist/renders/consume.d.ts +3 -2
  45. package/dist/renders/consume.d.ts.map +1 -1
  46. package/dist/renders/consume.js +23 -14
  47. package/dist/renders/cross-app-refused.d.ts +3 -2
  48. package/dist/renders/cross-app-refused.d.ts.map +1 -1
  49. package/dist/renders/cross-app-refused.js +5 -3
  50. package/dist/renders/decide-handshake.d.ts +28 -0
  51. package/dist/renders/decide-handshake.d.ts.map +1 -1
  52. package/dist/renders/decide-handshake.js +39 -4
  53. package/dist/renders/export-registry.d.ts +8 -1
  54. package/dist/renders/export-registry.d.ts.map +1 -1
  55. package/dist/renders/export-registry.js +3 -0
  56. package/dist/renders/fits.d.ts.map +1 -1
  57. package/dist/renders/fits.js +23 -1
  58. package/dist/renders/handshake.d.ts +6 -42
  59. package/dist/renders/handshake.d.ts.map +1 -1
  60. package/dist/renders/handshake.js +1 -1
  61. package/dist/renders/index.d.ts +5 -4
  62. package/dist/renders/index.d.ts.map +1 -1
  63. package/dist/renders/index.js +4 -3
  64. package/dist/renders/installed-blueprints-provider.d.ts.map +1 -1
  65. package/dist/renders/installed-blueprints-provider.js +3 -1
  66. package/dist/renders/match-precision/pairs.d.ts +5 -4
  67. package/dist/renders/match-precision/pairs.d.ts.map +1 -1
  68. package/dist/renders/match-precision/topk-probe.js +13 -8
  69. package/dist/renders/record-committed-one-shot.d.ts +18 -3
  70. package/dist/renders/record-committed-one-shot.d.ts.map +1 -1
  71. package/dist/renders/record-committed-one-shot.js +14 -7
  72. package/dist/renders/refresh-ws-token.d.ts +9 -12
  73. package/dist/renders/refresh-ws-token.d.ts.map +1 -1
  74. package/dist/renders/refresh-ws-token.js +13 -10
  75. package/dist/renders/render-identity.d.ts +14 -5
  76. package/dist/renders/render-identity.d.ts.map +1 -1
  77. package/dist/renders/render-identity.js +25 -12
  78. package/dist/renders/render-read-gate.d.ts +27 -1
  79. package/dist/renders/render-read-gate.d.ts.map +1 -1
  80. package/dist/renders/render-read-gate.js +17 -5
  81. package/dist/renders/render.d.ts +36 -19
  82. package/dist/renders/render.d.ts.map +1 -1
  83. package/dist/renders/render.js +174 -17
  84. package/dist/renders/report-render-failure.d.ts +69 -0
  85. package/dist/renders/report-render-failure.d.ts.map +1 -0
  86. package/dist/renders/report-render-failure.js +83 -0
  87. package/dist/renders/runtime-pull.d.ts.map +1 -1
  88. package/dist/renders/runtime-pull.js +6 -0
  89. package/dist/renders/slice-meta-derivation.d.ts +8 -1
  90. package/dist/renders/slice-meta-derivation.d.ts.map +1 -1
  91. package/dist/renders/slice-meta-derivation.js +1 -0
  92. package/dist/renders/submit-action.d.ts +41 -71
  93. package/dist/renders/submit-action.d.ts.map +1 -1
  94. package/dist/renders/submit-action.js +225 -78
  95. package/dist/renders/sync-context.d.ts +3 -1
  96. package/dist/renders/sync-context.d.ts.map +1 -1
  97. package/dist/renders/sync-context.js +38 -8
  98. package/dist/types.d.ts +71 -1
  99. package/dist/types.d.ts.map +1 -1
  100. package/dist/types.js +32 -0
  101. package/package.json +8 -8
@@ -2,7 +2,7 @@ import { DomainError } from '@ggui-ai/protocol';
2
2
  import type { BlueprintIndex, EmbeddingProvider, EnumerableVectorStore, VectorStore } from '@ggui-ai/mcp-server-core';
3
3
  export type { BlueprintIndex } from '@ggui-ai/mcp-server-core';
4
4
  import type { AestheticPresetRef, DirectionScope } from './fits.js';
5
- import { type BlueprintSource, type BlueprintVariance, type DataContract } from '@ggui-ai/protocol';
5
+ import { type BlueprintSource, type BlueprintVariance, type DataContract, type GeneratorBuild } from '@ggui-ai/protocol';
6
6
  import { type ContractValidationFinding, type ContractValidationResult } from '@ggui-ai/negotiator';
7
7
  import { type BlueprintDurabilityDeps } from './blueprint-durability.js';
8
8
  /**
@@ -102,6 +102,16 @@ export interface Blueprint {
102
102
  * A blueprint cache invalidates by regeneration; it never coerces.
103
103
  */
104
104
  readonly source: BlueprintSource;
105
+ /**
106
+ * The build of the engine that minted this blueprint (ggui#1280), set
107
+ * only on a generation mint (`source.kind === 'llm'`) whose stamp
108
+ * passed {@link admitGeneratorBuild}. It is written to the DURABLE
109
+ * record (`projectDurableBlueprint`) and to the vector-store row
110
+ * (`METADATA_KEYS.build`, ggui#1476), so a row read back via
111
+ * {@link rowToBlueprint} — a dedup return and a reuse included — names
112
+ * its MINTING build; an unreadable stored value reads as absent.
113
+ */
114
+ readonly build?: GeneratorBuild;
105
115
  /**
106
116
  * Lifecycle-owner marker for rows materialized by the marketplace
107
117
  * install bridge (`installToCache`). Orthogonal to {@link source}
@@ -255,6 +265,13 @@ export interface RegisterBlueprintInput {
255
265
  * empty variance as one stable sentinel.
256
266
  */
257
267
  readonly variance?: BlueprintVariance;
268
+ /**
269
+ * The minting engine's build (ggui#1280), from the generation's
270
+ * `metadata.build`. Pass it only for code a generation produced; the
271
+ * registry keeps it only when {@link admitGeneratorBuild} does, and a
272
+ * dedup keeps the row's MINTING build (first write wins).
273
+ */
274
+ readonly build?: GeneratorBuild;
258
275
  /**
259
276
  * WHO initiated this mint, for the durable record. `'agent'` is the
260
277
  * standard handshake → render flow; the operator tools
@@ -288,6 +305,40 @@ export declare function composeExactKey(kind: BlueprintKind, contractKey: string
288
305
  * the prompt's `cachedContractSummary` MUST equal what was embedded.
289
306
  */
290
307
  export declare function composeEmbeddingInput(contract: DataContract | undefined, intent: string): string;
308
+ /**
309
+ * ggui#1476 — the minting build a registry row stores, or `undefined` when
310
+ * the row has none or its stored value is unreadable. The ONE reader of the
311
+ * `build` key: the registry's row reader and the exporter both call it, so
312
+ * the key has one owner. It parses the stored JSON and validates it with the
313
+ * protocol's strict `generatorBuildSchema`; an unreadable value drops the
314
+ * FACT — the row reads as an unknown minting build — never the row, with one
315
+ * line per row id per process.
316
+ */
317
+ export declare function readGeneratorBuild(metadata: Record<string, string | number | boolean | null>, rowId: string): GeneratorBuild | undefined;
318
+ /**
319
+ * The one admission rule for a blueprint's build stamp (ggui#1280): keep
320
+ * `build` only for code a generation produced (`source.kind === 'llm'`),
321
+ * only when it passes the protocol's strict `generatorBuildSchema`, and only
322
+ * when it serializes within {@link MAX_BUILD_STAMP_BYTES} (ggui#1476 — the
323
+ * stamp rides every vector-store row's metadata).
324
+ * Otherwise the STAMP is dropped, with a line, and the registration goes
325
+ * ahead unstamped: a row whose minting build is unknown is a reported
326
+ * category, never an error, while a malformed stamp on a durable row would
327
+ * make every strict reader of that row refuse it (`ggui_ops_list_blueprints`
328
+ * validates its rows with `blueprintSchema`). Every writer of a stamp calls
329
+ * this, so the rule has one home.
330
+ */
331
+ export declare function admitGeneratorBuild(source: BlueprintSource, build: GeneratorBuild | undefined): GeneratorBuild | undefined;
332
+ /**
333
+ * ggui#1476 — the largest build stamp, serialized, a row may carry. The stamp
334
+ * rides every registry row's vector-store metadata, and a production vector
335
+ * backend bounds that metadata per row (a filterable-metadata budget of
336
+ * about 2 KB on one such backend, where a rejected write is swallowed by
337
+ * registration and reads as a silently empty cache). A real stamp — two
338
+ * 64-hex digests, a version and a mode — is about 250 bytes; the bound keeps
339
+ * an engine that reports many more digests from ever reaching that budget.
340
+ */
341
+ export declare const MAX_BUILD_STAMP_BYTES = 1024;
291
342
  /**
292
343
  * Default cap on registered blueprints per (scope, kind). When a
293
344
  * fresh registration would push the bucket past the cap,
@@ -1 +1 @@
1
- {"version":3,"file":"blueprint-registry.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-registry.ts"],"names":[],"mappings":"AA0CA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EAKrB,WAAW,EACZ,MAAM,0BAA0B,CAAC;AAKlC,YAAY,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAIL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,wBAAwB,EAC9B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,2BAA2B,CAAC;AAEnC;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AAE1E,mDAAmD;AACnD,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,CAAC;IACnC;;;;;OAKG;IACH,sDAAsD;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,sFAAsF;IACtF,QAAQ,CAAC,eAAe,CAAC,EAAE,kBAAkB,CAAC;IAC9C,wEAAwE;IACxE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,yGAAyG;IACzG,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,oFAAoF;IACpF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,qCAAqC;IACrC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;OASG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;;;;;OAOG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACpE;AAED;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAC9B,QAAQ,EAAE,YAAY,KACnB,wBAAwB,CAAC;AAE9B;;;;;;;;;;;;GAYG;AACH,qBAAa,sBAAuB,SAAQ,WAAW,CAAC,oBAAoB,CAAC;IAC3E,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;gBAC5C,QAAQ,EAAE,SAAS,yBAAyB,EAAE;CAQ3D;AAED,gFAAgF;AAChF,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,uBAAuB,CAAC;CAC/C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,UAAU,CAAC;AAE5D;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAGlE;AAED,2CAA2C;AAC3C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,qBAAqB,CAAC;IAC9C,mEAAmE;IACnE,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,CAAC,eAAe,CAAC,EAAE,kBAAkB,CAAC;IAC9C,oEAAoE;IACpE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,6FAA6F;IAC7F,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IACtC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC3C;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAER;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,YAAY,GAAG,SAAS,EAClC,MAAM,EAAE,MAAM,GACb,MAAM,CAER;AAgTD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAC;AAEnD,MAAM,WAAW,wBAAwB;IACvC;;;;;;;OAOG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CAChC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE5E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,sBAAsB,EAC7B,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,mBAAmB,CAAC,CA6G9B;AAmID;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,EACzD,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa,EACnB,WAAW,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAM3B;AA4DD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,EAClC,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAE3B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,EACb,KAAK,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;CAAE,EACpE,OAAO,GAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GACtE,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAaxC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE;IAAE,WAAW,EAAE,qBAAqB,CAAA;CAAE,EAC5C,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,aAAa,GACnB,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC,CAU/B;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAA;CAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,EACnE,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED,0EAA0E;AAC1E,MAAM,MAAM,2BAA2B,GACnC,UAAU,GACV,kBAAkB,GAClB,mBAAmB,GACnB,kBAAkB,GAClB,WAAW,GACX,WAAW,CAAC;AAKhB,kDAAkD;AAClD,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,OAAO,EAAE,2BAA2B,CAAC;IAC9C;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,kEAAkE;IAClE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,qBAAqB,EAC3B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE;IACN,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;CACvC,EACD,IAAI,EAAE;IAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EACrE,OAAO,GAAE;IAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,0BAA0B,CAAC,CAqErC;AAoBD;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE;IAAE,WAAW,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,EACzD,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,IAAI,CAAC,CAaf"}
1
+ {"version":3,"file":"blueprint-registry.d.ts","sourceRoot":"","sources":["../../src/renders/blueprint-registry.ts"],"names":[],"mappings":"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"}
@@ -41,7 +41,7 @@ import { createHash } from 'node:crypto';
41
41
  */
42
42
  import { randomUUID } from 'node:crypto';
43
43
  import { DomainError } from '@ggui-ai/protocol';
44
- import { blueprintSourceToFlat, flatToBlueprintSource, summarizeContract, } from '@ggui-ai/protocol';
44
+ import { blueprintSourceToFlat, flatToBlueprintSource, generatorBuildSchema, summarizeContract, } from '@ggui-ai/protocol';
45
45
  // `blueprintKey` + `variantKey` are server-only — pulled in from a
46
46
  // dedicated subpath because they import `node:crypto`, which browsers
47
47
  // can't bundle.
@@ -143,6 +143,10 @@ const METADATA_KEYS = {
143
143
  aestheticPresetVersion: 'aestheticPresetVersion',
144
144
  directionDigest: 'directionDigest',
145
145
  directionScope: 'directionScope',
146
+ // ggui#1476 — the minting engine's build, as a JSON string. Bounded at
147
+ // admission (MAX_BUILD_STAMP_BYTES) so it cannot crowd a vector backend's
148
+ // metadata budget; written only when present.
149
+ build: 'build',
146
150
  };
147
151
  function blueprintToMetadata(bp) {
148
152
  return {
@@ -186,6 +190,7 @@ function blueprintToMetadata(bp) {
186
190
  ...(bp.directionDigest !== undefined && bp.directionScope !== undefined
187
191
  ? { [METADATA_KEYS.directionScope]: bp.directionScope }
188
192
  : {}),
193
+ ...(bp.build !== undefined ? { [METADATA_KEYS.build]: JSON.stringify(bp.build) } : {}),
189
194
  };
190
195
  }
191
196
  function readDirectionScope(raw) {
@@ -207,6 +212,48 @@ function readJudgedCanvases(raw) {
207
212
  return undefined;
208
213
  }
209
214
  }
215
+ /** Row ids whose stored stamp was unreadable, already warned this process. */
216
+ const warnedUnreadableBuildIds = new Set();
217
+ /**
218
+ * ggui#1476 — the minting build a registry row stores, or `undefined` when
219
+ * the row has none or its stored value is unreadable. The ONE reader of the
220
+ * `build` key: the registry's row reader and the exporter both call it, so
221
+ * the key has one owner. It parses the stored JSON and validates it with the
222
+ * protocol's strict `generatorBuildSchema`; an unreadable value drops the
223
+ * FACT — the row reads as an unknown minting build — never the row, with one
224
+ * line per row id per process.
225
+ */
226
+ export function readGeneratorBuild(metadata, rowId) {
227
+ const stored = metadata[METADATA_KEYS.build];
228
+ if (stored === undefined)
229
+ return undefined;
230
+ if (typeof stored !== 'string') {
231
+ warnUnreadableBuild(rowId, `stored as ${stored === null ? 'null' : typeof stored}, not a JSON string`);
232
+ return undefined;
233
+ }
234
+ const raw = stored;
235
+ let parsed;
236
+ try {
237
+ parsed = JSON.parse(raw);
238
+ }
239
+ catch (err) {
240
+ warnUnreadableBuild(rowId, err instanceof Error ? err.message : String(err));
241
+ return undefined;
242
+ }
243
+ const build = generatorBuildSchema.safeParse(parsed);
244
+ if (!build.success) {
245
+ warnUnreadableBuild(rowId, build.error.issues.map((i) => i.message).join('; '));
246
+ return undefined;
247
+ }
248
+ return build.data;
249
+ }
250
+ function warnUnreadableBuild(rowId, why) {
251
+ if (warnedUnreadableBuildIds.has(rowId))
252
+ return;
253
+ warnedUnreadableBuildIds.add(rowId);
254
+ // eslint-disable-next-line no-console -- operator-visible degradation notice
255
+ console.warn(`[ggui] blueprint registry: blueprint_build_stamp_unreadable — row ${rowId} keeps its code; its minting build reads as unknown (${why})`);
256
+ }
210
257
  function readAestheticPreset(metadata) {
211
258
  const id = readScalarString(metadata[METADATA_KEYS.aestheticPresetId]);
212
259
  if (id === undefined)
@@ -242,6 +289,59 @@ function warnEvictionFallback(event, consequence, err) {
242
289
  // eslint-disable-next-line no-console -- operator-visible degradation notice
243
290
  console.warn(`[ggui] blueprint registry: ${event} — ${consequence}: ${err instanceof Error ? err.message : String(err)} (logged once per process)`);
244
291
  }
292
+ /**
293
+ * Stamp-drop reasons already warned this process — one line per process per
294
+ * reason, the {@link warnEvictionFallback} posture: visible without a line
295
+ * per generation when an engine keeps reporting the same bad stamp.
296
+ */
297
+ const warnedBuildStampDrops = new Set();
298
+ /**
299
+ * The one admission rule for a blueprint's build stamp (ggui#1280): keep
300
+ * `build` only for code a generation produced (`source.kind === 'llm'`),
301
+ * only when it passes the protocol's strict `generatorBuildSchema`, and only
302
+ * when it serializes within {@link MAX_BUILD_STAMP_BYTES} (ggui#1476 — the
303
+ * stamp rides every vector-store row's metadata).
304
+ * Otherwise the STAMP is dropped, with a line, and the registration goes
305
+ * ahead unstamped: a row whose minting build is unknown is a reported
306
+ * category, never an error, while a malformed stamp on a durable row would
307
+ * make every strict reader of that row refuse it (`ggui_ops_list_blueprints`
308
+ * validates its rows with `blueprintSchema`). Every writer of a stamp calls
309
+ * this, so the rule has one home.
310
+ */
311
+ export function admitGeneratorBuild(source, build) {
312
+ if (build === undefined)
313
+ return undefined;
314
+ const drop = (() => {
315
+ if (source.kind !== 'llm')
316
+ return { reason: 'not-generated', detail: 'code no generation produced carries no build' };
317
+ if (!generatorBuildSchema.safeParse(build).success)
318
+ return { reason: 'schema', detail: 'the stamp fails generatorBuildSchema' };
319
+ const bytes = new TextEncoder().encode(JSON.stringify(build)).length;
320
+ if (bytes > MAX_BUILD_STAMP_BYTES) {
321
+ return { reason: 'size', detail: `the stamp is ${bytes} bytes, over the ${MAX_BUILD_STAMP_BYTES}-byte bound` };
322
+ }
323
+ return undefined;
324
+ })();
325
+ if (drop === undefined)
326
+ return build;
327
+ if (!warnedBuildStampDrops.has(drop.reason)) {
328
+ warnedBuildStampDrops.add(drop.reason);
329
+ // eslint-disable-next-line no-console -- operator-visible degradation notice
330
+ console.warn(`[ggui] blueprint registry: blueprint_build_stamp_dropped — ${drop.detail}; ` +
331
+ 'the row registers unstamped (its minting build reads as unknown) (logged once per process per reason)');
332
+ }
333
+ return undefined;
334
+ }
335
+ /**
336
+ * ggui#1476 — the largest build stamp, serialized, a row may carry. The stamp
337
+ * rides every registry row's vector-store metadata, and a production vector
338
+ * backend bounds that metadata per row (a filterable-metadata budget of
339
+ * about 2 KB on one such backend, where a rejected write is swallowed by
340
+ * registration and reads as a silently empty cache). A real stamp — two
341
+ * 64-hex digests, a version and a mode — is about 250 bytes; the bound keeps
342
+ * an engine that reports many more digests from ever reaching that budget.
343
+ */
344
+ export const MAX_BUILD_STAMP_BYTES = 1024;
245
345
  function readScalarString(value) {
246
346
  return typeof value === 'string' ? value : undefined;
247
347
  }
@@ -333,6 +433,7 @@ function rowToBlueprint(key, metadata) {
333
433
  const aestheticPreset = readAestheticPreset(metadata);
334
434
  const directionDigest = readScalarString(metadata[METADATA_KEYS.directionDigest]);
335
435
  const directionScope = directionDigest !== undefined ? readDirectionScope(metadata[METADATA_KEYS.directionScope]) : undefined;
436
+ const build = readGeneratorBuild(metadata, key);
336
437
  return {
337
438
  id: key,
338
439
  kind: kindStr,
@@ -353,6 +454,7 @@ function rowToBlueprint(key, metadata) {
353
454
  ...(aestheticPreset !== undefined ? { aestheticPreset } : {}),
354
455
  ...(directionDigest !== undefined ? { directionDigest } : {}),
355
456
  ...(directionScope !== undefined ? { directionScope } : {}),
457
+ ...(build !== undefined ? { build } : {}),
356
458
  };
357
459
  }
358
460
  /**
@@ -436,8 +538,9 @@ export async function registerBlueprint(deps, scope, input, options = {}) {
436
538
  if (existing)
437
539
  return { ...existing, deduped: true };
438
540
  // Dangling binding (id present, row gone) — self-heal: drop the stale
439
- // binding and fall through to mint a fresh row.
440
- await deps.index.deleteId(scope, exactKey);
541
+ // binding and fall through to mint a fresh row. Conditional on the stale
542
+ // id, so a registration that bound the key in between keeps it (#1603).
543
+ await deps.index.deleteId(scope, exactKey, existingId);
441
544
  }
442
545
  const id = options.mintId?.() ?? `bp_${randomUUID()}`;
443
546
  const variance = input.variance ?? {};
@@ -452,6 +555,10 @@ export async function registerBlueprint(deps, scope, input, options = {}) {
452
555
  codeStore !== undefined
453
556
  ? codeStore.hashOf(input.sourceCode)
454
557
  : undefined;
558
+ // ggui#1280 / ggui#1476 — the minting engine's build, admitted once: the
559
+ // returned blueprint, the durable record and the vector-store row
560
+ // (`METADATA_KEYS.build`, via `blueprintToMetadata`) all carry it.
561
+ const build = admitGeneratorBuild(input.source, input.build);
455
562
  const blueprint = {
456
563
  id,
457
564
  kind: input.kind,
@@ -464,6 +571,7 @@ export async function registerBlueprint(deps, scope, input, options = {}) {
464
571
  createdAt,
465
572
  hitCount: 0,
466
573
  source: input.source,
574
+ ...(build !== undefined ? { build } : {}),
467
575
  ...(input.installed === true ? { installed: true } : {}),
468
576
  ...(input.intentSource === 'fallback' ? { intentSource: 'fallback' } : {}),
469
577
  ...(input.judgedCanvases !== undefined ? { judgedCanvases: [...input.judgedCanvases] } : {}),
@@ -606,12 +714,16 @@ async function maybeEvictLowestHitBlueprint(deps, scope, kind, cap) {
606
714
  if (victimKind !== undefined &&
607
715
  victimContractKey !== undefined &&
608
716
  victimVariantKey !== undefined) {
717
+ const victimExactKey = composeExactKey(victimKind, victimContractKey, victimVariantKey);
609
718
  try {
610
- await deps.index.deleteId(scope, composeExactKey(victimKind, victimContractKey, victimVariantKey));
719
+ // Conditional on the victim's own id: a key re-bound since to a
720
+ // different blueprint keeps its binding (#1603).
721
+ await deps.index.deleteId(scope, victimExactKey, victim.key);
611
722
  }
612
- catch {
613
- // Best-effort — a failed index delete leaves a self-healing
614
- // dangling binding, which `findBlueprintExact` resolves to null.
723
+ catch (err) {
724
+ // Best-effort — a failed index delete leaves a dangling binding, which
725
+ // `findBlueprintExact` resolves to null; named so an operator sees it.
726
+ warnUnbindFailed(scope, victimExactKey, victim.key, err);
615
727
  }
616
728
  }
617
729
  }
@@ -905,11 +1017,26 @@ export async function deleteBlueprint(deps, scope, id) {
905
1017
  const existing = await findBlueprintByUuid(deps.vectorStore, scope, id);
906
1018
  await deps.vectorStore.deleteVector(scope, id);
907
1019
  if (existing) {
1020
+ const exactKey = composeExactKey(existing.kind, existing.contractKey, existing.variantKey);
908
1021
  try {
909
- await deps.index.deleteId(scope, composeExactKey(existing.kind, existing.contractKey, existing.variantKey));
1022
+ // Conditional on the deleted id: if the key has since been bound to a
1023
+ // different blueprint, that binding is the live design and stays (#1603).
1024
+ await deps.index.deleteId(scope, exactKey, id);
910
1025
  }
911
- catch {
912
- // Best-effort — a dangling binding self-heals at the read site.
1026
+ catch (err) {
1027
+ // Best-effort — a dangling binding self-heals at the read site; named
1028
+ // so an operator sees it.
1029
+ warnUnbindFailed(scope, exactKey, id, err);
913
1030
  }
914
1031
  }
915
1032
  }
1033
+ /**
1034
+ * An index unbind failed after its row was deleted (#1603). Best-effort by
1035
+ * design: the dangling binding self-heals at the read site. Named, so an
1036
+ * operator sees it rather than a silent swallow.
1037
+ */
1038
+ function warnUnbindFailed(scope, exactKey, blueprintId, err) {
1039
+ // eslint-disable-next-line no-console -- operator-visible degradation notice
1040
+ console.warn(`[ggui] blueprint registry: blueprint_index_unbind_failed — scope ${scope}, key ${exactKey}, ` +
1041
+ `blueprint ${blueprintId}; the binding dangles until a read self-heals it: ${err instanceof Error ? err.message : String(err)}`);
1042
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"build-seed-pool.d.ts","sourceRoot":"","sources":["../../src/renders/build-seed-pool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAwB5D,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,CAuExB"}
1
+ {"version":3,"file":"build-seed-pool.d.ts","sourceRoot":"","sources":["../../src/renders/build-seed-pool.ts"],"names":[],"mappings":"AAYA,OAAO,EAAyB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAwB5D,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC;CAC9B;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,aAAa,CAAC,CA6ExB"}
@@ -82,6 +82,12 @@ export async function buildSeedPool(source, options) {
82
82
  // requires it) — an llm-minted record stays llm-sourced in
83
83
  // the pool; importing never re-labels authorship.
84
84
  source: record.source,
85
+ // ggui#1476 — the minting build travels with the artifact the same
86
+ // way. A stamp that fails `generatorBuildSchema` never reaches here:
87
+ // `fromPortableBlueprint` rejects the whole record above. The registry
88
+ // then admits what remains — a stamp on non-generated code, or one over
89
+ // the size bound, is dropped with a line and the row registers.
90
+ ...(record.build !== undefined ? { build: record.build } : {}),
85
91
  variance: record.variance,
86
92
  },
87
93
  // Seed pool is a fixed curated set — never evict.
@@ -166,8 +166,9 @@ export interface GguiConsumeHandlerDeps {
166
166
  readonly logger?: ConsumeLogger;
167
167
  /**
168
168
  * Optional active-consumer awareness seam. When bound, the handler
169
- * calls `enter(sessionId)` at the top of the long-poll and
170
- * `exit(sessionId)` in `finally` so a concurrent
169
+ * calls `enter(sessionId)` once the caller is admitted to the session
170
+ * (never for a refused or missing one) and `exit(sessionId)` in
171
+ * `finally` so a concurrent
171
172
  * `ggui_runtime_submit_action` append can query `hasActive` and
172
173
  * surface `consumerPresent: false` to the iframe when no long-poll
173
174
  * is registered for the targeted render — the iframe then emits
@@ -1 +1 @@
1
- {"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../../src/renders/consume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAEtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAuBrB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgC,CAAC;AACnD,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,YAAY,CAAC,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,IAAI,EAAE;QACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YAC5B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,CAAC;KACH,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,IAAI,EAAE;QACjB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAAC;CACV;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC;;sDAEkD;IAClD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,wDAAwD;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IACzD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,gBAAgB,EAAE,oBAAoB,CAAC;CAC3E;AAYD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiOpE"}
1
+ {"version":3,"file":"consume.d.ts","sourceRoot":"","sources":["../../src/renders/consume.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,EACL,KAAK,sBAAsB,EAE3B,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EAEtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAuBrB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAgC,CAAC;AACnD,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,YAAY,CAAC,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,IAAI,EAAE;QACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,QAAQ,CAAC,MAAM,EAAE;YACf,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;YAC5B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;SACzB,CAAC;KACH,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,IAAI,EAAE;QACjB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAAC;CACV;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC;;sDAEkD;IAClD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,wDAAwD;IACxD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;;;OAMG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IACzD;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,gBAAgB,EAAE,oBAAoB,CAAC;CAC3E;AAYD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAyOpE"}
@@ -73,22 +73,31 @@ export function createGguiConsumeHandler(deps) {
73
73
  outputSchema,
74
74
  async handler(rawInput, ctx) {
75
75
  const { sessionId, timeout = 0 } = z.object(inputSchema).parse(rawInput);
76
- // Register this long-poll on the active-consumer registry IMMEDIATELY
77
- // — before the app-scope resolution awaits — so a concurrent
78
- // `submit-action.ts` append observes `hasActive: true` for the
79
- // earliest possible window. `exit` is paired in `finally` below so
80
- // every termination path (success, timeout, error, app-scope reject)
81
- // decrements the count exactly once.
76
+ // Resolve render FIRST (ggui#1485). Cross-app (appId) + cross-user +
77
+ // missing all surface uniformly as session_not_found (don't leak
78
+ // whether the id exists for another app / another user), and a
79
+ // refused call must leave no trace on the session it named. Entering
80
+ // the active-consumer registry before this gate let another app's
81
+ // consume count as the session's consumer while its store read ran
82
+ // (a dispatch in that moment reported a consumer present), and its
83
+ // `exit` stamped the session's lastExitAt, which changed the grace
84
+ // wait of that session's dispatches for the next minute.
85
+ const stored = await deps.renderStore.get(sessionId);
86
+ if (!isVisibleToCaller(stored, ctx)) {
87
+ // `stored` is narrowed to StoredGguiSession past this guard.
88
+ throw new GguiSessionNotFoundError(sessionId);
89
+ }
90
+ // Register this long-poll on the active-consumer registry once the
91
+ // caller is admitted, so a concurrent `submit-action.ts` append
92
+ // observes `hasActive: true`. A dispatch landing during the store
93
+ // read above waits its own grace (`waitForConsumer`), which this
94
+ // `enter` wakes; with the default policy that wait is at least
95
+ // 150 ms, far longer than one store read, while a deployment's
96
+ // `consumerGraceMs` sets its own. `exit` is paired in `finally` below
97
+ // so every termination path after admission (success, timeout,
98
+ // error, abort) decrements the count exactly once.
82
99
  deps.activeConsumerRegistry?.enter(sessionId);
83
100
  try {
84
- // Resolve render. Cross-app (appId) + cross-user + missing
85
- // all surface uniformly as session_not_found (don't leak whether
86
- // the id exists for another app / another user).
87
- const stored = await deps.renderStore.get(sessionId);
88
- if (!isVisibleToCaller(stored, ctx)) {
89
- // `stored` is narrowed to StoredGguiSession past this guard.
90
- throw new GguiSessionNotFoundError(sessionId);
91
- }
92
101
  // `timeout` is schema-bounded to [0, 25] (SPEC §7.3) —
93
102
  // out-of-range values rejected INVALID_PARAMS before this line.
94
103
  const deadline = Date.now() + timeout * 1000;
@@ -10,7 +10,8 @@ export declare function logCrossAppRefused(tool: string, sessionId: string, call
10
10
  * ggui#1479 — the line a refusal leaves when a session's ownership could not
11
11
  * be read at all (the store threw): the tool, the session, the caller's app
12
12
  * and why. The call fails closed; this line is how an outage reads apart
13
- * from a probe.
13
+ * from a probe. A caller with no logger of its own passes the store's error
14
+ * text, so the cause rides the same line (ggui#1514).
14
15
  */
15
- export declare function logOwnershipUnverified(tool: string, sessionId: string, callerAppId: string, reason: 'read-failed'): void;
16
+ export declare function logOwnershipUnverified(tool: string, sessionId: string, callerAppId: string, reason: 'read-failed', error?: string): void;
16
17
  //# sourceMappingURL=cross-app-refused.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cross-app-refused.d.ts","sourceRoot":"","sources":["../../src/renders/cross-app-refused.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAGjH;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAGxH"}
1
+ {"version":3,"file":"cross-app-refused.d.ts","sourceRoot":"","sources":["../../src/renders/cross-app-refused.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAGjH;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CAIN"}
@@ -13,9 +13,11 @@ export function logCrossAppRefused(tool, sessionId, callerAppId, ownerAppId) {
13
13
  * ggui#1479 — the line a refusal leaves when a session's ownership could not
14
14
  * be read at all (the store threw): the tool, the session, the caller's app
15
15
  * and why. The call fails closed; this line is how an outage reads apart
16
- * from a probe.
16
+ * from a probe. A caller with no logger of its own passes the store's error
17
+ * text, so the cause rides the same line (ggui#1514).
17
18
  */
18
- export function logOwnershipUnverified(tool, sessionId, callerAppId, reason) {
19
+ export function logOwnershipUnverified(tool, sessionId, callerAppId, reason, error) {
20
+ const fields = error === undefined ? { tool, sessionId, callerAppId, reason } : { tool, sessionId, callerAppId, reason, error };
19
21
  // eslint-disable-next-line no-console -- operator-visible structured refusal line; handlers carry no logger
20
- console.warn(`[ggui] runtime_ownership_unverified ${JSON.stringify({ tool, sessionId, callerAppId, reason })}`);
22
+ console.warn(`[ggui] runtime_ownership_unverified ${JSON.stringify(fields)}`);
21
23
  }
@@ -95,6 +95,17 @@ export interface BlueprintLookupKeys {
95
95
  readonly variantKey: string;
96
96
  readonly exactKey: string;
97
97
  }
98
+ /**
99
+ * ggui#1568 — a deployment's answer to "which rows may the semantic tier
100
+ * not offer for this request?" See {@link HandshakeDecisionAdapter.semanticExclusion}.
101
+ */
102
+ export type SemanticExclusion = {
103
+ readonly kind: 'rows';
104
+ readonly keys: ReadonlySet<string>;
105
+ } | {
106
+ readonly kind: 'all';
107
+ readonly reason: string;
108
+ };
98
109
  export interface HandshakeDecisionAdapter {
99
110
  /**
100
111
  * Resolve the LLM for this request — the find-similar judge AND the
@@ -141,6 +152,23 @@ export interface HandshakeDecisionAdapter {
141
152
  * these from wherever it keeps a request's presentation facts.
142
153
  */
143
154
  resolveRequestFit?(ctx: HandlerContext): Promise<RequestFitFacts | undefined> | RequestFitFacts | undefined;
155
+ /**
156
+ * ggui#1568 — rows the deployment reserves from the semantic tier for this
157
+ * request: rows that must be reached only by their exact key, never by
158
+ * similarity (an A/B test's arm, served only to the traffic assigned to
159
+ * it, is the first such row). Resolved once per decision and applied to
160
+ * every pool probe. Not asked when `reuseMode` is `'exact-only'`, since
161
+ * the semantic tier is already off.
162
+ *
163
+ * `{ kind: 'rows', keys }` excludes each row named by
164
+ * {@link semanticExclusionKey}. `{ kind: 'all', reason }` turns the
165
+ * semantic tier off for this request: the answer when the deployment
166
+ * cannot say which rows are reserved. It must never answer an empty set it
167
+ * has not read. A hook that throws an operational error is read as
168
+ * `'all'` and reported through `warn`. A programmer error (TypeError and
169
+ * kin) is rethrown, as for every hook here. Absent ⇒ nothing is reserved.
170
+ */
171
+ readonly semanticExclusion?: (ctx: HandlerContext) => Promise<SemanticExclusion> | SemanticExclusion;
144
172
  /**
145
173
  * Optional deployment-specific pre-match, run BEFORE the find-similar
146
174
  * probe so a curated / byte-exact hit wins over everything — e.g. a
@@ -1 +1 @@
1
- {"version":3,"file":"decide-handshake.d.ts","sourceRoot":"","sources":["../../src/renders/decide-handshake.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"decide-handshake.d.ts","sourceRoot":"","sources":["../../src/renders/decide-handshake.ts"],"names":[],"mappings":"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"}
@@ -88,7 +88,8 @@ function coverageHasGap(gap) {
88
88
  gap.props.length > 0 ||
89
89
  gap.context.length > 0 ||
90
90
  gap.streams.length > 0 ||
91
- gap.gadgets.length > 0);
91
+ gap.gadgets.length > 0 ||
92
+ gap.actionMembers.length > 0);
92
93
  }
93
94
  /**
94
95
  * Project a coverage gap into `severity:'warn'` validation findings — one
@@ -127,6 +128,19 @@ function coverageGapFindings(gap, request) {
127
128
  push('context', 'contextSpec');
128
129
  push('streams', 'streamSpec');
129
130
  push('gadgets', 'gadgets');
131
+ // ggui#1428 — a shared action whose stored entry lacks a load-bearing
132
+ // member the draft declares: the served card will not behave that way.
133
+ for (const entry of gap.actionMembers) {
134
+ const dot = entry.lastIndexOf('.');
135
+ const name = entry.slice(0, dot);
136
+ const member = entry.slice(dot + 1);
137
+ findings.push({
138
+ code: COVERAGE_GAP_CODE,
139
+ severity: 'warn',
140
+ path: `actionSpec.${entry}`,
141
+ message: `the proposed cached UI declares action '${name}' without the \`${member}\` your draft declares, so the served card will not carry that behaviour. Default to ACCEPT (reuse-and-refine) — override only if the user or your flow depends on it.`,
142
+ });
143
+ }
130
144
  return findings;
131
145
  }
132
146
  /** Stable code for the VARIANCE_GAP warn finding on a variance-divergent reuse. */
@@ -402,6 +416,29 @@ export async function decideHandshake(adapter, input) {
402
416
  // ggui#607 — resolve the reuse policy once; 'exact-only' threads
403
417
  // disableSemantic into every pool probe below.
404
418
  const reuseMode = adapter.reuseMode ? await adapter.reuseMode(ctx) : 'full';
419
+ // ggui#1568 — the reserved rows, resolved once. An operational failure
420
+ // reads as 'all': the tier stays off rather than offering a reserved row.
421
+ let exclusion;
422
+ if (reuseMode === 'full' && adapter.semanticExclusion) {
423
+ try {
424
+ exclusion = await adapter.semanticExclusion(ctx);
425
+ }
426
+ catch (err) {
427
+ if (!isOperationalError(err))
428
+ throw err;
429
+ exclusion = { kind: 'all', reason: `semanticExclusion threw: ${errMessage(err)}` };
430
+ }
431
+ if (exclusion.kind === 'all') {
432
+ adapter.warn?.(`[decideHandshake] semantic tier off for this request, the reserved rows are unknown: ${exclusion.reason}`);
433
+ }
434
+ }
435
+ const probeOptions = reuseMode === 'exact-only'
436
+ ? { disableSemantic: true }
437
+ : exclusion?.kind === 'all'
438
+ ? { disableSemantic: true, disableSemanticCause: 'exclusion-unavailable' }
439
+ : exclusion?.kind === 'rows'
440
+ ? { excludeFromSemantic: exclusion.keys }
441
+ : undefined;
405
442
  // ggui#1427 — the request's fit facts, resolved once for every pool probe.
406
443
  const requestFit = adapter.resolveRequestFit ? await adapter.resolveRequestFit(ctx) : undefined;
407
444
  // The requesting agent's declared MCP tools (a set keyed by bare
@@ -442,9 +479,7 @@ export async function decideHandshake(adapter, input) {
442
479
  contract: parsedDraft.data,
443
480
  ...(variance !== undefined ? { variance } : {}),
444
481
  ...(requestFit !== undefined ? { fit: requestFit } : {}),
445
- }, ...(reuseMode === 'exact-only'
446
- ? [{ disableSemantic: true }]
447
- : []));
482
+ }, ...(probeOptions !== undefined ? [probeOptions] : []));
448
483
  // Isolated in its OWN try/catch, separate from the outer
449
484
  // pool-probe catch below: onBlueprintMatch's contract promises
450
485
  // non-blocking observation, so a throwing observer must never
@@ -1,5 +1,5 @@
1
1
  import { type VectorStore } from '@ggui-ai/mcp-server-core';
2
- import { type BlueprintSource, type DataContract, type BlueprintVariance } from '@ggui-ai/protocol';
2
+ import { type BlueprintSource, type DataContract, type BlueprintVariance, type GeneratorBuild } from '@ggui-ai/protocol';
3
3
  export interface ExportableBlueprint {
4
4
  readonly contract: DataContract;
5
5
  readonly componentCode: string;
@@ -19,6 +19,13 @@ export interface ExportableBlueprint {
19
19
  * artifactId fallback — useless prose for semantic matching.
20
20
  */
21
21
  readonly intent?: string;
22
+ /**
23
+ * ggui#1476 — the minting engine's build, when the row carries one, so
24
+ * the export codec (`toPortableBlueprint`) ships the portable
25
+ * blueprint's `build`. Read through the registry's one reader of the
26
+ * key; an unreadable stored value is absent.
27
+ */
28
+ readonly build?: GeneratorBuild;
22
29
  }
23
30
  /**
24
31
  * Enumerate every reusable TEMPLATE blueprint stored under `scope` in a
@@ -1 +1 @@
1
- {"version":3,"file":"export-registry.d.ts","sourceRoot":"","sources":["../../src/renders/export-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CA+CzC"}
1
+ {"version":3,"file":"export-registry.d.ts","sourceRoot":"","sources":["../../src/renders/export-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,WAAW,EACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAG3B,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC;IAChC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC;;;;;;OAMG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,+BAA+B,CACnD,WAAW,EAAE,WAAW,EACxB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAiDzC"}