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
4 changes: 2 additions & 2 deletions .github/adr-check-prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Rules:
- Base every claim strictly on the provided data. **Invent nothing.** Do not
guess an ADR number — only cite an ADR that appears in the ADR base.
- The `report` is **advisory**. It must make clear that nothing here blocks a
merge, that a human or an agent drafts the ADR(s) under `maintainers/adr/` with
merge, that a human or an agent drafts the ADR(s) under `doc/handwritten/for-maintainers/adr/` with
`Status: Proposed`, and that the maintainer accepts, supersedes, or deprecates.
Never claim to have written an ADR or to block anything.

Expand All @@ -95,6 +95,6 @@ nothing here blocks a merge.
**Conflicts with**
- ⚠️ ADR-NNNN (<title>) — <the contradiction>

_Agents: draft the ADR(s) under `maintainers/adr/` as `Status: Proposed` and link
_Agents: draft the ADR(s) under `doc/handwritten/for-maintainers/adr/` as `Status: Proposed` and link
them; the maintainer decides. See `AGENTS.md` → "Architecture decisions"._
```
6 changes: 3 additions & 3 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@

* [ ] Public API / error documentation updated
* [ ] README / `doc/` updated
* [ ] French translation (`doc/README.fr.md`) updated if user-facing behavior changed
* [ ] French translation (`doc/handwritten/for-users/README.fr.md`) updated if user-facing behavior changed
* [ ] No documentation change required

## Architecture decisions

<!-- Every pull request is checked against the ADR base (maintainers/adr/). Most
<!-- Every pull request is checked against the ADR base (doc/handwritten/for-maintainers/adr/). Most
embark no architectural decision — tick the first box. Agents draft ADRs as
`Proposed`; the maintainer accepts or supersedes. See maintainers/adr/README.md. -->
`Proposed`; the maintainer accepts or supersedes. See doc/handwritten/for-maintainers/adr/README.md. -->

* [ ] No architectural decision in this pull request
* [ ] New decision recorded — ADR drafted as `Proposed`: ADR-____
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/adr-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ name: adr-check
# recording a decision is a human-reviewed act, exactly like the sibling
# `changelog` workflow. It NEVER blocks anything and NEVER writes an ADR — every
# failure mode is a warning, and the verdict is a recommendation a human acts on.
# See maintainers/workflows/adr-check.en.md.
# See doc/handwritten/for-maintainers/workflows/adr-check.en.md.
on:
workflow_dispatch:
inputs:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: canary
# Early-warning that the documentation tooling still runs on the NEXT, not-yet-released .NET.
#
# The shipped tooling targets net8.0 and reaches every newer runtime purely by roll-forward (the worker uses
# LatestMajor; see maintainers/adr/0002-floor-the-tooling-runtime.md). A runtime breaking change in a future
# LatestMajor; see doc/handwritten/for-maintainers/adr/0002-floor-the-tooling-runtime.md). A runtime breaking change in a future
# major would surface here first — on a schedule, against the current preview — instead of in a user's CI the
# day that major ships. It is the upper-end counterpart of the `floor` job in ci.yml, which pins the lower end.
#
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:

# build-test above runs the whole suite on the LATEST .NET (10). This job proves the other end of the
# supported range: that the fce tool and its worker, which ship targeting net8.0 (the floor — see
# maintainers/adr/0002-floor-the-tooling-runtime.md), actually run on the .NET 8 RUNTIME. The net8 TFM
# doc/handwritten/for-maintainers/adr/0002-floor-the-tooling-runtime.md), actually run on the .NET 8 RUNTIME. The net8 TFM
# already guards the compile-time API surface on every build; what it cannot show is that the tooling
# executes on its advertised minimum runtime, which is what this job checks against the real artifacts.
floor:
Expand Down
4 changes: 2 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Two roles are covered: **writing code** and **reviewing pull requests**.
- Build: `dotnet build FirstClassErrors.sln`
- Test: `dotnet test FirstClassErrors.sln` (analyzer tests: `dotnet test FirstClassErrors.Analyzers.UnitTests`).
- Repository language is **English** (code, comments, commits, PRs, issues, and
review comments). French lives only in `doc/README.fr.md` and must stay in sync
review comments). French lives only in `doc/handwritten/for-users/README.fr.md` and must stay in sync
with the English README.
- `Error` and its hierarchy, `ErrorCode`, `ErrorContextKey`, `Outcome`/`Outcome<T>`
and any value object are **`class`, never `struct`** — a struct exposes a
Expand All @@ -21,7 +21,7 @@ Two roles are covered: **writing code** and **reviewing pull requests**.
## Architecture decisions (code changes)

Before finalizing a pull request, check it against the ADR base under
`maintainers/adr/` (format and conventions: `maintainers/adr/README.md`). An ADR
`doc/handwritten/for-maintainers/adr/` (format and conventions: `doc/handwritten/for-maintainers/adr/README.md`). An ADR
records a **significant, lasting decision** — one a future maintainer would ask
"why did they do it this way?" about — not every change. Apply the README's test:
*if the implementation changed but the decision stood, the ADR should not need
Expand Down
10 changes: 5 additions & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ errors should stay structured, documented, and close to the code.
source code, code comments, commit messages, branch names,
PR titles and descriptions, and issues.
* The English documentation is canonical.
* The French documentation in `doc/README.fr.md` is an intentional translation
* The French documentation in `doc/handwritten/for-users/README.fr.md` is an intentional translation
and must stay in sync with the English documentation when user-facing behavior changes.
* You may reply to me in French in the chat, but never write repository content in French
unless you are updating the French documentation.
Expand All @@ -34,7 +34,7 @@ errors should stay structured, documented, and close to the code.
* `FirstClassErrors.Cli` — command-line tool
* `FirstClassErrors.RequestBinder` — request binder for the primary-adapter boundary (+ `.UnitTests`)
* `FirstClassErrors.Usage` — usage examples
* `doc/` — documentation, including the French translation
* `doc/` — documentation: `handwritten/` (`for-users`, `for-maintainers`) and `generated/` (CI/CD living docs)

## Change guidelines

Expand Down Expand Up @@ -62,16 +62,16 @@ errors should stay structured, documented, and close to the code.

* When you add or change an error, update its documentation accordingly.
* When you change user-facing behavior, keep the English README and the French translation
(`doc/README.fr.md`) in sync.
(`doc/handwritten/for-users/README.fr.md`) in sync.
* When you change analyzers, update or add analyzer tests.
* When you change diagnostics, keep diagnostic IDs, messages, documentation, and tests consistent.

## Architecture decisions (ADRs)

Before finalizing a pull request, check the change against the ADR base under
`maintainers/adr/`. This is **advisory**: produce a recommendation, never a
`doc/handwritten/for-maintainers/adr/`. This is **advisory**: produce a recommendation, never a
blocker. Full procedure in [`AGENTS.md`](AGENTS.md) ("Architecture decisions");
format and conventions in [`maintainers/adr/README.md`](maintainers/adr/README.md).
format and conventions in [`doc/handwritten/for-maintainers/adr/README.md`](doc/handwritten/for-maintainers/adr/README.md).
The essentials, inlined so they hold even if `AGENTS.md` is not read:

* An ADR records a **significant, lasting decision** — one a future maintainer
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Contributing to FirstClassErrors

🌍 **Languages:**
🇬🇧 English (this file) | 🇫🇷 [Français](./doc/CONTRIBUTING.fr.md)
🇬🇧 English (this file) | 🇫🇷 [Français](doc/handwritten/for-users/CONTRIBUTING.fr.md)

FirstClassErrors treats errors as first-class, documented, diagnosable
concepts. The history of the repository should be as legible as the errors the
Expand Down Expand Up @@ -473,7 +473,7 @@ Ordered as the rules are: type, scope, description, body, breaking, issue.
### Adoption

This guide is the rule for commits in this repository. Deviating from it
requires a justification — an ADR under `maintainers/adr/`, or an update to this
requires a justification — an ADR under `doc/handwritten/for-maintainers/adr/`, or an update to this
guide.

It applies from its adoption on, to every commit created after. Prior history is
Expand Down
4 changes: 2 additions & 2 deletions FirstClassErrors.Analyzers/HelpLinks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ namespace FirstClassErrors.Analyzers;

/// <summary>
/// Builds the documentation URL surfaced by each diagnostic (the "help link" in the IDE). Per-rule pages are added
/// under <c>doc/analyzers/</c> in a later phase.
/// under <c>doc/handwritten/for-users/analyzers/</c> in a later phase.
/// </summary>
internal static class HelpLinks {

private const string Base = "https://github.com/Reefact/first-class-errors/blob/main/doc/analyzers";
private const string Base = "https://github.com/Reefact/first-class-errors/blob/main/doc/handwritten/for-users/analyzers";

public static string For(string diagnosticId) {
return $"{Base}/{diagnosticId}.en.md";
Expand Down
2 changes: 1 addition & 1 deletion FirstClassErrors.Cli/FirstClassErrors.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
Do NOT rely on `dotnet build` or `dotnet publish` to validate that the tool ships its worker: neither exercises
the .nupkg content, so both stay green even if the worker never reaches the package. The real gates are the
worker-present assertion in tools/packaging/pack.sh and the manual tool-install smoke test documented in
maintainers/ReleaseDryRun (install the packed tool, run `fce generate`, expect a non-empty catalog). -->
doc/handwritten/for-maintainers/ReleaseDryRun (install the packed tool, run `fce generate`, expect a non-empty catalog). -->
<Target Name="_CopyDocumentationWorker" AfterTargets="Build">
<ItemGroup>
<_DocumentationWorkerFiles Include="$(MSBuildThisFileDirectory)..\FirstClassErrors.GenDoc.Worker\bin\$(Configuration)\$(TargetFramework)\**\*.*" />
Expand Down
2 changes: 1 addition & 1 deletion FirstClassErrors.RequestBinder/README.nuget.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ Outcome<PlaceBookingCommand> command =
bind.New(s => new PlaceBookingCommand(s.Get(email), s.Get(stay)));
```

See the [request-binder guide](https://github.com/Reefact/first-class-errors/blob/main/doc/RequestBinder.en.md) for the full walkthrough, and the [repository documentation](https://github.com/Reefact/first-class-errors) for the rest of FirstClassErrors.
See the [request-binder guide](https://github.com/Reefact/first-class-errors/blob/main/doc/handwritten/for-users/RequestBinder.en.md) for the full walkthrough, and the [repository documentation](https://github.com/Reefact/first-class-errors) for the rest of FirstClassErrors.
56 changes: 28 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# FirstClassErrors

🌍 **Languages:**
🇬🇧 English (this file) | 🇫🇷 [Français](./doc/README.fr.md)
🇬🇧 English (this file) | 🇫🇷 [Français](doc/handwritten/for-users/README.fr.md)

| | |
| :-- | :-- |
Expand All @@ -15,7 +15,7 @@

**Turn your errors into structured, living knowledge about your system.**

![FirstClassErrors](./doc/images/first-class-errors.png "FirstClassErrors")
![FirstClassErrors](doc/handwritten/for-users/images/first-class-errors.png "FirstClassErrors")

## 🚨 The problem

Expand Down Expand Up @@ -124,7 +124,7 @@ To generate documentation, install the CLI:
dotnet tool install --global FirstClassErrors.Cli
```

Then follow the [Getting Started guide](doc/GettingStarted.en.md) to create and generate your first documented error.
Then follow the [Getting Started guide](doc/handwritten/for-users/GettingStarted.en.md) to create and generate your first documented error.

## 🎯 When it is a good fit

Expand All @@ -135,11 +135,11 @@ FirstClassErrors is especially useful for long-lived application or domain code
- support and operations investigate production failures;
- documentation must remain aligned with behavior.

For prototypes, tiny utilities, or low-level technical code, standard exceptions may be enough. See [When Not to Use FirstClassErrors](doc/WhenNotToUseFirstClassErrors.en.md).
For prototypes, tiny utilities, or low-level technical code, standard exceptions may be enough. See [When Not to Use FirstClassErrors](doc/handwritten/for-users/WhenNotToUseFirstClassErrors.en.md).

## 🔍 Analyzers and supply-chain information

The package includes Roslyn rules with stable `FCExxx` identifiers. They detect duplicate or malformed error codes, invalid documentation wiring, missing examples, and common API misuse. See the [analyzer rules reference](doc/analyzers/README.md).
The package includes Roslyn rules with stable `FCExxx` identifiers. They detect duplicate or malformed error codes, invalid documentation wiring, missing examples, and common API misuse. See the [analyzer rules reference](doc/handwritten/for-users/analyzers/README.md).

Released packages include signed build provenance and an embedded SPDX SBOM. See the release and verification details in the [supply-chain documentation](SECURITY.md).

Expand All @@ -153,39 +153,39 @@ For security vulnerabilities, follow the private process in [SECURITY.md](SECURI

### Discover

- [Getting Started](doc/GettingStarted.en.md)
- [Design Principles](doc/DesignPrinciples.en.md)
- [When Not to Use FirstClassErrors](doc/WhenNotToUseFirstClassErrors.en.md)
- [Getting Started](doc/handwritten/for-users/GettingStarted.en.md)
- [Design Principles](doc/handwritten/for-users/DesignPrinciples.en.md)
- [When Not to Use FirstClassErrors](doc/handwritten/for-users/WhenNotToUseFirstClassErrors.en.md)

### Understand the model

- [Core Concepts](doc/CoreConcepts.en.md)
- [Error Taxonomy and Composition](doc/ErrorTaxonomy.en.md)
- [Error Context Guide](doc/ErrorContext.en.md)
- [Core Concepts](doc/handwritten/for-users/CoreConcepts.en.md)
- [Error Taxonomy and Composition](doc/handwritten/for-users/ErrorTaxonomy.en.md)
- [Error Context Guide](doc/handwritten/for-users/ErrorContext.en.md)

### Write and use errors

- [Writing Errors Guide](doc/WritingErrorsGuide.en.md)
- [Usage Patterns](doc/UsagePatterns.en.md)
- [Binding requests at the boundary (RequestBinder)](doc/RequestBinder.en.md)
- [Best Practices](doc/BestPractices.en.md)
- [Testing Guide](doc/Testing.en.md)
- [Deterministic Error Tests](doc/DeterministicTesting.en.md)
- [Arbitrary Test Values](doc/ArbitraryTestValues.en.md)
- [Writing Errors Guide](doc/handwritten/for-users/WritingErrorsGuide.en.md)
- [Usage Patterns](doc/handwritten/for-users/UsagePatterns.en.md)
- [Binding requests at the boundary (RequestBinder)](doc/handwritten/for-users/RequestBinder.en.md)
- [Best Practices](doc/handwritten/for-users/BestPractices.en.md)
- [Testing Guide](doc/handwritten/for-users/Testing.en.md)
- [Deterministic Error Tests](doc/handwritten/for-users/DeterministicTesting.en.md)
- [Arbitrary Test Values](doc/handwritten/for-users/ArbitraryTestValues.en.md)

### Generate and operate the catalog

- [CI/CD and Operational Integration](doc/OperationalIntegration.en.md)
- [CI/CD and Operational Integration](doc/handwritten/for-users/OperationalIntegration.en.md)
- Catalog versioning
- [Overview and workflow](doc/CatalogVersioning.en.md)
- [Command reference](doc/CatalogVersioningReference.en.md)
- [CI/CD integration](doc/CatalogVersioningCI.en.md)
- [Architecture of the Documentation Pipeline](doc/ArchitectureOfTheDocumentationPipeline.en.md)
- [Writing a custom renderer](doc/WritingACustomRenderer.en.md)
- [Internationalization](doc/Internationalization.en.md)
- [Overview and workflow](doc/handwritten/for-users/CatalogVersioning.en.md)
- [Command reference](doc/handwritten/for-users/CatalogVersioningReference.en.md)
- [CI/CD integration](doc/handwritten/for-users/CatalogVersioningCI.en.md)
- [Architecture of the Documentation Pipeline](doc/handwritten/for-users/ArchitectureOfTheDocumentationPipeline.en.md)
- [Writing a custom renderer](doc/handwritten/for-users/WritingACustomRenderer.en.md)
- [Internationalization](doc/handwritten/for-users/Internationalization.en.md)

### Evaluate and troubleshoot

- [Comparison with error-handling libraries](doc/ComparisonWithOtherLibraries.en.md)
- [Analyzer rules (FCExxx)](doc/analyzers/README.md)
- [FAQ](doc/FAQ.en.md)
- [Comparison with error-handling libraries](doc/handwritten/for-users/ComparisonWithOtherLibraries.en.md)
- [Analyzer rules (FCExxx)](doc/handwritten/for-users/analyzers/README.md)
- [FAQ](doc/handwritten/for-users/FAQ.en.md)
2 changes: 1 addition & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Security Policy

🌍 **Languages:**
🇬🇧 English (this file) | 🇫🇷 [Français](./doc/SECURITY.fr.md)
🇬🇧 English (this file) | 🇫🇷 [Français](doc/handwritten/for-users/SECURITY.fr.md)

## Supported Versions

Expand Down
19 changes: 12 additions & 7 deletions doc/FirstClassErrors.Documentation.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
<!--
Documentation-only project.

This project compiles nothing. Its sole purpose is to surface everything
under doc/ in the Visual Studio Solution Explorer, so the documentation is
easy to find, read and edit right next to the code: the Markdown pages
(English *.en.md and French *.fr.md, including the analyzer pages under
analyzers/), the images, and any other asset that may be added later.
This project compiles nothing. Its sole purpose is to surface every piece of
documentation under doc/ in the Visual Studio Solution Explorer, so it is
easy to find, read and edit right next to the code. It covers the whole tree:

doc/generated/ - living documentation produced by CI/CD (e.g. GenDoc)
doc/handwritten/ - documentation written by hand
for-users/ the library's user documentation (English *.en.md and
French *.fr.md, including the analyzer pages and images)
for-maintainers/ the maintainer documentation (ADRs, workflow notes, ...)

The <None> glob below picks up new files automatically: no need to touch
this project or the solution when documentation is added or renamed. The
Expand Down Expand Up @@ -45,10 +49,11 @@
<!--
The repository's main README lives at the solution root, outside doc/, so
the glob above cannot reach it. Reference it as a link so it is browsable
from this project too. Link metadata is required for files located outside
from this project too, placed next to its French translation under
handwritten/for-users. Link metadata is required for files located outside
the project directory.
-->
<None Include="..\README.md" Link="README.md" />
<None Include="..\README.md" Link="handwritten\for-users\README.md" />
</ItemGroup>

</Project>
12 changes: 12 additions & 0 deletions doc/generated/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Generated documentation

This folder holds **living documentation produced automatically by CI/CD**.
Do not edit its contents by hand: anything here is regenerated (and overwritten)
on the next generation run.

- [`gendoc/`](gendoc) — error catalog emitted by the GenDoc toolchain
(`FirstClassErrors.GenDoc` / `fce generate`).

Handwritten documentation lives under [`../handwritten`](../handwritten):
[`for-users`](../handwritten/for-users) and
[`for-maintainers`](../handwritten/for-maintainers).
2 changes: 2 additions & 0 deletions doc/generated/gendoc/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Placeholder so the CI/CD output directory is tracked before the first
# generation run. GenDoc writes the rendered error catalog here.
Loading