@wildo-ai/platform-core-shared 1.1.0 → 1.1.2

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 (51) hide show
  1. package/dist/esm/index.d.ts +7 -0
  2. package/dist/esm/index.d.ts.map +1 -1
  3. package/dist/esm/index.js +7 -0
  4. package/dist/esm/index.js.map +1 -1
  5. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.d.ts +3 -3
  6. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.d.ts.map +1 -1
  7. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.js +39 -8
  8. package/dist/esm/wildo-application-executions/wildo-application-executions.custom.shared.resources-config.schemas.js.map +1 -1
  9. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.d.ts +4 -3
  10. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.d.ts.map +1 -1
  11. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.js +37 -6
  12. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.resources-config.schemas.js.map +1 -1
  13. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.d.ts +1 -0
  14. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.d.ts.map +1 -1
  15. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.js +13 -0
  16. package/dist/esm/wildo-application-tasks/wildo-application-tasks.custom.shared.schemas.js.map +1 -1
  17. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.d.ts +100 -0
  18. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.d.ts.map +1 -0
  19. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.js +578 -0
  20. package/dist/esm/workbench/workbench-aspect-resources.custom.shared.schemas.js.map +1 -0
  21. package/dist/esm/workbench/workbench-creation-board.custom.shared.schemas.d.ts +98 -0
  22. package/dist/esm/workbench/workbench-creation-board.custom.shared.schemas.d.ts.map +1 -0
  23. package/dist/esm/workbench/workbench-creation-board.custom.shared.schemas.js +86 -0
  24. package/dist/esm/workbench/workbench-creation-board.custom.shared.schemas.js.map +1 -0
  25. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.d.ts +157 -0
  26. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.d.ts.map +1 -0
  27. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.js +258 -0
  28. package/dist/esm/workbench/workbench-creation-plane.custom.shared.resources-config.schemas.js.map +1 -0
  29. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.d.ts +221 -0
  30. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.d.ts.map +1 -0
  31. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.js +292 -0
  32. package/dist/esm/workbench/workbench-creation-plane.custom.shared.schemas.js.map +1 -0
  33. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.d.ts +48 -0
  34. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.d.ts.map +1 -0
  35. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.js +48 -0
  36. package/dist/esm/workbench/workbench-domain-model.custom.shared.schemas.js.map +1 -0
  37. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.d.ts +146 -6
  38. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.d.ts.map +1 -1
  39. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.js +256 -8
  40. package/dist/esm/workbench/workbench-resources-types.custom.shared.schemas.js.map +1 -1
  41. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.d.ts +280 -55
  42. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.d.ts.map +1 -1
  43. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.js +191 -85
  44. package/dist/esm/workbench/workbench-resources.custom.shared.resources-config.schemas.js.map +1 -1
  45. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.d.ts +227 -49
  46. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.d.ts.map +1 -1
  47. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.js +466 -78
  48. package/dist/esm/workbench/workbench-resources.custom.shared.schemas.js.map +1 -1
  49. package/dist/tsconfig.build.tsbuildinfo +1 -1
  50. package/package.json +4 -5
  51. package/dist/esm/.builder.pid +0 -9
@@ -1 +1 @@
1
- {"version":3,"file":"workbench-resources.custom.shared.schemas.js","sourceRoot":"","sources":["../../../../src/workbench/workbench-resources.custom.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE7D,iBAAiB,CAAC,CAAC,CAAC,CAAC;AAErB;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,CAAC,MAAM,CAAC;IACzD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,cAAc,EAAE;IAC3D;;;;;;OAMG;IACH,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,cAAc,EAAE;IACnD;;;;;;;;;;;OAWG;IACH,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;IAClC;;;;;;;OAOG;IACH,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QAC9B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;KACtC,CAAC,CAAC;CACJ,CAAC,CAAC;AAIH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,CAAC,MAAM,qCAAqC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5D;;;;;;;;;;;;;;OAcG;IACH,+BAA+B,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,EAAE;IACjE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE;IACjD,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE;IACjD,2EAA2E;IAC3E,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/B,8FAA8F;IAC9F,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE;IAC1C,mEAAmE;IACnE,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,yBAAyB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;IAC3B,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;IACvB,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE;IACvB,8FAA8F;IAC9F,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\nimport { initZodDecorators } from '@wildo-ai/zod-decorators';\n\ninitZodDecorators(z);\n\n/**\n * An application's shared MODULE and the resources it owns — derived, never stored.\n *\n * The first resource backed by `PersistenceAdapter.INTROSPECTION`. Rows come from the companion's\n * `resource-specifications` behavior, whose `moduleOwnership` is exactly this shape\n * (`{ moduleId, resourceTypes }`), so nothing is reshaped on the way through: the binding names the\n * behavior and the path, and the schema describes what that behavior already answers.\n *\n * ## Why `moduleId` is the primary key\n *\n * There is no store to mint a surrogate in. A derived row must be identified by something the SOURCE\n * already guarantees unique, and a module id is that by construction — two modules with one id would\n * be a defect in the application, not in this projection.\n */\nexport const Workbench_ApplicationModule_Schema = z.object({\n moduleId: z.string().min(1).isPrimaryKey().isSummaryField(),\n /**\n * The resource types this module registers.\n *\n * A plain string array rather than foreign keys: these name resources in the OBSERVED\n * application's registry, not rows in any store this workbench can reach. Modelling them as\n * relationships would promise a join that cannot exist.\n */\n resourceTypes: z.array(z.string()).isSummaryField(),\n /**\n * `domain` or `engine` — or absent, which an application is free to leave unset.\n *\n * Carried because it is the ONE field that distinguishes a business-domain module from an engine\n * contribution, and the projection used to discard it. Without it a module carrying roles,\n * features, milestones and a product catalog is indistinguishable from a broken empty one.\n *\n * A plain nullable string rather than the `ApplicationModuleKind` union: this is a projection of\n * the OBSERVED application's declaration, which may be built against a different engine revision\n * than the workbench. Binding the union here would make the workbench refuse to display a kind the\n * observed app can legitimately declare — refusing to show exactly the drift it exists to reveal.\n */\n kind: z.string().min(1).nullable(),\n /**\n * What the module contributes, and how much of each.\n *\n * DERIVED from the module's own declared keys rather than from a fixed list, so a contribution\n * kind added to `SharedSaaSModule` appears here without a schema or projection change. Counts\n * rather than content: an inventory answers whether and how much, and the content belongs to\n * whichever behavior projects that contribution specifically.\n */\n contributions: z.array(z.object({\n contribution: z.string().min(1),\n count: z.number().int().nonnegative(),\n })),\n});\n\nexport type Workbench_ApplicationModule = z.infer<typeof Workbench_ApplicationModule_Schema>;\n\n/**\n * One relationship edge between two of the observed application's resources.\n *\n * ## Where the shape comes from\n *\n * MEASURED against a live `resources-registry` derivation rather than transcribed from the engine's\n * `ResourceRelationship` type: 16 edges, 12 keys present on all of them and `primaryScope` on 8. The\n * engine type carries more than the behavior emits, and a schema written from the type would refuse\n * every row for fields the projection never sends.\n *\n * ## Why the vocabularies are plain strings here\n *\n * `nature`, `cardinality*` and `accessScopeStrategy` ARE closed engine enums, and this is one of the\n * documented exceptions rather than an oversight: these rows cross a subprocess boundary as JSON\n * from the OBSERVED application's registry, which may be built against a different engine revision\n * than the workbench. Binding to the enum would make a row the observed app can legitimately produce\n * unparseable here — the workbench would refuse to show exactly the drift it exists to reveal. This\n * is a projection of someone else's runtime, not an authored value the framework controls.\n *\n * `resolvedSemantics` is deliberately ABSENT. It is a deep nested object (handling modes, foreign-key\n * persistence) that no current view reads, and copying it into the schema would freeze a shape whose\n * consumer does not exist yet.\n */\nexport const Workbench_ResourceRelationship_Schema = z.object({\n /**\n * Composed by the introspection source from the binding's `identityFields`, because a relationship\n * row carries no identifier of its own — see `IntrospectionResourceBinding.identityFields`.\n *\n * ## Why this is named for the resource rather than `relationshipId`\n *\n * A COMPOSED identity is written to the resource's own `resourceFieldIdentifier`. That is the one\n * name the source can resolve from the registry without introspecting decorators — the schema's\n * `.isPrimaryKey()` marker is not readable as a field NAME from the built configuration, and\n * duplicating the name onto the binding would create a second declaration that can disagree.\n *\n * Its sibling `workbenchApplicationModules` names its key `moduleId` instead, and the difference\n * is real rather than inconsistent: that behavior's rows arrive carrying `moduleId`, so nothing is\n * composed and the schema is free to keep the source's own name.\n */\n workbenchResourceRelationshipId: z.string().min(1).isPrimaryKey(),\n resourceType1: z.string().min(1).isSummaryField(),\n resourceType2: z.string().min(1).isSummaryField(),\n /** `one` / `many`, as the observed application's registry reports them. */\n cardinality1: z.string().min(1),\n cardinality2: z.string().min(1),\n /** `composition`, `aggregation`, `reference`, … — the observed app's vocabulary, not ours. */\n nature: z.string().min(1).isSummaryField(),\n /** The field carrying the join. Present on every measured edge. */\n foreignKeyField: z.string().min(1),\n accessScopeStrategy: z.string().min(1),\n parentResourceRequirement: z.string().min(1),\n isPrimaryScope: z.boolean(),\n allowCycle: z.boolean(),\n isDisabled: z.boolean(),\n /** Present on 8 of 16 measured edges — optional because the projection genuinely omits it. */\n primaryScope: z.string().min(1).optional(),\n});\n\nexport type Workbench_ResourceRelationship = z.infer<typeof Workbench_ResourceRelationship_Schema>;\n\n"]}
1
+ {"version":3,"file":"workbench-resources.custom.shared.schemas.js","sourceRoot":"","sources":["../../../../src/workbench/workbench-resources.custom.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { z } from 'zod';\nimport { initZodDecorators } from '@wildo-ai/zod-decorators';\n\ninitZodDecorators(z);\n\n\n/**\n * One relationship, as it rides on BOTH resources it joins.\n *\n * ## Why an edge appears on two rows rather than on one\n *\n * A relationship genuinely IS a property of both resources — \"what is `deals` related to?\" is a\n * question about `deals` and about everything `deals` touches — so carrying it on both is a\n * statement of what it means, not an encoding chosen to fit a row shape. Hanging every edge off one\n * arbitrarily-chosen endpoint would be the encoding, and the choice would have to be re-derived by\n * every reader.\n *\n * The consumer draws each edge once, keyed by {@link relationshipId}. The duplication costs one extra\n * copy of a small object per edge and buys a row that is complete on its own.\n *\n * ## Why the vocabularies are plain strings\n *\n * These values cross a subprocess boundary from the OBSERVED application's registry, which may be\n * built against a different engine revision than the workbench. Binding `nature` or the cardinalities to the engine enums would make a\n * row the observed application can legitimately produce unparseable here — the workbench refusing to\n * show exactly the drift it exists to reveal.\n */\nexport const Workbench_DomainResourceRelationship_Schema = z.object({\n /**\n * Stable identity for ONE edge within this projection, composed from every field carried about it.\n *\n * NOT the `resourceType1__resourceType2__foreignKeyField` triple the retired\n * `workbenchResourceRelationships` resource addressed a row by: that triple is not total here,\n * because a MANY-to-MANY edge carries\n * `jointResourceType` and no `foreignKeyField`. Two edges agreeing on every field below are\n * indistinguishable to a graph, so merging them loses nothing a reader could have seen.\n */\n relationshipId: z.string().min(1),\n resourceType1: z.string().min(1),\n resourceType2: z.string().min(1),\n cardinality1: z.string().min(1),\n cardinality2: z.string().min(1),\n /**\n * `composition`, `reference` or `association` — every member `RelationshipNature` declares — kept as\n * a plain string for the drift-tolerance reason above, not because a fourth one exists today.\n */\n nature: z.string().min(1),\n /** The field carrying the join. Absent on a junction-backed MANY-to-MANY, which has no FK column. */\n foreignKeyField: z.string().min(1).nullable(),\n /**\n * Which side's rows CARRY the foreign key — the direction an arrow must point.\n *\n * Resolved by the framework's own `resolveForeignKeyHolderResourceType`, from CARDINALITY, never\n * from declaration order: `(TODOS, USERS, MANY, ONE, { foreignKeyField })` is a valid child-first\n * declaration that puts the referenced resource in `resourceType2`, so a consumer reading position\n * draws half its arrows backwards.\n */\n foreignKeyHolderResourceType: z.string().min(1),\n /** The junction resource of a MANY-to-MANY, which the framework requires such an edge to name. */\n jointResourceType: z.string().min(1).nullable(),\n /** Whether this edge is the structural ownership anchor giving `resourceType2` its scope. */\n isPrimaryScope: z.boolean(),\n /**\n * Whether the edge is DECLARED BUT INACTIVE.\n *\n * The one field here whose absence made the graph WRONG rather than thinner: a disabled edge\n * constrains nothing at runtime, so drawing it like a live one tells a reader the application has\n * a relationship it does not have. Carried even though the dogfood application disables none\n * (measured 2026-08-31: 0 of 16) — a field that is uniformly `false` today is exactly the one that\n * silently misleads the first time it is not.\n */\n isDisabled: z.boolean(),\n /**\n * How a caller reaches rows on the far side — `requires_context`, `standalone`, and whatever else\n * the observed application's engine revision declares.\n *\n * A plain string for the same drift-tolerance reason `nature` is one.\n */\n accessScopeStrategy: z.string().min(1).nullable(),\n /** Whether the parent endpoint is `mandatory` or `optional` for the child's addressing. */\n parentResourceRequirement: z.string().min(1).nullable(),\n /**\n * WHICH resource this edge anchors scope to, when it anchors one.\n *\n * Not derivable from {@link isPrimaryScope}, which says only THAT it anchors. On an edge whose\n * endpoints are both scoped, the two answer different questions.\n */\n primaryScope: z.string().min(1).nullable(),\n /** Whether a cycle through this edge is permitted — a graph-shape fact a graph should be able to show. */\n allowCycle: z.boolean(),\n});\n\nexport type Workbench_DomainResourceRelationship = z.infer<typeof Workbench_DomainResourceRelationship_Schema>;\n\n/**\n * ONE resource of the observed application's domain model — node, module membership, specification\n * and edges in a single row.\n *\n * ## Why every field is a summary field\n *\n * A LIST renders the SUMMARY projection, and this resource's list IS its whole purpose: the graph\n * consumes the collection. A field left out of the summary is a field the graph cannot draw, and the\n * omission is silent — the row arrives, the field is simply absent. So the summary here is the full\n * row by design rather than by neglect.\n *\n * ## Why this is one row per RESOURCE rather than one row per module or one row for the graph\n *\n * Edges are resource-to-resource. A module-per-node projection would have to AGGREGATE them, which\n * destroys precisely the meanings the framework refuses to merge — nature, cardinality, foreign-key\n * direction — and a graph that draws every edge as one grey line has lost information the flat table\n * at least preserved.\n */\nexport const Workbench_DomainResource_Schema = z.object({\n /**\n * Composed by the introspection source from the binding's `identityFields` (`['resourceType']`).\n *\n * `.isSummaryField()` on the IDENTITY field is load-bearing rather than cosmetic: the projection a\n * list renders is the summary, and a row with no id is a row nothing can address — the failure that\n * made every relationship row unclickable before its id was marked.\n */\n workbenchDomainResourceId: z.string().min(1).isPrimaryKey().isSummaryField(),\n resourceType: z.string().min(1).isSummaryField(),\n /**\n * The module that registers this resource, or `null`.\n *\n * `null` is a FACT, not a gap: no module of the observed application owns this resource, which is\n * true of every ENGINE resource — and an application merges all of them, since `initializeResources`\n * applies the engine's core factory map unconditionally and both registries merge it. They are\n * carried rather than dropped because they are part of the running application, and because an edge\n * to the resource that gives a row its tenant scope is the most load-bearing edge in the graph.\n *\n * No `origin` field restates this. The absence of a module IS the distinction, and a second field\n * saying the same thing is a second thing that can disagree with the first.\n */\n moduleId: z.string().min(1).isSummaryField().nullable(),\n /** `domain` or `engine` — the kind the owning module declares, when there is one. */\n moduleKind: z.string().min(1).isSummaryField().nullable(),\n /**\n * Which part of its owner this resource belongs to — a SECOND grouping axis, under the module.\n *\n * Sourced from `ResourceSpecificationConfig.subDomain`. For engine resources that is the closed\n * `EngineResourceSubDomain` vocabulary (`auth`, `billing`, `users`, …), which exists because the\n * engine's 85 resources otherwise arrive as one flat set and every surface that has to present them\n * invents a grouping of its own.\n *\n * A plain `string` here rather than that enum, and deliberately: this schema is shared by a\n * workbench that observes an application whose own sub-domains it cannot enumerate. Pinning the\n * engine's vocabulary here would make an application's value invalid at the wire.\n *\n * `null` means the resource specification declares none — an application resource today, or an engine\n * resource with no spec at all. A consumer grouping by this must carry an \"unclassified\" bucket and\n * say so, rather than folding those rows into a real group.\n */\n subDomain: z.string().min(1).isSummaryField().nullable(),\n /**\n * Every field of the materialized `mainSchema`, with everything the framework knows about it.\n *\n * This replaced a bare `fieldNames: string[]`, whose JSDoc argued that \"a domain-model panel\n * answers what a resource HOLDS\" and that per-field extraction \"belongs to `resource-specifications`\".\n * The premise was right and the conclusion aged badly: a NAME answers \"does this field exist\",\n * which the node already implies by counting them, and a reader who opens a resource wants what\n * the field IS. The cost was then MEASURED rather than assumed — 715 fields across the 82 engine\n * resources extract to 264 KB, a fraction of what the relationship edges already cost — so the\n * reason to withhold it was gone.\n *\n * `params`, `derived` and `origin` are OPAQUE records on purpose. They are the extractor's own\n * output — authored spec prose, framework-derived structure, base-vs-variant provenance — and each\n * is an open shape that grows with the decorators. Restating them field by field here would make\n * this schema a second, always-lagging copy of a contract `@wildo-ai/saas-specifications` owns;\n * a consumer that needs one reads it through that package's type.\n */\n fields: z.array(z.object({\n fieldName: z.string().min(1),\n /** Which `{primitive}Spec()` decorator carried the authored prose, when one did. */\n specDecorator: z.string().min(1).nullable(),\n params: z.record(z.string(), z.unknown()).nullable(),\n derived: z.record(z.string(), z.unknown()).nullable(),\n origin: z.record(z.string(), z.unknown()).nullable(),\n /**\n * The field's DECORATOR record, as the schema declares it — beside `derived`, which is the\n * extractor's interpretation of it.\n *\n * It carries what the interpretation drops: `isSummaryField`, `isHidden`, `excludeFromCreate` /\n * `excludeFromUpdate`, `dataCategories`, and the index / unique / primary-key trio.\n *\n * It does NOT carry `*.ui-behavior.tsx` configuration, and that is a reachability limit rather\n * than an omission: those decorators are applied by a FRONTEND module the companion never loads,\n * because the subprocess resolves `library`, `specifications` and `service` targets and there is\n * no frontend one. Measured on the engine's resources — zero UI keys present.\n */\n metadata: z.record(z.string(), z.unknown()).nullable(),\n })).isSummaryField(),\n /**\n * Every operation the resource declares, projected to what a READER needs.\n *\n * Never the DTOs. A materialized operation carries six Zod schemas — request, response, summary,\n * context, internal, repository — each serializing to tens of kilobytes, so carrying the operation\n * objects would put megabytes on the wire to say which verbs exist. What is here is the identity,\n * the variant, the authorization and the flags that change what the operation DOES.\n *\n * An EMPTY `roles` array is a real answer — no role gate on that variant — and not a gap.\n */\n operations: z.array(z.object({\n operationIdentifier: z.string().min(1),\n /** The TRANSPORT kind: `api_call`, `internal_call`, `repository_only`, … */\n variantType: z.string().min(1).nullable(),\n /**\n * WHICH variant of that transport — `admin`, `summary`, `context` — or `null` for the default.\n *\n * The missing half of an operation's IDENTITY, and its absence was a defect rather than missing\n * detail: `organizations` declares four operations that are all `read` × `api_call`, separated\n * only by this key, and across the engine's core map 133 of 794 operations collided on the pair\n * without it.\n */\n variantKey: z.string().min(1).nullable(),\n /** For a CUSTOM operation, the core verb it behaves like. `null` for a core operation. */\n resourceOperationLike: z.string().min(1).nullable(),\n isDefault: z.boolean(),\n roles: z.array(z.string()),\n riskLevel: z.string().min(1).nullable(),\n isUnimplemented: z.boolean(),\n isDisabled: z.boolean(),\n requiresStepUpAuthentication: z.boolean(),\n admitsCrossTenantPlatformAdministration: z.boolean(),\n auditableEventType: z.string().min(1).nullable(),\n isMcpExposed: z.boolean(),\n requiredFeatures: z.array(z.string()),\n /**\n * Everything else the operation declares — HTTP verb, runtime mode, bulk and API-key posture,\n * notification fan-out, custom-implementation modes, authoritative fields.\n *\n * A DENY LIST over the operation's own keys on the producing side, for the same reason `advanced`\n * is, and this is the one that proved the argument: a hand-picked set of twelve fields shipped\n * without `variantKey`, `httpVerb`, `isBulkOperation` or `serviceRuntimeMode`. The six DTO\n * schemas are excluded by name — each serializes to tens of kilobytes.\n */\n attributes: z.record(z.string(), z.unknown()),\n /**\n * The authored specification for this operation, keyed by `operationIdentifier` — so every\n * VARIANT of one verb carries the same entry, which is what the specification describes.\n *\n * `null` means the specification does not mention the operation: a gap a reader can act on.\n */\n specification: z.record(z.string(), z.unknown()).nullable(),\n /** The authored `frontend.views` overlay for this operation, when there is one. */\n view: z.record(z.string(), z.unknown()).nullable(),\n })).isSummaryField(),\n /**\n * The operations for which the resource specification declares a FRONTEND view overlay (`frontend.views`).\n *\n * Refs only. The entries are authoring prose about how an operation surfaces, which belongs to a\n * specification reader; what a domain-model panel can act on is which operations have an authored\n * view and — by difference with `operations` — which do not.\n */\n viewRefs: z.array(z.string()).isSummaryField(),\n /**\n * The configuration facts that are neither prose nor structure — persistence, policy, bindings.\n *\n * Everything on the resource's `ResourceConfiguration` that decides how it BEHAVES rather than what\n * it holds: which database it lives in, whether it is a system resource, its retention,\n * transposition, portability and data-subject policies, its HTTP and introspection bindings.\n *\n * An OPAQUE record, and deliberately so. The producer builds it by DENY list over the\n * configuration's own keys rather than by enumerating the ones that exist today, because\n * `ResourceConfiguration` has grown several of these fields in as many months and an enumeration\n * reports the subset its author knew about. Typing it here would put that enumeration back.\n */\n advanced: z.record(z.string(), z.unknown()).isSummaryField(),\n /**\n * The authored specification's PROSE, or `null` when this resource has none.\n *\n * It rides in the row rather than being fetched on selection because a per-selection fetch is not\n * cheaper: `deriveRows` has no per-row path, so an addressed READ derives the WHOLE set and filters\n * it afterwards. \"Fetch the specification when a node is clicked\" would therefore be a second full\n * derivation of the entire application.\n */\n specification: z.object({\n /** Why this resource exists in the domain. */\n purpose: z.string(),\n /** The functional role it plays inside the business architecture. */\n businessRole: z.string(),\n /** How it evolves over time. Optional in the specification contract, so nullable here. */\n lifecycleRole: z.string().nullable(),\n /** Domain caveats not encoded structurally elsewhere. */\n businessConstraints: z.array(z.string()),\n }).isSummaryField().nullable(),\n /** Every relationship this resource participates in, on either side. */\n relationships: z.array(Workbench_DomainResourceRelationship_Schema).isSummaryField(),\n});\n\nexport type Workbench_DomainResource = z.infer<typeof Workbench_DomainResource_Schema>;\n\n/**\n * ONE FIELD of a domain resource — named so a consumer can hold one without re-deriving its type.\n *\n * Indexed off the row rather than declared separately, because the schema is the one authority for\n * the shape and a second declaration is a second thing that can drift from it.\n */\nexport type Workbench_DomainResourceField = Workbench_DomainResource['fields'][number];\n\n/** ONE OPERATION of a domain resource — indexed off the row, for the same reason. */\nexport type Workbench_DomainResourceOperation = Workbench_DomainResource['operations'][number];\n\n/**\n * The QUESTION a specification family answers — the axis the workbench groups them by.\n *\n * ## Why the families are grouped at all\n *\n * Fifteen rows in one undifferentiated list is a directory, not a review surface. A creator opening\n * the workbench is not looking for \"the `document-release-policy` family\"; they are looking for what\n * was decided about who this product is for, or about what it must promise. Grouping by the question\n * answered is what makes the list navigable without inventing twelve destinations.\n *\n * ## Why this is a display vocabulary and not a property of the family\n *\n * `ApplicationSpecificationFamilySemanticSchemaRef` names what a family MEANS and what validates it.\n * Nothing in the runtime branches on the concern below — it exists so a reader can find a row. Adding\n * it to the semantic authority would put a workbench presentation choice inside the contract the\n * journey lands artifacts against.\n *\n * The family → concern mapping deliberately lives with the projection that derives it (the\n * companion's `specification-artifacts` behavior), beside the semantic authority it must stay\n * exhaustive over, rather than here where the authority is not reachable.\n */\nexport enum WorkbenchSpecificationArtifactConcern {\n /** Why the product exists and who it is for — `vision-brief`, `market-snapshot`. */\n INTENT = 'intent',\n /** What it must do and what it costs — `requirements`, `feature-drafts`, `business-model`. */\n SCOPE = 'scope',\n /** How and when it gets built — `domain-plan`, `build-plan`, `roadmap`, `placement-plan`. */\n DELIVERY = 'delivery',\n /** How it presents itself — `brand-brief`. */\n IDENTITY = 'identity',\n /** What it must promise and publish — the assurance and governed-document families. */\n OBLIGATIONS = 'obligations',\n /**\n * A family the workbench has not been taught to group.\n *\n * A named member rather than a throw, and rather than silence. The population is derived from the\n * semantic authority, so a family added there arrives here with no classification — and the two\n * alternatives are both worse than a visible bucket: refusing the derivation would blank the whole\n * page over one unmapped row, and defaulting into a real concern would file the new family\n * somewhere plausible and wrong, which nobody would notice.\n *\n * A companion test asserts this member is currently UNUSED, so it stays a signal rather than\n * becoming a habit.\n */\n UNCLASSIFIED = 'unclassified',\n}\n\n/**\n * Whether a family has landed, and whether what landed still validates.\n *\n * THREE states, not two, because \"not landed\" and \"landed but invalid\" are the opposite instructions\n * to a reviewer: the first is work the journey has not done, the second is work it did that no longer\n * holds. A boolean `isValid` would report both as `false`.\n */\nexport enum WorkbenchSpecificationArtifactState {\n /** The family is exported by the application and its `_core` validator reports no error. */\n LANDED_VALID = 'landed_valid',\n /** The family is exported and its `_core` validator reports at least one ERROR-severity issue. */\n LANDED_INVALID = 'landed_invalid',\n /**\n * The application exports nothing for this family.\n *\n * Reported as a ROW rather than omitted — the same call `definition-specifications.behavior.ts`\n * makes for the same reason: *\"an omitted row and a family that does not exist would look the same\n * to the reader.\"* On a fresh application an empty list would say nothing; fifteen NOT_LANDED rows\n * say what the journey has left to produce.\n */\n NOT_LANDED = 'not_landed',\n}\n\n/**\n * ONE application-specification family, projected for a human reviewer.\n *\n * ## Why the prose fields are markdown strings\n *\n * `StringDisplayMode.MARKDOWN` renders GFM through the framework's own display chrome, which is what\n * lets headings, lists and paragraphs survive into the page. The alternative — modelling each\n * family's shape as nested schema fields — would have to be done fifteen times, would freeze twelve\n * `_core` contracts into this projection, and would still render as a form rather than as a document.\n *\n * The rendering is an OUTLINE, never a table. That is the acceptance criterion this resource exists\n * to satisfy: these artifacts are prose-heavy and their value is in the rationale, so a projection\n * that put them in columns would destroy exactly what makes them worth reviewing.\n *\n * ## Why the heavy fields are NOT summary fields\n *\n * `document`, `issues`, `decisionRecord` and `diagram` are excluded from the summary by omission, so\n * a list carries the INDEX while a detail page carries the documents. One derivation still computes\n * all of them either way — this bounds the RESPONSE, not the work.\n *\n * Which variant a caller gets matters, and is easy to state wrongly: the LIST operation's DEFAULT\n * variant answers the full row, and it is the operation's `summary` variant that applies this\n * projection. Measured against the live wonder-crm companion, 2026-08-31:\n * `GET /api/v1/workbench-specification-artifacts` → **149,089 B**, and\n * `…/workbench-specification-artifacts/summary` → **3,654 B** carrying the eight fields marked\n * below. A list layout renders the summary variant — which is also why the addressing field must be\n * marked, or every row in that list is unclickable.\n */\nexport const Workbench_SpecificationArtifact_Schema = z.object({\n /**\n * The family id — `vision-brief`, `market-snapshot`, `compliance-program`.\n *\n * The source's own key, marked `.isSummaryField()` because a list row with no id is a row nothing\n * can address: the summary projection is what a click reads the target from.\n */\n family: z.string().min(1).isPrimaryKey().isSummaryField(),\n /** The family's name in a creator's words — `Vision`, `Market`, `Assurance programme`. */\n title: z.string().min(1).isSummaryField(),\n /**\n * What this family IS, in one sentence a creator recognizes — static per family, present whether\n * or not anything landed. This is the summary card's subtitle: a card reading only\n * \"Governed-document drafts · Not landed\" tells a reader nothing they can act on; \"The drafts of\n * the public documents this product must publish\" does.\n */\n description: z.string().min(1).isSummaryField(),\n /**\n * A one-line PULSE of the landed content — `\"3 ICPs · 5 personas · 2 positionings\"`, the vision's\n * own one-liner — or `null` when the family has not landed.\n *\n * Derived server-side from the RAW value so the list answers \"how much is in there\" without any\n * client downloading fifteen full documents. It is a COUNT-and-headline summary, never a\n * truncation of prose: a clipped sentence reads as an accident, a count reads as an answer.\n */\n contentSummary: z.string().nullable().isSummaryField(),\n /** The question this family answers, which is the axis the list groups by. */\n concern: z.enum(WorkbenchSpecificationArtifactConcern).isSummaryField(),\n /** Landed and valid, landed and invalid, or not landed at all. */\n state: z.enum(WorkbenchSpecificationArtifactState).isSummaryField(),\n /** The `_core` contract the family's content must satisfy, verbatim from the semantic authority. */\n schemaRef: z.string().min(1),\n /**\n * Where the family's file lives, relative to the application root — the file a reader opens when\n * the rendering is not enough.\n *\n * `null` when this runtime places no file for the family. A placement and a RENDER PROFILE are\n * different things (`playbook-output-landing-target`), and only the placement is asked for here.\n */\n sourcePath: z.string().min(1).nullable().isSummaryField(),\n /** ERROR-severity issues the family's own validator reports on the landed content, right now. */\n errorCount: z.number().int().nonnegative().isSummaryField(),\n /** WARN-severity issues — authoring drift that does not invalidate the artifact. */\n warnCount: z.number().int().nonnegative().isSummaryField(),\n /**\n * Every playbook whose declared `outputs[].family` is this family.\n *\n * This is the durable half of \"what produced it\": a fact about the compiled catalog, in git, true\n * whether or not any run's state survives. A link to the RUN that produced this particular value\n * was deliberately rejected — runs, traces and the write register are a per-run cache under\n * `one-source-of-truth.md` Rule 5, so a durable artifact pointing into deletable state is dangling\n * by design. The link runs the other way: a run may name what it wrote.\n *\n * Empty for a family no playbook produces — which is a finding, not a gap.\n */\n producedByPlaybookRefs: z.array(z.string()).isSummaryField(),\n /**\n * The landed family value, RAW — exactly the object the specifications package exports.\n *\n * ## Why the raw value rides beside its rendering\n *\n * The per-family display templates (workbench `artifact-templates/`) render EDITORIALLY — an ICP\n * card, a requirement with its acceptance criteria, a placement decision with its rationale — and\n * an editorial template needs the VALUE, not a markdown projection of it. The markdown `document`\n * below stays: it is the structural fallback every family keeps behind the template error\n * boundary, and the whole rendering for a family no template covers yet.\n *\n * ## Untyped HERE, typed at the EDGE — a measured decision, not an omission\n *\n * The typed `_core` snapshot schemas live in `@wildo-ai/saas-specifications`, which depends on\n * `saas-frontend-lib` AND `saas-backend-lib` (its package.json) — while this package is the\n * platform's light contracts-only spine (`platform/CLAUDE.md`). Typing this field would drag the\n * whole engine into every consumer of this package for a shape only two consumers read. The two\n * readers type it themselves: the companion behavior validates through the semantic authority\n * before emitting, and the workbench templates narrow via TYPE-ONLY imports (erased at compile,\n * zero runtime dependency). Recorded with alternatives in\n * `.claude/plans/workbench-product-artifacts-ux-analysis.md` (D1).\n *\n * Deliberately NOT a summary field: the LIST carries the index, and this is the heaviest thing a\n * row owns. Emitted from the RAW landed value — never from a validator's parsed output, whose\n * schema `.default()`s would inject content the author never wrote.\n */\n content: z.record(z.string(), z.unknown()).nullable(),\n /**\n * The artifact rendered as a document, or `null` when the family has not landed.\n *\n * Produced by `renderSpecificationFamilyReviewDocument` — an outline over the landed value, not a\n * prompt block. The prompt renderers (`market-render-prompt`, `brand-render-prompt`) read the same\n * content for a language model and must never be reused here.\n */\n document: z.string().nullable(),\n /**\n * The validator's own findings, rendered for a reader, or `null` when there are none.\n *\n * Carried as content rather than as counts alone because a reviewer deciding whether to accept an\n * artifact needs to see WHICH rule failed and where, and the counts beside them in the list are\n * only the signal to come and look.\n */\n issues: z.string().nullable(),\n /**\n * `DECISIONS.md` committed beside the family, verbatim, or `null` when there is none.\n *\n * The strongest provenance this surface has: it names the playbook that produced the artifact and,\n * more importantly, records every question the creator was asked — including the ones they did NOT\n * answer, where \"the derivation chose for itself\". A run that asked nothing writes no such file, so\n * `null` here means \"no clarification was recorded\", never \"no clarification happened\".\n */\n decisionRecord: z.string().nullable(),\n /**\n * `DIAGRAM.md` committed beside the family, verbatim, or `null`.\n *\n * Three families have one today (`domain-plan`, `build-plan`, `roadmap`). It is surfaced rather\n * than re-derived: the diagram is already a committed output of the family, regenerated on every\n * landing, and rendering a second picture here would be a second thing that can disagree with it.\n */\n diagram: z.string().nullable(),\n});\n\nexport type Workbench_SpecificationArtifact = z.infer<typeof Workbench_SpecificationArtifact_Schema>;\n"]}