@cratis/pi 7.37.0 → 7.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/package/corpus/harnesses/copilot/instructions/ai-distribution.instructions.md +109 -0
  2. package/package/corpus/harnesses/copilot/instructions/application-profile.instructions.md +81 -0
  3. package/package/corpus/harnesses/copilot/instructions/capability-is-not-authority.instructions.md +45 -0
  4. package/package/corpus/harnesses/copilot/instructions/code-quality.csharp.instructions.md +92 -0
  5. package/package/corpus/harnesses/copilot/instructions/code-quality.instructions.md +83 -0
  6. package/package/corpus/harnesses/copilot/instructions/code-quality.typescript.instructions.md +90 -0
  7. package/package/corpus/harnesses/copilot/instructions/components.instructions.md +300 -0
  8. package/package/corpus/harnesses/copilot/instructions/concepts.instructions.md +138 -0
  9. package/package/corpus/harnesses/copilot/instructions/cratis-folder-is-configuration.instructions.md +29 -0
  10. package/package/corpus/harnesses/copilot/instructions/csharp.instructions.md +357 -0
  11. package/package/corpus/harnesses/copilot/instructions/dialogs.instructions.md +278 -0
  12. package/package/corpus/harnesses/copilot/instructions/documentation-structure-and-formatting.instructions.md +162 -0
  13. package/package/corpus/harnesses/copilot/instructions/documentation.instructions.md +90 -0
  14. package/package/corpus/harnesses/copilot/instructions/editing-cratis-docs.instructions.md +74 -0
  15. package/package/corpus/harnesses/copilot/instructions/efcore.instructions.md +84 -0
  16. package/package/corpus/harnesses/copilot/instructions/efcore.specs.instructions.md +45 -0
  17. package/package/corpus/harnesses/copilot/instructions/elixir.instructions.md +50 -0
  18. package/package/corpus/harnesses/copilot/instructions/exit-codes-and-wrappers.instructions.md +34 -0
  19. package/package/corpus/harnesses/copilot/instructions/framework.instructions.md +55 -0
  20. package/package/corpus/harnesses/copilot/instructions/frontend-quality.instructions.md +60 -0
  21. package/package/corpus/harnesses/copilot/instructions/frontend-testing.instructions.md +127 -0
  22. package/package/corpus/harnesses/copilot/instructions/git-commits.instructions.md +139 -0
  23. package/package/corpus/harnesses/copilot/instructions/github-actions.instructions.md +87 -0
  24. package/package/corpus/harnesses/copilot/instructions/glossary.instructions.md +63 -0
  25. package/package/corpus/harnesses/copilot/instructions/go-engineering.instructions.md +61 -0
  26. package/package/corpus/harnesses/copilot/instructions/go.instructions.md +116 -0
  27. package/package/corpus/harnesses/copilot/instructions/guards-and-fuses.instructions.md +61 -0
  28. package/package/corpus/harnesses/copilot/instructions/java.instructions.md +138 -0
  29. package/package/corpus/harnesses/copilot/instructions/kotlin.instructions.md +175 -0
  30. package/package/corpus/harnesses/copilot/instructions/local-work-artifacts.instructions.md +56 -0
  31. package/package/corpus/harnesses/copilot/instructions/new-repository-intake.instructions.md +35 -0
  32. package/package/corpus/harnesses/copilot/instructions/orleans.instructions.md +97 -0
  33. package/package/corpus/harnesses/copilot/instructions/profiles.instructions.md +403 -0
  34. package/package/corpus/harnesses/copilot/instructions/pull-requests.instructions.md +176 -0
  35. package/package/corpus/harnesses/copilot/instructions/react.instructions.md +203 -0
  36. package/package/corpus/harnesses/copilot/instructions/reactors.instructions.md +336 -0
  37. package/package/corpus/harnesses/copilot/instructions/rtk.instructions.md +48 -0
  38. package/package/corpus/harnesses/copilot/instructions/specs.csharp.instructions.md +147 -0
  39. package/package/corpus/harnesses/copilot/instructions/specs.instructions.md +133 -0
  40. package/package/corpus/harnesses/copilot/instructions/specs.scenarios.csharp.instructions.md +281 -0
  41. package/package/corpus/harnesses/copilot/instructions/specs.typescript.instructions.md +141 -0
  42. package/package/corpus/harnesses/copilot/instructions/storybook.instructions.md +85 -0
  43. package/package/corpus/harnesses/copilot/instructions/typescript.instructions.md +151 -0
  44. package/package/corpus/harnesses/copilot/instructions/verification-discipline.instructions.md +27 -0
  45. package/package/corpus/harnesses/copilot/instructions/vertical-slices.instructions.md +414 -0
  46. package/package/corpus/harnesses/copilot/instructions/web-fetching.instructions.md +12 -0
  47. package/package/corpus/harnesses/copilot/instructions/writing-correct-examples.instructions.md +57 -0
  48. package/package/corpus/harnesses/copilot/instructions/writing-cratis-docs.instructions.md +72 -0
  49. package/package/corpus/product-sync.json +2 -2
  50. package/package/corpus/skills/cratis-screenplay-discovery/SKILL.md +11 -6
  51. package/package/corpus/skills/cratis-screenplay-discovery/references/facilitation.md +9 -5
  52. package/package/corpus/skills/cratis-screenplay-discovery/references/human-workshop.md +1 -1
  53. package/package/corpus/skills/cratis-screenplay-discovery/references/plotting-and-handoff.md +28 -4
  54. package/package/corpus/skills/cratis-screenplay-discovery/references/storming-loop.md +2 -1
  55. package/package/corpus/skills/cratis-screenplay-discovery/verification.json +5 -0
  56. package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +23 -29
  57. package/package/corpus/skills/cratis-screenplay-model-authoring/references/mcp-loop.md +15 -1
  58. package/package/corpus/skills/cratis-screenplay-model-authoring/references/model-notes.md +208 -0
  59. package/package/corpus/skills/cratis-screenplay-model-authoring/verification.json +20 -1
  60. package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +19 -36
  61. package/package/corpus/skills/cratis-screenplay-model-review/references/report-template.md +26 -0
  62. package/package/corpus/skills/cratis-screenplay-model-review/verification.json +7 -0
  63. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/SKILL.md +14 -16
  64. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/core-rules-digest.md +8 -3
  65. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/handoff-template.md +5 -2
  66. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/intake.md +21 -0
  67. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/reasoning-notes.md +10 -6
  68. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/stop-or-assume.md +32 -1
  69. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/references/worked-example.md +5 -2
  70. package/package/corpus/skills/cratis-screenplay-modeling-lifecycle/verification.json +5 -0
  71. package/package/corpus/skills/cratis-screenplay-toolchain/SKILL.md +4 -0
  72. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.json +1716 -183
  73. package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract.version +1 -1
  74. package/package/corpus/skills/cratis-screenplay-toolchain/references/versions.md +40 -4
  75. package/package/corpus/skills/cratis-screenplay-toolchain/verification.json +6 -0
  76. package/package.json +1 -1
@@ -0,0 +1,162 @@
1
+ ---
2
+ applyTo: "**/Documentation/**/*.{md,mdx}"
3
+ paths:
4
+ - "**/Documentation/**/*.md"
5
+ - "**/Documentation/**/*.mdx"
6
+ ---
7
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
8
+
9
+ # Documentation structure and formatting
10
+
11
+ This is the authoritative rendering contract for product documentation consumed by the Astro Starlight site. For content and teaching voice, see [Writing Cratis Documentation](./writing-cratis-docs.instructions.md). For source ownership and the edit loop, see [Editing Cratis Documentation](./editing-cratis-docs.instructions.md).
12
+
13
+ Product `.md` and `.mdx` files are copied through the Documentation repository's `web/scripts/sync-content.mjs`; the converter preserves the extension and rewrites the content before Starlight renders it.
14
+
15
+ ## Frontmatter
16
+
17
+ ```yaml
18
+ ---
19
+ title: Append an event
20
+ description: Append a domain event to one event source and inspect the result.
21
+ tableOfContents: false # optional per-page override
22
+ sidebar:
23
+ badge: { text: New, variant: tip }
24
+ ---
25
+ ```
26
+
27
+ - Product pages should declare `title` and `description`. The title becomes the page H1; the description feeds metadata and AI-facing exports.
28
+ - Preserve existing frontmatter when editing unless the task deliberately changes it. The converter preserves only `title`, `description`, `sidebar`, and `tableOfContents` from authored frontmatter; it drops DocFX keys and other Starlight keys. It generates `editUrl` separately from the owning product source path, so the page's edit action does not point to the synchronized copy. That link is the contribution path for a reader who is not set up locally: never hand-author `editUrl`, and after moving a page confirm its generated edit link still opens the file. Features such as `template`, `hero`, `banner`, `head`, `prev`, `next`, `slug`, and `draft` work only on site-level pages authored directly in the Documentation repository.
29
+ - Product navigation comes from `toc.yml`, not Starlight autogeneration. `sidebar.badge` works, but `sidebar.order`, `sidebar.label`, and `sidebar.hidden` do not control product navigation.
30
+ - A frontmatter-less page falls back to its first H1, but that loses the description and relies on converter inference. Do not add new pages that way.
31
+
32
+ ## Headings
33
+
34
+ - Do not put an H1 in the body; frontmatter supplies it.
35
+ - The global “On this page” list shows H2 headings only. Organize the page around a short, flat set of `##` sections; use H3/H4 only inside them.
36
+ - Use sentence case and no trailing punctuation.
37
+ - Keep a real H2 when a section needs a stable URL anchor. A card or aside title is presentation, not document structure.
38
+
39
+ ## Files, folders, and navigation
40
+
41
+ - A navigable product folder normally has `toc.yml` plus one landing page: `<folder>/index.md[x]` or a sibling `<folder>.md[x]`.
42
+ - Never keep both `<folder>.md[x]` and `<folder>/index.md[x]`. A legacy `<folder>.md` sibling makes the sync move the directory index to `/overview/`; other duplicate landing shapes can fail the build. Either outcome can orphan the intended landing page or make compatibility links point back to themselves.
43
+ - A folder with neither an index nor a sibling landing has no page at its bare URL.
44
+ - Product bucket names are product-specific. Read that product's `PRODUCTS[].buckets` entry in `web/scripts/sync-content.mjs`; do not assume generic “Get started / Guides / Understand / Reference” labels.
45
+ - A missing built slug is dropped from the sidebar and counted as a broken toc entry. Keep that count at zero.
46
+ - `toc.yml` entries with external URLs, `../`, or `/api/` are intentionally dropped. A group with one child collapses to the child link. Check the generated sidebar rather than inferring it from YAML alone.
47
+ - Sync slugification lowercases path segments and removes characters outside `[a-z0-9_-]`; for example, `react.mvvm` becomes `reactmvvm`. Verify hand-authored site-absolute URLs against the built route.
48
+
49
+ ## Choose Markdown or MDX
50
+
51
+ Use the least powerful format that communicates the idea:
52
+
53
+ - Keep `.md` for headings, prose, links, GFM tables, fenced code, Mermaid/EventModeling diagrams, images, and Starlight aside directives.
54
+ - Use `.mdx` only when the page needs imported Astro components, expressions, props, or named slots. Every component costs machine readability: the Markdown mirror that assistants and "Copy Markdown" read keeps its imports and JSX. Spend that deliberately, where the component teaches better than plain Markdown.
55
+ - Imports and JSX in `.md` fail silently: the import can render as visible prose and the component as an inert element. Permissive Markdown HTML allowlists can hide this mistake. A page using a component must be `.mdx`.
56
+ - Do not rename a page to `.mdx` merely for a callout or diagram. Renames require checking `toc.yml`, inbound links, generated routes, and AI-facing Markdown output.
57
+ - Do not add raw HTML, inline styling, scripts, or one-off visual components to decorate a product page. Reuse an established component or make an explicit reusable site change in the Documentation repository.
58
+
59
+ ## Callouts and asides
60
+
61
+ The complete Starlight directive set is `note`, `tip`, `caution`, and `danger`. These work in both `.md` and `.mdx` and support a custom title:
62
+
63
+ ```markdown
64
+ :::caution[Do not use a raw Guid as the event source id]
65
+ Chronicle treats a raw `Guid` as an ordinary response value.
66
+ :::
67
+ ```
68
+
69
+ | Variant | Meaning |
70
+ |---|---|
71
+ | `note` | Neutral context or an important clarification |
72
+ | `tip` | A recommendation or easier path |
73
+ | `caution` | A likely mistake, compatibility trap, or behavior that produces the wrong result |
74
+ | `danger` | Destructive, security-sensitive, or data-loss consequences |
75
+
76
+ The set is closed. Do not use `warning`, `important`, `info`, or `success`: an unknown container directive silently renders as an unstyled `<div>` rather than failing the build.
77
+
78
+ Legacy DocFX alerts are converted as follows; prefer titled native directives when editing the surrounding content:
79
+
80
+ | DocFX | Starlight |
81
+ |---|---|
82
+ | `> [!NOTE]` / `> [!IMPORTANT]` | `:::note` |
83
+ | `> [!TIP]` | `:::tip` |
84
+ | `> [!WARNING]` | `:::caution` |
85
+ | `> [!CAUTION]` | `:::danger` |
86
+
87
+ In MDX, `<Aside type="tip" title="A specific title">…</Aside>` is available when component composition requires it. Directive asides can also take a Starlight icon attribute, but verify the icon name first; a bad aside icon fails the build.
88
+
89
+ ## Code blocks
90
+
91
+ - Always tag the language: `csharp`, `tsx`, `typescript`, `bash`, `yaml`, and so on.
92
+ - Expressive Code supports useful metadata such as ``title="Program.cs"`` and line/text markers. Use them to orient the reader or focus a diff, not to decorate every snippet.
93
+ - DocFX-era aliases include `env`, `pdl`, `ebnf`, `pql`, `gitignore`, `flow`, and `screenplay`; use a real language where one exists.
94
+ - Dedent snippets to column zero while preserving their internal indentation.
95
+ - Show both sides of a full-stack contract, but do not automatically hide sequential C#→generated-TypeScript explanations behind tabs. Use `FullStackTabs` only when the snippets are alternatives that remain understandable independently.
96
+ - The converter's DocFX-alert and link rewriting is not fully code-fence-aware. Literal `> [!NOTE]`, Markdown-link targets, or `href="…"` examples can be rewritten; inspect the synced output when documenting those syntaxes.
97
+
98
+ ## Tables, images, links, and diagrams
99
+
100
+ - Use GFM tables with a separator row and a blank line before the table. `remarkGfm` in the Documentation site's Astro config is load-bearing for `.mdx`; raw pipe text in a rendered page indicates that integration is missing or degraded.
101
+ - Keep images beside the source page, use meaningful alt text, and rely on the site's click-to-zoom behavior.
102
+ - In product source, relative links to files keep their real `.md` or `.mdx` extension. The converter strips either extension for the public route. Directory URLs end in `/`.
103
+ - Site-level MDX uses clean root-relative routes such as `/arc/backend/commands/`. Cross-product links are also root-relative: link from a CLI page to an Arc page as `[Browse your embedded event model](/arc/backend/csharp/embedded-event-model/)`. The route is the owning product's key plus the page's source path without its extension, slugified.
104
+ - Do not link another product's page through `https://cratis.io/...` or a GitHub `blob/` URL. Neither is checked by the site build: the first 404s until the next publish when the target is new, and the second sends a reader to raw source instead of the page.
105
+ - Named Markdown reference links are supported, but their labels are local to the page, not a cross-repository symbol registry. Define the target in the same authored page and use the owning product's verified public route:
106
+
107
+ ```markdown
108
+ Before running these commands, [install the Cratis CLI][cli-installation].
109
+
110
+ [cli-installation]: /cli/getting-started/
111
+ ```
112
+
113
+ Reuse a label within that page when helpful. Do not assume another repository's reference definitions or frontmatter `uid` are imported. Verify the generated route and any heading anchor with the full site's rendered-link check.
114
+ - There are no DocFX symbol links. DocFX `[text](xref:UID)` and `<xref:UID>` are converted to plain text or inline code, never to a link, and `lint-docs.mjs` reports any `xref:` left in the synced output. Link to a page route; name an API type in inline code.
115
+ - A product's own link gate cannot resolve root-relative links to other products. It skips them by rule, not by product name - with linkinator, skip the local-server URLs outside `/Documentation/` (`^https?://(localhost|127\.0\.0\.1):[0-9]+/(?!Documentation/)`). A name such as `arc/` would also match a product's own `Documentation/arc/` folder and silently stop checking its internal links. The Documentation site's `check-links.mjs` verifies every rendered root-relative link against the built site.
116
+ - Content published outside the site - a repository README, a package readme, pull request descriptions and release notes - is not rewritten, so it uses absolute `https://` URLs.
117
+ - Link text describes the destination; `here`, `click here`, and `see documentation` are hard lint errors.
118
+ - Use `mermaid` for architecture, sequence, flow, and state diagrams. Use `eventmodeling` for EventModeling diagrams. Both are pre-rendered to responsive SVG at build time.
119
+
120
+ ## MDX component surface
121
+
122
+ Place imports immediately after frontmatter, with a blank line before the first body content. Import only what the page uses. Starlight exports exactly `Aside`, `Badge`, `Card`, `CardGrid`, `Code`, `FileTree`, `Icon`, `LinkButton`, `LinkCard`, `Steps`, `TabItem`, and `Tabs`:
123
+
124
+ ```mdx
125
+ import { Aside, Steps, TabItem, Tabs } from '@astrojs/starlight/components';
126
+ ```
127
+
128
+ Shared Cratis components are default imports through exact `@components/<Name>.astro` paths; there is no bare `@components` barrel:
129
+
130
+ ```mdx
131
+ import FullStackTabs from '@components/FullStackTabs.astro';
132
+ import Recap from '@components/Recap.astro';
133
+ ```
134
+
135
+ Common shared components include `FullStackTabs`, `OsAwareTabs`, `TopicHero`, `SimpleCard`, `StackDiagram`, `YouWillLearn`, and `Recap`. Inspect the current component and an existing page before using its props or slots; do not infer an API from the component name.
136
+
137
+ Icon names must come from the installed Starlight set. Use `seti:windows`, not `windows`. Invalid icons in `Icon`, `TabItem`, `SimpleCard`, and `TopicHero` can produce an empty SVG without a build failure, so visual verification is mandatory.
138
+
139
+ ## AI-facing Markdown
140
+
141
+ The published `.md` mirror behind page actions such as “Copy Markdown” is copied from synchronized Markdown/MDX rather than reconstructed from rendered HTML. Synced frontmatter and converter rewrites are present, but MDX imports and JSX remain visible in that raw Markdown surface. Prefer plain Markdown unless a component creates a real teaching advantage, and inspect the emitted `.md` artifact when changing a page's authoring format. Generated AI indexes can process content separately; do not infer their exact representation from the page action.
142
+
143
+ ## Verification
144
+
145
+ Run the owning repository's local documentation gate first when it has one. Many product repositories expose:
146
+
147
+ ```bash
148
+ ./Documentation/verify-markdown.sh
149
+ ```
150
+
151
+ For full-fidelity rendering, use the sibling Documentation checkout:
152
+
153
+ ```bash
154
+ cd ../Documentation/web
155
+ npm run check
156
+ ```
157
+
158
+ The local gate validates the authored repository in isolation. The full site check builds and syncs every available sibling product, runs site linting and rendered-link checks, and can expose unrelated sibling failures; diagnose those separately rather than silently waiving them. Some optional local tools skip when not installed, so name what actually ran.
159
+
160
+ A successful build proves syntax, not presentation. For any aside, diagram, tabs, cards, or custom component change, preview the owning site and inspect light and dark screenshots using its local screenshot workflow.
161
+
162
+ End every file with a single trailing newline.
@@ -0,0 +1,90 @@
1
+ ---
2
+ applyTo: "**/Documentation/**/*.{md,mdx}"
3
+ paths:
4
+ - "**/Documentation/**/*.{md,mdx}"
5
+ ---
6
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
7
+
8
+ # How to write documentation
9
+
10
+ Documentation exists for one audience: **developers who need to use the framework** — not the team that built it. Write from the reader's perspective. They want to know *what this does*, *why they should care*, and *how to use it* — in that order.
11
+
12
+ Every page should answer: “If I were a developer encountering this concept for the first time, what would I need to understand to use it correctly?”
13
+
14
+ The site is built with [Astro Starlight](https://starlight.astro.build/). Documentation lives in the `Documentation/` folder of each product repository as [GitHub Flavored Markdown](https://github.github.com/gfm/); a converter synchronizes product `.md`/`.mdx` into the Starlight site, and all repositories are aggregated into one published site. Readers experience it as a single place — write for that whole, not for one repository in isolation. For the authoritative rendering contract, see [Documentation Structure and Formatting](./documentation-structure-and-formatting.instructions.md).
15
+
16
+ ## Give each page one primary reader purpose
17
+
18
+ Use [Diátaxis](https://diataxis.fr/) as a compass: decide whether the reader is primarily learning, solving a task, looking up a contract, or understanding a concept. Brief context that helps someone complete a tutorial or how-to is welcome. Move an exhaustive lookup or a long conceptual detour to its own linked page; do not split a coherent reader task merely to keep categories pure.
19
+
20
+ | Type | The reader is… | Reads like | Rule |
21
+ |---|---|---|---|
22
+ | **Tutorial** | learning by doing | a guided lesson | Steps that each produce a visible result. Briefly explain the invisible effect after a step; link out for deeper theory rather than stopping the lesson. The reader must succeed even before they fully understand. |
23
+ | **How-to guide** | solving a specific problem | a recipe | Assume competence. Goal → prerequisites → steps → done. No teaching. |
24
+ | **Reference** | looking something up | a dictionary | Exhaustive and terse. Tables, signatures, attributes, configuration. No narrative. |
25
+ | **Explanation** | trying to understand | a discussion | Concepts, trade-offs, architecture, *why*. No steps. Lean on diagrams. |
26
+
27
+ Diátaxis governs a page's purpose and voice, not a universal set of sidebar labels. Each product has navigation buckets suited to its domain; read `PRODUCTS[].buckets` in the Documentation site's sync script before placing a new section.
28
+
29
+ For a reader-centered writing workflow, use the **cratis-documentation-writing** skill; for source-verified snippets use **cratis-technical-examples**.
30
+
31
+ ## Onboarding is the most important documentation you write
32
+
33
+ Most readers decide whether to adopt Cratis in the first ten minutes. Protect that path.
34
+
35
+ - **One clear 'start here' entry per product**, not a menu of competing front doors. Let it direct readers to separate language or host procedures when those are genuinely different; do not force incompatible readers through one runnable recipe.
36
+ - Drive to a **visible payoff fast** — something running the reader can see. State it up front: “By the end you'll have X running.”
37
+ - **Thread tutorials when the product warrants a multi-chapter journey.** Use one realistic domain across chapters, each adding one concept and visible result. A small tool may need only a short guided lesson; don't create filler chapters to satisfy a template.
38
+ - **One cross-product capstone tutorial** builds a real full-stack feature using the relevant Cratis products together. This is the connective tissue between products — keep it current and runnable.
39
+
40
+ ## Connect the products
41
+
42
+ Readers do not care about repository boundaries — they are building one application.
43
+
44
+ - The site has **one front door** stating what Cratis is, with a one-sentence definition and a “start here” link for each product.
45
+ - Every product index opens with a **one-sentence definition** and a **“without vs. with” framing** of the problem it removes — lead with the pain, then the relief.
46
+ - **Cross-link at the seams** rather than re-explaining: show how the products meet in the reader's workflow. Before a procedure uses another product's command, link its installation procedure as a prerequisite instead of assuming the command is already available. Prefer the canonical procedure over copying installation commands that can drift.
47
+ - Maintain a **glossary** of shared terms and link to it instead of redefining terms per page. One term, one concept, everywhere.
48
+
49
+ ## Writing style
50
+
51
+ The project's voice is **direct, practical, and opinionated**. Write like an experienced colleague explaining something to a capable developer — confident but never condescending.
52
+
53
+ - **Active voice, present tense, second person.** “You append the event,” not “The event is appended.”
54
+ - **Lead with *why* before *how*.** A reader who understands the reasoning handles edge cases the docs do not cover.
55
+ - **Do not document the obvious.** If the API is self-explanatory, a complete code example is enough.
56
+ - Use headings, lists, tables, and code blocks — dense paragraphs lose readers.
57
+ - **Be honest about trade-offs.** A “when this is the wrong fit” section builds more trust than omitting the limits.
58
+ - Focus on public APIs and behavior. Explain internals only where they clarify a supported boundary or failure mode; link to third-party documentation rather than retelling it.
59
+
60
+ ## Diagrams
61
+
62
+ - Use [Mermaid](https://mermaid-js.github.io/mermaid/#/) where a concept has structure that prose conveys poorly — architecture, event and command flow, state transitions, projection and reactor pipelines. Many strong pages carry their load in prose, real code, and real output instead; add a diagram because it explains something, not because the page type seems to require one.
63
+
64
+ ## Code examples
65
+
66
+ - Prefer `record` types for events, commands, and read models — match the codebase.
67
+ - Use argument-free `[EventType]` for new events. A new generation or an explicit legacy identifier is valid only when documenting evolution of an existing stored-event contract.
68
+ - A standalone example must be **complete and correct** at its stated scope. Mark a partial excerpt as an excerpt, state its prerequisites, and never leave an essential step behind `// ...`. Do not offer an incomplete block as click-to-copy code.
69
+ - **Short illustrative snippets** may be purpose-built after checking their framework APIs against source. Derive substantial or runnable examples from compiled, tested sample or spec code; extract or check displayed snippets with the owning repository's tooling so they do not drift. Never substitute a bare “see the repository” link for showing the code.
70
+ - Where a feature spans products or languages, show both sides when both matter. Keep causal explanations sequential; use tabs only for alternatives.
71
+
72
+ ## Links
73
+
74
+ - **Link text must describe the destination.** Write `[Event types](...)`, never `[see documentation](...)`, `[here](...)`, or `[click here](...)`. Non-descriptive link text is a defect.
75
+ - Named Markdown reference links (`[Install the CLI][cli-installation]` with a same-page `[cli-installation]: /cli/getting-started/` definition) can make cross-product prerequisites readable and reusable. These are page-local labels, not DocFX symbols; verify the target route in the aggregated site.
76
+ - Use relative links for internal product-source references and root-relative site routes (`/arc/backend/commands/`) for another product's pages — not absolute `cratis.io` or GitHub URLs, and not `xref:` symbol links, which the site does not support. Verify every link resolves — broken links and links to non-existent folders fail review.
77
+
78
+ ## Cover the reader's needs at the product's scale
79
+
80
+ - Every navigable product needs an **index** that defines it and points to a first useful outcome.
81
+ - When a product has enough tutorials or how-to guides to warrant an index, list each by the **situation it solves**, with a one-line description (for example, "Dealing with concurrency" or "Multi-tenancy end to end"), not only by chapter number or API name. Don't add a landing page merely to satisfy this rule, or restructure navigation as a side effect of one page.
82
+ - Document the **diagnostic surface**: the CLI commands, MCP tools, and observable state that tell a reader why the product behaves as it does. A capability with no documented way to inspect it becomes a support request, and an AI assistant helping the reader cannot use it.
83
+ - Provide a **getting-started route**, exact reference, limitations, and recovery information where the product's complexity requires them. A small tool need not manufacture a multi-chapter tutorial, FAQ, glossary, or architecture diagram.
84
+ - Connect related products with links instead of duplicating the same explanation. Share task-area and product indexes through the site's AI-facing exports where useful; don't require a separate full-text download per product or claim that an export alone proves answer quality.
85
+
86
+ ## File rules
87
+
88
+ - Follow [Documentation Structure and Formatting](./documentation-structure-and-formatting.instructions.md) for frontmatter, landing pages, `toc.yml`, Markdown/MDX, links, and rendering.
89
+ - End every Markdown file with a single trailing newline.
90
+ - Run the owning repository's local documentation gate when present; use `cd ../Documentation/web && npm run check` for full-fidelity site verification when the sibling checkout is available.
@@ -0,0 +1,74 @@
1
+ ---
2
+ applyTo: "**/Documentation/**/*.{md,mdx}"
3
+ paths:
4
+ - "**/Documentation/**/*.md"
5
+ - "**/Documentation/**/*.mdx"
6
+ ---
7
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
8
+
9
+ # Editing Cratis documentation
10
+
11
+ Cratis documentation is split across product repositories and aggregated by the sibling `Documentation` repository. Find the authored source before editing; synchronized product copies under `Documentation/web/src/content/docs/` are disposable build output.
12
+
13
+ ## Find the source of truth
14
+
15
+ Common routes map as follows:
16
+
17
+ | Public route | Authored source |
18
+ |---|---|
19
+ | `/chronicle/**` | `Chronicle/Documentation/**` |
20
+ | `/arc/**` | `Arc/Documentation/**` |
21
+ | `/components/**` | `Components/Documentation/**` |
22
+ | `/chronicle-mcp/**`, `/authproxy/**`, `/cli/**`, `/fundamentals/**`, `/screenplay/**`, `/prologue/**`, `/prompter/**`, and other product routes | The product or family-source repository selected by `PRODUCTS` |
23
+ | `/contributing/**` | The organization `.github` repository (legacy fallback: `GitHubLanding`) |
24
+ | Site-level routes such as `/`, `/why-cratis`, `/cratis-stack`, `/glossary`, `/ai/**`, and `/compare-event-sourcing-*` | `Documentation/web/src/content/docs/**` |
25
+
26
+ The definitive source map is `PRODUCTS` and its optional `familySources` in `Documentation/web/scripts/sync-content.mjs`. The site prefers sibling checkouts and falls back to configured submodules. Do not hard-code a shorter product list when the script can answer ownership.
27
+
28
+ Never edit a synchronized subtree under `Documentation/web/src/content/docs/`. Each `PRODUCTS[].key` is regenerated there even when Git state or `.gitignore` makes a particular directory look hand-authored. Site-level files that are not populated from `PRODUCTS` are authored directly in the Documentation repository. Check `PRODUCTS`, source paths, and the site configuration when ownership is unclear.
29
+
30
+ ## Edit and verify
31
+
32
+ From the owning repository:
33
+
34
+ 1. Edit the authored `.md` or `.mdx` file and preserve its existing frontmatter unless the task deliberately changes it.
35
+ 2. Run that repository's local documentation gate when present, commonly `./Documentation/verify-markdown.sh`.
36
+ 3. For full rendering, run the site from the sibling checkout:
37
+
38
+ ```bash
39
+ cd ../Documentation/web
40
+ npm run check
41
+ ```
42
+
43
+ 4. Preview with `npm run dev` from that same `../Documentation/web` directory and inspect visual changes in light and dark.
44
+
45
+ The local gate validates authored content without requiring every sibling product. The full site check synchronizes every available product and can expose unrelated sibling or optional-tool failures; diagnose and report those separately. Report which checks actually ran when local prose, Markdown, or external-link tools skip because their executables are absent.
46
+
47
+ The published site builds when the Documentation repository's `main` changes and when a product repository dispatches `build-docs`. Product repositories such as Chronicle, Arc, and Components dispatch from a dedicated documentation workflow when `Documentation/**` changes on `main`, and also from their publish workflows. A merge is not proof the changed page is live: confirm that a site build containing it deployed before saying so. Because correcting a page is cheap, prefer a small accurate edit now over queuing a rewrite.
48
+
49
+ Restart `npm run dev` after a build/check. The build re-sync can degrade a running dev server, producing 500s or missing table rendering. If a change still appears stale, clear `web/.astro` and `web/node_modules/.astro`, restart, and recheck before blaming the source.
50
+
51
+ ## Add, move, rename, or delete a page
52
+
53
+ - Adding a page inside the existing structure, with its `toc.yml` entry, is part of writing it. Adding a navigation bucket, reordering a product's navigation, or moving pages between products is a separate decision about the product's information architecture: make it when the request asks for it, not as a side effect of writing one page.
54
+ - Product navigation comes from its `toc.yml`; site-level navigation comes from `astro.config.mjs`.
55
+ - Product navigation buckets are defined per product in `PRODUCTS[].buckets`. Read the actual names and section lists before changing them.
56
+ - Keep exactly one landing for a route. A sibling `<folder>.md[x]` collides with `<folder>/index.md[x]`; a legacy `.md` collision can move the directory index to `/overview/`, while other duplicate landing shapes can fail the build.
57
+ - Update inbound links and `toc.yml` together. For a published route change, inspect the Documentation site's redirect mechanism rather than assuming a source-file move preserves old URLs.
58
+ - Watch sync output for dropped toc entries and verify the built sidebar. External, `../`, and `/api/` toc targets are intentionally omitted; single-child groups collapse.
59
+
60
+ ## Links
61
+
62
+ - Product source links to files keep the real `.md` or `.mdx` extension. The converter removes either extension for the public route.
63
+ - Directory links end in `/`.
64
+ - Site-level MDX and cross-product links use clean root-relative public routes such as `/arc/backend/commands/` - never `https://cratis.io/...` or a GitHub `blob/` URL, which the site build does not check. There are no symbol (`xref:`) links: the converter turns them into plain text.
65
+ - A product's local link gate skips root-relative links to other products by rule, not by product name; the full site check is what verifies them. See [Documentation Structure and Formatting](./documentation-structure-and-formatting.instructions.md#tables-images-links-and-diagrams).
66
+ - Slugification removes punctuation from path segments (`react.mvvm` becomes `reactmvvm`), so verify hand-authored site-absolute paths against the build.
67
+
68
+ ## Content and rendering
69
+
70
+ - Match the page's Diátaxis type and the tour voice in [Writing Cratis Documentation](./writing-cratis-docs.instructions.md).
71
+ - Verify framework APIs against source using [Writing Correct Code Examples](./writing-correct-examples.instructions.md).
72
+ - Follow [Documentation Structure and Formatting](./documentation-structure-and-formatting.instructions.md) as the single authority for frontmatter, Markdown/MDX boundaries, asides, components, navigation behavior, and gates.
73
+
74
+ Commit in the repository that owns the authored source. Touch the Documentation repository only when the task deliberately changes site-level content, navigation composition, components, styling, redirects, or build behavior.
@@ -0,0 +1,84 @@
1
+ ---
2
+ applyTo: "**/*.cs"
3
+ paths:
4
+ - "**/*.cs"
5
+ profile: application
6
+ ---
7
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
8
+
9
+ # Entity Framework Core Instructions
10
+
11
+ > **⚠️ APPLIES ONLY TO PROJECTS USING ENTITY FRAMEWORK CORE**
12
+ > If your project does not reference `Microsoft.EntityFrameworkCore` or any EF Core packages, **ignore this entire file**. These rules are irrelevant outside of EF Core contexts.
13
+
14
+ `Cratis.Arc.EntityFrameworkCore` gives an Arc application EF Core-backed read models: two `DbContext` base types, convention-based registration, provider selection from the connection string, cross-database column helpers for migrations, concept-aware value conversion, and live observation of a `DbSet`. **That is the whole of what Arc ships** — it has no migration runner, no table-name constant convention, no design-time factory and no prescribed project split. Where an application adds one of those, it is that application's local convention, not Cratis; keep such conventions in the repository's own instructions, never present them as framework. The step-by-step workflow, the exact signatures and the traps live in the **cratis-arc-ef-core-migration** skill; this rule states the invariants.
15
+
16
+ ## DbContext base types **[contract]**
17
+
18
+ Always derive from one of Arc's base types — never directly from `DbContext`:
19
+
20
+ - **`ReadOnlyDbContext`** — for every read model / projection context (the vast majority). Its save-changes interceptor **throws** on any `SaveChanges`, so a projection cannot be bypassed by accident.
21
+ - **`BaseDbContext`** — only for a writable context that genuinely owns state (device state, infrastructure state).
22
+
23
+ ```csharp
24
+ public class StartupPhaseDbContext(DbContextOptions<StartupPhaseDbContext> options)
25
+ : ReadOnlyDbContext(options)
26
+ {
27
+ public DbSet<StartupPhase> StartupPhases => Set<StartupPhase>();
28
+ }
29
+ ```
30
+
31
+ Use the primary constructor; expose each `DbSet<T>` as an expression-bodied property over `Set<T>()`. Co-locate the context with the feature whose read models it holds.
32
+
33
+ ## Feature contexts — not god contexts **[convention]**
34
+
35
+ One focused `DbContext` per feature or tightly related feature group. Never aggregate unrelated entities into a single context: a context's shape is a cohesion boundary, and a god context couples every feature's schema change to every other's.
36
+
37
+ ## State mutation — the golden rule **[convention]**
38
+
39
+ > **Never mutate state directly through a DbContext.**
40
+
41
+ All state changes flow through events and Chronicle projections; a direct write bypasses the event log and the audit trail. Only projection infrastructure, the Chronicle engine, and deliberate reference-data synchronization write through a context — and those are `BaseDbContext`s, never `ReadOnlyDbContext`s.
42
+
43
+ ## Registration **[contract]**
44
+
45
+ Wire EF Core through the Arc builder and give it the connection string:
46
+
47
+ ```csharp
48
+ builder.AddCratisArc(arc => arc.WithEntityFrameworkCore(
49
+ options => options.ConnectionString = connectionString));
50
+ ```
51
+
52
+ With a non-empty connection string and `AutoDiscoverDbContexts` (the default), Arc discovers every public `BaseDbContext` subtype not marked `[IgnoreAutoRegistration]`, registering `ReadOnlyDbContext` subtypes read-only and the rest read-write. ⚠️ `WithEntityFrameworkCore()` with **no** connection string discovers nothing. Explicit registration remains available (`AddDbContextWithConnectionString<T>`, `AddReadOnlyDbContextWithConnectionString<T>`, `AddReadModelDbContextsFromAssemblies`, `AddReadModelDbContextsWithConnectionStringFromAssemblies`).
53
+
54
+ Select the provider with **`UseDatabaseFromConnectionString(connectionString)`** — never hard-code `UseSqlite` / `UseNpgsql` / `UseSqlServer`. It infers `DatabaseType` (`Sqlite`, `SqlServer`, `PostgreSql`) from the connection string, ensures a SQLite file's directory exists, and installs Arc's migrations SQL generator for that provider (which is what adds the JSON validation constraint for `[Json]` columns). An unsupported connection string throws `UnsupportedDatabaseType`.
55
+
56
+ ## Migrations **[contract]/[convention]**
57
+
58
+ Migrations are created and applied with the **standard EF Core tooling** (`dotnet ef migrations add`, `dotnet ef database update`, or `Database.Migrate()` at startup). Arc adds only the column helpers that keep one migration valid across all three providers — use them instead of raw `table.Column<T>()`:
59
+
60
+ | Helper | Use for |
61
+ | --- | --- |
62
+ | `table.StringColumn(migrationBuilder, …)` | text |
63
+ | `table.GuidColumn(migrationBuilder, …)` | GUID / UUID |
64
+ | `table.NumberColumn<T>(migrationBuilder, …)` | integers, longs, decimals |
65
+ | `table.BoolColumn(migrationBuilder, …)` | booleans |
66
+ | `table.DateTimeOffsetColumn(migrationBuilder, …)` | timestamps with offset |
67
+ | `table.AutoIncrementColumn(migrationBuilder, …)` | identity columns |
68
+ | `table.JsonColumn<TProperty>(migrationBuilder, …)` | a `[Json]`-mapped property |
69
+ | `migrationBuilder.Add{String,Guid,Number,Bool,DateTimeOffset,AutoIncrement,Json,Point,LineString,Polygon}Column(…)` | adding a column to an existing table |
70
+
71
+ Where a repository organizes its migrations (a dedicated project, a versioned file naming scheme, a table-name constants class) is its own convention: follow what the repository already does, and do not introduce one as if Arc required it.
72
+
73
+ ## Concepts and JSON **[contract]**
74
+
75
+ `ConceptAs<T>` properties map to their underlying primitive without per-property value converters: `BaseDbContext.OnModelCreating` applies the concept conversions, and every Arc registration path calls `AddConceptAsSupport()` so concepts also work inside LINQ predicates. (A context you register with plain EF `AddDbContext` must call `options.AddConceptAsSupport()` itself.) Mark a property `[Json]` to store it as a JSON column with the provider's validation constraint.
76
+
77
+ ## Observation **[contract]**
78
+
79
+ An EF Core read model can back an observable query: `dbSet.Observe(...)`, `ObserveById(...)` and `ObserveSingle(...)` (extension methods declared in the `Microsoft.EntityFrameworkCore` namespace, so they are in scope wherever the `DbSet` is) push changes through the provider's change notifier — see the skill for what each provider supports. At Arc v22.75.0 auxiliary sources support `ignoreQueryContext: true`; single-instance observations emit `default` on absence/deletion/filter exit. Indexer-property keys are supported; composite/shadow-only keys are refused at setup.
80
+
81
+ ## See also
82
+
83
+ - the **cratis-arc-ef-core-migration** skill — wiring, making an EF read model injectable into a command, writing a migration, observing, and specs.
84
+ - [efcore.specs.md](./efcore.specs.instructions.md) — `DbContext` specs with SQLite in-memory.
@@ -0,0 +1,45 @@
1
+ ---
2
+ applyTo: "**/for_*/**/*.cs, **/when_*/**/*.cs"
3
+ paths:
4
+ - "**/for_*/**/*.cs"
5
+ - "**/when_*/**/*.cs"
6
+ profile: application
7
+ ---
8
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
9
+
10
+ # Entity Framework Core Specs
11
+
12
+ > **⚠️ APPLIES ONLY TO PROJECTS USING ENTITY FRAMEWORK CORE**
13
+ > If your project does not reference `Microsoft.EntityFrameworkCore` or any EF Core packages, **ignore this entire file**. These rules are irrelevant outside of EF Core contexts.
14
+
15
+ EF Core specs verify database interaction logic — migrations, queries, and error handling. They use SQLite in-memory databases, which are fast, isolated, and disposable. This keeps specs independent of any real database server.
16
+
17
+ These specs are for code that interacts directly with `DbContext`. For event-sourcing integration specs (testing commands against Chronicle), use the Chronicle integration spec pattern in [specs.scenarios.csharp.md](./specs.scenarios.csharp.instructions.md) instead.
18
+
19
+ ## Database Setup
20
+
21
+ - Use SQLite in-memory database for all `DbContext` specs — it's fast and each spec gets a clean database.
22
+ - Configure and dispose the in-memory database properly to avoid state leakage between tests. Each spec run should start with a fresh schema.
23
+
24
+ ## Mocking DbContext
25
+
26
+ - `SaveChanges()` and `SaveChangesAsync()` are virtual — mock with NSubstitute.
27
+ - `DbSet<T>` methods are virtual — mock as needed.
28
+ - Pass options when substituting: `Substitute.For<YourDbContext>(options)`.
29
+
30
+ ```csharp
31
+ var options = new DbContextOptionsBuilder<YourDbContext>()
32
+ .UseSqlite("DataSource=:memory:")
33
+ .Options;
34
+
35
+ var context = Substitute.For<YourDbContext>(options);
36
+ ```
37
+
38
+ ## Simulating Failures
39
+
40
+ Mock `SaveChanges` / `SaveChangesAsync` to throw exceptions for testing error handling and recovery:
41
+
42
+ ```csharp
43
+ context.SaveChangesAsync(Arg.Any<CancellationToken>())
44
+ .Throws(new DbUpdateException("Simulated failure"));
45
+ ```
@@ -0,0 +1,50 @@
1
+ ---
2
+ applyTo: "**/*.ex,**/*.exs"
3
+ paths:
4
+ - "**/*.ex"
5
+ - "**/*.exs"
6
+ ---
7
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
8
+
9
+ <!-- Copyright (c) Cratis. All rights reserved. -->
10
+ <!-- Licensed under the MIT license. See LICENSE file in the project root for full license information. -->
11
+
12
+ # Elixir Conventions
13
+
14
+ Use Elixir and OTP idioms, not translated C# or JVM shapes. These conventions
15
+ are grounded in `Cratis/Chronicle.Elixir v3.10.2` (`Source/chronicle/mix.exs`,
16
+ `.formatter.exs`, and `lib/chronicle/`). Client-specific APIs belong in the
17
+ **cratis-chronicle-client-elixir** skill.
18
+
19
+ ## Build and format
20
+
21
+ - For Chronicle 3.10.x use Elixir 1.18 or later (`~> 1.18`).
22
+ - Run `mix compile --warnings-as-errors`, `mix test`, and
23
+ `mix format --check-formatted` with the project's formatter inputs.
24
+ - Use two-space indentation and let `mix format` own layout.
25
+ - Chronicle exports no `locals_without_parens` formatter configuration. Accept
26
+ parentheses around its DSL calls; do not assume `import_deps` supplies them.
27
+
28
+ ## Code shape
29
+
30
+ - PascalCase module names; snake_case functions, variables and struct fields.
31
+ - Use structs for event/read-model data and pattern-matching clauses for
32
+ dispatch. Schema-bearing structs need typed defaults; `nil` is not a type
33
+ declaration and registers as string in this client.
34
+ - Preserve tagged results such as `:ok`, `{:ok, value}`, and `{:error, reason}`.
35
+ Handle expected remote failures explicitly rather than using a success-only
36
+ match in a long-lived process.
37
+ - Put long-lived processes under the application's supervision tree. Wait for
38
+ actual client readiness, not merely a successful supervisor start.
39
+ - Process-local context is not inherited by `Task` processes; pass required
40
+ context explicitly at that boundary.
41
+ - Document public APIs with `@moduledoc`, `@doc`, and `@spec`; use `Logger` for
42
+ operational logging and keep credentials out of messages and crash reports.
43
+ - Use American English in identifiers, comments and documentation.
44
+
45
+ Every `.ex` and `.exs` source file starts with:
46
+
47
+ ```elixir
48
+ # Copyright (c) Cratis. All rights reserved.
49
+ # Licensed under the MIT license. See LICENSE file in the project root for full license information.
50
+ ```
@@ -0,0 +1,34 @@
1
+ ---
2
+ applyTo: "**/*"
3
+ ---
4
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
5
+
6
+ # Exit codes and wrappers
7
+
8
+ An exit code is a verdict, and a wrapper that loses it turns a red run green. Every line
9
+ is tagged **[contract]** (binding) or **[convention]** (the house default) per the Three
10
+ Levels of Authority in [`general.md`](../../../rules/general.md).
11
+
12
+ - **[contract] Three codes, three meanings.** `0` ran clean, `1` found defects, `2` could
13
+ not run. A tool that cannot distinguish "found nothing" from "never looked" has no
14
+ usable verdict.
15
+ - **[contract] `2` is never reported as a pass.** Could-not-run is an unknown, and
16
+ unknown is not pass; see [`verification-discipline.md`](./verification-discipline.instructions.md).
17
+ - **[contract] A wrapper's own success is not the child's verdict.** A script that runs a
18
+ checker and then exits `0` because *the script* finished has thrown the result away.
19
+ Propagate the child's status.
20
+ - **[contract] Pipelines and loops lose exit codes by default.** Use `set -euo pipefail`,
21
+ check `PIPESTATUS` where a pipeline's left side matters, and accumulate a failure flag
22
+ inside a loop rather than relying on the last iteration.
23
+ - **[contract] Green prints counts.** A clean run says how many subjects it examined. A
24
+ bare "OK" cannot be distinguished from a run over an empty set; see
25
+ [`guards-and-fuses.md`](./guards-and-fuses.instructions.md).
26
+ - **[contract] `--self-test` plants defects.** A checker ships a self-test that seeds
27
+ known violations and fails if it does not find every one of them. That is the only way
28
+ to know the checker still detects anything.
29
+ - **[contract] Never swallow output to make a gate quiet.** Redirecting stderr, adding
30
+ `|| true`, or catching and ignoring is a decision to stop checking. Say so out loud or
31
+ do not do it.
32
+ - **[convention] Name the subject in the failure line.** The path, the id, the rule — a
33
+ failure a reader cannot locate costs more than it saves.
34
+ - **[convention] Keep the wrapper thin.** Logic in a wrapper is logic no test covers.
@@ -0,0 +1,55 @@
1
+ ---
2
+ applyTo: "**/*"
3
+ profile: framework
4
+ ---
5
+ <!-- cratis-ai: generated Copilot instructions. Do not edit; rules/ is the source. -->
6
+
7
+ # Framework Profile — Contributing to Cratis Itself
8
+
9
+ > **Framework profile only.** This applies when you are working **inside a Cratis framework repository** (Arc, Chronicle, Fundamentals, Components, Specifications, and the like) — building the framework. If you are building an *application on* Cratis, ignore this file and follow the Application profile (`general.md` + `vertical-slices.md`).
10
+
11
+ The framework repos are **libraries**, not event-sourced applications. The application-profile architecture — vertical slices, model-bound `[Command]`/`[ReadModel]` artifacts, projections/read-models, reactors, MVVM app components — **does not exist here and must not be imposed**. A Cratis framework repo has its own architecture per its purpose.
12
+
13
+ ## What still applies (universal rules)
14
+
15
+ Everything tagged `profile: universal` holds in framework repos exactly as in apps: **C# conventions** (`csharp.md`), **TypeScript conventions** (`typescript.md`), **code quality** (`code-quality*.md`), **specs** (`specs.md` / `specs.csharp.md` / `specs.typescript.md` — `Cratis.Specifications` is how the framework tests itself, using the plain `Specification` base + NSubstitute against the classes under test — this is the dominant mode in framework repos. The in-process `*Scenario` family lives in `specs.scenarios.csharp.md` (`profile: application`); applications add it where pipelines, validation, constraints or projections contribute proof, starting with plain calls for pure decisions; a framework repo reaches for it only to test the very engine it provides — Arc → `CommandScenario`, Chronicle → `EventScenario`/`ReadModelScenario`/`ReactorScenario` — not as a general testing mode. The **cratis-application-slice-specifications** skill is application-oriented), **documentation**, **git-commits**, **pull-requests**, **concepts** (`ConceptAs<T>` / `EventSourceId<T>` are Fundamentals/Chronicle primitives the framework defines and uses), and **American English**.
16
+
17
+ ## What does NOT apply
18
+
19
+ Skip these `profile: application` rules entirely when in a framework repo: `vertical-slices.md`, `reactors.md`, `react.md`, `components.md`, `dialogs.md`, `frontend-quality.md`, `frontend-testing.md`, `storybook.md`, `efcore.md`, `efcore.specs.md`. Do not create vertical-slice folders, `[Command]`/`Handle()` records, read models, or MVVM app components in framework source.
20
+
21
+ ## The repos and their shape
22
+
23
+ Each framework repo is organized by what it builds, not by feature slices:
24
+
25
+ - **Fundamentals** — the base library. `ConceptAs<T>`, type discovery (`IInstancesOf<T>` / `IImplementationsOf<T>`), serialization, common primitives. `Source/DotNET` includes `Fundamentals.TypeDiscovery.Generator`, `Metrics.Roslyn` (`Cratis.Metrics.Roslyn`) and `OpenTelemetry` (`Cratis.OpenTelemetry`); `Source/JavaScript` publishes `@cratis/fundamentals`, and `Source/ESLintConfig` publishes `@cratis/eslint-config` (verified at v7.23.0).
26
+ - **Specifications** — BDD lifecycle, assertions and analyzers. `Source/Specifications` supplies common helpers, `Source/XUnit` and `Source/NUnit` supply runner-specific bases/assertions, and `Source/CodeAnalysis` supplies the bundled analyzers (v4.1.1).
27
+ - **Orleans** — shared silo hosting, grain serializers, jobs and jobs storage (MongoDB/SQL/in-memory), in `Cratis.Orleans*` packages (v1.16.3). The core does not require Chronicle; the optional `.Chronicle` adapter does.
28
+ - **Arc** — the CQRS + model-binding + proxy-generation engine. `Source/DotNET` (the command/query pipeline, validation, authorization, identity, the Roslyn **proxy generator**) + `Source/JavaScript` (`@cratis/arc`, `@cratis/arc.react`, `@cratis/arc.react.mvvm`). Arc.Core does **not** depend on Chronicle.
29
+ - **Chronicle** — the event-sourcing engine. `Source/Kernel` (the engine: **Orleans grains**, event sequences, observers/projections/reducers, storage providers — MongoDB and others), `Source/Clients` (the client SDKs incl. `DotNET` and `Testing`), `Infrastructure`, `Tools`, `Workbench`. The kernel is the deep, performance- and consistency-critical core. Its shared job engine, jobs storage, serializers and reusable silo hosting now come from the separate **Orleans** repo, not Chronicle-owned jobs code (Chronicle v19.50.0).
30
+ - **Components** — the React component library (Components-owned markup and styling contract; React Aria internally; optional PrimeReact/MUI presentation adapters under `Adapters/`). `Source/<Component>/` folder per component (`CommandDialog`, `DataPage`, `DataTables`, …) with Storybook stories; published as `@cratis/components`. (Application rules *consume* these components; here you *build* them.)
31
+
32
+ Repo conventions follow from this: `Source/DotNET` + `Source/JavaScript` for dual-stack libraries; `Kernel` vs `Clients` for Chronicle; a folder-per-component library layout for Components. Match the structure of the area you are editing — do not introduce app-style layouts.
33
+
34
+ ## Framework-contributor principles
35
+
36
+ - **Public API design is the product.** These libraries are consumed by every Cratis app, so the **Lovable APIs** value (`general.md`) is paramount: sane defaults, convention over configuration, extensible/overridable, minimal boilerplate. Design the API the app developer will love before the implementation.
37
+ - **Backward compatibility is a contract.** A change to a public type, attribute, interface, or generated-proxy shape is a breaking change for every downstream app — label PRs by semver impact (`major`/`minor`/`patch`) and treat removals/renames of public surface as `major`.
38
+ - **Convention discovery is built here.** `IInstancesOf<T>` / `IImplementationsOf<T>`, attribute-based discovery, and source generation are the mechanisms the framework *provides*; use them internally too rather than hand-registration where a convention fits. A Fundamentals project reference does not carry the type-discovery analyzer like its NuGet package does: reference `Fundamentals.TypeDiscovery.Generator` explicitly, or your project's types may be absent from the generated universe.
39
+ - **Source generators / analyzers** (Arc's proxy generator, Fundamentals) follow Roslyn conventions; their output is consumed verbatim by apps, so treat generated shape as public API.
40
+ - **Orleans grains** in the Chronicle kernel follow `orleans.md`.
41
+ - **An alternate implementation of an interface must match the primary one's *semantics*, not just its signature.** Chronicle ships several implementations of the same storage interfaces (MongoDB, SQL, in-memory) and the in-memory ones exist precisely so the real kernel code paths can run without infrastructure. When you touch one, **diff it against the persistent implementations** — the signature tells you nothing about the contract. The specific trap: query criteria carry **sentinels meaning "do not narrow"** (`EventSourceId.Unspecified`, `EventSourceType.Unspecified`/`Default`, `EventStreamType.All`, `EventStreamId.Default`, an empty event-type set). Callers asking for "everything" pass those sentinels, never `null`, so a plain `is not null` check narrows every row away and the read silently returns nothing. A divergence here does not fail — it makes specs pass vacuously, which is worse.
42
+ - **A stub that silently succeeds is a bug, not a placeholder.** An unimplemented method returning `Task.CompletedTask`/an empty result lets a spec assert on work that never happened. Implement it, or make it fail loudly — never leave it quietly lying.
43
+ - **Specs** use `Cratis.Specifications` (the `Establish`/`Because`/`should_` BDD style) with NSubstitute — the same philosophy as apps, without the Arc/Chronicle `*Scenario` app-testing helpers.
44
+ - **Treat "no spec touches this public API" as a defect in itself.** Public surface with zero coverage is where silent breakage lives — an entire read surface, including two shipped assertion helpers, was once dead in `Cratis.Chronicle.Testing` because nothing ever called it. When adding public API, add at least one spec that exercises it end to end.
45
+
46
+ ## Quality gates (framework)
47
+
48
+ - Build clean (Debug and Release) with **zero warnings, zero errors**.
49
+ - Specs pass for affected projects (C# via `dotnet test`; TS packages via their test command; Components also `build-storybook`).
50
+ - For public-facing changes (APIs, attributes, generated output, component props): update the product documentation and verify it.
51
+ - Match the repo's existing patterns; when a deep architectural question isn't answered by the universal rules or this file, consult the **repo's own docs/CONTRIBUTING** or ask — do not infer framework internals from a single call site.
52
+
53
+ ## Depth lives in the repo
54
+
55
+ This file is the cross-cutting framework-contributor baseline. Repo-specific internals — the Chronicle kernel's grain/observer/storage design, Arc's proxy-generator internals, the Components build pipeline — are owned by each repo's own documentation, not duplicated here. Follow those for area-specific detail.