@cratis/pi 7.34.1 → 7.36.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 (229) hide show
  1. package/package/corpus/agents/security-reviewer.md +1 -0
  2. package/package/corpus/agents/spec-writer.md +1 -1
  3. package/package/corpus/harnesses/pi/extensions/shared/rules.ts +3 -1
  4. package/package/corpus/hooks/scripts/cratis-nuget-pins.txt +7 -6
  5. package/package/corpus/hooks/scripts/cratis-release-notes-reviewed.cjs +7 -6
  6. package/package/corpus/hooks/scripts/cratis-store-mutations.json +7 -3
  7. package/package/corpus/product-sync.json +896 -0
  8. package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
  9. package/package/corpus/prompts/ship-changes.prompt.md +2 -2
  10. package/package/corpus/rules/ai-distribution.md +31 -3
  11. package/package/corpus/rules/application-profile.md +2 -1
  12. package/package/corpus/rules/components.md +66 -7
  13. package/package/corpus/rules/concepts.md +11 -3
  14. package/package/corpus/rules/csharp.md +3 -1
  15. package/package/corpus/rules/dialogs.md +9 -0
  16. package/package/corpus/rules/efcore.md +1 -1
  17. package/package/corpus/rules/elixir.md +49 -0
  18. package/package/corpus/rules/framework.md +5 -3
  19. package/package/corpus/rules/general.md +1 -0
  20. package/package/corpus/rules/glossary.md +4 -4
  21. package/package/corpus/rules/go-engineering.md +60 -0
  22. package/package/corpus/rules/go.md +115 -0
  23. package/package/corpus/rules/java.md +5 -2
  24. package/package/corpus/rules/kotlin.md +7 -5
  25. package/package/corpus/rules/orleans.md +65 -9
  26. package/package/corpus/rules/profiles.md +43 -6
  27. package/package/corpus/rules/pull-requests.md +3 -3
  28. package/package/corpus/rules/react.md +8 -1
  29. package/package/corpus/rules/reactors.md +27 -3
  30. package/package/corpus/rules/specs.csharp.md +11 -4
  31. package/package/corpus/rules/specs.scenarios.csharp.md +35 -4
  32. package/package/corpus/rules/specs.typescript.md +2 -1
  33. package/package/corpus/rules/storybook.md +1 -1
  34. package/package/corpus/rules/typescript.md +1 -1
  35. package/package/corpus/rules/vertical-slices.md +37 -5
  36. package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -2
  37. package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +18 -8
  38. package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +65 -0
  39. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +53 -57
  40. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +38 -42
  41. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +18 -7
  42. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authproxy.md +30 -0
  43. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +12 -9
  44. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +9 -9
  45. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +8 -5
  46. package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +20 -4
  47. package/package/corpus/skills/cratis-arc-command/SKILL.md +32 -10
  48. package/package/corpus/skills/cratis-arc-command/references/command-result.md +12 -5
  49. package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -0
  50. package/package/corpus/skills/cratis-arc-command/references/generated-values.md +3 -2
  51. package/package/corpus/skills/cratis-arc-command/references/handler-shapes.md +8 -8
  52. package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +22 -3
  53. package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +13 -1
  54. package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +19 -9
  55. package/package/corpus/skills/cratis-arc-command-kotlin/SKILL.md +44 -18
  56. package/package/corpus/skills/cratis-arc-command-kotlin/references/read-model-naming.md +29 -0
  57. package/package/corpus/skills/cratis-arc-command-operation/SKILL.md +10 -9
  58. package/package/corpus/skills/cratis-arc-command-operation/references/execution-and-recovery.md +2 -2
  59. package/package/corpus/skills/cratis-arc-command-operation/references/testing.md +4 -3
  60. package/package/corpus/skills/cratis-arc-command-typescript/SKILL.md +42 -22
  61. package/package/corpus/skills/cratis-arc-command-typescript/references/chronicle-events.md +36 -5
  62. package/package/corpus/skills/cratis-arc-command-typescript/references/command-operations.md +114 -0
  63. package/package/corpus/skills/cratis-arc-command-typescript/references/hosting-and-storage.md +37 -16
  64. package/package/corpus/skills/cratis-arc-command-typescript/references/identity-and-introspection.md +88 -0
  65. package/package/corpus/skills/cratis-arc-command-typescript/references/observability-and-host-scopes.md +25 -0
  66. package/package/corpus/skills/cratis-arc-command-typescript/references/proxy-generation.md +35 -4
  67. package/package/corpus/skills/cratis-arc-command-typescript/references/slice-layout.md +11 -0
  68. package/package/corpus/skills/cratis-arc-command-typescript/verification.json +8 -1
  69. package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +49 -19
  70. package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +12 -6
  71. package/package/corpus/skills/cratis-arc-go/SKILL.md +148 -0
  72. package/package/corpus/skills/cratis-arc-go/references/queries.md +80 -0
  73. package/package/corpus/skills/cratis-arc-hosting/SKILL.md +96 -0
  74. package/package/corpus/skills/cratis-arc-hosting/references/integrations-and-publish.md +80 -0
  75. package/package/corpus/skills/cratis-arc-identity-and-tenancy-kotlin/SKILL.md +137 -0
  76. package/package/corpus/skills/cratis-arc-observable-query-http/SKILL.md +20 -2
  77. package/package/corpus/skills/cratis-arc-query-kotlin/SKILL.md +26 -6
  78. package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +25 -20
  79. package/package/corpus/skills/cratis-arc-query-typescript/SKILL.md +32 -6
  80. package/package/corpus/skills/cratis-arc-query-typescript/references/storage-observation-and-compliance.md +66 -0
  81. package/package/corpus/skills/cratis-arc-query-typescript/verification.json +5 -1
  82. package/package/corpus/skills/cratis-arc-react-page/SKILL.md +24 -13
  83. package/package/corpus/skills/cratis-arc-react-page/references/data-page.md +20 -10
  84. package/package/corpus/skills/cratis-arc-react-page/references/data-tables.md +17 -3
  85. package/package/corpus/skills/cratis-arc-react-page/references/dialogs.md +14 -3
  86. package/package/corpus/skills/cratis-arc-react-page/references/from-screenplay.md +6 -1
  87. package/package/corpus/skills/cratis-arc-react-page/references/provenance.md +1 -1
  88. package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +11 -1
  89. package/package/corpus/skills/cratis-arc-react-page/verification.json +6 -1
  90. package/package/corpus/skills/cratis-arc-spring-data-kotlin/SKILL.md +163 -0
  91. package/package/corpus/skills/cratis-arc-testing-kotlin/SKILL.md +131 -0
  92. package/package/corpus/skills/cratis-arc-validation-kotlin/SKILL.md +44 -11
  93. package/package/corpus/skills/cratis-arc-validation-typescript/SKILL.md +5 -3
  94. package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +79 -25
  95. package/package/corpus/skills/cratis-chronicle-cli-operations/references/command-effects.md +57 -0
  96. package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +87 -99
  97. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/additional-surfaces.md +65 -0
  98. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/client-construction.md +42 -0
  99. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/compatibility-check.md +12 -0
  100. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/discovery.md +43 -19
  101. package/package/corpus/skills/cratis-chronicle-client-dotnet/references/hosting.md +29 -1
  102. package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +158 -162
  103. package/package/corpus/skills/cratis-chronicle-client-elixir/references/append-api.md +36 -15
  104. package/package/corpus/skills/cratis-chronicle-client-elixir/references/compliance.md +32 -0
  105. package/package/corpus/skills/cratis-chronicle-client-elixir/references/connections.md +56 -0
  106. package/package/corpus/skills/cratis-chronicle-client-elixir/references/event-sources.md +64 -0
  107. package/package/corpus/skills/cratis-chronicle-client-elixir/references/pitfalls.md +25 -0
  108. package/package/corpus/skills/cratis-chronicle-client-elixir/references/projections.md +48 -0
  109. package/package/corpus/skills/cratis-chronicle-client-elixir/references/upgrading.md +34 -0
  110. package/package/corpus/skills/cratis-chronicle-client-elixir/references/variants.md +13 -5
  111. package/package/corpus/skills/cratis-chronicle-client-elixir/verification.json +23 -0
  112. package/package/corpus/skills/cratis-chronicle-client-go/SKILL.md +162 -0
  113. package/package/corpus/skills/cratis-chronicle-client-go/references/projections.md +73 -0
  114. package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +87 -88
  115. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/connection-lifecycle.md +13 -0
  116. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/discovery-and-registration.md +14 -4
  117. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/event-sources.md +65 -0
  118. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/options.md +29 -0
  119. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/spring-boot.md +13 -0
  120. package/package/corpus/skills/cratis-chronicle-client-kotlin/references/variants.md +5 -4
  121. package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +165 -156
  122. package/package/corpus/skills/cratis-chronicle-client-typescript/references/read-models-and-projections.md +54 -11
  123. package/package/corpus/skills/cratis-chronicle-client-typescript/references/testing.md +126 -0
  124. package/package/corpus/skills/cratis-chronicle-client-typescript/references/variants.md +3 -5
  125. package/package/corpus/skills/cratis-chronicle-client-typescript/verification.json +19 -0
  126. package/package/corpus/skills/cratis-chronicle-compliance/SKILL.md +36 -13
  127. package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +110 -0
  128. package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +57 -0
  129. package/package/corpus/skills/cratis-chronicle-decision-reads/verification.json +12 -0
  130. package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +58 -19
  131. package/package/corpus/skills/cratis-chronicle-event-constraints/references/closing-streams.md +73 -0
  132. package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +32 -3
  133. package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +18 -5
  134. package/package/corpus/skills/cratis-chronicle-event-type-migration/SKILL.md +32 -2
  135. package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +134 -0
  136. package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +89 -0
  137. package/package/corpus/skills/cratis-chronicle-hosting/verification.json +14 -0
  138. package/package/corpus/skills/cratis-chronicle-mcp-inspection/SKILL.md +93 -66
  139. package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/blocked-tools.md +21 -7
  140. package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/deployment.md +77 -0
  141. package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/observational-tools.md +46 -4
  142. package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +15 -1
  143. package/package/corpus/skills/cratis-chronicle-projection/SKILL.md +44 -10
  144. package/package/corpus/skills/cratis-chronicle-projection/references/fluent-builder.md +7 -1
  145. package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
  146. package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +85 -105
  147. package/package/corpus/skills/cratis-chronicle-reactor/references/specifications.md +20 -1
  148. package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -2
  149. package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +35 -16
  150. package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +15 -3
  151. package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +23 -4
  152. package/package/corpus/skills/cratis-chronicle-web-workbench/SKILL.md +40 -15
  153. package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +20 -6
  154. package/package/corpus/skills/cratis-code-review/SKILL.md +25 -3
  155. package/package/corpus/skills/cratis-components-accessibility/SKILL.md +20 -4
  156. package/package/corpus/skills/cratis-components-schema-editor/SKILL.md +40 -28
  157. package/package/corpus/skills/cratis-components-schema-editor/references/tree-layout.md +62 -0
  158. package/package/corpus/skills/cratis-components-schema-editor/verification.json +14 -0
  159. package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +16 -8
  160. package/package/corpus/skills/cratis-components-styling/SKILL.md +57 -20
  161. package/package/corpus/skills/cratis-components-styling/verification.json +13 -0
  162. package/package/corpus/skills/cratis-components-toolbar/SKILL.md +37 -7
  163. package/package/corpus/skills/cratis-components-toolbar/verification.json +12 -0
  164. package/package/corpus/skills/cratis-engineering-csharp-conventions/SKILL.md +6 -0
  165. package/package/corpus/skills/cratis-engineering-csharp-conventions/references/exceptions-logging-and-di.md +5 -3
  166. package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +19 -6
  167. package/package/corpus/skills/cratis-fundamentals-concept/references/typescript-concepts.md +97 -0
  168. package/package/corpus/skills/cratis-fundamentals-concept/verification.json +4 -1
  169. package/package/corpus/skills/cratis-fundamentals-concept-go/SKILL.md +112 -0
  170. package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +54 -17
  171. package/package/corpus/skills/cratis-fundamentals-type-discovery/verification.json +14 -0
  172. package/package/corpus/skills/cratis-lens-browser-extension/SKILL.md +55 -28
  173. package/package/corpus/skills/cratis-performance-review/SKILL.md +5 -2
  174. package/package/corpus/skills/cratis-release-notes/SKILL.md +3 -1
  175. package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +5 -4
  176. package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +7 -11
  177. package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +26 -6
  178. package/package/corpus/skills/cratis-screenplay-command-surface/references/enum-numbers.md +4 -2
  179. package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +4 -1
  180. package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +7 -1
  181. package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +3 -2
  182. package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +6 -2
  183. package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -0
  184. package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generate-notes.md +34 -4
  185. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +17 -24
  186. package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +1 -1
  187. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +19 -2
  188. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +11 -3
  189. package/package/corpus/skills/cratis-screenplay-model-authoring/references/property-links.md +90 -4
  190. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +19 -2
  191. package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -1
  192. package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +3 -1
  193. package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +48 -0
  194. package/package/corpus/skills/cratis-screenplay-specifications/verification.json +3 -1
  195. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +4 -2
  196. package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +5 -4
  197. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +8 -6
  198. package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +8 -2
  199. package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +4 -2
  200. package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +7 -1
  201. package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +24 -11
  202. package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +10 -4
  203. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1543 -131
  204. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  205. package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +9 -3
  206. package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +23 -7
  207. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +1 -1
  208. package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +2 -0
  209. package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +27 -9
  210. package/package/corpus/skills/cratis-security-review/SKILL.md +9 -3
  211. package/package/corpus/skills/cratis-security-review/references/arc-boundaries.md +59 -0
  212. package/package/corpus/skills/cratis-specification-by-example/SKILL.md +7 -0
  213. package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +43 -11
  214. package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +16 -4
  215. package/package/corpus/skills/cratis-specifications-csharp/references/csharp-patterns.md +18 -5
  216. package/package/corpus/skills/cratis-specifications-csharp/references/integration-specs.md +21 -0
  217. package/package/corpus/skills/cratis-specifications-csharp/references/shared-lifecycle.md +34 -0
  218. package/package/corpus/skills/cratis-specifications-csharp/verification.json +13 -0
  219. package/package/corpus/skills/cratis-specifications-typescript/SKILL.md +14 -5
  220. package/package/corpus/skills/cratis-specifications-typescript/verification.json +12 -0
  221. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +8 -2
  222. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +6 -3
  223. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +10 -1
  224. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/scene-runtime.md +75 -0
  225. package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +5 -0
  226. package/package/corpus/skills/cratis-studio-mcp-safety-guidance/SKILL.md +14 -1
  227. package/package/profile-catalog.json +68 -1
  228. package/package.json +1 -1
  229. package/src/index.ts +3 -1
@@ -16,7 +16,7 @@ Enforce a new rule on an existing command. Invoke the **cratis-arc-command-valid
16
16
  - Reusable value invariant → `ConceptValidator<T>`.
17
17
  - Command-input / cross-field / pre-handler rule → `CommandValidator<T>`.
18
18
  - Handler needs fetched data first → `Provide()`.
19
- - State rule that must hold **under concurrency** → inject the read model into `Handle()`, return `Result<TEvent, ValidationResult>`.
19
+ - State rule that must hold **under concurrency** → enroll a stream decision with `IStreamReads`/`StreamDecision`, or use `[ProtectedDecision]` with an admitted `DecisionRead<T>`; plain read-model injection and `Result<TEvent, ValidationResult>` alone add no guard. Specify the race with `UseDecisionReads()` and seeded events, not pinned models.
20
20
  - Uniqueness → `[Unique]` / `IConstraint`.
21
21
 
22
22
  > **Never throw for normal business rejection** — a throw is HTTP 500, not a validation error. Recoverable rejection is a `ValidationResult` / `Result<,>`. Add a spec for the failure case (assert both not-successful and has-validation-errors). The skill carries the detail; don't duplicate it here.
@@ -45,8 +45,8 @@ The description is published verbatim as the release notes, so it follows the co
45
45
  - No development write-up: no Overview/Verification/Test plan headings (only a first `## Summary`
46
46
  is allowed), no review, testing or provenance notes. Those go in a PR comment.
47
47
  - `(#n)` ends the bullet that delivers an issue and `(part of #n)` marks anything that stays open;
48
- never `Closes`/`Fixes`/`Refs` before a number, and never an issue reference inside an HTML comment,
49
- which still closes the issue.
48
+ never `Closes`/`Fixes`/`Refs` before a number, and never an issue reference inside an HTML comment
49
+ (release-action removes comments, so it would close nothing).
50
50
  - Links are absolute `https://` URLs, never relative paths.
51
51
  - Post reviewer notes (checks run, what was not verified, review provenance, stacking, merge or
52
52
  deploy order) right after creating the PR with `gh pr comment <n> --body-file .ai-work/pr-notes.md`.
@@ -15,7 +15,7 @@ Do not copy or synchronize shared `.cratis/ai`, `.agents`, `.claude`, `.github`,
15
15
  never become an accidental source that republishes its local AI corpus.
16
16
 
17
17
  Shared Cratis capabilities are authored and reviewed in `Cratis/AI` and reach a
18
- repository through one of three channels, each with its own version semantics:
18
+ repository through these channels, each with its own version semantics:
19
19
 
20
20
  - **`cratis ai install` / `cratis ai update`** copy the corpus into `.cratis/ai/`
21
21
  from the current `main` of `Cratis/AI` (or an explicit `--source` path), record
@@ -25,11 +25,32 @@ repository through one of three channels, each with its own version semantics:
25
25
  prompts, and hooks are always installed; rules are filtered by profile and
26
26
  language; skills by the profile catalog; `harnesses/<harness>/` only for the
27
27
  harnesses selected.
28
- - **`@cratis/pi`** is the one versioned channel: an npm package cut per release,
28
+ - **`@cratis/pi`** is a versioned channel: an npm package cut per release,
29
29
  pinned and rolled back by package version. It yields to a managed install when
30
30
  `.cratis/ai.manifest.json` exists.
31
31
  - **Native plugin marketplaces** (Claude Code, Codex, Copilot, Cursor) expose the
32
- skills only, from the unpinned GitHub source.
32
+ skills only, from the unpinned `Cratis/AI` GitHub source.
33
+ - **`Cratis/AI.Distribution`** is a separate tag-versioned, deny-by-default public
34
+ evaluation marketplace. At **v0.3.0** it contains 29 skills and is explicitly
35
+ unsupported `0.x`, not a supported installation channel. Codex and Gemini
36
+ accept `--ref v0.3.0`; Pi accepts
37
+ `git:github.com/Cratis/AI.Distribution@v0.3.0`. Its documented Claude Code and
38
+ Copilot marketplace-add commands carry no ref. Live Chronicle CLI operations
39
+ (`cratis-chronicle-cli-operations`) and both Chronicle/Studio MCP skills remain
40
+ excluded, as do command execution, EF Core/event-type migration and reactors.
41
+ Sources: [v0.3.0 README](https://github.com/Cratis/AI.Distribution/blob/v0.3.0/README.md),
42
+ [release manifest](https://github.com/Cratis/AI.Distribution/blob/v0.3.0/marketplace-release.json)
43
+ and [exclusions](https://github.com/Cratis/AI.Distribution/blob/v0.3.0/provenance.json).
44
+
45
+ At CLI **v3.53.1**, install/update/uninstall support `--dry-run`; `--source`
46
+ or `CRATIS_AI_SOURCE` supplies a local corpus. Otherwise the CLI shallow-clones
47
+ Cratis/AI's default branch and deletes the download after the run. `status`
48
+ exits non-zero on local modifications; `--force` does not remove changed owned
49
+ MCP entries on uninstall. Consumer extension sections in `.cratis/ai.json` and
50
+ hook shebang/execute bits are preserved. Installation creates no model folder.
51
+ Sources: [AiCorpusSource.cs](https://github.com/Cratis/cli/blob/v3.53.1/Source/Cli/Commands/Ai/AiCorpusSource.cs)
52
+ and [AI commands](https://github.com/Cratis/cli/blob/v3.53.1/Documentation/ai/index.md)
53
+ (the latter's older model-directory claim does not override current behavior).
33
54
 
34
55
  ## Profile-selected MCP servers
35
56
 
@@ -44,6 +65,13 @@ servers, settings and comments, detect conflicts, support dry-run/status, and
44
65
  remove only unchanged owned entries on uninstall. Unsupported adapters must be
45
66
  reported explicitly rather than presented as configured.
46
67
 
68
+ At CLI v3.53.1 only Screenplay is registered: `.mcp.json` for Claude (with
69
+ `--project-root-env CLAUDE_PROJECT_DIR`), `.vscode/mcp.json` for Copilot,
70
+ `.cursor/mcp.json`, `.codex/config.toml` and OpenCode's config. Pi uses the
71
+ `cratis-mcp` harness extension rather than a config file. CodeScene's `cs-mcp`
72
+ is never registered by the CLI; neither Chronicle nor Studio MCP is registered
73
+ by the corpus. Source: [AiMcpHarnesses.cs](https://github.com/Cratis/cli/blob/v3.53.1/Source/Cli/Commands/Ai/AiMcpHarnesses.cs).
74
+
47
75
  Project model roots and opt-outs are consumer-owned configuration. Guidance
48
76
  installation never creates or manages a model directory: the Screenplay MCP locates the model
49
77
  itself (existing `.play` files, else `Source/` or `src/`, else a new `Screenplay/` folder). Ordinary
@@ -31,7 +31,7 @@ Commands are imperative intents (`Register`, `Create`); the slice folder is the
31
31
  Tagged **[contract]** (framework-enforced) or **[convention]** (house default). Mechanics and examples live in `vertical-slices.md`.
32
32
 
33
33
  1. **[contract] Model-bound — no controllers.** Commands are `[Command]` records with a public instance `Handle()` (Arc analyzers enforce this); queries are `static` methods on `[ReadModel]` records; projections/constraints/authorization use attributes. Arc generates the HTTP surface. Drop to fluent (`IProjectionFor<T>`, `IConstraint`) only when model-bound can't express the rule.
34
- 2. **[contract] Command validation & data flow.** Put command rejection in `CommandValidator<T>`, global value invariants in `ConceptValidator<T>`, and fetched/computed handler data in **`Provide()`** (runs after validation/authorization; may short-circuit with `ValidationResult.Error` / `Result<TProvided, ValidationResult>`). Keep `Handle()` focused on event construction. For a state-dependent rule that must hold **under concurrency**, inject the read model into `Handle()` and return a typed error via `Result<TEvent, ValidationResult>`. **Throwing from `Provide()`/`Handle()` is an exception (HTTP 500), not a validation rejection** — throw only for genuinely exceptional conditions, never for normal business rejection.
34
+ 2. **[contract] Command validation & data flow.** Put command rejection in `CommandValidator<T>`, global value invariants in `ConceptValidator<T>`, and fetched/computed handler data in **`Provide()`** (runs after validation/authorization; may short-circuit with `ValidationResult.Error` / `Result<TProvided, ValidationResult>`). Keep `Handle()` focused on event construction. For a state-dependent rule that must hold **under concurrency**, enroll a guarded stream decision (`IStreamReads`/`StreamDecision`) or use `[ProtectedDecision]` with an admitted `DecisionRead<T>`; plain injected models remain advisory. Return a typed rejection via `Result<TEvent, ValidationResult>` where needed; the result alone adds no guard. **Throwing from `Provide()`/`Handle()` is an exception (HTTP 500), not a validation rejection** — throw only for genuinely exceptional conditions, never for normal business rejection.
35
35
  3. **[contract] Event-source id resolution:** `ICanProvideEventSourceId` first; else the first qualifying property in declaration order — an `EventSourceId`/`EventSourceId<T>`-derived value *or* a `[Key]` property (no priority between them; two candidates is `ARCCHR0002`); else Arc generates one. A value actually used as a Chronicle stream identity derives from `EventSourceId<T>` with the underlying `IComparable` primitive — never `ConceptAs<Guid>` for that stream identity. `NotSet`, `New()`, and primitive→derived-id operators are optional domain/API conveniences, not Chronicle requirements; typed empty/zero values are real specified stream IDs, not `EventSourceId.Unspecified`.
36
36
  4. **[contract] Events never carry the event-source id** — it is implicit in the event context.
37
37
  5. **[contract] `[Key]` / `[Subject]` are distinct.** `[Key]` is for event-source/read-model/projection key resolution; `[Subject]` is compliance identity only. Don't put either on an `EventSourceId<T>` value (it already is both); use them only for non-`EventSourceId<T>` values.
@@ -52,6 +52,7 @@ Tagged **[contract]** (framework-enforced) or **[convention]** (house default).
52
52
 
53
53
  ## Implementation Workflow
54
54
 
55
+ - **Starting a brand-new application:** scaffold it instead of hand-writing the skeleton: `dotnet new install Cratis.Templates`, then `dotnet new cratis -n MyApp -o MyApp` (`--language Kotlin|Java`, `--Database MongoDB|PostgreSQL|MsSql|SQLite`; `cratis-aspire` for Aspire; `cratis-chronicle-console` or `cratis-chronicle-web` for a Chronicle client only). Non-interactive runs need `--allow-scripts yes`; the .NET templates target `net10.0`. The template writes `.cratis/ai.json`; run `cratis ai update` afterwards. Its `SomeModule/SomeFeature/Registration/` slice is the house shape. There is no Go, Python or Elixir template (verified at Cratis.Templates `v1.7.4`).
55
56
  - **Phase 0 — Find the contract / choose the level.** Before writing slice code, find what the code must match, and choose the level once for the whole scope.
56
57
  1. **Look for a Screenplay model** under the model root (the folder holding the project's `.play` files, or the root set by `mcpServers.screenplay.root` in `.cratis/ai.json`; search `**/*.play`) for the slice, command, event and read-model names. A `.play` file outside the root, an untracked or uncommitted draft, an empty directory, or an installed profile or skill is not opt-in; the repository is opted in only when the root holds a committed `.play` file (`git ls-tree -r --name-only HEAD` lists a `.play` file there, narrowed to `-- <root>` when a root is configured) or the project set that root explicitly (master definition: **cratis-screenplay-modeling-lifecycle**, "Decide the level first").
57
58
  2. **Model level** — an accepted model under the root covers the scope, or the repository is opted in and this scope has no model yet. The `.play` slice and its specs are the contract: change the model first (new behavior starts in discovery), verify it (V1–V3), get an independent review, then render with Stage or gap-fill by hand only what the renderer rejects. Hand-written code stays checked against the model (**cratis-application-slice-conformance**). Never edit Stage-managed output, never implement behavior the model does not state, never change the model to match existing code, never weaken protection to make it compile or render. Start with **cratis-screenplay-event-modeling** (decision rule), then **cratis-screenplay-modeling-lifecycle**. If the Screenplay skills are not installed, say so; do not author `.play` from memory.
@@ -16,7 +16,7 @@ The package root exports **only** setup (`CratisComponentsProvider`, configurati
16
16
  | Need | Use | Subpath |
17
17
  |---|---|---|
18
18
  | App root | `CratisComponentsProvider` | `@cratis/components` |
19
- | Page chrome, buttons, basic controls | `Page`, `Button`, `IconButton`, `TextInput`, `TextArea`, `NumberInput`, `Checkbox`, `Radio`, `Switch`, `Tooltip`, `ErrorBoundary`, `FormElement`, `ComboBox` (≥ 4.6.0 — single-selection, text-searching entity picker) | `@cratis/components/Common` |
19
+ | Page chrome, buttons, basic controls | `Page`, `Button`, `IconButton`, `TextInput`, `TextArea`, `NumberInput`, `Checkbox`, `Radio`, `Switch`, `Tooltip`, `ErrorBoundary`, `FormElement`, `ComboBox`, `ToggleGroup`, `Tabs`, `TagGroup`, `Breadcrumbs`, `DatePickerInput`, `ActionMenubar`, `ToolbarFocusMode`, `Surface` | `@cratis/components/Common` |
20
20
  | Icon | `Icon` (type) / `IconDisplay` | `@cratis/components/Common` |
21
21
  | Query list page | `DataPage`, `MenuItem`, `Column` | `@cratis/components/DataPage` |
22
22
  | Standalone query table | `DataTableForQuery` / `DataTableForObservableQuery`, `Column` | `@cratis/components/DataTables` |
@@ -28,8 +28,35 @@ The package root exports **only** setup (`CratisComponentsProvider`, configurati
28
28
  | Notifications | `Toaster`, `toast`, `toastCommandResult` | `@cratis/components/Notifications` |
29
29
  | Status & display | `Tag`, `Badge`, `Chip`, `Skeleton`, `Avatar`, `ProgressBar`, `ProgressSpinner`, `Message` | `@cratis/components/Display` |
30
30
  | Canvas tool palette | `Toolbar`, `ToolbarButton`, … | `@cratis/components/Toolbar` |
31
+ | Schema structure / object content | `SchemaEditor` / `ObjectContentEditor` / `ObjectNavigationalBar` | `@cratis/components/SchemaEditor`, `/ObjectContentEditor`, `/ObjectNavigationalBar` |
32
+ | Spatial canvas / pivot data | `Canvas` / `PivotViewer` | `@cratis/components/Canvas`, `/PivotViewer` |
33
+ | Chat | `Chat` | `@cratis/components/Chat` |
34
+ | Ordered configuration | `OrderedItemEditor`, `PropertyControls` | `@cratis/components/ConfigurationEditor` |
35
+ | Filter panel | `FilterPanel` | `@cratis/components/Filter` |
36
+ | Icon / Markdown editing | `IconPicker` / `MarkdownEditor` | `@cratis/components/IconPicker`, `/MarkdownEditor` |
37
+ | Time navigation | `TimeMachine` | `@cratis/components/TimeMachine` |
38
+ | Renderer contracts / built-in | renderer exports | `@cratis/components/renderer`, `/renderer/builtin` |
39
+ | CSS foundation / area sheets | layer order / structural CSS | `@cratis/components/styles/base`, `<subpath>/styles` |
31
40
  | Shared types | `JsonSchema`, `Json`, … | `@cratis/components/types` |
32
41
 
42
+ At Components 4.26.4, React and React DOM are `^19.0.0`, Arc and Arc React are
43
+ `>=20.3.1 <23`, Fundamentals is `^7.10.3`, and `reflect-metadata` `0.2.2` is required
44
+ (import it at the entry point). `tsyringe` `4.10.0` is optional for Components;
45
+ Arc React installs it. `Canvas` and `PivotViewer` need the optional `pixi.js ^8.20.0`
46
+ peer; ordinary pages do not. No `motion-dom` or `motion-utils` resolution pin is needed.
47
+
48
+ ### Common controls
49
+
50
+ All import from `@cratis/components/Common`:
51
+
52
+ | Control | Main props / choice |
53
+ | --- | --- |
54
+ | `ComboBox` | `options`, `value: string \| null`, `onChange(key)`, `filter`, `openOnFocus`, `loading`, `emptyMessage`, `failure`, `action`, `optionLayout` — a single-select entity picker |
55
+ | `ToggleGroup` | `options`, `value`, `onChange` — choose a value; radiogroup semantics with one Tab stop |
56
+ | `Tabs` | `tabs`, `value`, `onChange` — choose a panel, not a domain value |
57
+ | `TagGroup` | `value: string[]`, `onChange`, `editable`, `separators`, `allowDuplicates`, `removeIcon` |
58
+ | `Breadcrumbs` | `items`, `separator` — last item is `aria-current='page'` |
59
+
33
60
  Use `Dropdown` from `@cratis/components/Dropdown`, never a vendor select: it renders through the Components overlay environment, so it stacks correctly above dialogs, and it follows the WAI-ARIA button/listbox (or combobox, when `filter` is on) pattern. Its `onChange` receives the **value**, not an event — as do every CommandForm field's.
34
61
 
35
62
  ### Notifications — feedback for commands run outside a dialog
@@ -46,6 +73,14 @@ const result = await command.execute();
46
73
  if (toastCommandResult(result, { successTitle: 'Author registered' })) refresh();
47
74
  ```
48
75
 
76
+ Without a mounted toaster, neither `toast` nor `toastCommandResult` displays anything.
77
+ Mount **one**, not both: two toasters show every toast twice. The provider has no
78
+ Arc dependency; its position relative to `<Arc>` is not what enables notifications.
79
+
80
+ `ErrorBoundary` (`Common`) contains a failing section with a neutral message, never
81
+ exception text. Supply `fallback` (a node or `(reset) => node`), `onError`, and
82
+ `onReset` when needed; retry remounts only the protected section.
83
+
49
84
  For ad-hoc notifications, call the imperative `toast.success/info/warn/error(...)` — each takes an
50
85
  **options object**, not a bare string: `toast.info({ title: 'Saved', description: '…' })`.
51
86
 
@@ -65,7 +100,12 @@ Required props: `title`, `query` (`Constructor<TQuery>`; snapshot and observable
65
100
  auto-detected), `emptyMessage`, and `children`. Other props: `queryArguments`, `dataKey` (pass
66
101
  whenever the read model has an identity), `selection` / `onSelectionChange`, `globalFilterFields` /
67
102
  `defaultFilters`, `detailsComponent` (`React.FC<IDetailsComponentProps<T>>` = `{ item, onRefresh? }`),
68
- `onRefresh`, and the Cratis part props `tablePt: DataTableParts` / `paginatorPt: TablePaginatorParts`
103
+ `onRefresh` (forwarded unchanged to the details component; it never refetches the list),
104
+ `selectionMode='multiple'` with `selectedItems` / `onSelectedItemsChange`, and
105
+ `loadingMessage` / `failureMessage` / `unauthorizedMessage` for query-state rows.
106
+ Use an observable query for a live list; DataPage exposes no snapshot refresh handle.
107
+ Global search uses `globalSearchPlaceholder` / `globalSearchAriaLabel`; paginator
108
+ styling and labels use `paginatorClassName` / `paginatorAriaLabels`. The Cratis part props are `tablePt: DataTableParts` / `paginatorPt: TablePaginatorParts`
69
109
  / `menubarPt: ButtonParts` (plus `tableClassName` / `menubarClassName`).
70
110
 
71
111
  Columns and toolbar actions are compositional children:
@@ -123,15 +163,28 @@ An app does three things, once, at its root — or the components render unstyle
123
163
 
124
164
  1. **Import the stylesheets, in this order** — components do not import their own CSS:
125
165
 
126
- ```ts
127
- import '@cratis/components/tokens'; // the semantic --cratis-* variables every component reads
128
- import '@cratis/components/styles'; // structural rules for every component, in low-priority Cratis layers
129
- import '@cratis/components/theme'; // optional: the baseline light/dark look (auto, or `cratis-dark`/`cratis-light`)
166
+ In `index.css`, imported once by the entry point with `import './index.css'`:
167
+
168
+ ```css
169
+ @import '@cratis/components/tokens';
170
+ @import '@cratis/components/styles';
171
+ @import '@cratis/components/theme'; /* optional baseline light/dark look */
130
172
  ```
131
173
 
174
+ Direct CSS subpath imports from TypeScript need ambient declarations on TypeScript 6
175
+ (otherwise TS2882). To reduce the roughly 32 KiB gzip aggregate, replace `styles`
176
+ with `styles/base` plus the needed `<subpath>/styles` sheets. Area order does not matter.
177
+
132
178
  A product with its own design system omits `theme`, defines the `--cratis-*` variables itself, and imports those values *after* the two Components entries so they win the cascade.
133
179
 
134
- 2. **Mount `CratisComponentsProvider`** (from the package root) around the app. Its `value` carries `locale` (BCP 47 — drives dates, numbers, keyboard behavior and announcements) and `messages` (the Components-owned labels for `paginator`, `datePicker`, `dropdown`, `dialog`, `stepper`, `notifications`, `dataTable`, `columnFilter`, `toolbar`); `toaster` mounts the toast region. Renderer keys from Components 3 — `license`, `theme`, `pt`, `ripple`, `unstyled`, z-index — are a **type error**, on purpose. Keep the `value` object stable when it carries a large message catalog.
180
+ 2. **Mount `CratisComponentsProvider`** (from the package root) around the app. Its `value` carries `locale` (BCP 47 — drives dates, numbers, keyboard behavior and announcements) and `messages` (the Components-owned labels for `paginator`, `datePicker`, `dropdown`, `dialog`, `stepper`, `notifications`, `dataTable`, `filter`, `columnFilter`, `toolbar`); `icons` replaces the
181
+ product-wide glyphs (`close`, `remove`, `expand`, `sortAscending`, `sortDescending`,
182
+ `previous`, `next`, `clear`). Resolution is component prop → provider → built-in;
183
+ `null` hides only the glyph. `useCratisIcon()` (package root) resolves this vocabulary.
184
+ `locales` is deprecated; use `messages`. `toaster` accepts `boolean | ToasterProps`
185
+ and mounts the toast region. Provider props also include `overlayEnvironment`,
186
+ `rendererSetup` (non-secret booleans), experimental `libraryMode` (`strict` / `degrade`)
187
+ and `rendererFallback` (`core` / `throw`). Renderer keys from Components 3 — `license`, `theme`, `pt`, `ripple`, `unstyled`, z-index — are a **type error**, on purpose. Keep the `value` object stable when it carries a large message catalog.
135
188
 
136
189
  ```tsx
137
190
  import { CratisComponentsProvider } from '@cratis/components';
@@ -143,6 +196,9 @@ An app does three things, once, at its root — or the components render unstyle
143
196
  );
144
197
  ```
145
198
 
199
+ Components 4.22.1+ with `theme` imported maps Arc's `--color-error` and
200
+ `--color-error-bg` in dark schemes; a product theme omitting it must define both.
201
+
146
202
  3. **Install nothing else.** No PrimeReact, no PrimeIcons, no theme preset, no vendor provider. Only if the product wants a vendor's *look* on the nine primitive slots does it install one adapter package and pass its manifest to the provider's `library` prop — and the vendor's own provider, theme and license then stay the application's, outside Components.
147
203
 
148
204
  ### Writing styles
@@ -178,6 +234,9 @@ See [dialogs.md](./dialogs.md) for the full dialog guide.
178
234
 
179
235
  Components accepts an **`Icon`** (`@cratis/components/Common`) wherever a control takes an icon: either a React node — preferred — or a complete, consumer-owned icon-font class string. Components installs **no icon font**: a string is rendered on an `<i>` unchanged, so the product must load that stylesheet itself. `react-icons` is a Components dependency and the natural source of React icon nodes (`<FaHouse aria-hidden="true" />`). Not every `icon` prop has that shape — `DataPage.MenuItem.icon` is a React component *type* because the page instantiates it; follow the exported prop type.
180
236
 
237
+ Use provider `value.icons` for Components' own glyphs across the product;
238
+ `Dialog.closeIcon`, `TagGroup.removeIcon`, and other component props still win at one site.
239
+
181
240
  For the application's own SVG icons:
182
241
 
183
242
  - **Distinguish icons from status/interactive components.** A pure SVG icon is a simple presentational element. A component that wraps an icon with interactive behavior (e.g. a dropdown, tooltip, or complex state) is a _component_, not an icon — name it accordingly (e.g. `SliceStatus`, not `SliceStatusIcon`).
@@ -84,8 +84,11 @@ public record AuthorId(Guid Value) : EventSourceId<Guid>(Value), IGeneratable<Au
84
84
  - The exact `EventSourceId<T>` base supports conversions among its underlying
85
85
  `T`, string, typed ID, and untyped `EventSourceId`, but those operators do not
86
86
  construct your derived domain record from every source form.
87
- - String and Guid are the safest round-trip primitives. Other comparable values
88
- rely on Chronicle conversion behavior and require focused verification.
87
+ - String and Guid remain the safest stream-id primitives. Chronicle v19.50.0
88
+ uses invariant numeric conversion, `"O"` for date/time values and `"c"` for
89
+ TimeSpan (since 19.37.3; `Source/Clients/DotNET/Events/EventSourceId.cs:148-174`).
90
+ Preserve the old untyped id for streams written under legacy date/time or
91
+ decimal-comma culture formats; the new conversion can otherwise open a new stream.
89
92
  - Pass the identity explicitly to Chronicle append/read operations. Declaring an
90
93
  `EventSourceId<T>` property does not select the stream.
91
94
  - Do not put `[Key]` or `[Subject]` on an `EventSourceId<T>`-derived member;
@@ -126,4 +129,9 @@ Use GeoJSON types from `Cratis.Geospatial`: `Point` for a location,
126
129
  `LineString` for a route, and `Polygon` for an area. Do not use the removed
127
130
  experimental `Coordinate` type. Model geospatial absence according to the
128
131
  owning domain contract; do not invent a nullable event payload that conflicts
129
- with Chronicle event rules.
132
+ with Chronicle event rules. TypeScript imports `Point`, `LineString`, `LinearRing`,
133
+ and `Polygon` from `@cratis/fundamentals/geospatial` (verified at 7.23.0).
134
+ The wire shape is GeoJSON, for example
135
+ `{ "type": "Point", "coordinates": [longitude, latitude] }`: longitude first.
136
+ The removal of `Coordinate` in 7.15.1 is a stored-data compatibility break;
137
+ plan a migration rather than assuming the old shape deserializes as GeoJSON.
@@ -53,6 +53,8 @@ Every rule here reduces noise. `var` avoids redundant type repetition. Expressio
53
53
  - Prefer LINQ (`.Where`, `.Any`, `.Select`, `.FirstOrDefault`) over a `foreach` that filters inside its body with an `if`/`continue` or an early `return` — put the filter in the query so the intent is explicit (`items.Where(predicate)`, `return items.Any(predicate);`). Reserve `foreach` for genuine iteration with side effects. (Filtering inside a loop is what the analyzers flag as a "missed opportunity to use Where".)
54
54
  - Don't use regions — they hide code instead of organizing it. If a file needs regions, it needs refactoring.
55
55
  - Never add postfixes like `Async`, `Impl`, `Service` to class names — they add noise without information.
56
+ - Name a method without the `Async` suffix unless a synchronous method of the same name also exists, never write an explicit `private` modifier (property setters excepted), and never put a `.Features.` segment in a namespace.
57
+ - The `Cratis.Architecture.CodeAnalysis` analyzer package (26 diagnostics, `CRARCH0001`–`CRARCH0026`; verified at `v1.0.2`) enforces these and others: `CRARCH0003` postfixes, `0004` `.Features.` namespaces, `0005` regions, `0006`/`0024` `LoggerMessage`, `0007` `IServiceProvider` injection, `0008` `is null`, `0017` namespace matches folder, `0019` `Async` suffix, `0022` explicit `private`, `0023` typed logger category; `0012` (`async void`) and `0014` (test types in production) are errors. When a repository has the package, a `CRARCH` warning is the house convention, not noise.
56
58
  - For types with no implementation body, omit the braces (e.g. `public interface IMyInterface;`).
57
59
  - Prefer `record` types for immutable data structures (events, commands, read models, concepts) — they give you value equality, immutability, and concise syntax for free.
58
60
 
@@ -306,7 +308,7 @@ public class ReactorSideEffectHandlers(IInstancesOf<IReactorSideEffectHandler> h
306
308
 
307
309
  - Never inject `IEnumerable<TInterface>` to enumerate implementations of an abstraction. That signature only works if every implementation is hand-registered, which defeats convention-based discovery. Use `IInstancesOf<TInterface>` instead.
308
310
  - Never write `services.AddSingleton<TInterface, Impl>()` or `services.AddTransient<TInterface, Impl>()` for a type that exists to be discovered. Mark the implementation with `[Singleton]` (for singletons) or rely on the `IFoo → Foo` convention (for transients) and remove the registration line.
309
- - `IInstancesOf<T>` resolves at the point of access — implementations added later in the assembly become available without touching the consumer or any composition root.
311
+ - `IInstancesOf<T>` fixes its type set at construction and resolves instances on each enumeration through the consumer's service provider (Fundamentals 7.23.0). It does not discover late-loaded implementations on access. A singleton consumer captures the root provider; it must not enumerate scoped implementations. Resolve a scoped or transient consumer inside a scope when any implementation is scoped.
310
312
  - `IEnumerable<T>` is still the right type to **return** from a method that yields a sequence of values. The rule applies only when the goal is to enumerate **implementations** of an abstraction.
311
313
 
312
314
  ## Logging
@@ -250,6 +250,9 @@ Use `buttons={null}` for dialogs that contain their own internal actions (e.g. a
250
250
  | Prop | Type | Notes |
251
251
  |---|---|---|
252
252
  | `title` | `string` | Header text |
253
+ | `subtitle` | `ReactNode` | Secondary header content |
254
+ | `placement` | `'center' \| 'start' \| 'end'` | Defaults to center; start/end are RTL-aware side sheets |
255
+ | `closeIcon` | `ReactNode` | Header dismissal glyph; `null` hides only the glyph |
253
256
  | `visible` | `boolean` | Controlled open state; defaults to `true` |
254
257
  | `buttons` | `DialogButtons \| ReactNode \| null` | Prefer `DialogButtons` enum; `null` for no footer |
255
258
  | `isValid` | `boolean` | Disables the confirm button when `false` |
@@ -265,4 +268,10 @@ Use `buttons={null}` for dialogs that contain their own internal actions (e.g. a
265
268
  | `style` / `contentStyle` / `className` | | Modal-root and content-region styling |
266
269
  | `pt` | `DialogParts` | Per-part attributes: `backdrop`, `positioner`, `root`, `header`, `title`, `close`, `content`, `footer`, `confirm`, `cancel` |
267
270
 
271
+ `CommandDialog` forwards these Dialog presentation props (since Components 4.14.1).
272
+ It also accepts `confirmBeforeExecute(values) => boolean | Promise<boolean>`:
273
+ after validation and `onBeforeExecute`, only `true` executes. Fields are disabled
274
+ while confirmation is pending; changed command values discard approval without executing.
275
+ This is a pre-execution gate, unlike the post-success `onConfirm` close gate.
276
+
268
277
  `resizable`, `ptOptions` and `unstyled` are accepted for source compatibility and do nothing. There is no `modal`, `draggable`, `footer` or `onHide` — the dialog is always modal, the footer comes from `buttons`, and closing is reported through `onCancel`/`onClose`. Style the dialog through its parts (`pt`, or `[data-cratis-part='root']` selectors), never through React Aria class names.
@@ -75,7 +75,7 @@ Where a repository organizes its migrations (a dedicated project, a versioned fi
75
75
 
76
76
  ## Observation **[contract]**
77
77
 
78
- An EF Core read model can back an observable query: `dbSet.Observe(...)`, `ObserveById(...)` and `ObserveSingle(...)` (extension methods declared in the `Microsoft.EntityFrameworkCore` namespace, so they are in scope wherever the `DbSet` is) push changes through the provider's change notifier — see the skill for what each provider supports.
78
+ An EF Core read model can back an observable query: `dbSet.Observe(...)`, `ObserveById(...)` and `ObserveSingle(...)` (extension methods declared in the `Microsoft.EntityFrameworkCore` namespace, so they are in scope wherever the `DbSet` is) push changes through the provider's change notifier — see the skill for what each provider supports. At Arc v22.75.0 auxiliary sources support `ignoreQueryContext: true`; single-instance observations emit `default` on absence/deletion/filter exit. Indexer-property keys are supported; composite/shadow-only keys are refused at setup.
79
79
 
80
80
  ## See also
81
81
 
@@ -0,0 +1,49 @@
1
+ ---
2
+ applyTo: "**/*.ex,**/*.exs"
3
+ paths:
4
+ - "**/*.ex"
5
+ - "**/*.exs"
6
+ ---
7
+
8
+ <!-- Copyright (c) Cratis. All rights reserved. -->
9
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
10
+
11
+ # Elixir Conventions
12
+
13
+ Use Elixir and OTP idioms, not translated C# or JVM shapes. These conventions
14
+ are grounded in `Cratis/Chronicle.Elixir v3.10.2` (`Source/chronicle/mix.exs`,
15
+ `.formatter.exs`, and `lib/chronicle/`). Client-specific APIs belong in the
16
+ **cratis-chronicle-client-elixir** skill.
17
+
18
+ ## Build and format
19
+
20
+ - For Chronicle 3.10.x use Elixir 1.18 or later (`~> 1.18`).
21
+ - Run `mix compile --warnings-as-errors`, `mix test`, and
22
+ `mix format --check-formatted` with the project's formatter inputs.
23
+ - Use two-space indentation and let `mix format` own layout.
24
+ - Chronicle exports no `locals_without_parens` formatter configuration. Accept
25
+ parentheses around its DSL calls; do not assume `import_deps` supplies them.
26
+
27
+ ## Code shape
28
+
29
+ - PascalCase module names; snake_case functions, variables and struct fields.
30
+ - Use structs for event/read-model data and pattern-matching clauses for
31
+ dispatch. Schema-bearing structs need typed defaults; `nil` is not a type
32
+ declaration and registers as string in this client.
33
+ - Preserve tagged results such as `:ok`, `{:ok, value}`, and `{:error, reason}`.
34
+ Handle expected remote failures explicitly rather than using a success-only
35
+ match in a long-lived process.
36
+ - Put long-lived processes under the application's supervision tree. Wait for
37
+ actual client readiness, not merely a successful supervisor start.
38
+ - Process-local context is not inherited by `Task` processes; pass required
39
+ context explicitly at that boundary.
40
+ - Document public APIs with `@moduledoc`, `@doc`, and `@spec`; use `Logger` for
41
+ operational logging and keep credentials out of messages and crash reports.
42
+ - Use American English in identifiers, comments and documentation.
43
+
44
+ Every `.ex` and `.exs` source file starts with:
45
+
46
+ ```elixir
47
+ # Copyright (c) Cratis. All rights reserved.
48
+ # Licensed under the MIT license. See LICENSE file in the project root for full license information.
49
+ ```
@@ -21,9 +21,11 @@ Skip these `profile: application` rules entirely when in a framework repo: `vert
21
21
 
22
22
  Each framework repo is organized by what it builds, not by feature slices:
23
23
 
24
- - **Fundamentals** — the base library. `ConceptAs<T>`, type discovery (`IInstancesOf<T>` / `IImplementationsOf<T>`), serialization, common primitives. `Source/DotNET` (C#) + `Source/JavaScript` (`@cratis/fundamentals`) + the shared ESLint config.
24
+ - **Fundamentals** — the base library. `ConceptAs<T>`, type discovery (`IInstancesOf<T>` / `IImplementationsOf<T>`), serialization, common primitives. `Source/DotNET` includes `Fundamentals.TypeDiscovery.Generator`, `Metrics.Roslyn` (`Cratis.Metrics.Roslyn`) and `OpenTelemetry` (`Cratis.OpenTelemetry`); `Source/JavaScript` publishes `@cratis/fundamentals`, and `Source/ESLintConfig` publishes `@cratis/eslint-config` (verified at v7.23.0).
25
+ - **Specifications** — BDD lifecycle, assertions and analyzers. `Source/Specifications` supplies common helpers, `Source/XUnit` and `Source/NUnit` supply runner-specific bases/assertions, and `Source/CodeAnalysis` supplies the bundled analyzers (v4.1.1).
26
+ - **Orleans** — shared silo hosting, grain serializers, jobs and jobs storage (MongoDB/SQL/in-memory), in `Cratis.Orleans*` packages (v1.16.3). The core does not require Chronicle; the optional `.Chronicle` adapter does.
25
27
  - **Arc** — the CQRS + model-binding + proxy-generation engine. `Source/DotNET` (the command/query pipeline, validation, authorization, identity, the Roslyn **proxy generator**) + `Source/JavaScript` (`@cratis/arc`, `@cratis/arc.react`, `@cratis/arc.react.mvvm`). Arc.Core does **not** depend on Chronicle.
26
- - **Chronicle** — the event-sourcing engine. `Source/Kernel` (the engine: **Orleans grains**, event sequences, observers/projections/reducers, storage providers — MongoDB and others), `Source/Clients` (the client SDKs incl. `DotNET` and `Testing`), `Infrastructure`, `Tools`, `Workbench`. The kernel is the deep, performance- and consistency-critical core.
28
+ - **Chronicle** — the event-sourcing engine. `Source/Kernel` (the engine: **Orleans grains**, event sequences, observers/projections/reducers, storage providers — MongoDB and others), `Source/Clients` (the client SDKs incl. `DotNET` and `Testing`), `Infrastructure`, `Tools`, `Workbench`. The kernel is the deep, performance- and consistency-critical core. Its shared job engine, jobs storage, serializers and reusable silo hosting now come from the separate **Orleans** repo, not Chronicle-owned jobs code (Chronicle v19.50.0).
27
29
  - **Components** — the React component library (Components-owned markup and styling contract; React Aria internally; optional PrimeReact/MUI presentation adapters under `Adapters/`). `Source/<Component>/` folder per component (`CommandDialog`, `DataPage`, `DataTables`, …) with Storybook stories; published as `@cratis/components`. (Application rules *consume* these components; here you *build* them.)
28
30
 
29
31
  Repo conventions follow from this: `Source/DotNET` + `Source/JavaScript` for dual-stack libraries; `Kernel` vs `Clients` for Chronicle; a folder-per-component library layout for Components. Match the structure of the area you are editing — do not introduce app-style layouts.
@@ -32,7 +34,7 @@ Repo conventions follow from this: `Source/DotNET` + `Source/JavaScript` for dua
32
34
 
33
35
  - **Public API design is the product.** These libraries are consumed by every Cratis app, so the **Lovable APIs** value (`general.md`) is paramount: sane defaults, convention over configuration, extensible/overridable, minimal boilerplate. Design the API the app developer will love before the implementation.
34
36
  - **Backward compatibility is a contract.** A change to a public type, attribute, interface, or generated-proxy shape is a breaking change for every downstream app — label PRs by semver impact (`major`/`minor`/`patch`) and treat removals/renames of public surface as `major`.
35
- - **Convention discovery is built here.** `IInstancesOf<T>` / `IImplementationsOf<T>`, attribute-based discovery, and source generation are the mechanisms the framework *provides*; use them internally too rather than hand-registration where a convention fits.
37
+ - **Convention discovery is built here.** `IInstancesOf<T>` / `IImplementationsOf<T>`, attribute-based discovery, and source generation are the mechanisms the framework *provides*; use them internally too rather than hand-registration where a convention fits. A Fundamentals project reference does not carry the type-discovery analyzer like its NuGet package does: reference `Fundamentals.TypeDiscovery.Generator` explicitly, or your project's types may be absent from the generated universe.
36
38
  - **Source generators / analyzers** (Arc's proxy generator, Fundamentals) follow Roslyn conventions; their output is consumed verbatim by apps, so treat generated shape as public API.
37
39
  - **Orleans grains** in the Chronicle kernel follow `orleans.md`.
38
40
  - **An alternate implementation of an interface must match the primary one's *semantics*, not just its signature.** Chronicle ships several implementations of the same storage interfaces (MongoDB, SQL, in-memory) and the in-memory ones exist precisely so the real kernel code paths can run without infrastructure. When you touch one, **diff it against the persistent implementations** — the signature tells you nothing about the contract. The specific trap: query criteria carry **sentinels meaning "do not narrow"** (`EventSourceId.Unspecified`, `EventSourceType.Unspecified`/`Default`, `EventStreamType.All`, `EventStreamId.Default`, an empty event-type set). Callers asking for "everything" pass those sentinels, never `null`, so a plain `is not null` check narrows every row away and the read silently returns nothing. A divergence here does not fail — it makes specs pass vacuously, which is worse.
@@ -130,6 +130,7 @@ A claim is only as good as the signal behind it — a build result, a test run,
130
130
  | **Contributing to a Cratis framework repo** (framework profile) | `framework.md`; creating a repository in the Cratis organization: `new-repository-intake.md` |
131
131
  | Slice anatomy (commands, `Provide()`, validators, events, projections, read models, reactors, constraints, compliance, cross-slice) | `vertical-slices.md` |
132
132
  | C# / TypeScript style | `csharp.md`, `typescript.md` |
133
+ | Go style, source and module files | `go.md`; framework contributors also read `go-engineering.md`; product APIs use `cratis-chronicle-client-go`, `cratis-arc-go` and `cratis-fundamentals-concept-go` |
133
134
  | Service lifetimes — why anything taking a scoped dependency is scoped or transient, never a singleton | `csharp.md` |
134
135
  | React + Arc + Cratis Components + MVVM + dialogs | `react.md`, `components.md`, `dialogs.md` |
135
136
  | Frontend engineering quality & testing | `frontend-quality.md`, `frontend-testing.md`, `storybook.md` |
@@ -23,7 +23,7 @@ One precise line per load-bearing term, so the same word means the same thing ev
23
23
  - **Projection** — declares how a read model is built by consuming **events** (model-bound attributes, or fluent `IProjectionFor<T>`); pure events→state, no side effects, never reads other read models.
24
24
  - **Reducer** — `IReducerFor<T>`; a "current state + event → next state" read-model builder; the last-resort escape hatch when projections can't express the transition.
25
25
  - **Reactor** — `IReactor`; observes events and produces **side effects** (notifications, commands, follow-up events). The "if this then that".
26
- - **Observer** — Chronicle's umbrella for anything consuming an event sequence (projection, reducer, reactor); carries subscription / replay / **quarantine** state.
26
+ - **Observer** — Chronicle's umbrella for anything consuming an event sequence (projection, reducer, reactor); carries subscription / replay / **quarantine** state. Projection replay and catch-up each walk the sequence in one globally ordered job step; a new catch-up failure stops that step. Full replay is inactive and completion does not resume a quarantined observer (Chronicle v19.50.1, `Documentation/concepts/observers.mdx`, `Observation/Jobs/{CatchUpObserver,ReplayObserver}.cs` under `Source/Kernel/Core/`).
27
27
  - **Sink** — where a read model is persisted (MongoDB, EF Core).
28
28
  - **AutoMap** — Chronicle's on-by-default mapping of matching event→read-model property names; **never call `.AutoMap()`**.
29
29
  - **Query** — a `static` method on a `[ReadModel]`; returns derived state, **snapshot** (one-shot) or **observable** (live).
@@ -34,8 +34,8 @@ One precise line per load-bearing term, so the same word means the same thing ev
34
34
  - **Provide()** — the command method that fetches/computes data after validation/authorization and before `Handle()`; may short-circuit with a `ValidationResult`.
35
35
  - **Causation chain** — the ordered links saying how an append came about (root process → command → …), each carrying properties. A command records its **name and its property values** there, so an event says what the command was asked to do; the chain lives in the event log and is as permanent as the events.
36
36
  - **Constraint** — `IConstraint`; an **append-time** invariant (uniqueness / concurrency) enforced at the event-store level.
37
- - **DCB (Dynamic Consistency Boundary)** — enforcing a state-dependent rule **under concurrency** by injecting the read model into `Handle()` and returning `Result<TEvent, ValidationResult>`.
38
- - **Consistency boundary** — the scope within which an invariant holds atomically (an event source, or the read model a DCB rule inspects).
37
+ - **DCB (Dynamic Consistency Boundary)** — enforcing a state-dependent rule under concurrency over explicitly enrolled event-state reads: stream decisions/exact scopes or protected, admitted projection decision reads. Plain injected models and `Result<TEvent, ValidationResult>` alone are advisory, not a guard.
38
+ - **Consistency boundary** — the scope within which an invariant holds atomically (an event source, a routed stream, or the event state enrolled by an admitted protected decision read).
39
39
  - **EventForEventSourceId** — self-describing wrapper to append an event to a **specific** (cross-stream) event source, from a command `Handle()` or from a reactor handler (reactor support has shipped since Chronicle 15.35). It carries the event stream type and id, source type, subject, occurred time, tags and causation, so it is also how a reactor sets those explicitly.
40
40
  - **ReactorDelivery** — the identity of one delivery of one event to one reactor partition; declare it as a handler parameter and Chronicle passes it in. Stable across a replay and across recovering a failed partition, so a receipt kept under its `Id` is what makes a side effect survive re-delivery. An identity, not a guarantee — Chronicle does not know whether the effect ran.
41
41
 
@@ -53,7 +53,7 @@ One precise line per load-bearing term, so the same word means the same thing ev
53
53
  - **`[PII]`** — marks an inherently personal value so Chronicle can manage/erase it.
54
54
  - **`[NotAudited]`** — an **Arc** marking (`Cratis.Arc.Chronicle.Commands`, not a Chronicle type) for a value that is secret but *not* personal data (password, token, API key), so it is never written to the causation chain. Withholds only; it does not encrypt the value, so pair it with `[Encrypted]` for an operational secret. It never enrolls a value in erasure the way Chronicle's `[PII]` does.
55
55
  - **`[Encrypted]`** — a Chronicle marking (`Cratis.Chronicle.ProtectedValues`, Chronicle 19.32.0+) that encrypts an **operational secret** (API key, token, a company's bank account number) at rest on the event, without erasure. It does not keep a command input off the causation chain, so a secret gets `[Encrypted]` **plus** `[NotAudited]`. Never combine it with `[PII]` (`CHR0053`); never put it on an event source id (`CHR0052`).
56
- - **`[OnceOnly]`** — marks a reactor handler (or the whole reactor class) as non-replayable: Chronicle skips it for every event arriving as part of a **replay** — observer rewind, redaction, revision. Replay-exclusion only, not exactly-once and not per-event-source deduplication; recovering a failed partition re-delivers the event as an ordinary observation and the handler runs again. Use a `ReactorDelivery` receipt for that case.
56
+ - **`[OnceOnly]`** — marks a reactor handler (or the whole reactor class) as non-replayable: Chronicle skips it for every event arriving as part of a **replay** — observer rewind, redaction, revision. Replay-exclusion only, not exactly-once, not a per-event-source run limit or deduplication; ordinary catch-up, crash redelivery and failed-partition recovery can run the handler again (Chronicle v19.50.1, `Documentation/code-analysis/CHR0022.mdx`). Use a `ReactorDelivery` receipt for that case.
57
57
  - **Namespace / tenant** — Chronicle isolates tenants by **namespace**; each namespace has its own events, observers, and read models.
58
58
 
59
59
  ## Profiles
@@ -0,0 +1,60 @@
1
+ ---
2
+ profile: framework
3
+ applyTo: "**/*.go,go.mod,go.sum,**/go.mod,**/go.sum"
4
+ paths:
5
+ - "**/*.go"
6
+ - "go.mod"
7
+ - "go.sum"
8
+ - "**/go.mod"
9
+ - "**/go.sum"
10
+ ---
11
+
12
+ <!-- Copyright (c) Cratis. All rights reserved. -->
13
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
14
+
15
+ # Go framework parity and module releases
16
+
17
+ `cratis/engineering/go` composes the Go language profile. Repository-owned
18
+ context, not this rule, defines module paths, layout, quality-gate commands,
19
+ release configuration and the exact C# parity target.
20
+
21
+ ## Preserve the product contract
22
+
23
+ Before changing a Go port, inspect its owning C# API, implementation and tests
24
+ at the parity target revision. Translate concepts idiomatically, not literally:
25
+ context plus errors, constructors/options, explicit registration, named values
26
+ and deliberate stream lifetimes. Do not change sibling implementations to
27
+ accommodate the port.
28
+
29
+ Preserve routes, verbs, camelCase JSON where contracted, envelopes, UUID byte
30
+ order/encoding, protobuf fields and RPCs, tenancy, event ordering, retry and
31
+ checkpoint semantics. Record each deliberate divergence in repository-owned
32
+ parity documentation with source path/revision, Go surface, status, executable
33
+ evidence and caller migration implications. A compilation check is not wire,
34
+ streaming or lifecycle parity. Unsupported behavior fails explicitly, never as
35
+ no-op success. Keep a limited conformance result limited; do not claim whole-product parity.
36
+
37
+ ## Release compatibility
38
+
39
+ - Review signatures, interface growth, public struct comparability, wrapped
40
+ errors, defaults and wire behavior. API-diff tools supplement consumer tests.
41
+ - Experimental v0 breaking APIs require a **minor** bump and migration notes,
42
+ not a patch. From v1, incompatible APIs need a planned major version.
43
+ - Apply exactly one release-intent label under the repository's PR policy.
44
+ Check how its configured `Cratis/release-action` maps v0 changes before release.
45
+ - Root modules use immutable `vX.Y.Z` tags created through the configured
46
+ release-action workflow. Do not create duplicate manual releases or move tags.
47
+ Nested modules need their own explicitly reviewed tag policy.
48
+ - Plan `/v2` migrations across the module directive, imports, examples, consumers
49
+ and parallel support. Neither v0 nor v1 gets a `/v0` or `/v1` suffix.
50
+ - Correct a bad release with a new release and, when appropriate, documented
51
+ retractions in a newer published version. Retraction does not erase downloads
52
+ or prohibit an explicit request for the old version.
53
+ - Verify release consumption without local workspace/replacement assistance.
54
+ Source/tag availability, module download, consumer compilation and proxy/pkg.go.dev
55
+ indexing are separate results. Indexing delay never justifies retagging.
56
+
57
+ Adapted from the repository-owned
58
+ [Chronicle.Go parity rule](https://github.com/Cratis/Chronicle.Go/blob/v0.9.1/.cratis/ai/rules/go-cratis-parity.md)
59
+ and [repository-owned module release guidance](https://github.com/Cratis/Chronicle.Go/tree/v0.9.1/.cratis/ai/skills),
60
+ with repository-specific paths and commands removed.