@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
@@ -0,0 +1,115 @@
1
+ ---
2
+ applyTo: "**/*.go,go.mod,go.sum,**/go.mod,**/go.sum"
3
+ paths:
4
+ - "**/*.go"
5
+ - "go.mod"
6
+ - "go.sum"
7
+ - "**/go.mod"
8
+ - "**/go.sum"
9
+ ---
10
+
11
+ <!-- Copyright (c) Cratis. All rights reserved. -->
12
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
13
+
14
+ # Go conventions
15
+
16
+ Use Go's own packages, constructors, explicit registration and standard `testing`.
17
+ Do not import C# namespace layouts, one-type-per-file rules, `I` interface prefixes,
18
+ `Async` suffixes or .NET specification mechanics. Product APIs belong in the
19
+ matching Go skill; repository-owned context supplies module paths, layout and
20
+ exact commands.
21
+
22
+ ## Minimum version and dependencies
23
+
24
+ - Read the `go` directive, build constraints and CI before choosing a feature.
25
+ The minimum is not the newest locally installed compiler; a `toolchain`
26
+ preference does not replace minimum-version testing. Do not raise it incidentally.
27
+ - Iterators require Go 1.23; `T.Context` and `B.Loop` require 1.24;
28
+ stable `testing/synctest` and `WaitGroup.Go` require 1.25.
29
+ - Prefer the standard library when it meets the contract. Review dependency
30
+ capability, license and compatibility before adding one.
31
+ - Change module files only for authorized dependency work. Review tidy changes,
32
+ including indirect minimum-version changes; keep sums consistent. A consumer
33
+ must not need a developer's workspace or local replacement.
34
+ - Never edit generated code; change its authoritative inputs and pinned generator.
35
+
36
+ ## Names, public APIs and values
37
+
38
+ - Format handwritten Go with `gofmt`; use its tabs and the repository's import grouping.
39
+ - Use MixedCaps and preserve `ID`, `HTTP`, `URL`, `JSON` and `RPC` initialisms.
40
+ Avoid package stuttering and catch-all packages. Use American English.
41
+ - Keep public surfaces small and caller-oriented. Define interfaces at consuming
42
+ boundaries or where public substitution is a supported contract, not for every type.
43
+ - Document exported declarations with comments beginning with their names.
44
+ Explain nil/zero semantics, concurrency, ownership, cancellation, error identities
45
+ and cleanup. Add executable examples for important public workflows.
46
+ - Make zero values useful where possible; reject invalid construction early.
47
+ Document option defaults, validation, ordering and duplicates.
48
+ - Use named domain values instead of interchangeable primitives. Defined types
49
+ do not inherit codec methods; explicitly forward text/JSON codecs and test wire
50
+ formats. See `cratis-fundamentals-concept-go` when using Fundamentals.Go.
51
+ - Document whether slices, maps, config and results are owned, copied or borrowed.
52
+ Copying a slice/map header is not a detached copy. Do not copy a used mutex,
53
+ wait group or atomic value, or expose pooled bytes after returning their buffer.
54
+
55
+ ## Errors, context and diagnostics
56
+
57
+ - Return ordinary failures as the final `error`; inspect errors, including cleanup.
58
+ Libraries must not exit the process or panic for expected failures.
59
+ - Preserve documented error identity with `errors.Is`/`errors.As`, not strings.
60
+ Wrapping with `%w` exposes that identity as API; do it deliberately. Do not
61
+ return an `error` interface containing a typed nil.
62
+ - Add useful operation context. Handle/log an error at one boundary rather than
63
+ repeatedly logging and returning it. A partial or ambiguous write is not success
64
+ and must not trigger a blind retry.
65
+ - Put `context.Context` first for blocking/cancelable work and propagate it through
66
+ RPCs, HTTP, storage and callbacks. Never escape caller cancellation by replacing
67
+ it with `Background`. Do not retain request contexts in long-lived clients.
68
+ - Call acquired cancel functions. Context values carry request metadata, not
69
+ dependencies or configuration; use private keys with typed accessors.
70
+ - Prefer injectable `log/slog` at a supported minimum. Do not mutate global logging
71
+ from a library. Redact credentials and sensitive payloads.
72
+
73
+ ## Goroutines, streams and iterators
74
+
75
+ - Each goroutine needs an owner, termination condition and observable join path.
76
+ Cancellation requests termination; it does not join workers.
77
+ - Bound workers, queues, subscriptions, buffers and retries; define backpressure.
78
+ Make blocking operations cancellation-aware. Close channels only after senders stop.
79
+ - Do not hold locks while calling user code or performing slow I/O. Call
80
+ `WaitGroup.Add` before launching work when not using version-supported `Go`.
81
+ - Stop immediately when iterator `yield` returns false. Release resources on
82
+ exhaustion, early exit, failure and cancellation; call `iter.Pull`'s stop function.
83
+ Specify ordering, errors and whether a stream can be consumed more than once.
84
+ - Preserve protocol metadata, tenancy, checkpoints and duplicate-delivery semantics.
85
+ No generic retry or stream helper may promise exactly-once effects.
86
+ - Validate remote TLS identities. Development exceptions must be explicit.
87
+ Use cryptographic randomness for secrets, never `math/rand`.
88
+
89
+ ## Specifications and checks
90
+
91
+ - Use standard `testing`, meaningful subtests, useful got/want diagnostics and
92
+ table-driven cases where setup/assertions actually match. Use external `_test`
93
+ packages to exercise public contracts where practical.
94
+ - Use `t.Helper`, `t.Cleanup` and `t.TempDir`. Isolate state before `t.Parallel`.
95
+ Synchronize with channels/joins, not guessed sleeps. Fake-time tests do not
96
+ establish real-network behavior.
97
+ - Cover error identity, nil/zero input, cancellation/deadlines, partial outcomes,
98
+ early stream exit and resource ownership. Bound fuzz duration and preserve
99
+ failing seeds. Use race checks where supported; race-free does not mean leak-free.
100
+ - Run the repository's build, tests, formatting, vet and pinned golangci-lint gates,
101
+ with race and vulnerability scanning as separate checks. Respect the declared
102
+ minimum without silent toolchain upgrades. Report absent tools honestly.
103
+
104
+ ## Adaptation and attribution
105
+
106
+ This condensed rule adapts the repository-owned Go baseline at
107
+ [Chronicle.Go v0.9.1](https://github.com/Cratis/Chronicle.Go/blob/v0.9.1/.cratis/ai/rules/go.md)
108
+ and [Arc.Go v0.1.1](https://github.com/Cratis/Arc.Go/blob/v0.1.1/.cratis/ai/rules/go.md),
109
+ not their project paths or commands. The baseline's adapted readability,
110
+ error-boundary, public-option and goroutine recommendations retain attribution:
111
+ [Google Go style](https://google.github.io/styleguide/go/guide.html), Google,
112
+ [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/); and
113
+ [Uber Go style](https://github.com/uber-go/guide/blob/master/style.md), Uber
114
+ Technologies, Inc., [Apache-2.0](https://github.com/uber-go/guide/blob/master/LICENSE).
115
+ No community code snippets are reproduced here.
@@ -41,7 +41,9 @@ modeling, dialog, license, judgment, gray). See [general.md](./general.md).
41
41
 
42
42
  - PascalCase for class and interface names.
43
43
  - camelCase for methods, fields, and local variables.
44
- - No `I` prefix on interfaces — name the interface for what it does.
44
+ - New application and Arc-style interfaces have no `I` prefix — name them
45
+ for what they do. Chronicle.Kotlin's published interfaces retain their names
46
+ (`IEventStore`, `IChronicleClient`, `IProjectionFor`, `IReactorMiddleware`).
45
47
  - Never suffix a class with `Impl`, `Manager`, or `Helper` purely to
46
48
  disambiguate — name it for its role; reserve `Default<Name>` for the
47
49
  concrete counterpart of an interface meant to be overridden.
@@ -127,7 +129,8 @@ modeling, dialog, license, judgment, gray). See [general.md](./general.md).
127
129
 
128
130
  ## Testing
129
131
 
130
- - JUnit 5 is the house test runner.
132
+ - JUnit Jupiter is the house test runner (the Cratis JVM repositories use
133
+ Jupiter 6.1.x).
131
134
  - A test for a Java-facing surface belongs beside the Java production code
132
135
  (`src/test/java/.../<Thing>Test.java`) and must actually compile and run
133
136
  against that surface — a Kotlin-only test does not prove Java call-site
@@ -43,10 +43,11 @@ dialog, license, judgment, gray). See [general.md](./general.md).
43
43
 
44
44
  - PascalCase for class, interface, and object names.
45
45
  - camelCase for functions, properties, and local variables.
46
- - No `I` prefix on interfaces — Kotlin does not carry that convention; name
47
- the interface for what it does (`CommandPipeline`, not `ICommandPipeline`)
48
- unless a concrete/interface pair genuinely needs `Default<Name>` for the
49
- implementation.
46
+ - New application and Arc-style interfaces have no `I` prefix; name them for
47
+ what they do (`CommandPipeline`, not `ICommandPipeline`). Reserve
48
+ `Default<Name>` for a concrete/interface pair when needed. Chronicle.Kotlin's
49
+ published types retain their names (`IEventStore`, `IChronicleClient`,
50
+ `IProjectionFor`, `IReactorMiddleware`); do not rename framework APIs.
50
51
  - Never suffix a class with `Impl`, `Service`, or `Async` purely to
51
52
  disambiguate — name it for its role.
52
53
 
@@ -165,7 +166,8 @@ should assume by default:
165
166
 
166
167
  ## Testing
167
168
 
168
- - JUnit 5 is the house test runner for Kotlin and Java alike.
169
+ - JUnit Jupiter is the house test runner for Kotlin and Java alike (the
170
+ Cratis JVM repositories use Jupiter 6.1.x).
169
171
  - A Kotlin test lives beside its Kotlin production code
170
172
  (`src/test/kotlin/.../<Thing>Test.kt`); a Java-facing surface also gets a
171
173
  Java test that compiles and runs against it, because Kotlin-only tests do
@@ -10,27 +10,83 @@ paths:
10
10
  > **⚠️ APPLIES ONLY TO PROJECTS USING MICROSOFT ORLEANS**
11
11
  > If your project does not reference `Microsoft.Orleans` or any Orleans packages, **ignore this entire file**. These rules are irrelevant outside of Orleans contexts.
12
12
 
13
- In the Cratis organization, Orleans is the Chronicle kernel's actor runtime (`Source/Kernel/`). These conventions describe how that kernel is shaped, verified against `Cratis/Chronicle` **v18.3.0**; follow them in any Cratis repository that hosts Orleans grains.
13
+ In the Cratis organization, Orleans is the Chronicle kernel's actor runtime (`Source/Kernel/`). The kernel conventions below are verified against `Cratis/Chronicle` **v19.50.0**. Shared hosting and jobs come from `Cratis/Orleans` **v1.16.3**; use its setup for other services that co-host a silo.
14
14
 
15
15
  ## General
16
16
 
17
17
  - Do **not** split grain interfaces into a separate project. Grain interfaces and their implementations live together in `Kernel/Core`; the `Contracts` project holds the gRPC contracts, not grain interfaces.
18
18
  - Clustering is chosen by the host, not the grain code: the server uses `UseLocalhostClustering(siloPort, gatewayPort, serviceId, clusterId)` for local development and the MongoDB storage integration switches on `UseMongoDBClustering` (`MongoDBMembershipStrategy.Multiple`) when clustering is enabled. A silo pointed at non-local shared storage while still on localhost clustering is logged as a **warning** at startup (each such node forms its own single-node cluster over the same data); `Cratis__Chronicle__Clustering__Type=MongoDB` on every node is what joins them.
19
- - Do **not** add `[Alias]` to grain interfaces or grain methods — rely on the default alias Orleans generates. `[Alias(nameof(Type))]` is used only on `[GenerateSerializer]` **state and definition records** in `Kernel/Concepts` (`ReadModelDefinition`, `IndexDefinition`, `ReadModelChangeContext`, `ProjectionFuture`), where a stable serialization alias must survive a rename.
19
+ - Do **not** add `[Alias]` to grain interfaces or grain methods — rely on the default alias Orleans generates. `[Alias(nameof(Type))]` is used only on `[GenerateSerializer]` **state and definition records** in `Kernel/Concepts` (`ReadModelDefinition`, `IndexDefinition`, `ReadModelChangeContext`, `ProjectionFuture`, `ClearPartitionQuarantineResult`), where a stable serialization alias must survive a rename.
20
20
 
21
21
  ## Grain storage providers
22
22
 
23
- - Storage provider names are constants in `WellKnownGrainStorageProviders` (`Kernel/Core`), **one name per concern** — 25 of them at v18.3.0 (`Namespaces`, `EventSequences`, `ObserverDefinitions`, `ObserverState`, `FailedPartitions`, `Jobs`, `JobSteps`, `Recommendations`, `Projections`, `ProjectionsManager`, `ProjectionFutures`, `Reactors`, `Reducers`, `ReducersManager`, `ReadModels`, `ReadModelsManager`, `ReadModelReplayManager`, `Constraints`, `EventStoreSubscriptionsManager`, `EventSeeding`, `Webhooks`, `WebhooksManager`, `DataProtectionKeys`, `PatchManager`, `System`). Reference a provider only through its constant — never a magic string, and there is no "default" provider.
24
- - Each concern has its own `IGrainStorage` implementation (`JobGrainStorageProvider`, `EventSequencesStorageProvider`, `NamespacesStateStorageProvider`, …) taking the kernel's `IStorage` abstraction — **not** a MongoDB collection. The storage backend (MongoDB, SQL, in-memory) is selected behind `IStorage`, so a grain storage provider never references a database driver.
23
+ - Storage provider names are constants in `WellKnownGrainStorageProviders` (`Kernel/Core`), **one name per concern** — 23 of them at v19.50.0 (`Namespaces`, `EventSequences`, `ObserverDefinitions`, `ObserverState`, `FailedPartitions`, `Recommendations`, `Projections`, `ProjectionsManager`, `ProjectionFutures`, `Reactors`, `Reducers`, `ReducersManager`, `ReadModels`, `ReadModelsManager`, `ReadModelReplayManager`, `Constraints`, `EventStoreSubscriptionsManager`, `EventSeeding`, `Webhooks`, `WebhooksManager`, `DataProtectionKeys`, `PatchManager`, `System`). Reference a provider only through its constant — never a magic string, and there is no "default" provider.
24
+ - Each concern has its own `IGrainStorage` implementation (`EventSequencesStorageProvider`, `NamespacesStateStorageProvider`, …) taking the kernel's `IStorage` abstraction — **not** a MongoDB collection. The storage backend (MongoDB, SQL, in-memory) is selected behind `IStorage`, so a grain storage provider never references a database driver.
25
25
  - Every provider is registered once, in `StorageProviderExtensions.AddStorageProviders(this ISiloBuilder)`, as a keyed singleton wrapped in `ResilientGrainStorage` (a Polly resilience pipeline configured from `Chronicle:ResilientStorage`). A new concern adds a constant, an `IGrainStorage` over `IStorage`, and one `AddKeyedSingleton(WellKnownGrainStorageProviders.<Name>, CreateResilientStorageFor<…>)` line there — nothing else.
26
26
  - Grains declare their state with `[PersistentState(nameof(<StateType>), WellKnownGrainStorageProviders.<Name>)]`.
27
27
 
28
+ Registration excerpt inside Chronicle's `StorageProviderExtensions`; the provider
29
+ is `Cratis.Chronicle.EventSequences.EventSequencesStorageProvider(IStorage)`:
30
+
28
31
  ```csharp
29
- public class JobGrainStorageProvider(IStorage storage) : IGrainStorage
32
+ // Copyright (c) Cratis. All rights reserved.
33
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
34
+
35
+ services.AddKeyedSingleton(WellKnownGrainStorageProviders.EventSequences, CreateResilientStorageFor<Cratis.Chronicle.EventSequences.EventSequencesStorageProvider>);
36
+ ```
37
+
38
+ Jobs are the exception to the kernel's `IStorage` shape: `JobGrainStorageProvider`
39
+ and `JobStepGrainStorageProvider` live in `Cratis.Orleans.Jobs` and take
40
+ `Cratis.Orleans.Storage.IJobsStorage`. Chronicle registers them under
41
+ `Cratis.Orleans.WellKnownGrainStorageProviders.Jobs` and `.JobSteps`, still wrapped
42
+ in its resilient storage pipeline.
43
+
44
+ ## Co-host a silo with Cratis.Orleans
45
+
46
+ For service authors, `Cratis.Orleans` supplies hosting, grain serializers, and the
47
+ shared job system without requiring Chronicle. With `Cratis.Orleans` and
48
+ `Cratis.Orleans.Storage.MongoDB` 1.16.3, this host uses durable MongoDB membership
49
+ and jobs storage (a local MongoDB server is required):
50
+
51
+ ```csharp
52
+ // Copyright (c) Cratis. All rights reserved.
53
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
54
+
55
+ using Cratis.Orleans.Hosting;
56
+ using Cratis.Orleans.Setup;
57
+ using Microsoft.AspNetCore.Builder;
58
+ using MongoDB.Driver;
59
+
60
+ var builder = WebApplication.CreateBuilder(args);
61
+ const string connectionString = "mongodb://localhost:27017";
62
+ builder.AddCratisOrleans(new CratisOrleansOptions
30
63
  {
31
- // ReadStateAsync / WriteStateAsync / ClearStateAsync over
32
- // storage.GetEventStore(key.EventStore).GetNamespace(key.Namespace).Jobs
33
- }
64
+ ClusterId = "my-service",
65
+ ServiceId = "my-service",
66
+ Clustering = ClusteringMode.MongoDB,
67
+ DatabaseName = "my-service-orleans",
68
+ ConnectionString = connectionString
69
+ });
70
+ builder.Services.AddCratisOrleansMongoDBJobsStorage(new MongoClient(connectionString));
34
71
 
35
- services.AddKeyedSingleton(WellKnownGrainStorageProviders.Jobs, CreateResilientStorageFor<JobGrainStorageProvider>);
72
+ var app = builder.Build();
73
+ app.Run();
36
74
  ```
75
+
76
+ - Register jobs storage separately: `AddCratisOrleansMongoDBJobsStorage`,
77
+ `AddCratisOrleansSqlJobsStorage` (`Cratis.Orleans.Setup`), or
78
+ `AddCratisOrleansInMemoryJobsStorage` (`Cratis.Orleans.Storage`).
79
+ - Give grain implementations a unique `[GrainType("unique-name")]`. Orleans'
80
+ default type name derives from the class name alone; a collision across
81
+ assemblies prevents silo startup.
82
+ - Reminders deliberately use Orleans' in-memory service in both clustering
83
+ modes; they do not survive a full restart. Jobs rehydrate from durable jobs
84
+ storage and do not use reminders. Do not switch to the incompatible MongoDB
85
+ reminder table merely because clustering uses MongoDB.
86
+ - `AddCratisOrleans` enables activity propagation itself. If a host keeps an
87
+ explicit `AddActivityPropagation()` call, it must be **before**, never after,
88
+ `AddCratisOrleans`, to avoid duplicate Orleans propagation filters/spans.
89
+ - Keep Orleans package versions aligned: the Release-build guard rejects a
90
+ `Microsoft.Orleans.Reminders`/`Microsoft.Orleans.Server` version mismatch.
91
+ - `Enabled = false` makes `AddCratisOrleans` a no-op for specification hosts;
92
+ it does not register the silo or its collaborators.
@@ -72,9 +72,12 @@ profile includes neither Screenplay nor Stage.
72
72
  | Profile ID | Description | Automatically Includes |
73
73
  |---|---|---|
74
74
  | `cratis/arc` | Arc CQRS framework | `cratis/arc/csharp`, `cratis/arc/java`, `cratis/arc/kotlin` |
75
- | `cratis/chronicle` | Chronicle event sourcing engine | `cratis/chronicle/compliance`, `cratis/chronicle/csharp`, `cratis/chronicle/elixir`, `cratis/chronicle/java`, `cratis/chronicle/kotlin`, `cratis/chronicle/multi-tenancy`, `cratis/chronicle/typescript`, `cratis/chronicle/web-workbench` |
75
+ | `cratis/chronicle` | Chronicle event sourcing engine (does not compose `cratis/chronicle/mcp`) | `cratis/chronicle/compliance`, `cratis/chronicle/csharp`, `cratis/chronicle/elixir`, `cratis/chronicle/java`, `cratis/chronicle/kotlin`, `cratis/chronicle/multi-tenancy`, `cratis/chronicle/typescript`, `cratis/chronicle/web-workbench` |
76
76
  | `cratis/components` | React component library | (no child profiles) |
77
77
  | `cratis/fundamentals` | Core primitives (`ConceptAs<T>`, `EventSourceId<T>`) | (no child profiles) |
78
+ | `cratis/arc/go` | Experimental Arc.Go HTTP CQRS (root module) | `cratis/language/go`, `cratis/fundamentals/go` |
79
+ | `cratis/chronicle/client-go` | Experimental standalone Chronicle.Go client | `cratis/language/go`, `cratis/fundamentals/go` |
80
+ | `cratis/fundamentals/go` | Fundamentals.Go named scalar concepts and codecs | `cratis/language/go` |
78
81
  | `cratis/specifications` | Specification framework | (no child profiles) |
79
82
  | `cratis/specifications/dotnet` | C# specifications and application slice conformance (`cratis-application-slice-conformance`), alongside slice specifications | `cratis/specifications` |
80
83
 
@@ -82,8 +85,9 @@ profile includes neither Screenplay nor Stage.
82
85
 
83
86
  | Profile ID | Description | Automatically Includes |
84
87
  |---|---|---|
85
- | `cratis/engineering` | Engineering conventions and workflows | `cratis/engineering/core`, `cratis/engineering/csharp`, `cratis/engineering/elixir`, `cratis/engineering/kotlin`, `cratis/engineering/react`, `cratis/engineering/typescript` |
88
+ | `cratis/engineering` | Engineering conventions and workflows | `cratis/engineering/core`, `cratis/engineering/csharp`, `cratis/engineering/elixir`, `cratis/engineering/go`, `cratis/engineering/kotlin`, `cratis/engineering/react`, `cratis/engineering/typescript` |
86
89
  | `cratis/engineering/csharp` | C# engineering conventions | `cratis/engineering/core` |
90
+ | `cratis/engineering/go` | Go framework parity and immutable module releases | `cratis/engineering/core`, `cratis/language/go` |
87
91
  | `cratis/engineering/typescript` | TypeScript engineering conventions | `cratis/engineering/core` |
88
92
  | `cratis/engineering/react` | React engineering conventions | `cratis/engineering/core` |
89
93
 
@@ -94,13 +98,15 @@ profile includes neither Screenplay nor Stage.
94
98
  | `cratis/language/csharp` | C# language conventions |
95
99
  | `cratis/language/typescript` | TypeScript language conventions |
96
100
  | `cratis/language/elixir` | Elixir language conventions |
101
+ | `cratis/language/go` | Go conventions for source, go.mod and go.sum |
97
102
  | `cratis/language/kotlin` | Kotlin language conventions |
98
103
  | `cratis/language/java` | Java language conventions |
99
104
 
100
105
  ### Arc and Chronicle on the JVM (Kotlin and Java)
101
106
 
102
107
  Arc.Kotlin (`io.cratis:arc`) and its optional Chronicle integration
103
- (`io.cratis:arc-chronicle-spring-boot-starter`) bring the same command/query
108
+ (`io.cratis:cratis`, the all-in-one event-sourced application artifact, or
109
+ `io.cratis:arc-chronicle-spring-boot-starter`) bring the same command/query
104
110
  model-bound shape to the JVM that Arc .NET brings to C#, for both Kotlin and
105
111
  Java application code. `cratis/arc/client-kotlin` carries the skills for both
106
112
  languages — Java application code still needs Kotlin and KSP on the build,
@@ -111,6 +117,9 @@ since Arc generates Kotlin adapters for Java declarations.
111
117
  | `cratis-arc-command-kotlin` | `@Command`, `handle()`/`provide()`, Chronicle event responses, command authorization, TypeScript proxy generation |
112
118
  | `cratis-arc-query-kotlin` | `@ReadModel` queries, GET vs RFC QUERY, observable queries (`Flow`, `Flow.Publisher`, RxJava 3) over SSE/WebSocket |
113
119
  | `cratis-arc-validation-kotlin` | `FluentModelValidator` shared rules, `CommandValidator`/`QueryValidator`/`ConceptValidator`/`ModelValidator`, Jakarta constraints |
120
+ | `cratis-arc-testing-kotlin` | Real in-process command/query scenarios, bounded observable collection, read-model pins and Chronicle append assertions |
121
+ | `cratis-arc-identity-and-tenancy-kotlin` | Authentication handlers, identity details, tenant resolution and propagation, opt-in trusted platform headers |
122
+ | `cratis-arc-spring-data-kotlin` | JPA/Mongo repositories, paging, observations, concept converters, tenant storage and transaction boundaries |
114
123
 
115
124
  Standalone Chronicle client usage (no Arc) for Kotlin and Java is
116
125
  `cratis-chronicle-client-kotlin`, reused by `cratis/chronicle/client-java`.
@@ -119,8 +128,10 @@ JVM language conventions are `kotlin.md` and `java.md`.
119
128
  ### Arc for TypeScript on Node.js
120
129
 
121
130
  Arc for TypeScript (`@cratis/arc.core` with the Express, Fastify, Hono,
122
- MongoDB, Drizzle, testing and experimental Chronicle packages) brings the same
123
- model-bound command/query shape to a Node.js server. Its packages are a source
131
+ MongoDB, Drizzle, testing and experimental Chronicle packages, plus
132
+ `@cratis/arc.proxygenerator`, `@cratis/eslint-plugin-arc-core` and experimental
133
+ `@cratis/cratis`) brings the same model-bound command/query shape to a Node.js
134
+ server. Verified at GitHub pre-release **v0.57.2**: its packages are a source
124
135
  preview and are not published to npm. It is separate from `@cratis/arc`, the
125
136
  published client runtime that generated proxies import in a frontend.
126
137
  `cratis/arc/server-typescript` carries the skills; `cratis/arc/typescript` adds
@@ -139,6 +150,30 @@ Node.js server and a C# or React-frontend project has no use for them. Select
139
150
  Standalone Chronicle client usage (no Arc) in TypeScript is
140
151
  `cratis-chronicle-client-typescript`.
141
152
 
153
+ ### Experimental Go modules
154
+
155
+ Select `cratis/language/go` for a Go repository without importing any HTTP or
156
+ Chronicle guidance. `cratis/engineering/go` adds contributor parity and release
157
+ policy through [go-engineering.md](./go-engineering.md), composing rather than
158
+ duplicating [go.md](./go.md). Set `languages: ["go"]` in `.cratis/ai.json` so
159
+ language-filtered composition selects the Go children. The catalog/manifest
160
+ register `go`; there is no separate extension-based detection registry in the
161
+ corpus's harness setup or Pi package.
162
+
163
+ | Profile | Skill | Verified experimental version |
164
+ | --- | --- | --- |
165
+ | `cratis/chronicle/client-go` | `cratis-chronicle-client-go` | Chronicle.Go v0.9.1 (Chronicle kernel 19.32.3 profile) |
166
+ | `cratis/arc/go` | `cratis-arc-go` | Arc.Go v0.1.1 |
167
+ | `cratis/fundamentals/go` | `cratis-fundamentals-concept-go` | Fundamentals.Go v0.3.2 |
168
+
169
+ Arc and Chronicle profiles compose language and Go concepts, **not each other**
170
+ or C# client/HTTP skills. These profiles are explicit opt-ins; existing aggregate
171
+ Arc/Chronicle and application profiles are unchanged. Only the Arc.Go root module
172
+ is released; Chronicle/MongoDB integrations and Go generator tools remain source
173
+ previews. `cratis/application/go` and Go scaffolding are deferred; do not prescribe
174
+ `dotnet new` as a Go template. Each module currently requires Go 1.26, but generic
175
+ language policy always follows the consuming repository's `go.mod` minimum.
176
+
142
177
  ### Specialized Profiles
143
178
 
144
179
  | Profile ID | Description |
@@ -149,6 +184,8 @@ Standalone Chronicle client usage (no Arc) in TypeScript is
149
184
  | `cratis/codescene` | Opt-in CodeScene Code Health change gates, refactoring, debt prioritization and risk-based testing; requires an account and available MCP tools; each user registers the MCP server (see below) |
150
185
  | `cratis/studio` | Studio MCP safety guidance |
151
186
  | `cratis/cli` | CLI operations |
187
+ | `cratis/cli/terminal-workbench` | Human-operated terminal Workbench |
188
+ | `cratis/chronicle/mcp` | Chronicle MCP inspection and exact tool-effect guidance |
152
189
  | `cratis/lens` | Lens browser extension |
153
190
  | `cratis/screenplay` | Model-first event modeling: lifecycle, phase skills, toolchain, review, render and gap-fill, plus the whole `.play` language |
154
191
  | `cratis/stage` | Stage rendering and sandbox |
@@ -355,7 +392,7 @@ profile: application
355
392
  - **Full catalog:** [profile-catalog.json](../profile-catalog.json)
356
393
  - **Application rules:** [general.md](./general.md) (Application profile section)
357
394
  - **Framework rules:** [framework.md](./framework.md)
358
- - **Engineering conventions:** [csharp.md](./csharp.md), [typescript.md](./typescript.md)
395
+ - **Engineering conventions:** [csharp.md](./csharp.md), [typescript.md](./typescript.md), [go.md](./go.md), [go-engineering.md](./go-engineering.md)
359
396
 
360
397
  ## See Also
361
398
 
@@ -6,7 +6,7 @@ applyTo: "**/*"
6
6
 
7
7
  ## The description is the release note
8
8
 
9
- **The PR description is published verbatim as the GitHub release. In repositories released by `cratis/release-action`, it also closes every issue written as `(#n)`; elsewhere, follow the repository's own release and issue-closing process.** Write the note the person upgrading should read, not a development write-up. The same contract applies to release notes typed into a manual workflow run or written straight into a release. Where it is installed, the `verify-release-notes` check enforces it on release-bound PRs into the default branch carrying `major`/`minor`/`patch` (it re-runs when the label is added); it warns on `no-release` and unlabelled PRs, which must still be written this way because any of them may become releasable. `release-action` does not run for a `no-release` PR, so `(#n)` closes nothing there. Editing the description re-runs the check. HTML comments are not shown on the release page and the check ignores them for headings, keywords and placeholders, but a `(#n)` inside a comment still closes the issue (`release-action` skips only fenced and inline code) and the check fails it, so never put an issue reference in a comment. The template's own comment can stay: its `(#123)` examples are inline code.
9
+ **The PR description is published verbatim as the GitHub release. In repositories released by `cratis/release-action`, it also closes every issue written as `(#n)`; elsewhere, follow the repository's own release and issue-closing process.** Write the note the person upgrading should read, not a development write-up. The same contract applies to release notes typed into a manual workflow run or written straight into a release. Where it is installed, the `verify-release-notes` check enforces it on release-bound PRs into the default branch carrying `major`/`minor`/`patch` (it re-runs when the label is added); it warns on `no-release` and unlabelled PRs, which must still be written this way because any of them may become releasable. `release-action` does not run for a `no-release` PR, so `(#n)` closes nothing there. Editing the description re-runs the check. HTML comments are not shown on the release page and the check ignores them for headings, keywords and placeholders, and `release-action` removes them before publishing, so a `(#n)` only inside a comment closes nothing; the check fails it, so never put an issue reference in a comment. The template's own comment can stay: its `(#123)` examples are inline code, and the comment is not published.
10
10
 
11
11
  ### Allowed shape
12
12
 
@@ -102,7 +102,7 @@ Quick reminders:
102
102
 
103
103
  Confirm the current repository workflow contract before selecting release intent because release-intent labels can trigger publication. A direct request to ship with a named label authorizes applying that label and completing the repository's standard pull-request workflow, including the release it normally triggers. Do not ask for separate authorization at each step. If the user did not request shipping or publication, a proposed semantic label describes impact but does not grant authority.
104
104
 
105
- - Exactly one of `major`/`minor`/`patch`/`no-release`, set in the creating command (`gh pr create --label patch`), in every repository, including samples, docs and tooling repositories (`no-release` when nothing is shipped). To change intent, swap labels in one command: `gh pr edit <n> --remove-label minor --add-label patch`. Never add a second.
105
+ - Exactly one of `major`/`minor`/`patch`/`no-release`, set in the creating command (`gh pr create --label patch`), in every repository, including samples, docs and tooling repositories (`no-release` when nothing is shipped). To change intent, swap labels in one command: `gh pr edit <n> --remove-label minor --add-label patch`. Never add a second: with more than one of them, release-action releases nothing and reports `reason=error`. Re-running a `pull_request` workflow replays the original label payload, so fix a label mistake by editing the PR or pushing; a `workflow_dispatch` run needs an explicit `version` and the PR description as `release-notes`, and without notes it closes no issues.
106
106
  - Dependabot PRs carry only `no-release`. release-action never releases them, and the `major`/`minor`/`patch` Dependabot adds describe the dependency's version, not this product's.
107
107
  - Label the PR according to semantic versioning impact:
108
108
  - **major** — breaking changes to public APIs
@@ -172,4 +172,4 @@ Before marking code/automation work ready, select the affected-project gates tha
172
172
  - `yarn lint` — zero errors
173
173
  - `npx tsc -b` — zero TypeScript errors
174
174
  - Code follows all project coding standards and conventions
175
- - **Required CI checks pass.** After an authorized push, inspect checks and failure logs. Diagnose within a bounded attempt, fix in-scope causes, and re-run relevant gates after each fix. Report unrelated/environmental failures and missing authority as blockers rather than retrying indefinitely or silently waiving required checks.
175
+ - **Required CI checks pass.** After an authorized push, inspect checks and failure logs. Diagnose within a bounded attempt, fix in-scope causes, and re-run relevant gates after each fix. Report unrelated/environmental failures and missing authority as blockers rather than retrying indefinitely or silently waiving required checks. If a release job fails after a concurrent merge (the release for the tag exists for another commit), re-run it: it releases under the next version (release-action v1.4.2 fails the job rather than reporting success).
@@ -149,7 +149,7 @@ Out-of-dialog execution branches in this order:
149
149
  const result = await command.execute();
150
150
  if (!result.isAuthorized) { redirectToLogin(); return; }
151
151
  if (!result.isValid) { /* validationResults → inline field errors */ return; }
152
- if (result.hasExceptions) { toast.error('Something went wrong'); console.error(result.exceptionMessages); return; }
152
+ if (result.hasExceptions) { toast.error({ title: 'Something went wrong' }); console.error(result.exceptionMessages); return; }
153
153
  // happy path — refresh queries, close, etc.
154
154
  ```
155
155
 
@@ -163,12 +163,19 @@ if (result.hasExceptions) { toast.error('Something went wrong'); console.error(r
163
163
  - **`asCommandFormField<P>(Component, opts)`** — wrap a custom input (rich text, address picker) so it participates in `CommandForm` with validation/error wiring.
164
164
  - **`CommandScope`** + `useCommandScope()` (`@cratis/arc.react/commands`) — aggregate state across multiple commands (and queries) on one screen; commands and queries rendered inside the scope register themselves (the `ICommandScope` API also exposes `addCommand`/`addQuery`/`addChildScope` for manual registration); scopes nest (a child reports up to its parent); injectable as `ICommandScope` (nearest enclosing scope). Props: `setHasChanges`, `setIsPerforming`, `onBeforeExecute`, `onSuccess(cmd, result)`, `onFailed`, `onException`, `onUnauthorized`. `ICommandScope` members: `hasChanges`, `isPerforming`, `hasValidationFailures`, `hasExceptions`, `validationFailures`/`exceptions` (this scope), `aggregatedValidationFailures`/`aggregatedExceptions` (scope + children), `execute()` (runs only commands with changes), `revertChanges()`, `parent`.
165
165
 
166
+ At Arc v22.75.0 `CommandForm` defaults to safe exception text rather than raw
167
+ server messages; customize with `exceptionMessage` or `exceptionDisplayComponent`
168
+ (`ExceptionDisplayProps`). `showErrors={false}` hides built-in display. Dynamic
169
+ accessors need explicit `fieldName`; custom field validation failures block submit.
170
+
166
171
  ### `<Arc>` global configuration
167
172
 
168
173
  Top-level provider for microservice name and API base path. Config props (with defaults):
169
174
 
170
175
  | Prop | Default | Notes |
171
176
  |---|---|---|
177
+ | `apiBasePath` | — | Backend API prefix; `<Arc basePath>` is deprecated, not router configuration |
178
+ | `detailsType` | — | Constructor for typed identity details |
172
179
  | `httpHeadersCallback` | — | returns `HeadersInit` merged into every request (bearer/tenant headers) |
173
180
  | `queryTransportMethod` | `ServerSentEvents` | SSE is capped at 4 connections on HTTP/1.1 |
174
181
  | `observableQueryTransferMode` | `Delta` | `Delta` = server ChangeSet/client diff; `Full` = all items as `added` |
@@ -56,7 +56,9 @@ public class OrderNotifications(INotificationService notifications) : IReactor
56
56
  - With a `[Replay]` handler, **only** it runs during replay — the regular handler does not also run.
57
57
  - Without one, the regular handler runs during replay exactly as before, so this changes nothing for existing reactors.
58
58
  - An event type handled *only* by a `[Replay]` handler is still subscribed to.
59
- - Reach for **`[OnceOnly]`** instead when the side effect should simply not happen again; use `[Replay]` when replay needs to do something *different* rather than nothing.
59
+ - Reach for **`[OnceOnly]`** when the side effect must not repeat **during replay**;
60
+ use `[Replay]` when replay needs different work. Neither suppresses ordinary
61
+ catch-up or recovery redelivery, nor limits runs per event source.
60
62
 
61
63
  ## Taking Dependencies
62
64
 
@@ -188,16 +190,38 @@ Cross-service events route through Chronicle's outbox/inbox rather than a shared
188
190
  - Chronicle creates/reuses the outbox→inbox subscription from the observer's `[EventStore]` metadata, or from `[EventStore]` on the event type/assembly. Put `[assembly: EventStore("<source-store>")]` in the contracts project when every event there originates from one service; use observer-level `[EventStore("<source-store>")]` to override.
189
191
  - An observer-level `[EventStore]` **cannot** be combined with `[EventSequence]`, `[EventLog]`, or `Reactor(eventSequence: ...)`.
190
192
 
193
+ ## Storage lookup failures are not absence
194
+
195
+ At **Chronicle v19.50.1**, a failed next-event lookup leaves the observer's
196
+ position unchanged. Routing defers delivery and the watchdog retries; only
197
+ `NotFound` proves absence and permits fast-forward. The watchdog likewise does
198
+ not advance on storage error. This fixes #4770, not every legacy delivery or
199
+ completion limitation. Quarantined observers do not resume from this retry.
200
+ Sources: `Source/Kernel/Core/Observation/States/Routing.cs` and
201
+ `Observation/Observer.Watchdog.cs` at v19.50.1.
202
+
191
203
  ## Confirming downstream completion — `WaitForCompletion`
192
204
 
193
- The default is fire-and-forget. When a caller's correctness depends on all observers (projections, reducers, reactors) having processed an appended event before returning — integration tests, synchronous webhook surfaces — call `WaitForCompletion` (from `Cratis.Chronicle.Observation`) on the `AppendResult`/`AppendManyResult`. It returns an `AppendResultWaitForCompletionResult` carrying `IsSuccess` and `FailedPartitions` (the full set across all affected observers, not just the first to fail). Reach for it deliberately — not as a default.
205
+ The default is fire-and-forget. When a caller's correctness depends on all observers (projections, reducers, reactors) having processed an appended event before returning — integration tests, synchronous webhook surfaces — call `WaitForCompletion` (from `Cratis.Chronicle.Observation`) on the `AppendResult`/`AppendManyResult`. At Chronicle **v19.50.0**, it returns `AppendResultWaitForCompletionResult` with
206
+ `IsSuccess`, `FailedPartitions`, `TimedOut` and `OutstandingObservers`. Inspect
207
+ all of these: timeout returns `TimedOut = true`, not a successful completion.
208
+ The optional `TimeSpan?` defaults to a 5-second server wait plus 200 ms client
209
+ grace; `Timeout.InfiniteTimeSpan` disables both deadlines. Filtering excludes
210
+ observers that do not consume the appended events when the client supplies the
211
+ first sequence number. Source: `Source/Clients/DotNET/Observation/AppendResultWaitForCompletionExtensions.cs`.
212
+ Reach for it deliberately, not as a default.
194
213
 
195
214
  ## Critical Rules
196
215
 
197
216
  1. **Idempotent** — Reactors may be called more than once for the same event (e.g. during replay or recovery). Design accordingly. For a side effect that must **not** repeat on replay (emails, payments, external writes), mark the handler method `[OnceOnly]` — Chronicle then skips that handler for every event arriving as part of a **replay** (observer rewind, redaction, revision). That is the whole of it: `[OnceOnly]` is replay-exclusion, **not** exactly-once and **not** a per-event-source counter. Recovering a failed partition re-delivers the event as an ordinary observation, so the handler runs again — which is the point of a retry. When the side effect must survive that retry too, take a `ReactorDelivery` parameter alongside the attribute and keep a receipt under its identity, which is stable across the failure and the recovery.
198
217
  2. **Use event data directly** — Never query the read model back inside a reactor. The event contains all the information you need.
199
218
  3. **Return events and commands instead of injecting the plumbing** — If the reactor needs to produce new events, return them directly as `Task<TEvent>`, `Task<EventForEventSourceId>`, or a collection thereof. For intent in another slice, return the `[Command]` (Arc executes it; a denied or invalid result fails the partition) — or inject `ICommandPipeline` and inspect the result. Either way the handler is `[OnceOnly]`. Avoid injecting `IEventLog` directly into a reactor.
200
- 4. **Single responsibility** — Each reactor class should have a focused purpose. Multiple handler methods in one reactor are fine if they serve the same automation concern.
219
+ 4. **Stable identity and single responsibility** — Give side-effecting reactors
220
+ an explicit `[Reactor("stable-id")]`: full-type-name identity changes on a rename
221
+ or move and catches up from the start, repeating side effects even with `[OnceOnly]`.
222
+ Chronicle v19.50.0 discovery warns on likely drift; `ArtifactIdentityDrift = Fail`
223
+ rejects Warning-level reactor/event-type drift (not Information-level read-model
224
+ findings). Each reactor class should have a focused purpose. Multiple handler methods in one reactor are fine if they serve the same automation concern.
201
225
  5. **Failure behavior** — If a reactor throws, *or* a returned side-effect event fails to append (constraint violation, concurrency violation, or error), the failing event-source partition pauses until the issue is resolved. Repeated failures can **quarantine** the observer: once `QuarantineOnFailedPartitionCount`/`QuarantineOnFailedPartitionPercentage` (under `Observers`) is crossed, the observer enters the `Quarantined` state — reminders cancelled, retries stopped, automatic recovery suppressed. **A quarantine ends when an operator clears it (`ClearObserverQuarantine()`), or when the observer is subscribed again** — for an application observer that is when the client connects again, for example after a redeploy; Kernel-owned observers are subscribed again when the Kernel starts. A periodic watchdog (default 60s, `WatchdogInterval`) re-routes stuck/dead observers but does not rescue quarantined ones. Design for resilience.
202
226
  6. **Don't throw to validate malformed inbound events** — reactors are not data-quality validators; invalid payloads must be rejected at the command/append site. When a malformed cross-service fact reaches a consumer, throwing just to reject it pauses the partition and can quarantine the whole observer. Instead append a clear failure/dead-letter event (e.g. `ProvisioningFailed`) or surface it via the operational failure path, and skip partial side effects.
203
227
  7. **No state** — Reactors should be stateless. Inject dependencies via primary constructor, but do not store mutable state on the class.
@@ -17,8 +17,9 @@ Extends the base [specs.md](./specs.md) (folder structure, naming, philosophy) w
17
17
 
18
18
  ## Frameworks
19
19
 
20
- - [xUnit](https://xunit.net/) for execution.
21
- - [Cratis.Specifications](https://github.com/Cratis/Specifications) for BDD specification by example — the `Specification` base class discovers `Establish`/`Because`/`Destroy` by convention (no attributes).
20
+ - [xUnit](https://xunit.net/) **2.x** for execution (not v3).
21
+ - Reference `Cratis.Specifications.XUnit` **4.1.1** for the `Specification` base, convention lifecycle and `ShouldXxx` assertions; the namespace remains `Cratis.Specifications`. Its `Cratis.Specifications` dependency supplies `Catch` and `SpecificationMethods`, not the base or assertions.
22
+ - 4.x targets net8.0/net9.0/net10.0; net48 requires 3.x. `Cratis.Specifications.NUnit` is an alternative with `[Test]` and public test methods; xUnit remains the house default.
22
23
  - [NSubstitute](https://nsubstitute.github.io/) for mocking collaborators.
23
24
  - Spec projects are named `<Source>.Specs`.
24
25
 
@@ -44,7 +45,11 @@ public class when_combining_parts : Specification
44
45
  | `void Establish()` | setup, before `Because()` | each class in the chain has its own, run base-first — never call `base.Establish()` |
45
46
  | `void Because()` | the single action under test | only in concrete spec files, never in a reusable context |
46
47
  | `[Fact] void should_*()` | one assertion per fact | use the `ShouldXxx()` extension methods |
47
- | `void Destroy()` | teardown after each test | |
48
+ | `void Destroy()` | teardown after each fact by default | once per eligible class with shared lifecycle opt-in |
49
+
50
+ Shared lifecycle is optional (4.1.0+): add `[assembly: Xunit.TestFramework("Cratis.Specifications.SpecificationTestFramework", "Cratis.Specifications.XUnit")]`. Eligible classes derive from `Specification`, have one public parameterless constructor, do not implement `IDisposable`, and contain only plain facts. Construction, Establish/Because and Destroy run once; all facts share the instance and must not mutate it. Initialization failure fails every fact. Other classes keep per-fact execution. Keep the stock lifecycle by default; details are in the **cratis-specifications-csharp** skill's shared-lifecycle reference.
51
+
52
+ CRSPEC0001–CRSPEC0007 are warnings bundled in `.Specifications`, `.XUnit`, and `.NUnit` 4.0.0+. With warnings as errors, a non-`should_` fact, multiple specs per file (given contexts exempt), a fact on a given context, a `should_` without a test attribute, explicit base lifecycle calls, non-public specs with facts, or `Because` on a given context fail the build. Follow **cratis-specification-by-example**; do not suppress these diagnostics.
48
53
 
49
54
  ## Reusable layered contexts
50
55
 
@@ -87,7 +92,9 @@ async Task Because() => _error = await Catch.Exception(_sut.DoSomething);
87
92
 
88
93
  ## Assertion extension methods
89
94
 
90
- From `Cratis.Specifications`: `.ShouldEqual(expected)`, `.ShouldBeTrue()`, `.ShouldBeFalse()`, `.ShouldBeNull()`, `.ShouldNotBeNull()`, `.ShouldBeEmpty()`, `.ShouldNotBeEmpty()`, `.ShouldContain(item)`, `.ShouldNotContain(item)`, `.ShouldContainOnly(items)`, `.ShouldBeOfExactType<T>()`, `.ShouldBeGreaterThan(n)`, `.ShouldBeLessThan(n)`.
95
+ From the `Cratis.Specifications.XUnit` package (namespace `Cratis.Specifications`): `.ShouldEqual(expected)`, `.ShouldBeTrue()`, `.ShouldBeFalse()`, `.ShouldBeNull()`, `.ShouldNotBeNull()`, `.ShouldBeEmpty()`, `.ShouldNotBeEmpty()`, `.ShouldContain(item)`, `.ShouldNotContain(item)`, `.ShouldContainOnly(items)`, `.ShouldBeOfExactType<T>()`, `.ShouldBeGreaterThan(n)`, `.ShouldBeLessThan(n)`.
96
+
97
+ Additional helpers include `ShouldNotEqual`, `ShouldBeSame`/`ShouldNotBeSame`, `ShouldMatch(Func<T, bool>)`, `ShouldBeInRange`, inclusive comparisons `ShouldBeGreaterThanOrEqual`/`ShouldBeLessThanOrEqual`, `ShouldContainSingleItem`, `ShouldEachConformTo`, ordered collection `ShouldEqual(IEnumerable<T>)`, collection `ShouldContain(Predicate<T>)`, `ShouldBeAssignableFrom<T>`, and string `ShouldContain(substring, StringComparison)`. `Catch.Exception` accepts `Action` or `Func<Task>`; `Catch.Exception<T>(Action)` catches only T.
91
98
 
92
99
  ## Conventions
93
100