@cratis/pi 7.37.0 → 7.38.1
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/harnesses/copilot/instructions/ai-distribution.instructions.md +109 -0
- package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +81 -0
- package/package/corpus/harnesses/copilot/instructions/capability-is-not-authority.instructions.md +45 -0
- package/package/corpus/harnesses/copilot/instructions/code-quality.csharp.instructions.md +92 -0
- package/package/corpus/harnesses/copilot/instructions/code-quality.instructions.md +83 -0
- package/package/corpus/harnesses/copilot/instructions/code-quality.typescript.instructions.md +90 -0
- package/package/corpus/harnesses/copilot/instructions/components.instructions.md +300 -0
- package/package/corpus/harnesses/copilot/instructions/concepts.instructions.md +138 -0
- package/package/corpus/harnesses/copilot/instructions/cratis-folder-is-configuration.instructions.md +29 -0
- package/package/corpus/harnesses/copilot/instructions/csharp.instructions.md +357 -0
- package/package/corpus/harnesses/copilot/instructions/dialogs.instructions.md +278 -0
- package/package/corpus/harnesses/copilot/instructions/documentation-structure-and-formatting.instructions.md +162 -0
- package/package/corpus/harnesses/copilot/instructions/documentation.instructions.md +90 -0
- package/package/corpus/harnesses/copilot/instructions/editing-cratis-docs.instructions.md +74 -0
- package/package/corpus/harnesses/copilot/instructions/efcore.instructions.md +84 -0
- package/package/corpus/harnesses/copilot/instructions/efcore.specs.instructions.md +45 -0
- package/package/corpus/harnesses/copilot/instructions/elixir.instructions.md +50 -0
- package/package/corpus/harnesses/copilot/instructions/exit-codes-and-wrappers.instructions.md +34 -0
- package/package/corpus/harnesses/copilot/instructions/framework.instructions.md +55 -0
- package/package/corpus/harnesses/copilot/instructions/frontend-quality.instructions.md +60 -0
- package/package/corpus/harnesses/copilot/instructions/frontend-testing.instructions.md +127 -0
- package/package/corpus/harnesses/copilot/instructions/git-commits.instructions.md +139 -0
- package/package/corpus/harnesses/copilot/instructions/github-actions.instructions.md +87 -0
- package/package/corpus/harnesses/copilot/instructions/glossary.instructions.md +63 -0
- package/package/corpus/harnesses/copilot/instructions/go-engineering.instructions.md +61 -0
- package/package/corpus/harnesses/copilot/instructions/go.instructions.md +116 -0
- package/package/corpus/harnesses/copilot/instructions/guards-and-fuses.instructions.md +61 -0
- package/package/corpus/harnesses/copilot/instructions/java.instructions.md +138 -0
- package/package/corpus/harnesses/copilot/instructions/kotlin.instructions.md +175 -0
- package/package/corpus/harnesses/copilot/instructions/local-work-artifacts.instructions.md +56 -0
- package/package/corpus/harnesses/copilot/instructions/new-repository-intake.instructions.md +35 -0
- package/package/corpus/harnesses/copilot/instructions/orleans.instructions.md +97 -0
- package/package/corpus/harnesses/copilot/instructions/profiles.instructions.md +403 -0
- package/package/corpus/harnesses/copilot/instructions/pull-requests.instructions.md +176 -0
- package/package/corpus/harnesses/copilot/instructions/react.instructions.md +203 -0
- package/package/corpus/harnesses/copilot/instructions/reactors.instructions.md +336 -0
- package/package/corpus/harnesses/copilot/instructions/rtk.instructions.md +48 -0
- package/package/corpus/harnesses/copilot/instructions/specs.csharp.instructions.md +147 -0
- package/package/corpus/harnesses/copilot/instructions/specs.instructions.md +133 -0
- package/package/corpus/harnesses/copilot/instructions/specs.scenarios.csharp.instructions.md +281 -0
- package/package/corpus/harnesses/copilot/instructions/specs.typescript.instructions.md +141 -0
- package/package/corpus/harnesses/copilot/instructions/storybook.instructions.md +85 -0
- package/package/corpus/harnesses/copilot/instructions/typescript.instructions.md +151 -0
- package/package/corpus/harnesses/copilot/instructions/verification-discipline.instructions.md +27 -0
- package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +414 -0
- package/package/corpus/harnesses/copilot/instructions/web-fetching.instructions.md +12 -0
- package/package/corpus/harnesses/copilot/instructions/writing-correct-examples.instructions.md +57 -0
- package/package/corpus/harnesses/copilot/instructions/writing-cratis-docs.instructions.md +72 -0
- package/package/corpus/product-sync.json +2 -2
- package/package/corpus/skills/cratis-screenplay-discovery/SKILL.md +11 -6
- package/package/corpus/skills/cratis-screenplay-discovery/references/facilitation.md +9 -5
- package/package/corpus/skills/cratis-screenplay-discovery/references/human-workshop.md +1 -1
- package/package/corpus/skills/cratis-screenplay-discovery/references/plotting-and-handoff.md +28 -4
- package/package/corpus/skills/cratis-screenplay-discovery/references/storming-loop.md +2 -1
- package/package/corpus/skills/cratis-screenplay-discovery/verification.json +5 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +23 -29
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +15 -1
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/model-notes.md +208 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +20 -1
- package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +19 -36
- package/package/corpus/skills/cratis-screenplay-model-review/references/report-template.md +26 -0
- package/package/corpus/skills/cratis-screenplay-model-review/verification.json +7 -0
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +14 -16
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/core-rules-digest.md +8 -3
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/handoff-template.md +5 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/intake.md +21 -0
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/reasoning-notes.md +10 -6
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/stop-or-assume.md +32 -1
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/worked-example.md +5 -2
- package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/verification.json +5 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +4 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1716 -183
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
- package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +40 -4
- package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/admission.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,116 @@
|
|
|
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
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
11
|
+
|
|
12
|
+
<!-- Copyright (c) Cratis. All rights reserved. -->
|
|
13
|
+
<!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
|
|
14
|
+
|
|
15
|
+
# Go conventions
|
|
16
|
+
|
|
17
|
+
Use Go's own packages, constructors, explicit registration and standard `testing`.
|
|
18
|
+
Do not import C# namespace layouts, one-type-per-file rules, `I` interface prefixes,
|
|
19
|
+
`Async` suffixes or .NET specification mechanics. Product APIs belong in the
|
|
20
|
+
matching Go skill; repository-owned context supplies module paths, layout and
|
|
21
|
+
exact commands.
|
|
22
|
+
|
|
23
|
+
## Minimum version and dependencies
|
|
24
|
+
|
|
25
|
+
- Read the `go` directive, build constraints and CI before choosing a feature.
|
|
26
|
+
The minimum is not the newest locally installed compiler; a `toolchain`
|
|
27
|
+
preference does not replace minimum-version testing. Do not raise it incidentally.
|
|
28
|
+
- Iterators require Go 1.23; `T.Context` and `B.Loop` require 1.24;
|
|
29
|
+
stable `testing/synctest` and `WaitGroup.Go` require 1.25.
|
|
30
|
+
- Prefer the standard library when it meets the contract. Review dependency
|
|
31
|
+
capability, license and compatibility before adding one.
|
|
32
|
+
- Change module files only for authorized dependency work. Review tidy changes,
|
|
33
|
+
including indirect minimum-version changes; keep sums consistent. A consumer
|
|
34
|
+
must not need a developer's workspace or local replacement.
|
|
35
|
+
- Never edit generated code; change its authoritative inputs and pinned generator.
|
|
36
|
+
|
|
37
|
+
## Names, public APIs and values
|
|
38
|
+
|
|
39
|
+
- Format handwritten Go with `gofmt`; use its tabs and the repository's import grouping.
|
|
40
|
+
- Use MixedCaps and preserve `ID`, `HTTP`, `URL`, `JSON` and `RPC` initialisms.
|
|
41
|
+
Avoid package stuttering and catch-all packages. Use American English.
|
|
42
|
+
- Keep public surfaces small and caller-oriented. Define interfaces at consuming
|
|
43
|
+
boundaries or where public substitution is a supported contract, not for every type.
|
|
44
|
+
- Document exported declarations with comments beginning with their names.
|
|
45
|
+
Explain nil/zero semantics, concurrency, ownership, cancellation, error identities
|
|
46
|
+
and cleanup. Add executable examples for important public workflows.
|
|
47
|
+
- Make zero values useful where possible; reject invalid construction early.
|
|
48
|
+
Document option defaults, validation, ordering and duplicates.
|
|
49
|
+
- Use named domain values instead of interchangeable primitives. Defined types
|
|
50
|
+
do not inherit codec methods; explicitly forward text/JSON codecs and test wire
|
|
51
|
+
formats. See `cratis-fundamentals-concept-go` when using Fundamentals.Go.
|
|
52
|
+
- Document whether slices, maps, config and results are owned, copied or borrowed.
|
|
53
|
+
Copying a slice/map header is not a detached copy. Do not copy a used mutex,
|
|
54
|
+
wait group or atomic value, or expose pooled bytes after returning their buffer.
|
|
55
|
+
|
|
56
|
+
## Errors, context and diagnostics
|
|
57
|
+
|
|
58
|
+
- Return ordinary failures as the final `error`; inspect errors, including cleanup.
|
|
59
|
+
Libraries must not exit the process or panic for expected failures.
|
|
60
|
+
- Preserve documented error identity with `errors.Is`/`errors.As`, not strings.
|
|
61
|
+
Wrapping with `%w` exposes that identity as API; do it deliberately. Do not
|
|
62
|
+
return an `error` interface containing a typed nil.
|
|
63
|
+
- Add useful operation context. Handle/log an error at one boundary rather than
|
|
64
|
+
repeatedly logging and returning it. A partial or ambiguous write is not success
|
|
65
|
+
and must not trigger a blind retry.
|
|
66
|
+
- Put `context.Context` first for blocking/cancelable work and propagate it through
|
|
67
|
+
RPCs, HTTP, storage and callbacks. Never escape caller cancellation by replacing
|
|
68
|
+
it with `Background`. Do not retain request contexts in long-lived clients.
|
|
69
|
+
- Call acquired cancel functions. Context values carry request metadata, not
|
|
70
|
+
dependencies or configuration; use private keys with typed accessors.
|
|
71
|
+
- Prefer injectable `log/slog` at a supported minimum. Do not mutate global logging
|
|
72
|
+
from a library. Redact credentials and sensitive payloads.
|
|
73
|
+
|
|
74
|
+
## Goroutines, streams and iterators
|
|
75
|
+
|
|
76
|
+
- Each goroutine needs an owner, termination condition and observable join path.
|
|
77
|
+
Cancellation requests termination; it does not join workers.
|
|
78
|
+
- Bound workers, queues, subscriptions, buffers and retries; define backpressure.
|
|
79
|
+
Make blocking operations cancellation-aware. Close channels only after senders stop.
|
|
80
|
+
- Do not hold locks while calling user code or performing slow I/O. Call
|
|
81
|
+
`WaitGroup.Add` before launching work when not using version-supported `Go`.
|
|
82
|
+
- Stop immediately when iterator `yield` returns false. Release resources on
|
|
83
|
+
exhaustion, early exit, failure and cancellation; call `iter.Pull`'s stop function.
|
|
84
|
+
Specify ordering, errors and whether a stream can be consumed more than once.
|
|
85
|
+
- Preserve protocol metadata, tenancy, checkpoints and duplicate-delivery semantics.
|
|
86
|
+
No generic retry or stream helper may promise exactly-once effects.
|
|
87
|
+
- Validate remote TLS identities. Development exceptions must be explicit.
|
|
88
|
+
Use cryptographic randomness for secrets, never `math/rand`.
|
|
89
|
+
|
|
90
|
+
## Specifications and checks
|
|
91
|
+
|
|
92
|
+
- Use standard `testing`, meaningful subtests, useful got/want diagnostics and
|
|
93
|
+
table-driven cases where setup/assertions actually match. Use external `_test`
|
|
94
|
+
packages to exercise public contracts where practical.
|
|
95
|
+
- Use `t.Helper`, `t.Cleanup` and `t.TempDir`. Isolate state before `t.Parallel`.
|
|
96
|
+
Synchronize with channels/joins, not guessed sleeps. Fake-time tests do not
|
|
97
|
+
establish real-network behavior.
|
|
98
|
+
- Cover error identity, nil/zero input, cancellation/deadlines, partial outcomes,
|
|
99
|
+
early stream exit and resource ownership. Bound fuzz duration and preserve
|
|
100
|
+
failing seeds. Use race checks where supported; race-free does not mean leak-free.
|
|
101
|
+
- Run the repository's build, tests, formatting, vet and pinned golangci-lint gates,
|
|
102
|
+
with race and vulnerability scanning as separate checks. Respect the declared
|
|
103
|
+
minimum without silent toolchain upgrades. Report absent tools honestly.
|
|
104
|
+
|
|
105
|
+
## Adaptation and attribution
|
|
106
|
+
|
|
107
|
+
This condensed rule adapts the repository-owned Go baseline at
|
|
108
|
+
[Chronicle.Go v0.9.1](https://github.com/Cratis/Chronicle.Go/blob/v0.9.1/.cratis/ai/rules/go.md)
|
|
109
|
+
and [Arc.Go v0.1.1](https://github.com/Cratis/Arc.Go/blob/v0.1.1/.cratis/ai/rules/go.md),
|
|
110
|
+
not their project paths or commands. The baseline's adapted readability,
|
|
111
|
+
error-boundary, public-option and goroutine recommendations retain attribution:
|
|
112
|
+
[Google Go style](https://google.github.io/styleguide/go/guide.html), Google,
|
|
113
|
+
[CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/); and
|
|
114
|
+
[Uber Go style](https://github.com/uber-go/guide/blob/master/style.md), Uber
|
|
115
|
+
Technologies, Inc., [Apache-2.0](https://github.com/uber-go/guide/blob/master/LICENSE).
|
|
116
|
+
No community code snippets are reproduced here.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*"
|
|
3
|
+
---
|
|
4
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
5
|
+
|
|
6
|
+
# Guards, scans and fuses
|
|
7
|
+
|
|
8
|
+
A guard that cannot fail is worse than no guard: it converts "nobody looked" into a green
|
|
9
|
+
check. Every line is tagged **[contract]** (binding) or **[convention]** (the house
|
|
10
|
+
default) per the Three Levels of Authority in [`general.md`](../../../rules/general.md).
|
|
11
|
+
|
|
12
|
+
**Scope.** This rule governs two situations: *authoring* a scanner, guard, allowlist or
|
|
13
|
+
checker, and *running a pass* that mutates a computed set of subjects rather than the
|
|
14
|
+
targets the request named. An ordinary edit, review, fix, or a change to the one file the
|
|
15
|
+
user pointed at is outside it and carries none of the machinery below.
|
|
16
|
+
|
|
17
|
+
## Non-vacuity
|
|
18
|
+
|
|
19
|
+
- **[contract] A scan over a possibly-empty population carries a non-vacuity check.**
|
|
20
|
+
Assert the subject count is what you expect before believing the result, and fail when
|
|
21
|
+
the population is unexpectedly empty.
|
|
22
|
+
- **[contract] Report the count on success.** "Checked 0 files, found 0 problems" and
|
|
23
|
+
"checked 412 files, found 0 problems" are different verdicts and must read differently.
|
|
24
|
+
- **[contract] A pattern that matches nothing is a defect in the pattern** until proven
|
|
25
|
+
otherwise. Prove a matcher still matches by planting a violation; see
|
|
26
|
+
[`exit-codes-and-wrappers.md`](./exit-codes-and-wrappers.instructions.md).
|
|
27
|
+
|
|
28
|
+
## Allowlists
|
|
29
|
+
|
|
30
|
+
- **[contract] Every allowlist entry records its reason** — why this subject is exempt,
|
|
31
|
+
and what would end the exemption.
|
|
32
|
+
- **[contract] Every allowlist entry has a sibling check** that fails when the entry
|
|
33
|
+
becomes unnecessary, so the list shrinks instead of accumulating forever.
|
|
34
|
+
- **[convention] Prefer an expiry to a permanent exemption.** An entry nobody revisits is
|
|
35
|
+
a rule quietly deleted.
|
|
36
|
+
|
|
37
|
+
## Bulk and irreversible passes
|
|
38
|
+
|
|
39
|
+
These contracts are keyed to the *risk class* of the effect — bulk deletion, history
|
|
40
|
+
rewriting, cross-repository migration, anything irreversible or high-fanout — not to
|
|
41
|
+
whether a person is watching. An autonomous session runs them exactly as an interactive
|
|
42
|
+
one does.
|
|
43
|
+
|
|
44
|
+
- **[contract] Distinguish "subject set empty" from "qualifying set empty".** Finding no
|
|
45
|
+
candidates at all is a different situation from finding candidates that none qualified;
|
|
46
|
+
a pass must refuse to proceed on the first.
|
|
47
|
+
- **[contract] Every pass carries a per-pass fuse** — a maximum number of subjects it may
|
|
48
|
+
act on in one run, which stops the run rather than trimming the work silently.
|
|
49
|
+
- **[contract] Know the recovery before the forward action.** For a reversible effect,
|
|
50
|
+
know how it is undone. For an irreversible one, preserve what the recovery needs first —
|
|
51
|
+
a backup ref, a copy under `.ai-work/keep/`, the list of targets — and stop if nothing
|
|
52
|
+
can be preserved and the request did not name the targets. Do not demand an exact
|
|
53
|
+
inverse where none can exist.
|
|
54
|
+
- **[contract] Re-read preconditions immediately before each mutation and stop when drift
|
|
55
|
+
invalidates the authorized scope, safety assumptions, or recovery plan.** Benign drift
|
|
56
|
+
within an already authorized bounded pass does not require another confirmation.
|
|
57
|
+
- **[convention] When the targets were not already established in the conversation, show
|
|
58
|
+
the dry-run list and act on it once the user has answered.** A user who has reviewed
|
|
59
|
+
and authorized those targets is not asked to approve the same pass again. The list is a
|
|
60
|
+
message in the conversation, not a retained artifact: do not write receipts, ledgers,
|
|
61
|
+
snapshots or escrow copies of it.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*.java"
|
|
3
|
+
paths:
|
|
4
|
+
- "**/*.java"
|
|
5
|
+
---
|
|
6
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
7
|
+
|
|
8
|
+
# Java Conventions
|
|
9
|
+
|
|
10
|
+
Java is a supported, first-class Cratis application language alongside Kotlin
|
|
11
|
+
— an Arc.Kotlin-based application can be entirely Java source, with Kotlin and
|
|
12
|
+
KSP present only in the build (Arc generates Kotlin adapters for Java
|
|
13
|
+
declarations under the hood). Write idiomatic modern Java; do not import
|
|
14
|
+
Kotlin idioms into Java source, and do not treat Java as a second-class
|
|
15
|
+
citizen of a Kotlin codebase. Arc/Chronicle-specific shapes (`@Command`,
|
|
16
|
+
`@ReadModel`, `@EventType`, and the rest) live in the matching skill, not
|
|
17
|
+
here.
|
|
18
|
+
|
|
19
|
+
## Building
|
|
20
|
+
|
|
21
|
+
- Use `./gradlew build` (or the repository's Maven equivalent) from the
|
|
22
|
+
command line; it is the definition of "the build is clean" — zero warnings,
|
|
23
|
+
zero errors.
|
|
24
|
+
- Treat compiler warnings as errors (`-Xlint:all -Werror`); do not suppress a
|
|
25
|
+
warning to get to green.
|
|
26
|
+
|
|
27
|
+
## Formatting
|
|
28
|
+
|
|
29
|
+
- Four-space indentation, no tabs.
|
|
30
|
+
- One public top-level type per file, named after that type.
|
|
31
|
+
- Sort imports alphabetically; no wildcard imports.
|
|
32
|
+
- Braces on the same line as the declaration (`if (...) {`), closing brace on
|
|
33
|
+
its own line.
|
|
34
|
+
|
|
35
|
+
## Language — American English Only
|
|
36
|
+
|
|
37
|
+
All identifiers, Javadoc, and string literals use **American English**
|
|
38
|
+
spelling (initialize, serialize, behavior, color, organization, center,
|
|
39
|
+
modeling, dialog, license, judgment, gray). See [general.md](../../../rules/general.md).
|
|
40
|
+
|
|
41
|
+
## Naming
|
|
42
|
+
|
|
43
|
+
- PascalCase for class and interface names.
|
|
44
|
+
- camelCase for methods, fields, and local variables.
|
|
45
|
+
- New application and Arc-style interfaces have no `I` prefix — name them
|
|
46
|
+
for what they do. Chronicle.Kotlin's published interfaces retain their names
|
|
47
|
+
(`IEventStore`, `IChronicleClient`, `IProjectionFor`, `IReactorMiddleware`).
|
|
48
|
+
- Never suffix a class with `Impl`, `Manager`, or `Helper` purely to
|
|
49
|
+
disambiguate — name it for its role; reserve `Default<Name>` for the
|
|
50
|
+
concrete counterpart of an interface meant to be overridden.
|
|
51
|
+
|
|
52
|
+
## Records and Immutable Data
|
|
53
|
+
|
|
54
|
+
- Prefer a `record` for an immutable value holder (DTOs, command payloads,
|
|
55
|
+
query results, read models) over a hand-written class with a constructor,
|
|
56
|
+
getters, `equals`, `hashCode`, and `toString` — the record gives all of that
|
|
57
|
+
for free and keeps the file short.
|
|
58
|
+
- Give a record component a validating compact constructor when the type must
|
|
59
|
+
never hold an invalid value, rather than validating at every call site that
|
|
60
|
+
constructs one.
|
|
61
|
+
- Favor `sealed` interfaces with a closed set of `permits` implementations
|
|
62
|
+
over a discriminator field, when a value can genuinely only be one of a
|
|
63
|
+
known set of shapes — pattern matching over the sealed hierarchy replaces
|
|
64
|
+
the `instanceof` chain.
|
|
65
|
+
|
|
66
|
+
## Nullability
|
|
67
|
+
|
|
68
|
+
- Prefer `Optional<T>` for a method's **return type** when absence is a normal
|
|
69
|
+
outcome the caller must handle; never use `Optional` as a field type, a
|
|
70
|
+
constructor parameter, or a method parameter — that is not what it is for.
|
|
71
|
+
- Prefer a non-null default and an explicit `Objects.requireNonNull(...)` at a
|
|
72
|
+
constructor boundary over accepting `null` and checking for it throughout a
|
|
73
|
+
class.
|
|
74
|
+
- On a surface consumed from Kotlin (an Arc/Chronicle read model, event, or
|
|
75
|
+
command reached from Kotlin code), be deliberate about which fields are
|
|
76
|
+
genuinely optional — a Java field with no null-safety annotation reads as
|
|
77
|
+
non-null to Kotlin-facing generated code by default.
|
|
78
|
+
|
|
79
|
+
## Classes
|
|
80
|
+
|
|
81
|
+
- Favor composition over inheritance; an `interface` plus one or more
|
|
82
|
+
implementing classes is the house shape for an overridable collaborator, not
|
|
83
|
+
a base class meant to be extended.
|
|
84
|
+
- Make a class `final` unless it is deliberately designed for extension.
|
|
85
|
+
- Prefer constructor injection over field injection for a Spring-managed
|
|
86
|
+
bean — a `final` field set in the constructor over an `@Autowired` field.
|
|
87
|
+
|
|
88
|
+
## Asynchronous Code
|
|
89
|
+
|
|
90
|
+
- `CompletionStage<T>` (or its `CompletableFuture` implementation) is the
|
|
91
|
+
house shape for an asynchronous Java API, mirroring how Kotlin exposes
|
|
92
|
+
`suspend` — Arc's generated adapters await a returned `CompletionStage`
|
|
93
|
+
without reflection.
|
|
94
|
+
- Never block on a `CompletionStage` inside a method that itself returns
|
|
95
|
+
one — compose with `.thenApply`/`.thenCompose` or `.thenAccept` instead of
|
|
96
|
+
calling `.get()`/`.join()` inside the async chain.
|
|
97
|
+
- Give a Java caller its own explicit scope (an `ExecutorService`, or the
|
|
98
|
+
scope type the host library provides) rather than reaching for a shared
|
|
99
|
+
global one.
|
|
100
|
+
|
|
101
|
+
## Javadoc
|
|
102
|
+
|
|
103
|
+
- Every public type and method meant for consumption outside its package gets
|
|
104
|
+
a Javadoc comment (`/** ... */`) — what it does and why, not a restatement
|
|
105
|
+
of its name.
|
|
106
|
+
- Use `@param`, `@return`, and `@throws` for parameters, return values, and
|
|
107
|
+
checked exceptions.
|
|
108
|
+
|
|
109
|
+
## Exceptions
|
|
110
|
+
|
|
111
|
+
- Use exceptions for genuinely exceptional, unrecoverable conditions — not for
|
|
112
|
+
control flow a caller is expected to handle. A command or query rejection a
|
|
113
|
+
user can act on is a validation result, not a thrown exception; see the Arc
|
|
114
|
+
validation skills.
|
|
115
|
+
- Prefer an unchecked exception with a clear name over a checked exception
|
|
116
|
+
that forces every caller to catch or declare it; reserve checked exceptions
|
|
117
|
+
for conditions a caller genuinely has a recovery path for.
|
|
118
|
+
|
|
119
|
+
## Dependency Injection
|
|
120
|
+
|
|
121
|
+
- Constructor injection is the default for a Spring-managed bean; avoid field
|
|
122
|
+
injection (`@Autowired` on a field) even though Spring supports it.
|
|
123
|
+
|
|
124
|
+
## Logging
|
|
125
|
+
|
|
126
|
+
- Log through the host's structured logging facility (SLF4J via Spring Boot),
|
|
127
|
+
not `System.out`/`System.err`.
|
|
128
|
+
- Log at the boundary where a decision is made or an error is handled, not at
|
|
129
|
+
every intermediate call.
|
|
130
|
+
|
|
131
|
+
## Testing
|
|
132
|
+
|
|
133
|
+
- JUnit Jupiter is the house test runner (the Cratis JVM repositories use
|
|
134
|
+
Jupiter 6.1.x).
|
|
135
|
+
- A test for a Java-facing surface belongs beside the Java production code
|
|
136
|
+
(`src/test/java/.../<Thing>Test.java`) and must actually compile and run
|
|
137
|
+
against that surface — a Kotlin-only test does not prove Java call-site
|
|
138
|
+
compatibility for a mixed-language library.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*.kt,**/*.kts"
|
|
3
|
+
paths:
|
|
4
|
+
- "**/*.kt"
|
|
5
|
+
- "**/*.kts"
|
|
6
|
+
---
|
|
7
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
8
|
+
|
|
9
|
+
# Kotlin Conventions
|
|
10
|
+
|
|
11
|
+
Kotlin is a JVM-first, coroutine-first language. Use its own idioms — data
|
|
12
|
+
classes, `null`-aware types, coroutines, sealed hierarchies — instead of
|
|
13
|
+
carrying Java or C# patterns across unchanged. A Cratis Arc or Chronicle
|
|
14
|
+
application on Kotlin follows Spring Boot conventions for wiring and this
|
|
15
|
+
file's conventions for everything else; Arc/Chronicle-specific shapes
|
|
16
|
+
(`@Command`, `@ReadModel`, `@EventType`, and the rest) live in the matching
|
|
17
|
+
skill, not here.
|
|
18
|
+
|
|
19
|
+
## Building
|
|
20
|
+
|
|
21
|
+
- Use `./gradlew build` from the command line; it is the definition of "the
|
|
22
|
+
build is clean" — zero warnings, zero errors.
|
|
23
|
+
- Use `./gradlew test` to run tests.
|
|
24
|
+
- Treat compiler warnings as errors. `allWarningsAsErrors` is the house
|
|
25
|
+
default for Kotlin compilation; do not add a suppression to get to green.
|
|
26
|
+
|
|
27
|
+
## Formatting
|
|
28
|
+
|
|
29
|
+
- Four-space indentation, no tabs.
|
|
30
|
+
- One top-level public declaration per file, named after that declaration.
|
|
31
|
+
- Sort imports alphabetically; no wildcard imports.
|
|
32
|
+
- Trailing commas in multi-line parameter lists and call sites — they keep
|
|
33
|
+
diffs to one line when a member is added or removed.
|
|
34
|
+
- Insert a blank line before the opening `{` of a multi-line `if`/`when`/`for`
|
|
35
|
+
block; keep single-expression bodies on one line.
|
|
36
|
+
|
|
37
|
+
## Language — American English Only
|
|
38
|
+
|
|
39
|
+
All identifiers, KDoc, and string literals use **American English** spelling
|
|
40
|
+
(initialize, serialize, behavior, color, organization, center, modeling,
|
|
41
|
+
dialog, license, judgment, gray). See [general.md](../../../rules/general.md).
|
|
42
|
+
|
|
43
|
+
## Naming
|
|
44
|
+
|
|
45
|
+
- PascalCase for class, interface, and object names.
|
|
46
|
+
- camelCase for functions, properties, and local variables.
|
|
47
|
+
- New application and Arc-style interfaces have no `I` prefix; name them for
|
|
48
|
+
what they do (`CommandPipeline`, not `ICommandPipeline`). Reserve
|
|
49
|
+
`Default<Name>` for a concrete/interface pair when needed. Chronicle.Kotlin's
|
|
50
|
+
published types retain their names (`IEventStore`, `IChronicleClient`,
|
|
51
|
+
`IProjectionFor`, `IReactorMiddleware`); do not rename framework APIs.
|
|
52
|
+
- Never suffix a class with `Impl`, `Service`, or `Async` purely to
|
|
53
|
+
disambiguate — name it for its role.
|
|
54
|
+
|
|
55
|
+
## Visibility
|
|
56
|
+
|
|
57
|
+
- Kotlin's implicit-public default is what most declarations should use;
|
|
58
|
+
spelling `public` is a style choice, not a requirement — decide once per
|
|
59
|
+
file or module and stay consistent within it.
|
|
60
|
+
- Mark a declaration `internal` when it must not cross a module boundary, and
|
|
61
|
+
`private` for anything a class does not need to expose. Do not default
|
|
62
|
+
everything to `public` "to be safe" — a wider surface than necessary is a
|
|
63
|
+
bigger contract to keep stable.
|
|
64
|
+
- Compile-time discovery (KSP, reflection-based scanning) generally requires
|
|
65
|
+
**public** top-level types and members. A declaration silently excluded from
|
|
66
|
+
discovery because it is `internal` or `private` is a visibility bug, not a
|
|
67
|
+
framework limitation — check the matching skill's discovery rules before
|
|
68
|
+
assuming a narrower visibility is safe.
|
|
69
|
+
|
|
70
|
+
## Nullability
|
|
71
|
+
|
|
72
|
+
Kotlin's type system is the first line of defense against null-related bugs —
|
|
73
|
+
trust it the same way C# nullable reference types are trusted.
|
|
74
|
+
|
|
75
|
+
- Prefer a non-nullable type and a real default over a nullable one with a
|
|
76
|
+
defensive check.
|
|
77
|
+
- Use `?.`, `?:`, and `requireNotNull()`/`checkNotNull()` instead of manual
|
|
78
|
+
`if (x != null)` guards.
|
|
79
|
+
- A nullable outer collection (`List<T>?`) is supported; a nullable *element*
|
|
80
|
+
inside a collection (`List<T?>`) is a narrower, often-unsupported shape in
|
|
81
|
+
generated/serialized contracts — do not reach for it without checking
|
|
82
|
+
whether the surface you are writing actually allows it.
|
|
83
|
+
- Data classes model state, not behavior — keep validation and invariants in
|
|
84
|
+
the type that owns them (a concept, a validator), not scattered across every
|
|
85
|
+
call site that happens to touch a nullable field.
|
|
86
|
+
|
|
87
|
+
## Classes and Data
|
|
88
|
+
|
|
89
|
+
- Prefer `data class` for immutable value holders (DTOs, events, command
|
|
90
|
+
payloads, read models) — value equality, `copy()`, and `componentN()`
|
|
91
|
+
destructuring come for free.
|
|
92
|
+
- Prefer a primary constructor with `val` properties over a body full of
|
|
93
|
+
assignment statements.
|
|
94
|
+
- Reach for a `sealed class`/`sealed interface` hierarchy instead of an enum
|
|
95
|
+
with a payload bolted on, whenever the variants carry different data.
|
|
96
|
+
- Favor composition over inheritance; an `interface` plus a `Default*`
|
|
97
|
+
implementation is the house shape for an overridable collaborator, not a
|
|
98
|
+
base class meant to be extended.
|
|
99
|
+
|
|
100
|
+
## Coroutines
|
|
101
|
+
|
|
102
|
+
- An asynchronous API is `suspend`, not a returned `Future`/`CompletableFuture`
|
|
103
|
+
— Kotlin callers compose `suspend` functions directly, and a JVM-facing
|
|
104
|
+
bridge (`CompletionStage`) is layered on top for Java callers, never the
|
|
105
|
+
other way around.
|
|
106
|
+
- Per-call state travels in a `CoroutineContext` element; never a
|
|
107
|
+
`ThreadLocal`. A coroutine can move between threads, and thread-local state
|
|
108
|
+
silently goes stale when it does.
|
|
109
|
+
- Never launch on `GlobalScope`. Use the scope the host (Spring Boot's bounded
|
|
110
|
+
application coroutine scope, a test's `runBlocking`/`runTest`) already
|
|
111
|
+
provides.
|
|
112
|
+
- Cleanup that must run even after cancellation goes in
|
|
113
|
+
`withContext(NonCancellable) { ... }`; everything else should stay
|
|
114
|
+
cancellable rather than swallow the cancellation.
|
|
115
|
+
- Bridge a genuinely thread-bound third-party API with a
|
|
116
|
+
`ThreadContextElement`; do not leak a raw `ThreadLocal` into coroutine-facing
|
|
117
|
+
state as a shortcut.
|
|
118
|
+
|
|
119
|
+
## Java Interop
|
|
120
|
+
|
|
121
|
+
Kotlin/Java interop is a first-class concern whenever a library or an
|
|
122
|
+
application may be consumed from Java — which every Arc/Chronicle application
|
|
123
|
+
should assume by default:
|
|
124
|
+
|
|
125
|
+
- Add `@JvmStatic` to companion-object factories a Java caller needs to call
|
|
126
|
+
without `Companion.`.
|
|
127
|
+
- Add `@JvmOverloads` to a function with default parameter values so Java
|
|
128
|
+
gets the shorter overloads too.
|
|
129
|
+
- Give a function returning a value class or an inline class a `@JvmName`
|
|
130
|
+
when Java needs to call it — the mangled synthetic name is not meant to be
|
|
131
|
+
called directly.
|
|
132
|
+
- Prefer a `List<T>`/`Map<K, V>` parameter type over a Kotlin-only collection
|
|
133
|
+
interface on any Java-facing surface.
|
|
134
|
+
|
|
135
|
+
## KDoc
|
|
136
|
+
|
|
137
|
+
- Every public type, function, and property meant for consumption outside its
|
|
138
|
+
module gets a KDoc comment (`/** ... */`) — what it does and why, not a
|
|
139
|
+
restatement of its name.
|
|
140
|
+
- Keep the summary to one or two sentences; use `@param`, `@return`, and
|
|
141
|
+
`@throws` for the rest.
|
|
142
|
+
|
|
143
|
+
## Exceptions
|
|
144
|
+
|
|
145
|
+
- Use exceptions for genuinely exceptional, unrecoverable conditions — not for
|
|
146
|
+
control flow a caller is expected to handle. A command or query rejection a
|
|
147
|
+
user can act on is a validation result, not a thrown exception; see the
|
|
148
|
+
Arc validation skills.
|
|
149
|
+
- Define a custom exception type when a caller needs to distinguish it from
|
|
150
|
+
other failures; do not throw a bare `RuntimeException`/`IllegalStateException`
|
|
151
|
+
for something callers are expected to catch specifically.
|
|
152
|
+
|
|
153
|
+
## Dependency Injection
|
|
154
|
+
|
|
155
|
+
- Constructor injection through the primary constructor is the default; avoid
|
|
156
|
+
field/property injection.
|
|
157
|
+
- Give a collaborator an interface and a `Default*` implementation when an
|
|
158
|
+
application might reasonably override it, bound with Spring's
|
|
159
|
+
`@ConditionalOnMissingBean` so a consumer can replace it without forking.
|
|
160
|
+
|
|
161
|
+
## Logging
|
|
162
|
+
|
|
163
|
+
- Log through the host's structured logging facility (SLF4J via Spring Boot),
|
|
164
|
+
not `println`.
|
|
165
|
+
- Log at the boundary where a decision is made or an error is handled, not at
|
|
166
|
+
every intermediate call.
|
|
167
|
+
|
|
168
|
+
## Testing
|
|
169
|
+
|
|
170
|
+
- JUnit Jupiter is the house test runner for Kotlin and Java alike (the
|
|
171
|
+
Cratis JVM repositories use Jupiter 6.1.x).
|
|
172
|
+
- A Kotlin test lives beside its Kotlin production code
|
|
173
|
+
(`src/test/kotlin/.../<Thing>Test.kt`); a Java-facing surface also gets a
|
|
174
|
+
Java test that compiles and runs against it, because Kotlin-only tests do
|
|
175
|
+
not prove Java call-site compatibility.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*"
|
|
3
|
+
---
|
|
4
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
5
|
+
|
|
6
|
+
# Local AI work artifacts belong in `.ai-work/` only
|
|
7
|
+
|
|
8
|
+
AI-assisted sessions produce working artifacts: plans, handover documents, session
|
|
9
|
+
notes, continuation prompts, status boards, TODO and scratch analyses, research
|
|
10
|
+
dumps, and similar coordination files. These are **work records, not documentation**.
|
|
11
|
+
|
|
12
|
+
- Create every such artifact inside **`.ai-work/`** at the repository root — never at
|
|
13
|
+
the repository root itself, never under documentation folders, never anywhere else.
|
|
14
|
+
- `.ai-work/` is listed in `.gitignore` and must stay untracked. Never commit anything
|
|
15
|
+
inside it, never `git add -f` anything inside it, and never remove the ignore entry.
|
|
16
|
+
- These artifacts must never enter git history or reach GitHub — not on any branch.
|
|
17
|
+
If you find one tracked in git, move it into `.ai-work/` and remove it from
|
|
18
|
+
tracking in a dedicated commit.
|
|
19
|
+
- A genuine follow-up that must survive the session is **not** a work record — suggest
|
|
20
|
+
opening a GitHub issue for it (or open one when asked) so future work is tracked
|
|
21
|
+
where everyone can see it, instead of leaving a planning file behind.
|
|
22
|
+
- Knowledge that must outlive the session (real documentation, ADRs, operator
|
|
23
|
+
guides) is written deliberately into the repository's documentation structure
|
|
24
|
+
through normal review — not left behind as a work record.
|
|
25
|
+
- **A session prompt or handover states when it is valid.** A fresh-session prompt,
|
|
26
|
+
continuation prompt or handover in `.ai-work/` opens with its preconditions: the
|
|
27
|
+
repository, the branch, the expected `HEAD` commit, every worktree path it names,
|
|
28
|
+
and the date it was written. Without them nothing tells a later session whether
|
|
29
|
+
the prompt still describes reality.
|
|
30
|
+
- **Check the preconditions before acting on a prompt.** A session that starts from
|
|
31
|
+
one compares them with `git rev-parse --show-toplevel`, `git rev-parse HEAD`,
|
|
32
|
+
`git branch --show-current` and `git worktree list` first. A mismatch (a moved
|
|
33
|
+
`HEAD`, a missing worktree, another branch) means **the prompt is stale — not
|
|
34
|
+
that the work is lost.** Do not recreate
|
|
35
|
+
a worktree, reset, or discard anything because of it; look at the branches, the
|
|
36
|
+
reflog and the open pull requests for where the work is now, then update or
|
|
37
|
+
replace the prompt.
|
|
38
|
+
- **A worktree is a work record too.** Create it outside the repository tree, for
|
|
39
|
+
example in a sibling `../.worktrees/` directory. A nested worktree inherits the
|
|
40
|
+
parent's `.globalconfig` alongside its own, causing .NET's `MultipleGlobalAnalyzerKeys`
|
|
41
|
+
errors or silently changing analyzer severities. Remove the worktree you created for
|
|
42
|
+
a task once its branch is merged to the default branch — pushed is not merged. Do it
|
|
43
|
+
from the parent checkout, after `git status --ignored` in the worktree, because a
|
|
44
|
+
nested `.ai-work/`, `.env` files and local databases are ignored and are deleted with it.
|
|
45
|
+
If the branch must outlive the task unmerged, leave the worktree and say so in the
|
|
46
|
+
handoff. Never `--force` a removal; a refusal means look, not push harder.
|
|
47
|
+
- **A decision log is not a work record.** A decision — a durable choice with a
|
|
48
|
+
decider and a date — is documentation: it lives in **`decisions/`** (or the
|
|
49
|
+
repository's documented decisions folder) and is reviewed like any other
|
|
50
|
+
documentation. A handover may summarize decisions; it never holds the only
|
|
51
|
+
copy. If a session produced a real decision, land the record in `decisions/`
|
|
52
|
+
before the session's `.ai-work/` files are discarded.
|
|
53
|
+
- The record's shape (front matter, status and stage values, supersession
|
|
54
|
+
pointers) is defined by the decision-record skill and the shared vocabulary
|
|
55
|
+
once this repository carries them; until then use the repository's existing
|
|
56
|
+
decisions folder and keep decider and date explicit.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**/*"
|
|
3
|
+
profile: framework
|
|
4
|
+
---
|
|
5
|
+
<!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
|
|
6
|
+
|
|
7
|
+
# New Repository Strategy Intake
|
|
8
|
+
|
|
9
|
+
This is Cratis organization process for maintainers creating repositories under the
|
|
10
|
+
Cratis organization. It does not apply to applications built on Cratis.
|
|
11
|
+
|
|
12
|
+
When a repository is created in the Cratis organization, prepare one transient,
|
|
13
|
+
no-effect Strategy intake proposal. Do not create, comment on, assign, mention,
|
|
14
|
+
link, or otherwise mutate a GitHub issue unless a current repository profile and
|
|
15
|
+
the exact operation are separately accepted. Tool access and a request to create
|
|
16
|
+
the repository do not supply that issue-effect authority.
|
|
17
|
+
|
|
18
|
+
The proposal should include only the bounded facts needed for Strategy triage:
|
|
19
|
+
|
|
20
|
+
- repository name, URL, visibility, and creation state;
|
|
21
|
+
- purpose, intended users, lifecycle, and whether it is canonical, generated,
|
|
22
|
+
experimental, operational, or scheduled for retirement;
|
|
23
|
+
- accountable owner or explicit vacancy and cross-repository boundaries;
|
|
24
|
+
- upstream/downstream dependencies and current owning records;
|
|
25
|
+
- release, distribution, credential, security, privacy, compliance, and data
|
|
26
|
+
expectations; and
|
|
27
|
+
- requested Strategy identity, portfolio, metadata, ownership, and local AI
|
|
28
|
+
context review.
|
|
29
|
+
|
|
30
|
+
First decide whether no record, an existing Strategy record, a bounded update
|
|
31
|
+
proposal, a new proposal, or a sensitive human route is appropriate. Treat the
|
|
32
|
+
result as Strategy intake, not strategic approval. Do not invent Strategy
|
|
33
|
+
metadata or copy private Strategy content into a public repository. Repository
|
|
34
|
+
creation does not require an issue URL; unresolved Strategy reconciliation is an
|
|
35
|
+
explicit next action for the authorized human/owning process.
|