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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Version
- **Hosted CI collapses to one gate on `main`, no longer duplicated on pull requests** ([#236](https://github.com/L3DigitalNet/project-standards/issues/236)). `Check` and `Validate standards graph` now trigger on `push: branches: [main]` and `workflow_dispatch` only — neither runs on `pull_request` or on `testing` any more. `Coherence` is deleted outright: `tests/coherence` carries neither the `performance` nor the `compatibility` marker, so it was already selected by `Check`'s ordinary pytest step and the standalone workflow was pure duplication. The seven cheap workflows (format, lint-markdown, validate-markdown-frontmatter, validate-specs, validate-standards, go, and any other under two minutes) keep their `pull_request` triggers unchanged.
- **`scripts/verify.sh` stops a battery at the first red lane and sizes the `--full` compatibility lane for the machine that runs it** ([#236](https://github.com/L3DigitalNet/project-standards/issues/236)). `--fail-fast` skips every remaining serial lane once one has come back red and is the default for `--full`, where roughly 35 minutes of compatibility matrix ran after the ordinary lane had already failed on the 2026-09-01 train; `--keep-going` restores the run-every-lane behaviour and stays the default for the fast gate, whose three lanes are already running when the first red appears. A lane cut short is reported in the lane table as `skipped (--fail-fast)`, never omitted. `VERIFY_FULL_COMPAT_WORKERS` now defaults to `16` instead of a literal tuned for the retired 21-core workstation. Repository tooling only: no package, payload, or consumer-visible byte changes.

- **`project-standards standards cut-successor <standard-id> <version>` performs the mechanical half of a payload cut.** Released payload bytes are immutable, so every fix and every feature reaches a published family as a new `versions/<version>/` directory copied from its predecessor — a procedure with four declaration sites that had to be moved by hand and in the right order. The command copies the predecessor tree, stamps the copied `payload.toml` with the new version and freshly computed per-file digests, computes the aggregate through the same `validate_payload_integrity` the repository validators use, indexes the payload in the family's `standard.toml`, adds the catalog entry immediately after the family's last one, and then reruns `sync-payload-projection` and `render-catalog`. The successor inherits the predecessor's catalog role and only a `default` predecessor is demoted to `retained`, so a reference-only or internal family does not acquire a default. Every line in the new tree that still names the predecessor is **reported, never rewritten** — a permalink or a migration `from` endpoint is correct history that a blanket substitution would corrupt — with one exception the payload contract leaves no choice about: a migration's `to` endpoint must name its containing version, and is re-pointed and reported as an applied edit. `--from` selects a predecessor other than the family's newest, `--dry-run` prints the plan and writes nothing, `--scaffold-test` writes the successor's contract-test module with the cut's mechanical assertions and a TODO block listing the predecessor test's behavior cases, and the command refuses outright when the successor directory already exists ([#227](https://github.com/L3DigitalNet/project-standards/issues/227)).

## [5.28.0] — 2026-09-01

### Added
Expand Down
26 changes: 24 additions & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ project-standards {--help | --version}

## DESCRIPTION

`project-standards` is the unified command-line surface for this repository's tooling. It exposes 34 leaf commands under one entry point: two frontmatter operations (`validate`, `fix`), 5 control/adoption operations (`init`, `reconcile`, `render`, `adopt`, `list`), the `mcp` server, eleven `standards` operations, one repository-only `packages` release check, seven `spec` verbs, and seven `agent-handoff` verbs.
`project-standards` is the unified command-line surface for this repository's tooling. It exposes 35 leaf commands under one entry point: two frontmatter operations (`validate`, `fix`), 5 control/adoption operations (`init`, `reconcile`, `render`, `adopt`, `list`), the `mcp` server, twelve `standards` operations, one repository-only `packages` release check, seven `spec` verbs, and seven `agent-handoff` verbs.

Under unified authority, `validate` and `fix` invoke the provider selected by the applied Markdown Frontmatter package. Read-only validation consumes one immutable file snapshot; `fix` applies only the provider's typed plan through the platform executor and then revalidates. After `project-standards fix`, run `project-standards reconcile --check`, review the digest-only plan, and run `project-standards reconcile --apply` before the final `project-standards validate`. The standalone schema, ID, reference, ID-fix, and format-write surfaces use the same selected payload while retaining their narrower output contracts. In v5 legacy-only repositories, these commands warn and retain the local validator sequence as a bounded compatibility path. The six standalone console-script names documented under [Standalone commands](#standalone-commands) remain installed for scripting and back-compatibility.

Expand Down Expand Up @@ -354,7 +354,7 @@ project-standards agent-handoff delta [--repo <dir>] --since <ref> [--json]
Command group for V5 catalog selection plus V1 graph/catalog maintenance and V2 package authoring. Running `project-standards standards` with no verb prints usage to standard error and exits 2; `project-standards standards --help` prints usage and exits 0.

```text
project-standards standards {list | show | enable | disable | version | validate-graph | render-catalog | validate-packages | render-consumer-catalog | generate-package-schemas | sync-payload-projection} [<args>...]
project-standards standards {list | show | enable | disable | version | validate-graph | render-catalog | cut-successor | validate-packages | render-consumer-catalog | generate-package-schemas | sync-payload-projection} [<args>...]
```

There are no group-level options other than `-h` / `--help`; each verb defines its own flags. An unrecognized verb exits 2.
Expand Down Expand Up @@ -441,6 +441,28 @@ Options:

Exit status: `0` catalog written or fresh · `1` graph findings or stale output · `2` invalid invocation, unsafe output path, or load/write error.

### `standards cut-successor`

Author `standards/<standard-id>/versions/<version>/` as a copy of its predecessor, stamp the copied `payload.toml` with the new version and freshly computed per-file digests, index the payload in the family's `standard.toml`, advertise it in the catalog major that already carries the family, and then rerun `sync-payload-projection` and `render-catalog`. Released payload bytes are immutable, so this is how every fix and every feature reaches a published family.

The successor inherits the predecessor's catalog role, and a `default` predecessor is demoted to `retained`. A reference-only or internal family therefore keeps its role rather than acquiring a default.

```text
project-standards standards cut-successor <standard-id> <version> [--root <path>] [--from <version>] [--scaffold-test] [--dry-run] [--json]
```

Options:

- **`--root <path>`** — Repository root. Default: the current directory.
- **`--from <version>`** — Predecessor to copy. Default: the family's highest indexed version.
- **`--scaffold-test`** — Write `tests/package_contract/test_<standard-id>_<version>.py` carrying the cut's mechanical assertions and a TODO block listing the predecessor test's behavior cases.
- **`--dry-run`** — Print the resolved plan and write nothing.
- **`--json`** — Emit the plan, the aggregate digest, and the review list as JSON.

Every line inside the new payload tree that still names the predecessor version is **reported, never rewritten**: a migration endpoint or a permalink into the predecessor's published documentation is correct history, and only the author can tell those from the references the cut must move. Family landing pages (`README.md`, `agent-summary.md`, `adopt.md` at the family root) are likewise left to the author. The command refuses to run when the successor directory already exists, so it can never overwrite work in progress or mutate released bytes.

Exit status: `0` cut written and generated artifacts refreshed · `1` the follow-on projection or catalog writer reported findings · `2` invalid invocation, an existing successor, or a payload/catalog load or write error.

### `standards validate-packages`

Validate every discovered V2 package family, immutable payload, catalog source, and cross-package graph without executing providers or writing files.
Expand Down
1 change: 1 addition & 0 deletions src/project_standards/cli_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"standards": frozenset({0, 1, 2}),
"standards validate-graph": frozenset({0, 1, 2}),
"standards render-catalog": frozenset({0, 1, 2}),
"standards cut-successor": frozenset({0, 1, 2}),
"standards validate-packages": frozenset({0, 1, 2}),
"standards render-consumer-catalog": frozenset({0, 1, 2}),
"standards generate-package-schemas": frozenset({0, 1, 2}),
Expand Down
Loading