| title | Product specifications |
|---|---|
| description | Find the product contract that owns a capability and keep its evidence aligned with implementation. |
Copilot treats an SDD as a shared, testable product contract. Before changing a
capability, find its owner in specs/CATALOG.md, read the primary SDD and any
companion, then inspect the registered workflows, entrypoints, code, tests, and
user documentation.
capability change
-> owning SDD
-> policy/use case/port/adapter/presentation
-> tests and workflow contracts
-> user/operator documentation
-> catalog verification date
Text equivalent: a product change begins at its owning SDD, crosses the named architecture boundaries, is verified by tests and workflow contracts, updates the user-facing documentation, and finishes by refreshing catalog evidence.
Open `specs/CATALOG.md` and select the capability ID whose scope owns the behavior. Read the full SDD, including fixed invariants, configuration, UI states, failure recovery, test budget, and traceability. Update code, tests, workflows, visible content, documentation, and the SDD together when applicable. Edit repository-relative paths and `lastVerified` in `specs/catalog.json`; never edit the generated table by hand. Run the commands below and include any required human UX evidence in the PR.corepack pnpm run generate:specifications
corepack pnpm run validate:specifications
corepack pnpm run validate:documentation
corepack pnpm run validate:workflowsThe specification validator rejects missing or escaped paths, duplicate
capability/spec ownership, invalid status/date metadata, unregistered top-level
SDDs, and a stale generated CATALOG.md.
The package tasks above are declared by this Copilot source repository. A consumer must verify its own selected-source commands and execution directory; copying this standard does not install those script names. Generated catalogs therefore describe regeneration and validation outcomes without prescribing a project package manager. When no concrete invocation is verified, keep that prerequisite explicit. Declarations, structural validation and product execution are separate evidence. See grounded draft guidance.
Discovery also rejects every symbolic link encountered under specs/, including
unregistered file links and directory links. It never follows their targets.
Replace a reported link with ordinary repository files, register any resulting
SDD, regenerate the catalog and retry. A blocked command leaves the existing
catalog and link targets unchanged. Ordinary root README.md, _template.md
and CATALOG.md, and ordinary non-Markdown files, retain their exclusions;
those names do not exempt a symbolic link. The standalone SDK applies the same
rule to generation and validation. Its exported discovery helper reports an
unsupported tree explicitly instead of returning a partial file list.
Catalog evidence uses the consumer repository's own roots and language
conventions. Source, entrypoints, tests and documentation can be any regular
contained files; specs/ and workflow publication boundaries stay fixed. Run
copilot doctor before enabling the gate and verify compiler/framework tooling
separately. See layout support and migration.
Nested SDD directories are preserved in the generated catalog. For example,
specs/group/example.md links to ./group/example.md from specs/CATALOG.md,
in both the primary-SDD table and the evidence map. Companion SDDs keep their
directories too, so equal filenames in separate groups point to separate files.
Root-level SDD links and ../ links to other repository evidence keep their
existing format. Regenerate the catalog after upgrading to repair older flattened
links; the source files and registered paths do not need to move.
Accepted filenames containing parentheses, spaces, Unicode, hashes, percent signs
or backticks also keep navigable links. For example, specs/group/foo).md becomes
./group/foo%29.md, and docs/literal%20.md becomes ../docs/literal%2520.md.
The catalog preserves literal path labels and encodes each destination segment;
do not pre-encode paths in catalog.json. Regenerate the catalog with the normal
commands below after updating the shared SDK validator. The same renderer serves
primary SDDs, companion SDDs and every evidence role.
Technical terminology may retain designators such as DEL/C1 and connector
C1. Use fully qualified IDs when referring to acceptance cases in case-role
fields, explicit references and case-ID lists. Ordinary technical operands are
not counted as cases; identity, budget, reciprocal mapping and immutable owner
checks still apply. See the SDD consistency guide.
Capability titles appear as literal text in the catalog's specification link
labels and evidence headings. Markdown such as [draft](https://example.invalid),
backticks, emphasis, pipes, HTML and entity-looking strings stays visible as title
text. Carriage-return and newline runs become a display space. Ordinary and
multilingual titles keep their text under the renderer's normal whitespace rules.
Author the title in specs/catalog.json without pre-escaping it. Generation keeps
that source JSON unchanged and uses character references where needed in the
generated Markdown. Capability IDs, companion counts, evidence paths, ownership
and readiness rules retain their meaning.
After updating the matching SDK, regenerate and validate with the normal catalog commands to repair an existing index. Existing path, symlink, output-publication and size safeguards continue to apply.
For a new product, register existing Draft specifications and user documentation
under SDK version-1 proposed capabilities. Keep entrypoints, code and
tests explicitly empty until real implementation evidence exists. The
initialization lifecycle
uses the existing documentation workflow and then the normal feature gate.
Generated entries say Not yet implemented (proposed capability).; validation
preserves Draft/readiness blockers and does not certify application tests.
In this Copilot source repository, use the package tasks shown above. A repository adopting the source-vendored SDK copies these three matching files from the same reviewed SDK version, retaining their original layout:
src/infrastructure/specification_catalog_validator.cjssrc/infrastructure/specification_catalog_publication.cjssrc/domain/specification_catalog_path_policy.cjs
Its existing standalone entrypoint works with Node and no application package:
node src/infrastructure/specification_catalog_validator.cjs --write
node src/infrastructure/specification_catalog_validator.cjsRun them from that repository after creating the catalog and its referenced
documents. These commands check catalog metadata, registered files and the
generated index. SDD content/consistency and application execution remain
separate checks in the ordinary workflow. Generation creates or safely replaces
specs/CATALOG.md; validation
returns nonzero for stale output, missing arrays, unsafe or nonexistent supplied
files, or missing required evidence. Follow the reported field/output recovery,
regenerate and retry. Keep all source-vendored dependencies at the same reviewed
revision. Upgrade an older installed Action/SDK through its normal reviewed route;
changing its validator, declaring fake evidence or disabling a gate cannot
establish readiness.
For a stale index, this standalone entrypoint reports its existing --write
option. Run the generation invocation shown above, then the read-only validation
invocation. Recovery does not require adding package.json or an absent
validate:specifications or generate:specifications project script.
When implementation exists, record its actual entrypoints, source and meaningful
tests and review the implementation before changing to implemented. Mixed
proposed/implemented catalogs are supported; implemented, as-built and deprecated
entries retain their full evidence requirements. Existing dates and extension
metadata remain unchanged by generation. Native catalogs still need a compatible
reviewed publication adapter.
Generation accepts a missing specs/CATALOG.md or a regular file under real
repository directories. It rejects existing or dangling output links and
nonregular collisions. The writer pins its directories during synchronous I/O,
prepares a private exclusive temporary file, then publishes the complete catalog
atomically. It cannot follow a replaced parent or final link to overwrite its
target, and a competing new file is preserved. Regenerating a regular file also
preserves the bytes of any other hard-link alias. Read-only validation verifies
its opened index before consuming data.
Unsafe access returns nonzero with an actionable diagnostic and no generation success receipt. Inspect links, directory/file collisions, concurrent changes, free space and permissions before retrying the normal generation command. Review and preserve any intentional link target before replacing that link with a regular repository output. Pre-publication failures preserve the old index; another writer or relocation after atomic publication requires inspection and fresh regeneration. Cleanup never removes another writer's temporary replacement. If the first stat of a newly created temporary file fails, cleanup retries that identity read once. A verified match can be removed safely; generation still fails. Unavailable identity or failed cleanup produces a diagnostic naming the generated UUID entry. Inspect it in the original specs directory and verify ownership before manual cleanup; the generator preserves unverifiable or foreign entries. Directory restoration uses the caller's original identity; a replaced or unavailable caller path fails without claiming success.
Updated CLI/Action bundles include this behavior. A source-vendored portable
validator must copy the matching specification_catalog_validator.cjs,
specification_catalog_publication.cjs and specification_catalog_path_policy.cjs
in their original infrastructure/domain layout; the isolated-copy regression
verifies that complete dependency set. This is destination safety, not a change
to catalog evidence or implementation-readiness requirements.
Repositories can opt into pre-branch-sdd: true for feature and
contract-change issues. Before adding in-progress, ensure the repository
has this catalog, the specification standard, and the template. The Action
finds the owning capability, asks blocking questions in issue comments, and
validates the draft against the same catalog rules in a detached worktree.
It publishes the SDD as the first commit on the exact issue-linked branch and
adds branched only after remote verification. Subsequent material changes
revise the same SDD on the retained branch. See
Pre-branch SDDs for the contributor flow.
Several capabilities existed before their SDD. Their status is As-built baseline, which means the behavior was reconstructed from current repository evidence. It does not mean all behavior is ideal.
Every retrospective SDD separates:
- observed behavior;
- the intentional contract maintainers choose to preserve;
- known debt and limitations;
- historic rationale that remains unknown; and
- proposed improvements that are not yet implemented.
Do not rewrite a limitation as an implemented guarantee. Create a proposal or update the SDD status before changing architecture or public behavior.
For a catalogued change, reviewers should be able to answer yes to all of these:
- Does the owning SDD describe the visible normal, pending, action-required, failed/blocked, partial, and complete states?
- Are configuration defaults, bounds, precedence, migration, and fixed safety rules explicit?
- Do pure policy, application use cases, semantic ports, adapters, composition, and presentation keep the documented dependency direction?
- Does the numeric risk-derived test budget still cover retries, replay, races, provider errors, security, UX, and migration?
- Do issue, PR, comment, check, Job Summary, CLI, and documentation surfaces say what happened, what is retained, and what to do next?
- Are the catalog date and paths current, and do all validation commands pass?
Human evidence remains necessary where automation cannot judge GitHub or terminal readability: desktop/mobile, light/dark, screen-reader order, narrow terminal widths, and real provider/setup/merge-queue behavior.
A generated candidate that fails its single bounded repair remains unpublished. The pre-branch gate owns its reusable issue status card and exposes only closed check IDs and bounded section/row/count facts. The validator's raw text, IDs, paths and candidate are not public evidence. Diagnostics do not establish readiness or implementation acceptance. See blocked preparation recovery for limits, locale fallback, retention and retry behavior. Contributors should add deterministic rejection/retry/privacy cases when extending these checks.
The automatic SDD writer recognizes the SDK version-1 publication profile before model analysis. A repository-owned primary-SDD schema can be valid and still require a reviewed compatible adapter; the Action preserves that schema and its readiness instead of synthesizing SDK fields. See publication profiles.
Regression fixtures for this boundary include the actual pinned catalog and
schema from vypdev/symphonia, with source revision, blob and SHA-256 provenance
in src/testing/fixtures/sdd-native-catalog. They exercise explicit unsupported
recovery and zero premature model/branch work. Separate real SDK scratch writes
prove decoded metadata preservation. Native structural fixture validation,
complete consumer readiness and live workflow acceptance are separate claims.
Production validation continues to use the bundled policy.