Skip to content

Commit 1056c00

Browse files
committed
docs(cli): #18769's pending changeset declares the os validate --strict narrowing an at-tier review exhibited
`.changeset/18677-validate-per-package-authoring-pass.md` declined its `**BREAKING**` banner on the strength of a negative — "not declared breaking, because the narrowing could not be exhibited" — and the negative is false. The fixture that exhibits it did not exist when that entry was written: on the two-package `CONFIG_FLIP` config shipped in `packages/cli/test/lint-per-package-authoring-parity.test.ts`, `os validate --json --strict` reads exit 0 / 0 warnings with `validate.ts` restored to its pre-#18769 blob `bafa54b07f` and exit 1 / 1 warning at head. The entry is still pending and unreleased (`@objectstack/cli` 17.4.0 on npm equals the manifest version, and the CHANGELOG carries none of this text), so this is a forward edit to an unpublished file, not a rewrite of landed history. It adds the banner, the measured table, the mechanism that explains why the union fold cannot see the finding, and the ADR-0087 disposition the banner owes; it also narrows "nothing that builds today stops validating", which was the sentence an upgrader would have been misled by. ⛔ Out of scope, deliberately: the landed clause-② declaration on #18677 and what a `yes (narrowing)` that shipped declared `no` owes beyond this file. That is the maintainer's, and this commit does not answer it. Claude-Session: https://claude.ai/code/session_01DvvamiacK328idtBYJBxV3 Co-authored-by: Claude <noreply@anthropic.com>
1 parent be7aeb8 commit 1056c00

1 file changed

Lines changed: 16 additions & 1 deletion

File tree

‎.changeset/18677-validate-per-package-authoring-pass.md‎

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,21 @@ After: both report 4, the same set, in the same order.
1717

1818
**The loop is now one seam, not two copies.** `runPerPackageAuthoringRules` lives beside `artifactPackages` / `packageBodyAsStack` in `utils/artifact-packages.ts`, whose header already forbids a second copy of that shape by name. What would have drifted between two hand-written loops is not the package reading but the **verdict** — the de-duplication key, the severity split, the `where` prefix. `os build`'s observable output is unchanged (text face byte-identical modulo timings; `--json` payload identical).
1919

20-
**Severity mapping is `os build`'s, unchanged.** A per-package `error` refuses (exit 1); an advisory joins `warnings`. So `os validate` is narrowed only to the bar the command that *ships* already holds: every input it can now refuse is one `os build` already refuses, which means **nothing that builds today stops validating**. No newly-refused input could be exhibited on any fixture — across the repo's own two-package example and three constructed variants the observable change is advisory-only, because `packageBodyAsStack` hands each package the artifact's whole `packages[]` as resolution context and the reference-integrity suite resolves object names through it. Graded `minor` rather than `patch` for the new observable step line, the new advisories and the newly reachable non-zero exit; ⛔ **not** declared breaking, because the narrowing could not be exhibited and is bounded by an existing gate.
20+
**Severity mapping is `os build`'s, unchanged.** A per-package `error` refuses (exit 1); an advisory joins `warnings`. So `os validate` is narrowed only to the bar the command that *ships* already holds: every input it can now refuse is one `os build` already refuses.
21+
22+
**BREAKING** — `os validate --strict` can now fail a project it passed before. Measured on a two-package fixture whose union fold is clean and whose per-package run is not (`core` owns `pp_account`; a sibling package owns the view that displays `pp_account.industry`), driving the CLI from source:
23+
24+
| `os validate` on that fixture | before | after |
25+
|---|---|---|
26+
| `--json` | warnings 0, exit 0 | warnings 1, exit 0 |
27+
| `--json --strict` | exit 0 | **exit 1** |
28+
29+
The one warning is `field-no-consumers` at `package 'com.example.ppflip.core' — object "pp_account" · field "industry"`, which `os build` already reports on the same fixture: nothing is refused here that `os build` does not already refuse, and the default (non-strict) face is unchanged in that measurement. A run that must keep its old verdict drops `--strict`; a project that wants to keep the flag fixes what the per-package pass reports, which is what `os build` has been reporting all along.
30+
31+
Why the union fold does not see it: `packageBodyAsStack` hands each package the artifact's whole `packages[]` as resolution context, so a cross-package *reference* still resolves and the reference-integrity rules stay quiet — but a reachability rule asks what the **stack** reads, and per package the stack is that one package's own body. A field whose only consumer lives in a sibling package is therefore live to the union run and inert to the per-package run, and that is the shape that reaches `--strict`.
32+
33+
Graded `minor` rather than `patch` for the new observable step line, the new advisories and the newly reachable non-zero exit; the launch window refuses `major`, so the breaking-ness is carried by the banner above and the ADR-0087 disposition below.
2134

2235
Unchanged and out of scope: the ADR-0130 D4 union fold (#17069, fixed — `authoringRuleUnionStack` is in both commands), `--json` rendering (#11727), and disagreements *within* the per-package pass's verdicts (#18204). `os lint` still runs the union pass alone; its `artifactPackages` / `packageBodyAsStack` imports serve its own intra-package duplicate-name advisory, not the shared table.
36+
37+
<!-- adr-0087: not-required (no-migration-prescription) Nothing an author writes changes: no spec key, export, config field or payload key is removed, renamed or added. What moved is which stacks one CLI command's existing rule table is run over, so `objectstack migrate meta` has nothing to rewrite and the ledger has nothing to record. -->

0 commit comments

Comments
 (0)