Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,21 @@ jobs:
- name: Flows page matches the kit
run: python scripts/check-flows-page.py

# docs/csharp-component.html is the interactive form of the C# component
# guide; its embedded data must list the guide's checks and the starter
# contract's rules, not a stale copy of either.
- name: C# component page matches the guide and the starter contract
run: python scripts/check-csharp-page.py

# The starter contract must be green on a fresh seed and every rule must
# bite. The engine is specfuse-loop's, a test-time dependency here, in the
# same direction as the core package below: the kit depends on the loop,
# never the reverse.
- name: C# starter contract is green and every rule bites
run: |
python -m pip install --quiet 'specfuse-loop>=0.30'
./scripts/test-csharp-contract-template.sh

- name: Clean-install and bootstrap from the built wheel
run: |
python -m venv /tmp/ci
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ See [`examples/hello-orders/`](examples/hello-orders/) for a complete worked exa
| **Handbooks** ([`handbooks/`](handbooks/)) | 6 authoritative documents: REST API, AsyncAPI, Arazzo, vendor extensions, AI access policy framework, and the generator's project file. Together these define the full spec-authoring contract. |
| **Samples** ([`samples/`](samples/)) | 4 canonical YAML templates — endpoints, async messages, scenarios, recipes — that every authored file should pattern-match against. |
| **Schemas** ([`schemas/`](schemas/)) | Working Spectral rulesets and custom functions for validation under `schemas/spectral/`. CI lints the bundled example against them. [`schemas/README.md`](schemas/README.md) also covers how to run Spectral so a crash cannot pass as a clean spec, and how to turn the ruleset on against specs that predate it. |
| **Templates** ([`templates/`](templates/)) | The `project-init/` skeleton, plus the AI Access Policy template. |
| **Templates** ([`templates/`](templates/)) | The `project-init/` skeleton, the AI Access Policy template, and the starter generated-code contract for C# component repos (`component-contract/csharp/`: 16 rules, a mutation test, the expectations skeleton, the CI workflow, and the tooling that re-applies tracked temporary patches to generated code after every regen). |
| **Claude assets** | 5 Claude Code sub-agents and 20 authoring skills (`/specfuse-authoring:design-scenario`, `/specfuse-authoring:design-async`, `/specfuse-authoring:design-recipe`, etc.) that automate spec design. Distributed as the `specfuse-authoring` plugin in the `specfuse/specfuse` marketplace; `init` wires the plugin and scaffolds the contract the skills read into `.specfuse/authoring/`. |
| **Bundled example** ([`examples/hello-orders/`](examples/hello-orders/)) | A 61-file complete Specfuse project — 2 domains, 3 entities, 1 state-transition event, 1 cross-domain scenario, 2 setup recipes, filled AI access policy, CI workflow. Serves as the kit's regression net. |

Expand All @@ -71,6 +71,7 @@ See [`examples/hello-orders/`](examples/hello-orders/) for a complete worked exa
| Look up a `x-*` extension | [`handbooks/Vendor_Extensions.md`](handbooks/Vendor_Extensions.md) | — |
| Implement field encryption at runtime | [`handbooks/Field_Encryption_Runtime.md`](handbooks/Field_Encryption_Runtime.md) | — |
| Configure the generator project file | [`handbooks/Project_File.md`](handbooks/Project_File.md) | — |
| Set up or audit a C# backend repo that receives generated code | [`docs/csharp-component-guide.md`](docs/csharp-component-guide.md), with [`docs/csharp-component.html`](docs/csharp-component.html) as the interactive map | hand the guide to Claude (§"How to use this guide with Claude"); seed [`templates/component-contract/csharp/`](templates/component-contract/csharp/) |
| See how it all fits together | [`docs/flows.html`](docs/flows.html), an interactive map of the lifecycle, project layout, skills, validation layers and upgrades. Every project gets a copy at `.specfuse/authoring/docs/flows.html`. | Open it in a browser |
| See a complete worked example | [`examples/hello-orders/README.md`](examples/hello-orders/README.md) | — |

Expand Down
11 changes: 8 additions & 3 deletions docs/component-repos.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Run these from the spec repo's generate wrapper as soon as the group finishes, s

Commit generated code in the component repo. Every regen then shows up as a reviewable diff in a component PR. CI and teammates build without Java or generator access. And a spec change and its effect on each component are visible side by side.

Ignore the generator's volatile bookkeeping files, such as the per-group `*.generated-paths.json` manifests. The Dart package may need its own `.gitignore` exception if the app ignores `*.g.dart` at the root.
Commit the generator's per-group `*.generated-paths.json` path manifests too: they record every emitted path and every file a regen moved, and their `capturedAt` comes from the spec repo's `<stateDir>/<group>.paths.json` baseline rather than the clock, so a regen that moved nothing leaves them byte-identical. The Dart package may need its own `.gitignore` exception if the app ignores `*.g.dart` at the root.

**What a green build does not prove.** A regen can change a field's name or an enum's wire value while every hand-written type that mirrors it still compiles. When you review a regen PR:

Expand Down Expand Up @@ -121,12 +121,17 @@ The generator keeps one file per group under `stateDir` (default `.specfuse/stat
- `baseline` rewrites every group's state file, so restore the files for groups whose component was not on a clean, merged `main` (`git checkout -- .specfuse/state/<group>.json`). Commit the rest in a spec-repo PR on its own (no spec changes), citing the component PR and commit.
- `baseline` rewrites only `<group>.json`. If `<group>.paths.json` has drifted too, it takes a real regen whose output matches the component's `main` byte for byte.

## 7. Contract checks in the component (optional)
## 7. Contract checks in the component

A component can also guard its generated tree mechanically, with a CI check that fails when generated files are hand-edited or don't meet the shape the component depends on, plus a short doc describing that expected shape. Tooling for this is not shipped by the kit yet ([#171](https://github.com/specfuse/authoring/issues/171)). Until it is, keep any such check small and specific to the component.
A component can guard its generated tree mechanically: a contract file (`gen-contract.yml`) whose rules fail when generated files are hand-edited or do not meet the shape the component depends on, run as a `code` gate in `.specfuse/verification.yml`, plus a short prose doc (`docs/generated-code-expectations.md`) saying what "acceptable" means beyond the rules. The ownership is settled ([#171](https://github.com/specfuse/authoring/issues/171)): the rules and the prose are the component's, the engine is `specfuse.loop.gen_contract` in specfuse-loop 0.30+, and what the generator's own QA harness reads from those two files is published as a stable interface ([`CONSUMER-CONTRACT.md`](https://github.com/clabonte/generator/blob/main/docs/CONSUMER-CONTRACT.md)).

For C#, the kit ships a starter: [`templates/component-contract/csharp/`](../templates/component-contract/csharp/), 16 rules green on a fresh seed, each with a mutation case, and the full walkthrough is [`csharp-component-guide.md`](csharp-component-guide.md) §6. `add-component` will seed it once [#181](https://github.com/specfuse/authoring/issues/181) lands; until then its README has the copy-and-sed steps. Other languages keep any such check small and specific to the component.

When generated code is wrong and the fix cannot wait for a generator release, the same guide's §9.1 covers the stop-gap: a workaround from hand-written code where one exists, otherwise a tracked patch that `post-generate.sh` re-applies after every regen until the fix ships. Its `apply-gen-patches.sh` is language-neutral.

## Where to go next

- [`csharp-component-guide.md`](csharp-component-guide.md): the C# component in full, with an audit checklist for Claude
- [`Project_File.md`](../handbooks/Project_File.md): `destination`, `cleanGenerated`, `cleanScope`, `stateDir`
- [`Vendor_Extensions.md` §4.5](../handbooks/Vendor_Extensions.md): `x-manual`, the operations that stay hand-written
- [`generator-access.md`](generator-access.md): generator access for whoever runs regens
Loading
Loading