Skip to content

Releases

LiteSpec 5.2.0

Choose a tag to compare

@github-actions github-actions released this 12 Nov 17:13
5ea5d7f

LiteSpec 5.2.0 generates the agent instructions in a consumer's AGENTS.md from one template and reports when they drift, narrows rules to the provisions that apply to the edited file or the change set, ships a LiteSpec skill for Claude Code and OpenCode, and requires a technical decision only for a choice of one of six named kinds. It is a minor release: no provision ID is removed or renamed. A consumer runs model render, moves provision-shaped conventions into the conventions folder, and may give each technical decision its kind, as Part H describes.

Part A: Generated Agent Protocol in AGENTS.md

  • templates/consumer/project-agents.md is the only source of the consumer protocol. Its LiteSpec part sits inside a generated region, <!-- generated:agent-protocol --> ... <!-- /generated:agent-protocol -->, opening with the precedence sentence: when the file disagrees with tool output or a record, the tool output and the record win. The ## Project Commands part stays outside the region, written by the project.
  • init writes the region into a fresh AGENTS.md, and inserts it into an existing one that holds none, after the first heading or at the end. It never touches text outside the region, and it never rewrites a region that is already there.
  • model render rewrites the region from the carried release and the project file: release, size, shape, stacks, layers, extensions, selection key, and command form.
  • model check reports agent-protocol-drift when the region differs from what render would write, and agent-protocol-missing when AGENTS.md holds no region. Both block.
  • The region holds 40 lines or fewer: commands and the rules an agent cannot guess, and no description of LiteSpec. It states one order: query the model for the records, run rules <path> for each file to edit, read the pages rules cites, then read neighboring code. The phrase "generated agent context" is gone; the query output is the task context. The rules lines cite load-applicable-provisions-before-editing.
  • The site selection page renders the same template, filled for the chosen selection, through one shared generated module. /llms.txt embeds the filled template under "Agent Protocol" instead of this repository's AGENTS.md.

The rule is litespec/core/agent#keep-the-agent-protocol-current. Decision 0037, Generate the Agent Protocol, records why.

Part B: Narrower Rules Output, Change Sets and Lookup by ID

  • When the target is code, provisions matched only through a marked record print as one line per record: use-case/spending.approve-expense: <n> provisions about the record; model check checks <m>; run rules use-case/spending.approve-expense for the rest. A record path or record ID still prints them in full.
  • rules --since <ref> takes every file changed since <ref>, returns the union with duplicates removed, leaves out the tool-checked provisions, and prints a report skeleton: one line per judgment provision with its Reviewed for question and an empty How judged: line.
  • rules <provision-id> prints that provision in full: strength, statement, rationale, example, Reviewed for or Checked by, and page. rules <page-id> prints the page's provision list. Both read the carried provisions.json, so they work offline.
  • The duty is reworded: litespec/core/agent#load-applicable-provisions-before-editing runs rules <path> before editing a file, and answers each judgment provision rules --since <base> lists before reporting done. The stale provision count is gone from its rationale.
  • A provision that holds only in some situations states a when key on its **Applies to:** line: query, command, upload, document-number, erasure, project, or audit-adoption. rules returns it on a code path only when the condition holds for the record the file marks; a record path prints it with its condition shown.
  • When the target is code, a Decided: group prints first: each decision the file follows with its choice and reopenedWhen, then each departure covering a provision in the result with its reason and, for a gap, its expiresOn.
  • The stage provision carries when: project, so it applies once to the project and never per record. The audit adoption provision carries when: audit-adoption, so it applies only to the decision the audit extension selection names in its new decision field in .litespec/project.yaml.
  • The site serves /5.2.0/provisions.json, one object per provision, outside search results. The published URLs page states the ID-to-URL rule: litespec/<page>#<slug> is https://litespec.dev/<release>/<page>/#<slug> as HTML and <page>.md as Markdown.

Decision 0038, Narrow Rules Output per File and Change Set, records why.

Part C: The LiteSpec Skill

  • templates/skill/litespec/ holds SKILL.md with references/commands.md and references/report.md. The frontmatter names litespec, with a description that triggers on work in a repository holding .litespec/project.yaml. The body stays under 200 lines and carries the procedure, not the provisions: read the protocol region and the project file, query the model, run rules per file, stop on unresolved conflict, check the change set, and write the completion report.
  • litespec skill add [--agent claude|opencode|agents]... [--global] installs one generated copy per target; litespec skill remove deletes them. Without --agent, add installs for agents and claude, which together reach Claude Code and OpenCode. Each target gets its own copy, never a link, so it works in git and on Windows without Developer Mode.
  • Every copy carries metadata.generated-by: litespec. A project-scope copy is also stamped with the release; a global copy names no release, so one global skill serves projects on different releases. add replaces a copy it wrote and refuses a folder without its marker, with exit 1; remove deletes only a folder carrying the marker. Global scope writes under the user's home and needs no project file.
  • init --skill <agent>[,<agent>] installs the skill at project scope during setup, and --skill-global installs it at global scope instead. Without --skill, init prints the skill add command as its last line.
  • model render rewrites project-scope copies that carry the marker. model check reports skill-drift when a project copy differs from what the carried release generates. Global copies live outside the project and stay outside the check.

The rule is litespec/core/agent#keep-the-agent-protocol-current, which also names the skill. The skill page states the full syntax. Decision 0039, Ship a LiteSpec Skill, records why.

Part D: Decision Kinds, Convention Marks and Decision Indexes

  • A technical decision carries an optional kind: provider, package, format, boundary, topology, or replacement. A product decision takes none. litespec/core/model#record-each-technical-choice-as-a-decision requires a decision only for a choice of one of the six kinds; otherwise the class documentation states the reason, and the mark names the record the class serves. Claimwick's 0005-render-receipts-as-pdf reads package.
  • model check reports decision-kind-missing for a technical decision with no kind, and decision-scope-invalid for a technical decision whose followers all sit in one module and each already carry an implements mark. Both are advisory.
  • The default litespec/core/agent#search-the-provisions-before-recording-a-decision queries rules for the decision's subject first: where a provision makes the choice, the code follows that provision instead. litespec new decision <name> prints the provisions whose statement matches the name's words before it writes the files.
  • A follows or proves mark may name a project convention as <project>/conventions#<slug>. An unknown convention ID reports mark-unknown, as an unknown decision does. Claimwick gains one convention that a class follows.
  • A decision chooses between options at one moment, and its reopenedWhen names what would reopen it. A convention is a standing rule every change follows, and its Reviewed for question names how a reviewer finds a breach. model check reports convention-folder-invalid for a convention-shaped file under .litespec/ outside governance/conventions/, where rules never reads it. A convention's Applies to takes a path glob or the scope keys provisions use, such as stack: dotnet; artifact: command-handler, and anything neither reports convention-scope-invalid. Both are advisory. model check accepts .litespec/governance/conventions/ and the convention files in it, which the folder and page checks refused although rules reads them there.
  • Folders carry ownership and layer only. A decision's concern is computed from its followers' paths, so it cannot drift. model render writes a decision-index region into the README of each decisions folder that carries the fence, grouped by kind, then by concern, with the choice, follower count and modules, reopenedWhen, and markers for decision-unimplemented, decision-basis-missing and decision-scope-invalid. It writes a departure-index region grouped by gap or permanent, ordered by expiresOn, with the provisions each departure covers.
  • The book's decision chapter groups by kind, then by concern; each decision page lists its followers by module; and an external-system page shows the decision that chooses its provider. model check reports decision-home-drift for a module-level decision followed from more than one module, or a product-level decision followed only from one module. It is advisory.

Decision 0040, Require Decisions Only for Six Kinds of Choice, records why.

Part E: Strength and Modal Word Agree

  • The rule is litespec/core/authoring#match-strength-to-the-modal-word: a required statement holds MUST...
Read more

LiteSpec 5.1.0

Choose a tag to compare

@github-actions github-actions released this 12 Nov 00:41
1fb1a2c

LiteSpec 5.1.0 lets a project require an explanation file for every record on the layers it names, and adds behavior Standards for keyboards, screen readers, reduced motion, color schemes and older browsers. It pins third-party packages to their major version, so a consumer takes patch and minor releases without waiting for LiteSpec. model check is several times faster on large projects. It is a minor release: no provision ID is removed or renamed. A consumer with a shared UI package adds a Browser Support section to its design contract, as Part H describes.

Part A: Explanation Files a Project Requires

  • explanations.layers in .litespec/project.yaml names the layers whose records must each carry an explanation file. It takes intent, behavior or both. Every page record on a named layer then needs its <name>.md beside its record file, with the sections its record type defines. Projects that leave the key out are unaffected.
  • model check reports explanation-missing for a missing file or a missing required section, and project-invalid when explanations.layers names a layer the project does not claim in layers.
  • litespec new writes the explanation file from templates/consumer/<type>.md when the new record's layer is listed, and from templates/consumer/explanation.md for a type with no template of its own.
  • litespec new feature <module>.<name> writes the record feature/<name> in the module's folder. In 5.0.0 it refused every name: without a module it asked for one, and with one it rejected the identifier.

The rule is litespec/core/model#require-explanation-files-on-the-layers-a-project-names, and the project file reference lists the field.

Part B: How a Screen Behaves

  • Controlled UI Governance names three layers of a screen: product, behavior and parts. The parts never lower the behavior: a baseline component that closes a modal on an outside press, or traps Tab in a menu, is overridden.
  • The pattern and foundation pages gain behavior Standards drawn from WCAG 2.2. They cover overlay dismissal and initial focus, live regions by urgency, when a field error appears and how assistive technology reads it, one send in flight, sortable and scrolling tables, aligned figures, calendar dates without a time zone, sibling pages as links, 3:1 focus indicators and input boundaries, color schemes, reduced motion, pause controls, text sizes in rem, and focus on a route change.
  • The route suite checks focus after a route change, every declared color scheme and reduced motion.
  • The pattern pages state what they contradicted before:
    • Amounts show the decimals each currency defines, and money fields are text inputs.
    • The session warning no longer expires.
    • The theme follows the device by default.
    • Every Compact line states its pattern's narrow behavior.

Part C: Packages Pinned to Their Major

  • litespec.manifest.yaml pins each third-party package to its major, written N.x, such as Marten: 9.x. The consumer's central version file or lockfile holds the exact version, so a consumer takes a patch or minor release of a baseline package without waiting for a LiteSpec release.
  • Three packages stay exact: LiteSpec.Analyzers, which matches the CLI release, and the shadcn and shadcn-svelte CLIs, whose exact version the UI source lock records. The node and pnpm entries under stack stay exact too.
  • dependency-version-drift reports a direct package outside its pin: another major, or a prerelease inside the pinned major. Its message reads ... is outside its manifest pin '9.x'. for a major pin and keeps ... differs from its manifest pin ... for an exact pin.

Decision 0036, Pin Third-Party Packages to Their Major, records why.

Part D: The Book

  • A use case shows its Kind once, and a scenario shows Given, When, Then and Result in their own sections only.
  • The norun proof state reads "Not run".
  • A page record no longer lists its own entries as links. In 5.0.0 they appeared under raw keys such as use-case.records.id.
  • The top bar carries the Litenova family mark.

Part E: Faster Model Check

On a project of 3,142 records and 19,334 files, litespec model check took 195 s in 5.0.0 and takes about 18 s in 5.1.0, with the same output. The checks run in parallel, the schema evaluator stops at the first failing shape, and record lookups use indexes built once per run. A run also reads the release's provision pages and schemas once, where 5.0.0 read the provision pages three times and could parse a schema once per parallel worker.

Part F: The Documentation and litespec.dev

  • learn/README.md is the starting page: what LiteSpec is, a five-minute picture, then five pages in reading order. Each concept is explained on one page, and the others link to it.
  • learn/reading-tracks.md and guide/folder-reference.md are removed. Their content is in learn/how-litespec-works.md and the folder reference.
  • On litespec.dev:
    • The sidebar is one tree in five groups, in reading order: Learn, Tutorial, Guides, Standard and Reference. Every area and folder opens and closes, starts open when it holds the current page, and lists its overview first.
    • Breadcrumbs show every level, and every breadcrumb entry in the page's structured data links its page.
    • A folder's overview page is titled by its folder, such as "CLI Commands Overview".
    • The Standard has an index page of linked cards, and "On this page" opens the section in view.
    • A pattern lists its facts with each label beside its value, and its Default links to the option it names.
    • The landing page is the opening title and the release badge, which links to this changelog.
    • Screens 1600px and wider get a wider column and larger type, and muted text reads at 6:1 or more in light mode.
    • Pages animate only when the reader's system allows motion.
    • On a phone, the page browser has a filter.

Part G: Provision Changes Since v5.0.0

Provision Changes Since v5.0.0

Added (41):

  • litespec/core/model#require-explanation-files-on-the-layers-a-project-names
  • litespec/frontend/components#make-touch-targets-fit-a-finger
  • litespec/frontend/components#show-a-focus-indicator-that-stands-out
  • litespec/frontend/data#keep-a-calendar-date-free-of-a-time-zone
  • litespec/frontend/patterns/create-edit-remove#refuse-a-second-send-while-one-is-in-flight
  • litespec/frontend/patterns/dialogs-and-overlays#hold-a-toast-while-a-modal-is-open
  • litespec/frontend/patterns/dialogs-and-overlays#keep-tab-free-to-leave-a-menu-or-popover
  • litespec/frontend/patterns/dialogs-and-overlays#keep-the-page-behind-a-modal-still
  • litespec/frontend/patterns/dialogs-and-overlays#keep-unsaved-input-through-a-dismissal
  • litespec/frontend/patterns/dialogs-and-overlays#pause-a-timed-toast-while-it-is-in-use
  • litespec/frontend/patterns/dialogs-and-overlays#place-initial-focus-on-the-safe-action
  • litespec/frontend/patterns/feedback-and-states#announce-each-status-by-its-urgency
  • litespec/frontend/patterns/feedback-and-states#keep-unsent-input-when-the-connection-drops
  • litespec/frontend/patterns/feedback-and-states#mark-a-loading-region-busy
  • litespec/frontend/patterns/feedback-and-states#move-focus-to-a-refusal
  • litespec/frontend/patterns/forms-and-fields#expose-a-field-error-to-assistive-technology
  • litespec/frontend/patterns/forms-and-fields#keep-submit-enabled-to-reveal-errors
  • litespec/frontend/patterns/forms-and-fields#mark-every-required-field
  • litespec/frontend/patterns/forms-and-fields#match-the-keyboard-to-the-value
  • litespec/frontend/patterns/forms-and-fields#refuse-enter-while-text-is-being-composed
  • litespec/frontend/patterns/forms-and-fields#show-a-field-error-after-the-field-is-left
  • litespec/frontend/patterns/forms-and-fields#state-each-fields-purpose
  • litespec/frontend/patterns/forms-and-fields#take-a-name-in-one-field-of-any-script
  • litespec/frontend/patterns/lists-and-tables#announce-a-lists-result-count
  • litespec/frontend/patterns/lists-and-tables#keep-the-header-row-in-view
  • litespec/frontend/patterns/lists-and-tables#make-a-scrolling-table-a-named-region
  • litespec/frontend/patterns/lists-and-tables#mark-the-sorted-column
  • litespec/frontend/patterns/lists-and-tables#shape-a-list-by-its-container
  • litespec/frontend/patterns/money-time-density#align-figures-in-a-column
  • litespec/frontend/patterns/money-time-density#mark-a-moment-with-its-machine-value
  • litespec/frontend/patterns/navigation#draw-sibling-pages-as-links-not-tabs
  • litespec/frontend/rendering#move-focus-on-a-route-change
  • litespec/frontend/rendering#split-long-client-work
  • litespec/frontend/ui#give-every-input-a-visible-boundary
  • litespec/frontend/web/components#enforce-trusted-types-on-raw-markup
  • litespec/frontend/web/ui#build-within-the-browser-support-target
  • litespec/frontend/web/ui#give-moving-content-a-pause-control
  • litespec/frontend/web/ui#honor-reduced-motion
  • litespec/frontend/web/ui#render-each-declared-color-scheme
  • litespec/frontend/web/ui#set-text-sizes-in-relative-units
  • litespec/quality/ci#assert-loading-stability-and-blocking-time-per-route

Removed (0):

None.

Renamed (0):

None.

Extensions added (0):

None.

Extensions removed (0):

None.

Part H: Upgrading a Consumer

  1. Install LiteSpec.Cli 5.1.0 (dotnet tool update LiteSpec.Cli --version 5.1.0) or rerun the install script, and set reviewedLiteSpecVersion: 5.1.0 in .litespec/project.yaml.
  2. A project with a shared UI package adds a ## Browser Support section to its design contract, naming the browser target, as templates/consumer/design-contract.md shows. Without it, model check reports ui-design-contract-invalid with missing required section 'Browser Support'.
  3. A project that references `L...
Read more

LiteSpec 5.0.0

Choose a tag to compare

@github-actions github-actions released this 10 Nov 09:59
16bd125

LiteSpec 5.0.0 lets a project claim only the record layers it uses, writes every file a person edits in YAML, replaces exceptions with departures, and ships the litespec command line as a native executable for Windows, Linux and macOS. It is a major release: a consumer upgrades by following the steps in Part H, then running litespec model check until it is clean.

Part A: Claim the Record Layers the Project Uses

  • layers in the project file replaces the conformance level. A project names each record layer it claims, intent, behavior, implementation and proof, leaving layers out only from the bottom; implementation and proof each take litespec, LiteSpec's practice for the layer, or own, which keeps the team's practice and checks only that code and tests mark their records.
  • Every provision and every finding code carries the record layer it governs and whether it ties that layer to the records (trace). model check, rules, the book and the analyzers report only what the claim covers, and the book shows an unclaimed layer as not claimed.
  • A page's Scope block names its Concern; a provision's Applies to line may name its layer and trace.
  • The operations alert and runbook checks belong to the delivery extension.
  • The analyzers read the claim: the traceability rules run when Implementation is claimed, the architecture rules when it follows litespec, and LS4001 when Proof is claimed.

Part B: People Write YAML, Programs Exchange JSON

  • .litespec/project.yaml, litespec.manifest.yaml, the schemas (schemas/<name>.schema.yaml), the pattern catalog (.litespec/implementation/patterns/catalog.yaml), the UI source lock (ui-source-lock.yaml) and the presets are YAML that states its schemaVersion and names its schema in a first-line # yaml-language-server: $schema=<url> comment. Check results, --format json output, the book data and the provision index stay JSON.
  • The project file holds frontends and ui.package at the top level, stackConfig.dotnet.webapi and worker as lists, and no conformance, $schema, unstructuredDocs, paths.records, surfaces, sites, apiSolution or refusals.prefixes.
  • The schemas publish at https://litespec.dev/5.0.0/schemas/<name>.schema.yaml, including the new check-result.schema.yaml; a harness result that fails it reports proof-invalid.
  • litespec model render writes the UI source lock: each component's digest, the preset and the CLI pin.

Part C: One Departure Record

  • The departure record replaces the exception record. It covers provisions, pages or finding codes on its subject or paths, with a reason; a gap the team means to close carries expiresOn and exit, and a lasting choice carries neither. It lives in .litespec/governance/departures/.
  • departure-expired and departure-invalid replace the exception codes. No departure covers the findings the model needs to load.

Part D: One Name per Concept

  • A finding's outcome is blocking, reported or covered; severity leaves the JSON, and model check ends with N findings, M blocking, K covered.
  • Completion stages read unfulfilled, specified, coded and verified.
  • The qualified identifier is gone; a record shows its folder path and its module.
  • Provision strengths read required, default and advisory.

Part E: A Smaller, Bound Standard

  • Near-duplicate provisions keep one home, and every citation follows it. Departures, testing and formats each have one page; how-to guides live under docs/guide/.
  • Each UI pattern offers its Default and at most two other options.
  • The jobs extension is cut to what a small team follows; realtime and customer-rules are extensions; tenant delegation is part of tenancy; sagas and workflow engines leave the standard.
  • litespec-maintain validate reports a cited finding code, template or example record that does not exist, a Checked by line for the model check that names no code, a page the index does not reach, and a pattern with more than three options. The finding-code, folder and pin tables are generated.
  • quality/testing.md holds one mock rule for every stack: a test substitutes only what the code under test does not own and what is not deterministic.
  • An agent never weakens a test that proves a scenario, and model check --since reports proof-hash-drift for a proving test that changed while its scenario did not.

Part F: A Native Command Line on Every Platform

  • The CLI compiles ahead of time with .NET Native AOT for win-x64, win-arm64, linux-x64, linux-arm64, linux-musl-x64, linux-musl-arm64, osx-x64 and osx-arm64, and needs no .NET runtime.
  • LiteSpec.Cli on NuGet is a per-platform tool package, so dotnet tool install, dotnet tool restore and dotnet litespec work unchanged; every GitHub release carries a standalone archive per platform, SHA256SUMS, install.sh and install.ps1, each with a build provenance attestation.
  • litespec init --install standalone writes a project that runs the CLI as litespec; in a consumer root, the install scripts install the release that .litespec/project.yaml reviews.
  • The Linux glibc binaries run on glibc 2.28 and later and the musl binaries on Alpine 3.21 and later; the CLI computes SHA-256 itself.
  • The CLI and the maintainer tool check every schema with LiteSpec's own JSON Schema evaluator, draft 2020-12 without dynamic references, anchors, unevaluatedProperties, unevaluatedItems and contentSchema.
  • Every archive and package ships THIRD-PARTY-NOTICES.md.

Part G: Provision Changes Since v4.0.0

Provision Changes Since v4.0.0

Added (162):

  • litespec/backend/domain#raise-the-past-tense-of-a-methods-own-verb
  • litespec/backend/dotnet/domain#keep-clock-reads-and-random-values-out-of-domain
  • litespec/backend/dotnet/domain#keep-double-and-float-out-of-exact-quantities
  • litespec/backend/dotnet/domain#mark-each-changing-root-method-with-one-use-case
  • litespec/backend/dotnet/naming#check-architectural-role-suffixes
  • litespec/backend/dotnet/naming#check-repository-variable-names
  • litespec/backend/dotnet/naming#check-result-part-names
  • litespec/backend/dotnet/persistence#keep-pipeline-owned-collaborators-out-of-handlers
  • litespec/backend/dotnet/stack#identify-an-aggregate-root-by-its-mark-and-state-record
  • litespec/backend/dotnet/stack#pin-the-test-packages-in-the-manifest
  • litespec/backend/dotnet/stack#run-mutation-testing-with-stryker-net
  • litespec/backend/dotnet/stack#start-the-integration-database-in-a-container
  • litespec/backend/dotnet/stack#test-with-xunit-v3-on-microsoft-testing-platform
  • litespec/backend/persistence#test-persistence-against-the-pinned-database
  • litespec/core/agent#protect-proofs-from-implementation-edits
  • litespec/core/departures#depart-from-advice-without-a-record
  • litespec/core/departures#record-a-project-wide-lowering-as-a-departure
  • litespec/core/departures#record-accepted-gaps-as-departures
  • litespec/core/language#cite-shared-provisions-in-their-published-form
  • litespec/core/language#exclude-declared-content-paths-from-the-ascii-check
  • litespec/core/language#exclude-the-compound-that-names-another-concept
  • litespec/core/language#follow-the-identifier-form-of-each-record-type
  • litespec/core/language#keep-wire-codes-stable
  • litespec/core/language#name-records-with-one-to-six-words
  • litespec/core/language#record-the-project-vocabulary-as-data
  • litespec/core/language#reject-a-recorded-synonym-inside-its-scope
  • litespec/core/language#resolve-every-identifier-citation
  • litespec/core/language#review-each-term-for-its-lookalikes
  • litespec/core/language#state-mannered-terms-literally
  • litespec/core/language#use-every-identifier-once
  • litespec/core/language#use-the-declared-record-identifier-grammar
  • litespec/core/model#classify-every-specification-file
  • litespec/core/model#declare-structured-specification-metadata
  • litespec/core/model#derive-a-computed-fact-instead-of-restating-it
  • litespec/core/model#keep-code-out-of-intent-and-behavior-fields
  • litespec/core/model#rewrite-every-link-on-a-rename
  • litespec/core/model#scaffold-pages-and-reserve-identifiers
  • litespec/core/model#start-each-explanation-file-with-its-title
  • litespec/core/model#state-what-happens-in-every-behavior-statement
  • litespec/core/model#use-one-metadata-carrier
  • litespec/core/model#validate-a-single-page-before-committing
  • litespec/core/release#record-accepted-debt-as-a-departure
  • litespec/core/scope#claim-the-record-layers-the-project-uses
  • litespec/core/scope#write-every-hand-written-litespec-file-in-yaml
  • litespec/core/scopes#depart-from-a-rule-only-through-a-recorded-departure
  • litespec/core/scopes#give-every-provision-its-layer-and-trace
  • litespec/ext/customer-rules#bound-tenant-rule-runs-per-period
  • litespec/ext/customer-rules#isolate-hook-failures-from-the-trigger
  • litespec/ext/customer-rules#record-the-customer-rules-catalog
  • litespec/ext/customer-rules#refuse-unknown-catalog-entries
  • litespec/ext/customer-rules#state-what-a-hook-may-not-assume
  • litespec/ext/customer-rules#state-what-a-hook-may-rely-on
  • litespec/ext/customer-rules#treat-tenant-rules-as-data
  • litespec/ext/customer-rules#version-catalog-entries
  • litespec/ext/delivery#ask-only-unanswered-questions
  • litespec/ext/delivery#close-incident-departures-within-seven-days
  • litespec/ext/delivery#cover-every-quality-requirement-with-an-alert-or-a-check
  • litespec/ext/delivery#hold-back-example-rows-from-the-implementing-worker
  • litespec/ext/delivery#name-every-runbook-from-an-alert-job-reaction-or-failure-policy
  • litespec/ext/delivery#name-the-requirement-and-runbook-on-every-alert
  • litespec/ext/delivery#point-each-operations-file-at-its-decision
  • litespec/ext/delivery#restrict-a-worker-to-its-paths
    ...
Read more

LiteSpec 4.0.0

Choose a tag to compare

@github-actions github-actions released this 09 Nov 01:09

LiteSpec 4.0.0 is a standard for specification-driven development of one bounded-context business application by people and coding agents. It defines a strict specification model of linked records beside graded engineering provisions, with git as the decision record. A consumer pins this release in reviewedLiteSpecVersion. The release takes effect as the v4.0.0 tag.

Part A: The Nature of LiteSpec

  • The specification model is strict: a record follows its schema, links resolve, and code and tests mark the records they serve; a violation is a defect.
  • Each provision states its strength, rule, default or advice, and where it applies; a check exists where one is cheap and sure.
  • Git is the decision record: a record in the repository is decided, and the pull request that changes it is its review.
  • The specification is closed: an agent builds what the specification states and takes anything missing to the owner or the backlog board.
  • Every record is about the software: what the application does, holds, refuses at runtime or runs on.

Part B: Git Is the Decision Record

  • Records carry no history of their own; git carries who changed what and when.
  • Completion is computed from code, tests and passing scenarios, and the book shows it first.
  • An exception carries reason, exit and expiry; an expired exception is a blocking finding.
  • A date about the outside world sits with its source as readOn.

Part C: Eight Commands

  • The CLI has eight commands: init, new, rename, model check, model format, model query, book and rules.
  • model check is the one command CI runs: schema, folders, names, links, locality, reachability, marks and exceptions.
  • model render has three regions: alert-inventory, runbook-index and operations-log.
  • An additional command, finding code, analyzer rule or generated file needs an owner decision that records it.

Part D: Provisions by Situation

  • Each page declares its stack and layer; a provision adds Applies to only when narrower than its page.
  • Every provision states Strength: rule, default or advice.
  • The provision index carries scope and strength; the site groups Standard, Reference, Learn and LiteSpec's own records.

Part E: Rules for the File at Hand

  • litespec rules <path or record id> lists the applying provisions grouped by strength, with why each was retrieved; --full adds rationale and example.
  • Project conventions and departures merge into the result; a departure shows in place of the provision it replaces.
  • A retrieval evaluation with a precision target proves the command.

Part F: The Consumer Uses the Same Structure

  • Layer and artifact derive from the stack structure and the records a file marks.
  • Project conventions live in .litespec/governance/conventions/ in provision shape.
  • A departure names the provision it replaces and a scope.
  • Records use the same layer and artifact terms, so one query answers file, records and provisions together.

Part G: Surfaces That State the Nature

  • The README, AGENTS.md, the core pages, the command pages, the templates and this changelog state the nature above.
  • The docs index groups pages with generated counts; the site navigation follows the same groups.

Part H: Consumers Adopt the Whole Contract

  • A consumer pins one release and adopts a later release by accepting its whole contract.
  • A consumer declares the conformance level it claims in .litespec/project.json: records, traced or full. The levels nest, and model check, the book, rules and the analyzers report only the part of the contract the level claims.
  • At records a project keeps its own code layout and needs no stack; at traced its code and tests mark their records and its test runs prove scenarios, in its own layout; at full it takes the selected stacks, the code layout, the analyzers and the operations provisions.
  • Provision identifiers stay stable within a major version; the changelog of each release lists the provision changes since the previous tag, generated by litespec-maintain changelog.

Part I: Every Record Is About the Software

  • Intent reads module, then feature, then requirement; Behavior reads module, then aggregate, then use case.
  • Features sit under intent/modules/<module>/features/ with their requirements as entries; a requirement identifier has the form requirement/<feature>.<name>.
  • A folder under intent/modules/ that names no declared module is a blocking finding.
  • Reachability blocks: a goal reaches a journey or a quality requirement, a problem reaches a feature or requirement, a feature or requirement reaches Behavior, a constraint is answered, research is cited, and a decision decides a record that reaches Behavior.
  • Identifiers are short and unique in the product; the qualified identifier is computed from identifier segments plus placement, never written.

Part J: One Placement Model for Every Layer

  • Every record has one parent; the container is the parent; product, module, aggregate and entry point are the only folder nodes.
  • Behavior, Implementation and Governance place each type per the placement table in the model page; Proof holds no authored records.
  • Code and tests match the qualified identifier of the record they mark in folder and namespace, including frontend module folders.
  • Module dependsOn holds no cycle; an integration event has one publishing module.

Part K: Fields That State the Product

  • Every record carries type, id, title, terms and records plus its type fields; every record carries one summary, and a record that makes a testable claim carries one statement.
  • The project file carries project, size, shape, stacks, stackConfig, paths, marks, proof, dependencies, screenshots, refusals, selectedExtensions and reviewedLiteSpecVersion.
  • risk sits on permission only; setBy uses product, operator or tenant; a rule names where retained facts live in retainedIn; a use case states its field read and write lifecycle.

Part L: Complete Work Before Merging

  • A branch may be incomplete; what merges is complete. model check reports reachability locally and blocks in the pull-request check; an exception with expiresOn parks one record.
  • The folder wins: an identifier whose home segment disagrees with its folder is a blocking finding; each name segment is unique in the product.
  • Tiers: G reads records and always blocks, S reads code and blocks where qualified, A reports and never blocks.
  • An exception is live when present and unexpired.

Part M: The Module Layout as the Default Architecture

  • Layers are roles: Domain, Application, Infrastructure and WebApi with the reference table the architecture page states.
  • One application project holds every module; hosts hold composition and HTTP plumbing.
  • The folder tree uses closed folder sets per level; use case folders are flat; cross-module access runs only through Contracts/ along dependsOn.
  • The layer-projects extension holds the five-project layout for consumers that select it.

Part N: Gaps Closed in the Standard

  • A deviation is an exception of kind departure whose covers names the provision it replaces.
  • Product patterns live in implementation/patterns/; product copy rules live in implementation/writing/; document pages may sit at a layer root.
  • Module rules live in behavior/modules/<module>/rules/; adapter tests sit under the adapter's Infrastructure/ path.
  • Guidance precedence lives in one provision on the agent page.

Part O: Checks a Partial Adopter Can Read

  • Findings about Intent that no Behavior reaches yet report locally and block in the pull-request check, so Intent can run ahead of Behavior.
  • The .NET reader reads several web and worker hosts, reports a default project root that matches nothing as reader-missing, and at traced finds an aggregate root by its mark and its state record.
  • A JUnit test case proves a Behavior scenario through a litespec.proves property, so a runner whose steps carry no mark, or a stack with no code reader, still proves its scenarios.
  • model check lists level A findings as a summary by code unless --all is given, and its JSON output maps G, S and A to error, warning and note.
  • init writes a project file the schema accepts for every preset, including the records preset, and no size requires an exception record.

Part P: Analyzers as Proof and a Smaller Rules Output

  • A structural boundary needs an architecture test only where no analyzer or model check finding covers it; analyzer-lowering-unrecorded reports an analyzer rule lowered or switched off without an exception, so an analyzer can stand as the proof.
  • LS1013 reports a switch over a state or closed-set record hierarchy that leaves a sealed case to its discard arm; the tests, not the compiler, catch a new case.
  • LS2012 also reports a handler that takes the authorization guard.
  • litespec rules prints statements only for the provisions that need judgment, the checked provisions as one line with their codes, and the layer-wide provisions by identifier; every provision on a page that names kinds of file names its own.

Provision Changes Since v3.0.0

Added (238):

  • litespec/backend/architecture#organize-code-by-module-aggregate-and-use-case
  • litespec/backend/architecture#read-another-module-only-through-its-contracts
  • litespec/backend/architecture#restrict-commands-to-their-own-module-aggregates
  • litespec/backend/architecture#subscribe-across-modules-only-to-integration-events
  • litespec/backend/dotnet/api#place-endpoints-in-their-use-case-folders
  • litespec/backend/dotnet/application#use-the-use-case-folder-layout
  • litespec/backend/dotnet/architecture#follow-declared-module-dependencies
  • litespec/backend/dotnet/architecture#follow-layer-direction-in-every-file
  • `litespec/backend/dotnet/architecture#keep-application-types-i...
Read more

LiteSpec 3.0.0

Choose a tag to compare

@github-actions github-actions released this 01 Nov 01:20

LiteSpec 3.0.0 is a top-down specification standard for one bounded-context business application, written by agents and judged by machines, so people review only what is theirs to decide. A consumer installs this release as the LiteSpec.Cli local .NET tool at the release version and records it in reviewedLiteSpecVersion. The release takes effect as the v3.0.0 tag.

Layers

  • Four layers: Intent (why and what we promise; product people review it), Behavior (how the system behaves; developers review it), Implementation (code) and Proof (tests, checks, computed statuses and the book).
  • Each layer is written from the one above. Nothing above Implementation is computed from code; code and tests point up. Facts from the world enter Intent as research or constraints, and what a lower layer needs travels up as a question with a decider.
  • The translation rules Specify, Implement and Verify state what each boundary receives, must add, may not decide, and checks.
  • Consumer docs sit in one folder per layer: docs/intent, docs/behavior, docs/implementation, docs/proof and docs/governance.

Records

  • Each record page is a YAML record file holding one mapping with its entries in records; an optional explanation file beside it holds Markdown under H2 sections.
  • A module page is module.yaml in its module folder and an aggregate page is aggregate.yaml in its aggregate folder; the glossary is docs/glossary.yaml.
  • Anything a check reads or a reviewer approves is a record field; the explanation file only helps a reader understand. Product, constraint, rule set, actor, role and external system hold summary; goal holds whyItMatters; problem holds situation; feature holds offering; decision holds consequences; topic holds summary, position and refusals; journey holds betweenSteps.
  • Use cases hold purpose, whatHappens and exposure; reactions, jobs, notifications and setting sets hold purpose and whatHappens; screens hold summary; integration events hold summary and delivery; runbooks hold impact, prerequisites, procedure, verification, recovery and escalation; exceptions hold exit and consequences; research sources carry a key.
  • Prose cites a record by its identifier, such as [the refund rule](rule/refund.within-window); research cites a source as [text][key].
  • A Markdown page that holds no record is a document with an optional frontmatter block holding only its page style and common fields.
  • Journeys are product sentences with step ids, finishedWhen and a per-step failure; use cases point up with serves.
  • Requirements state exceptions with except and a fallback, and carry risk and setBy.
  • Use cases are commands or queries with access (grant and tenant; auth sits on the entry point), changes, reads, consistency, effects (runs, sends, emits, calls), idempotency, audit, typed query output in include groups, freshness and paging. Generic refusals are derived.
  • Record types include reaction, job, notification, setting and integration event. Aggregates have entity, saga and store kinds, and data classes with erasure positions. A retention schedule page holds retention rows.
  • Reactions and jobs declare edges in effects with the same verb grammar as use cases; a reaction may omit timing, which reads as async, and a top-level verb beside effects is refused.
  • An idempotency key templates {field} placeholders over the record's input fields, and scope is tenant, account, login or global; reaction and job placeholders name triggering event or run window fields and are not checked.
  • Reaction and job onFailure is a structured policy: mode is retry, skip-and-log or discard; a retry policy holds maxAttempts, initialDelay, maxDelay and backoff; then is dead-letter, with deadLetter, surfacesIn and runbook, with ISO 8601 durations.
  • Approval is data: approvedBy, approvedOn and a semantic approvedHash, written by litespec model approve.

Review and checks

  • Product people read journey chapters and ballots; developers review Behavior diffs; a named security reviewer sees tier 1 access and data changes. Tier 3 questions auto-approve after a veto window.
  • Every check has a level: G (record graph, blocking), S (stack reader, blocking where qualified) and A (advisory).
  • Every edge between use cases, reactions, jobs, notifications, integration events and external systems is declared and checked. A calls edge counts only through a port anchored to an external-system record.
  • A refusal proof confirms from the asserted code, a client code refusals.aliases translates, or the HTTP status refusals.statuses maps to the code.
  • An integration fact that drives a use case or rule confirms its scenario or rule claim from inside the host.
  • An effect-undeclared finding names a one-hop helper as via 'Type.Method'.
  • A term's labels sit outside the approval hash, so adding a language reopens no approval.
  • A project declares its use-case verb vocabulary in vocabulary: verbs, phrasal verbs counted as one, and retired synonyms with their replacement, checked by use-case-verb-unknown.
  • effect-timing-invalid (level S) reports a command whose sends or calls effect runs inline; consequences run from an event handler or a job after the commit.
  • event-tense-invalid accepts a past tense followed by a prepositional complement and a mark method naming its state, and term-clash skips a hyphenated pair opening with a function word.
  • state-unreached (level G) reports every state no transition enters. An aggregate writes its creation as a transition from - in its transitions field, so its first state is reached too.
  • The approval hash covers every written record field except the identity, workflow and approval fields the guide lists, and compares numbers by value, so 50.00 and 50 hash alike. For research, decision and topic pages it also covers the explanation file.
  • prose-missing reports a significant use case with no purpose field and a significant command with no whatHappens field.
  • explanation-orphaned, explanation-missing, format-drift, source-link-bare, source-key-unknown and source-unused (level A) report an orphaned explanation, a missing article explanation, a record outside canonical form, and a research source linked directly, cited by an unknown key, or never cited.
  • record-invalid reports a record file that does not parse, with the parser message and line.
  • reader-missing (level S) also reports a .NET file that cannot be read or parsed, a declared stack root that resolves to no folder, a server project with no backend reader, and a configured bill of materials that cannot be read, is not SPDX or CycloneDX, or yields no packages.
  • A test proves a scenario across machines: the proof ledger hashes each test file by its path relative to the project root and its text with normalized line endings.

Application Layer

  • A command handler loads or creates one aggregate, calls one domain method, stages it and returns; validation, authorization, idempotency, audit, the timestamp, holds, the commit and fault classification are pipeline stages, and a change to another aggregate is a consequence. A record declaring consistency: atomic is the one exception.
  • Each command implements one use case with one success path; a find-or-create flow is two use cases the owning boundary chooses between, and a lost race ends with the use case's conflict refusal at commit.
  • Uniqueness is enforced by the store: a unique index, an identity derived from the owner, aggregate state for a once-only rule, or a key the aggregate declares and persistence claims at commit. Each constraint maps by name to its conflict refusal, and no handler reserves or checks a key.
  • A refusal code built at run time from a key, such as the conflict for a lost uniqueness key, declares its template in the project file refusals.composed, and refusal-unimplemented reads the code as raised where its key is a literal in the code.
  • Every aggregate carries a version the store compares at commit.
  • A message whose target must be the caller carries no target or declares a self grant the guard enforces.
  • Audit targets and reasons the message carries are declared beside it; the handler adds only values it learns while running.
  • Messages, provider calls and changes to other aggregates run in event handlers after the commit; the outbox delivers each event to each handler separately.
  • Query handlers take no repository and never write. Work over many records is a job issuing one command per record, each in its own unit of work.
  • Result parts are named {UseCase}QueryResult{Part} or {UseCase}CommandResult{Part}, event handlers are {Action}On{Fact}Handler in an On{Fact} folder of the subscriber's aggregate, and repository variables are named after their interface.

Mobile

  • An android stack builds a native Android app with .NET for Android and plain Android views: no MAUI, no WebView screens. It sits at docs/frontend/mobile/android/ under shared mobile pages for structure, screens and navigation, data and state, device capabilities, and testing, so a later mobile stack reuses them.
  • The mobile solution lives at apps/mobile/ with platform-free core projects beside one app project per platform; a client-only app holds Domain, Application and Infrastructure, a server app holds the generated API client.
  • The android-client preset starts a client-only Android consumer, and the manifest pins the Android API level in stack.android.

Tools

  • litespec model diff has --intent and --behavior views with a security queue, and litespec book renders journey chapters and a ballots page.
  • litespec new scaffolds a record file with its explanation file for an article type, litespec rename rewrites an id in ...
Read more

LiteSpec 2.0.0

Choose a tag to compare

@github-actions github-actions released this 23 Oct 09:36

LiteSpec 2.0.0 is the standards contract for one bounded-context business application, built by people and agents. People and agents write intent records; the model builder reads the code, screens, tests, and test runs and computes the links between the two. A consumer installs this release as the LiteSpec.Cli local .NET tool at the release version, records it in reviewedLiteSpecVersion, and keeps it for as long as it serves. The release takes effect as the v2.0.0 tag.

Structure

  • The folder a page sits in decides who applies it. core/, workspace/ and quality/ apply to every project. Pages directly in backend/ and frontend/ are the principles every backend and every frontend follows.
  • A stack is a folder inside its area: backend/dotnet/, frontend/web/react/, frontend/web/svelte/ and frontend/blazor/. Selecting a stack applies its folder and every folder above it, so frontend/web/ holds the TypeScript web pages React and Svelte share.
  • A deeper page, an extension's replaces, or a project deviation record replaces a named provision of a shallower page.
  • An extension for every stack sits in ext/; an extension for one stack sits in that stack's ext/ folder, such as backend/dotnet/ext/efcore.md. Extensions ship for outbox, tenancy, plans, audit, caching, realtime, jobs, stage and delegation, among others.
  • A provision ID is its page and heading: litespec/<page>#<slug>, such as litespec/backend/dotnet/domain#model-every-closed-set-of-domain-values-without-enums. Headings carry no ID; the ID, the file and the published address follow one rule. docs/reference/provisions.md lists every provision with its verification mark.
  • Pages follow the page contract in docs/core/authoring.md: ASCII only, one term per concept, capitalized modals only inside a Statement, a Default or a Replacement, Title Case on every heading, an Overview title on every section index, and nothing about other releases. LiteSpec writes US English.
  • Every provision is marked checkable, naming the command that checks it and the finding it reports, or guidance, naming the observable evidence and where to look.

Selection

  • A project names a size, a shape, and its stacks in litespec.project.json. Size is small or large and decides the record types and test projects. Shape is server, with one backend stack, or client-only, with none, which applies the backend architecture, domain, application and identifier principles.
  • litespec init --preset dotnet-react|dotnet-svelte|blazor-client --size small|large writes a starting litespec.project.json. A preset adds no rule.
  • The LiteSpec.Cli package carries the whole release beside its binary: the manifest, schemas, docs, and templates, so a consumer needs no checkout of this repository. litespec init writes .config/dotnet-tools.json pinning the tool at the release and fills the ## LiteSpec block of AGENTS.md with the release, size, shape, stacks, and selection index of the new project.
  • A departure from a rule is a deviation record with its reason and review date. A finding the project accepts for now is a known gap record with an owner and an end date.

Records and the Model

  • docs/core/model.md defines the record types, each answering one question: product, goal, problem, feature, constraint, research, decision and requirement for why; journey for the steps toward one goal; module, aggregate, rule, event, use case, result and scenario for how the business works; actor, role, permission, entry point and external system for who acts and how they arrive; limit and runbook for operation; deviation, known gap and glossary term for how the project builds and speaks.
  • Every record carries an owner and a status of draft, approved or retired. A draft names its decider and decide-by date, an approved record is replaced rather than edited, and only a decision carries replaces.
  • Identifiers use the type/home.name form, chosen by a person and stable once approved.
  • An aggregate names its states, the transitions between them, and its classified data. A rule is an invariant, a precondition, a calculation or a cross-aggregate rule. A use case is a command, a query or a reaction, and carries its input and output. A result is a success or a refusal with a stable code. A scenario states its given, when and then, with an optional examples table.
  • A requirement is functional, quality or business, and names the feature that delivers it. A measured quality requirement carries its measure, target, conditions, check and evidence.
  • The builder computes implemented, verified and reachable over the records, and the effective status of each record. docs/core/product.md places business intent in a product brief and requirement pages, docs/core/domain.md states the domain records, and docs/core/access.md states who may act and how each use case is reached.
  • An owners entry maps a readable owner name to its CODEOWNERS handles, and litespec model check reports owner-unknown for a record whose owner, directly or through its mapped handles, belongs to no team owning its path.
  • The model builder reads a refusal code where code declares one: a Code member of an exception, failure, or refusal type, an exception constructor argument, or a value named code. Any literal counts as evidence that a recorded code is thrown, and a rule's bare refusal code declares a guard no caller reaches because an earlier check refuses first.
  • A rule that governs an aggregate and an erasure or export use case in another module covers that aggregate's personal data.
  • Events link by their natural name (AccessCodeIssuedEvent is event/access-code.issued) or by the record id the event class states. Reactions and jobs link through an <implements> tag or the use-case folder that holds them, an endpoint that holds its behavior implements its use case, and a creation row (- in From) reaches its state.

The Command Line

  • One .NET 10 command line, litespec, with validate, provisions, consumer, ui, model, book, init and patterns. The reporting commands take --root <path> and --format json, and every command writes UTF-8 with \n line ends on every platform.
  • litespec model build writes model.json with the computed implements, calls and proves links; check reports open findings and expired known gaps; render writes the generated page regions; query prints one record with its links both ways; diff reports the records a change adds, changes and removes for review. It reads C# through Roslyn, React and Svelte routes, and TRX or JUnit XML test results, each stack through its own reader.
  • litespec book generates the project book, a static site with one page per record, an index per type, a lens per actor, a review page, a glossary and search.
  • litespec consumer checks the project file, the selection of size, shape, stacks and extensions, every record page against schemas/record.schema.json, and the project vocabulary. litespec ui checks the controlled web UI contract.
  • litespec consumer validates a large consumer in seconds: it reads pages and source surfaces in parallel and reports findings in a fixed order.
  • litespec validate and litespec provisions check this repository's own pages, schemas, manifest and provision index.
  • litespec patterns draws the UI pattern wireframes for a person to choose from. preview writes one offline page with every option at desktop and phone width, svg prints one option, and check reports broken wireframes.

Analyzers

  • LiteSpec.Analyzers is a NuGet package of Roslyn analyzers that report a breach of a .NET provision as an error in the editor and the build, each diagnostic linking to its provision. Rules cover Domain (outer-layer references, closed value sets, state records, Domain exceptions, events and their placement, binary floating point, clock and random reads, repositories, documentation, and typed identifiers), the outer layers (implementation shape, handler and endpoint naming, reactions and jobs), naming and style, and one assertion rule for test projects.
  • A rule runs only in the layers its provision covers. The layer comes from the LiteSpecLayer MSBuild property or the assembly name suffix. The package runs on the .NET 9.0.300 SDK, Visual Studio 17.14, and later.
  • docs/backend/dotnet/packages.md adds the convention to reference the package from the five application projects, the manifest pins it, and the rules the analyzers check completely are marked checkable.

The Site

  • litespec.dev publishes every page of the release for people, with a navigation tree, provision cards, highlighted code, tabbed UI pattern options with a full-screen viewer, search, and light and dark themes.
  • Agents read /llms.txt, a raw Markdown copy of every page, one index per selection of shape and stacks, one bundle per layer, and the schemas. /latest redirects to the current release.
  • docs/learn/ holds explanation pages that teach what LiteSpec is, why it exists, and how its parts and tools fit together, among them the reading tracks and the lineage of borrowed practices.

UI Patterns

  • A pattern page in docs/frontend/patterns/ answers one group of recurring interface questions. Each pattern names its question, its default option, its compact behavior and its rationale. Each option carries a wireframe in a closed text language, its rationale and its cost.
  • The wireframe language, defined in docs/frontend/patterns.md, states structure and real copy, never style. An agent builds an option in its own stack and design system. A pattern ID is litespec/frontend/patterns/<group>#<pattern>.
  • Ten groups ship: page frames, lists and tables, record detail, forms and fields, dialogs and overlays, create, edit and remove, feedback and states, navigation, money, time and density, and admin screens. A project catalog cites a pattern...
Read more

v1.18.0

Choose a tag to compare

@litenova litenova released this 14 Oct 07:30

This release adds the dotnet-svelte profile, the UI pattern decision standard with its pattern library, and the site extension for a static public website. A consumer on v1.17.0 adopts it by reading the entries below and recording 1.18.0 in reviewedStandardsVersion.

  • Added docs/frontend/patterns.md with ten provisions under standards/rule/frontend-patterns.*. A workspace with a controlled frontend keeps one pattern catalog at paths.uiPatterns: each pattern records the options considered with rationale and cost, the chosen option, its source, the compact-screen behaviour, and the implementation per platform. Agents build from the chosen option and report improvement proposals after their work; the owner accepts, refuses, or defers.
  • Named each floorplan as the chosen option of one page-frame pattern in docs/frontend/ui.md, with a pattern-decision row in its evidence matrix. AGENTS.md gains a Pattern feedback section, and every frontend.* and blazor.* load plan loads the new page.
  • Added standards/rule/frontend-ui.hold-the-declared-base-colour and standards/rule/frontend-ui.keep-separators-at-the-subtle-step. A token stylesheet carries the values the declared base colour publishes and no value outside them except under a named local extension or override, and a structural separator or input border stays at the border step. The evidence is a project check comparing the :root and dark blocks to the published base colour; claimwick check tokens is one such check.
  • Added standards/rule/frontend-ui.derive-each-page-type-from-a-named-reference and standards/rule/frontend-ui.publish-one-registry-item-per-floorplan. Every route tags the registry item its page type was built from, and the shared package publishes a registry listing one item per floorplan the design contract declares.
  • Routed the source-lock registry gate through the same override decision as the components.json gate. An additional registry passes both gates under an override against standards/rule/frontend-ui.pin-the-baseline-in-the-shared-package, and both gates refuse with that provision identifier without it. uiBaseline.registry.allowAdditional is true, and the source-lock schema accepts a registry outside the built-in one.
  • Extended standards/rule/frontend-ui.keep-tokens-in-one-stylesheet to the stylesheets the shared package ships beside the token sheet: such a sheet declares no literal colour. tools/validate-ui.mjs reports oklch(, rgb(, hsl(, and # hex values there.
  • Documented shadcn's agent skill and MCP server in docs/workspace/dependencies.md, with the source pages and the date read.
  • Replaced the stale baseline-provision identifier the validators emitted with frontend-ui.pin-the-baseline-in-the-shared-package, the identifier the UI page defines.
  • Added the UI pattern library at patterns/ui: every recurring screen, element, and scenario of a business application, each with several drawn options, a recommended option, and a compact-screen behaviour, drawn with the neutral Acme Supply cast. patterns/ui/library.json is the library as data, generated by node patterns/ui/library.mjs --write and checked by --check against schemas/ui-pattern-library.schema.json.
  • Added the library viewer and tools: node patterns/ui/build.mjs renders patterns/ui/dist/ui-patterns.html with light and dark themes, viewports from 390 CSS pixels to full screen, comparison, and slideshow; node patterns/ui/serve.mjs serves it and writes the reviewer choices file; audit.mjs and shoot.mjs measure and photograph mocks with Playwright from the consumer workspace.
  • Added the library field to schemas/ui-pattern-catalog.schema.json: a catalog entry cites one library pattern id, keeps the library option ids, and may add options of its own.
  • Added standards/rule/frontend-patterns.start-from-the-pattern-library and standards/rule/frontend-patterns.promote-library-improvements. A catalog starts from the library patterns and their recommended options, recording a different choice with its reason; an accepted proposal that is not specific to one product goes back to the library as a new or refined option.
  • Added the dotnet-svelte profile (docs/profile/svelte.md) with six frontend pages under docs/svelte/: structure, rendering, components, UI governance, data, and testing. A Svelte frontend keeps its addresses under src/routes and its frame and use-case code under src/lib/app and src/lib/modules, mirroring the backend's Application folders in kebab case. Rendering modes follow the audience: a console ships as a static SvelteKit application, a public surface renders on the server, and a device client ships as one static page.
  • Pinned the Svelte toolchain in standards.manifest.json: Svelte, SvelteKit with the static and node adapters, the Vite plugin, Bits UI, the shadcn-svelte CLI, TanStack Svelte Query, Form, and Table, svelte-i18n, MSW, svelte-check, eslint-plugin-svelte, lucide-svelte, and testing-library/svelte. uiBaselineSvelte holds the shadcn-svelte baseline in the same shape as the React one, and overridePolicy reviews svelte-ui overrides beside frontend-ui ones.
  • Taught the validators the svelte platform. tools/validate-ui.mjs reads .svelte sources, .visual.svelte drawings, class: directives, and style attributes and directives; refuses direct bits-ui, @melt-ui/svelte, and @tanstack/svelte-table imports from Svelte applications; selects the baseline from the source lock generator; and cites svelte-ui and svelte-components provisions. tools/validate-consumer.mjs accepts the platform and reads .svelte test titles, and tools/validate-parity.mjs accepts .svelte mapping files.
  • Added templates/consumer/standards.project.svelte.json, the project wiring for a dotnet-svelte consumer, with the profile, one Svelte frontend, and the shared package block. Linked the profile and its pages from AGENTS.md, README.md, and docs/README.md.
  • Fixed the consumer fixture: the Consumers-section replacement now tolerates CRLF templates, so the four error cases mutate the page they mean to mutate on a Windows checkout.
  • Added the site extension (docs/ext/site.md) with provisions under standards/rule/ext-site.*. A consumer shipping a public static website beside its application selects site, declares each site in paths.sites with its name, path, and generator, and prerenders every page to static files with no third-party loads, full search and language-model discovery files, JSON-LD structured data, single-sourced facts, visible placeholders that fail a release build, and prices read from consumer records. The conventions default to Astro with static output, server-rendered Astro or Svelte components, Tailwind styles, and a light scheme with a reader-chosen dark scheme.
  • Pinned the site generator stack in standards.manifest.json: astro 7.3.8 and @astrojs/svelte 9.0.1.
  • Extended schemas/standards-project.schema.json with optional paths.sites, taught tools/validate-consumer.mjs to require a declared site path holding its generator config when site is selected, and added passing and failing cases.