@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.
- package/package/corpus/agents/security-reviewer.md +1 -0
- package/package/corpus/agents/spec-writer.md +1 -1
- package/package/corpus/harnesses/pi/extensions/shared/rules.ts +3 -1
- package/package/corpus/hooks/scripts/cratis-nuget-pins.txt +7 -6
- package/package/corpus/hooks/scripts/cratis-release-notes-reviewed.cjs +7 -6
- package/package/corpus/hooks/scripts/cratis-store-mutations.json +7 -3
- package/package/corpus/product-sync.json +896 -0
- package/package/corpus/prompts/add-business-rule.prompt.md +1 -1
- package/package/corpus/prompts/ship-changes.prompt.md +2 -2
- package/package/corpus/rules/ai-distribution.md +31 -3
- package/package/corpus/rules/application-profile.md +2 -1
- package/package/corpus/rules/components.md +66 -7
- package/package/corpus/rules/concepts.md +11 -3
- package/package/corpus/rules/csharp.md +3 -1
- package/package/corpus/rules/dialogs.md +9 -0
- package/package/corpus/rules/efcore.md +1 -1
- package/package/corpus/rules/elixir.md +49 -0
- package/package/corpus/rules/framework.md +5 -3
- package/package/corpus/rules/general.md +1 -0
- package/package/corpus/rules/glossary.md +4 -4
- package/package/corpus/rules/go-engineering.md +60 -0
- package/package/corpus/rules/go.md +115 -0
- package/package/corpus/rules/java.md +5 -2
- package/package/corpus/rules/kotlin.md +7 -5
- package/package/corpus/rules/orleans.md +65 -9
- package/package/corpus/rules/profiles.md +43 -6
- package/package/corpus/rules/pull-requests.md +3 -3
- package/package/corpus/rules/react.md +8 -1
- package/package/corpus/rules/reactors.md +27 -3
- package/package/corpus/rules/specs.csharp.md +11 -4
- package/package/corpus/rules/specs.scenarios.csharp.md +35 -4
- package/package/corpus/rules/specs.typescript.md +2 -1
- package/package/corpus/rules/storybook.md +1 -1
- package/package/corpus/rules/typescript.md +1 -1
- package/package/corpus/rules/vertical-slices.md +37 -5
- package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -2
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +18 -8
- package/package/corpus/skills/cratis-application-slice-specifications/references/query-and-decision-scenarios.md +65 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +53 -57
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +38 -42
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +18 -7
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authproxy.md +30 -0
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +12 -9
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +9 -9
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/observable-emission-guards.md +8 -5
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +20 -4
- package/package/corpus/skills/cratis-arc-command/SKILL.md +32 -10
- package/package/corpus/skills/cratis-arc-command/references/command-result.md +12 -5
- package/package/corpus/skills/cratis-arc-command/references/decisions-and-routing.md +95 -0
- package/package/corpus/skills/cratis-arc-command/references/generated-values.md +3 -2
- package/package/corpus/skills/cratis-arc-command/references/handler-shapes.md +8 -8
- package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +22 -3
- package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +13 -1
- package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +19 -9
- package/package/corpus/skills/cratis-arc-command-kotlin/SKILL.md +44 -18
- package/package/corpus/skills/cratis-arc-command-kotlin/references/read-model-naming.md +29 -0
- package/package/corpus/skills/cratis-arc-command-operation/SKILL.md +10 -9
- package/package/corpus/skills/cratis-arc-command-operation/references/execution-and-recovery.md +2 -2
- package/package/corpus/skills/cratis-arc-command-operation/references/testing.md +4 -3
- package/package/corpus/skills/cratis-arc-command-typescript/SKILL.md +42 -22
- package/package/corpus/skills/cratis-arc-command-typescript/references/chronicle-events.md +36 -5
- package/package/corpus/skills/cratis-arc-command-typescript/references/command-operations.md +114 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/hosting-and-storage.md +37 -16
- package/package/corpus/skills/cratis-arc-command-typescript/references/identity-and-introspection.md +88 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/observability-and-host-scopes.md +25 -0
- package/package/corpus/skills/cratis-arc-command-typescript/references/proxy-generation.md +35 -4
- package/package/corpus/skills/cratis-arc-command-typescript/references/slice-layout.md +11 -0
- package/package/corpus/skills/cratis-arc-command-typescript/verification.json +8 -1
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +49 -19
- package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +12 -6
- package/package/corpus/skills/cratis-arc-go/SKILL.md +148 -0
- package/package/corpus/skills/cratis-arc-go/references/queries.md +80 -0
- package/package/corpus/skills/cratis-arc-hosting/SKILL.md +96 -0
- package/package/corpus/skills/cratis-arc-hosting/references/integrations-and-publish.md +80 -0
- package/package/corpus/skills/cratis-arc-identity-and-tenancy-kotlin/SKILL.md +137 -0
- package/package/corpus/skills/cratis-arc-observable-query-http/SKILL.md +20 -2
- package/package/corpus/skills/cratis-arc-query-kotlin/SKILL.md +26 -6
- package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +25 -20
- package/package/corpus/skills/cratis-arc-query-typescript/SKILL.md +32 -6
- package/package/corpus/skills/cratis-arc-query-typescript/references/storage-observation-and-compliance.md +66 -0
- package/package/corpus/skills/cratis-arc-query-typescript/verification.json +5 -1
- package/package/corpus/skills/cratis-arc-react-page/SKILL.md +24 -13
- package/package/corpus/skills/cratis-arc-react-page/references/data-page.md +20 -10
- package/package/corpus/skills/cratis-arc-react-page/references/data-tables.md +17 -3
- package/package/corpus/skills/cratis-arc-react-page/references/dialogs.md +14 -3
- package/package/corpus/skills/cratis-arc-react-page/references/from-screenplay.md +6 -1
- package/package/corpus/skills/cratis-arc-react-page/references/provenance.md +1 -1
- package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +11 -1
- package/package/corpus/skills/cratis-arc-react-page/verification.json +6 -1
- package/package/corpus/skills/cratis-arc-spring-data-kotlin/SKILL.md +163 -0
- package/package/corpus/skills/cratis-arc-testing-kotlin/SKILL.md +131 -0
- package/package/corpus/skills/cratis-arc-validation-kotlin/SKILL.md +44 -11
- package/package/corpus/skills/cratis-arc-validation-typescript/SKILL.md +5 -3
- package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +79 -25
- package/package/corpus/skills/cratis-chronicle-cli-operations/references/command-effects.md +57 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +87 -99
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/additional-surfaces.md +65 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/client-construction.md +42 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/compatibility-check.md +12 -0
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/discovery.md +43 -19
- package/package/corpus/skills/cratis-chronicle-client-dotnet/references/hosting.md +29 -1
- package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +158 -162
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/append-api.md +36 -15
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/compliance.md +32 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/connections.md +56 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/event-sources.md +64 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/pitfalls.md +25 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/projections.md +48 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/upgrading.md +34 -0
- package/package/corpus/skills/cratis-chronicle-client-elixir/references/variants.md +13 -5
- package/package/corpus/skills/cratis-chronicle-client-elixir/verification.json +23 -0
- package/package/corpus/skills/cratis-chronicle-client-go/SKILL.md +162 -0
- package/package/corpus/skills/cratis-chronicle-client-go/references/projections.md +73 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +87 -88
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/connection-lifecycle.md +13 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/discovery-and-registration.md +14 -4
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/event-sources.md +65 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/options.md +29 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/spring-boot.md +13 -0
- package/package/corpus/skills/cratis-chronicle-client-kotlin/references/variants.md +5 -4
- package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +165 -156
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/read-models-and-projections.md +54 -11
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/testing.md +126 -0
- package/package/corpus/skills/cratis-chronicle-client-typescript/references/variants.md +3 -5
- package/package/corpus/skills/cratis-chronicle-client-typescript/verification.json +19 -0
- package/package/corpus/skills/cratis-chronicle-compliance/SKILL.md +36 -13
- package/package/corpus/skills/cratis-chronicle-decision-reads/SKILL.md +110 -0
- package/package/corpus/skills/cratis-chronicle-decision-reads/references/admission-and-ownership.md +57 -0
- package/package/corpus/skills/cratis-chronicle-decision-reads/verification.json +12 -0
- package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +58 -19
- package/package/corpus/skills/cratis-chronicle-event-constraints/references/closing-streams.md +73 -0
- package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +32 -3
- package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +18 -5
- package/package/corpus/skills/cratis-chronicle-event-type-migration/SKILL.md +32 -2
- package/package/corpus/skills/cratis-chronicle-hosting/SKILL.md +134 -0
- package/package/corpus/skills/cratis-chronicle-hosting/references/operations.md +89 -0
- package/package/corpus/skills/cratis-chronicle-hosting/verification.json +14 -0
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/SKILL.md +93 -66
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/blocked-tools.md +21 -7
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/deployment.md +77 -0
- package/package/corpus/skills/cratis-chronicle-mcp-inspection/references/observational-tools.md +46 -4
- package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +15 -1
- package/package/corpus/skills/cratis-chronicle-projection/SKILL.md +44 -10
- package/package/corpus/skills/cratis-chronicle-projection/references/fluent-builder.md +7 -1
- package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +8 -0
- package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +85 -105
- package/package/corpus/skills/cratis-chronicle-reactor/references/specifications.md +20 -1
- package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +35 -16
- package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +15 -3
- package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +23 -4
- package/package/corpus/skills/cratis-chronicle-web-workbench/SKILL.md +40 -15
- package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +20 -6
- package/package/corpus/skills/cratis-code-review/SKILL.md +25 -3
- package/package/corpus/skills/cratis-components-accessibility/SKILL.md +20 -4
- package/package/corpus/skills/cratis-components-schema-editor/SKILL.md +40 -28
- package/package/corpus/skills/cratis-components-schema-editor/references/tree-layout.md +62 -0
- package/package/corpus/skills/cratis-components-schema-editor/verification.json +14 -0
- package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +16 -8
- package/package/corpus/skills/cratis-components-styling/SKILL.md +57 -20
- package/package/corpus/skills/cratis-components-styling/verification.json +13 -0
- package/package/corpus/skills/cratis-components-toolbar/SKILL.md +37 -7
- package/package/corpus/skills/cratis-components-toolbar/verification.json +12 -0
- package/package/corpus/skills/cratis-engineering-csharp-conventions/SKILL.md +6 -0
- package/package/corpus/skills/cratis-engineering-csharp-conventions/references/exceptions-logging-and-di.md +5 -3
- package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +19 -6
- package/package/corpus/skills/cratis-fundamentals-concept/references/typescript-concepts.md +97 -0
- package/package/corpus/skills/cratis-fundamentals-concept/verification.json +4 -1
- package/package/corpus/skills/cratis-fundamentals-concept-go/SKILL.md +112 -0
- package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +54 -17
- package/package/corpus/skills/cratis-fundamentals-type-discovery/verification.json +14 -0
- package/package/corpus/skills/cratis-lens-browser-extension/SKILL.md +55 -28
- package/package/corpus/skills/cratis-performance-review/SKILL.md +5 -2
- package/package/corpus/skills/cratis-release-notes/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-automations-and-translations/SKILL.md +5 -4
- package/package/corpus/skills/cratis-screenplay-command-surface/SKILL.md +7 -11
- package/package/corpus/skills/cratis-screenplay-command-surface/references/compliance.md +26 -6
- package/package/corpus/skills/cratis-screenplay-command-surface/references/enum-numbers.md +4 -2
- package/package/corpus/skills/cratis-screenplay-command-surface/references/generated-values-and-responses.md +4 -1
- package/package/corpus/skills/cratis-screenplay-command-surface/verification.json +7 -1
- package/package/corpus/skills/cratis-screenplay-event-modeling/SKILL.md +3 -2
- package/package/corpus/skills/cratis-screenplay-event-modeling/references/parsed-not-runnable.md +6 -2
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/SKILL.md +1 -0
- package/package/corpus/skills/cratis-screenplay-legacy-extraction/references/generate-notes.md +34 -4
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +17 -24
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +19 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-tools.md +11 -3
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/property-links.md +90 -4
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +19 -2
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/gap-fill-handoff.md +3 -1
- package/package/corpus/skills/cratis-screenplay-scenario-coverage/SKILL.md +3 -1
- package/package/corpus/skills/cratis-screenplay-specifications/references/examples-and-routes.md +48 -0
- package/package/corpus/skills/cratis-screenplay-specifications/verification.json +3 -1
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/SKILL.md +4 -2
- package/package/corpus/skills/cratis-screenplay-streams-and-consistency/references/streams-example.md +5 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +8 -6
- package/package/corpus/skills/cratis-screenplay-toolchain/references/cheat-sheet-example.md +8 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/diagnostics.md +4 -2
- package/package/corpus/skills/cratis-screenplay-toolchain/references/doc-contradictions.md +7 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/executable-subset.md +24 -11
- package/package/corpus/skills/cratis-screenplay-toolchain/references/renderable-subset.md +10 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1543 -131
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/verdicts.md +9 -3
- package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +23 -7
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +1 -1
- package/package/corpus/skills/cratis-screenplay-ui-composition/SKILL.md +2 -0
- package/package/corpus/skills/cratis-screenplay-ui-composition/references/screen-composition-contract.md +27 -9
- package/package/corpus/skills/cratis-security-review/SKILL.md +9 -3
- package/package/corpus/skills/cratis-security-review/references/arc-boundaries.md +59 -0
- package/package/corpus/skills/cratis-specification-by-example/SKILL.md +7 -0
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +43 -11
- package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +16 -4
- package/package/corpus/skills/cratis-specifications-csharp/references/csharp-patterns.md +18 -5
- package/package/corpus/skills/cratis-specifications-csharp/references/integration-specs.md +21 -0
- package/package/corpus/skills/cratis-specifications-csharp/references/shared-lifecycle.md +34 -0
- package/package/corpus/skills/cratis-specifications-csharp/verification.json +13 -0
- package/package/corpus/skills/cratis-specifications-typescript/SKILL.md +14 -5
- package/package/corpus/skills/cratis-specifications-typescript/verification.json +12 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +8 -2
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +6 -3
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +10 -1
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/scene-runtime.md +75 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/verification.json +5 -0
- package/package/corpus/skills/cratis-studio-mcp-safety-guidance/SKILL.md +14 -1
- package/package/profile-catalog.json +68 -1
- package/package.json +1 -1
- 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
|
-
-
|
|
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
|
|
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
|
-
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
|
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/`).
|
|
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** —
|
|
24
|
-
- Each concern has its own `IGrainStorage` implementation (`
|
|
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
|
-
|
|
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
|
-
|
|
32
|
-
|
|
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
|
-
|
|
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:
|
|
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
|
|
123
|
-
|
|
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,
|
|
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]`**
|
|
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`.
|
|
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. **
|
|
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
|
-
-
|
|
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
|
|
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
|
|
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
|
|