Repository navigation
Commit 623b686
authored
feat(api-extractor): versioned API model, Effect-aware diff and semver verdict (PR1) (#1)
* docs(plans): requirements for the Effect-aware public-API tool
Requirements-only unified plan (ce-brainstorm, round-3 contract): premise
table with sources, a survey of what already solves the problem, approach B
(model-first), and R1-R23 mapped to Done 1-9.
* docs(plans): planning contract and units for the Effect-aware public-API tool
* feat(api-extractor): versioned API model, Effect-aware diff and semver verdict
Repository foundation (MIT with Microsoft's notice, packs pinned to a
systemfsoftware main SHA) and the model core: an Effect Schema model with
schemaVersion 1, one canonical serialiser, a polarity-aware diff that
decomposes Effect/Stream/Layer channels and expands local aliases, and a
declarative rule corpus whose unmatched changes fail closed as major.
Property tests cover AE1-AE5; the locale test runs the serialiser in child
processes under tr_TR, de_DE and C. Plan dispositions recorded in the doc.
* docs(plans): supersede the plan with the public-family-package ruling
The 0205 plan was frozen once PR1 units ran, so the root ruling of 2026-10-10
lands as a new dated plan declaring supersedes: public systemfsoftware packages
come from this repository's flake now (KTD2), the verdict is a cell (KTD14),
.sfs-deps is built in CI (KTD12), and R8 keeps the oracle's compiler line on the
fallback (KTD9). Only tsdown-config, vitest-config and stryker-config wait on P1.
* feat(api-extractor): verdict on effect-cell-types, packages from the flake
flake.nix pins systemfsoftware ba6664c1; its sfs-deps output and the
consumer-store check (lib.mkConsumerStore) supply effect-cell-types,
effect-schema-law, vitest and tsconfig as .sfs-deps tarballs. The verdict is
a Workflow decision (judgeSurfaces) run by a Sandwich cell that writes
canonical JSON or fails with SurfaceRejected / RuleCorpusRejected. Codec laws
via ruleOfSchemas sit next to each schema. CI builds .sfs-deps once and
compares x86_64 and arm64 output bytes.
* refactor(api-extractor): simplify the PR1 core without changing its bytes
ce-simplify-code pass: compare normalised types by canonical key instead of
re-normalising at every level; key lattice members and overload signatures
once; derive bump order and keyword names from their schemas; share the
corpus-ambiguity fields between the decision error and the cell error; one
outputsOf fixture for both determinism probes. host-digest over 200
fixed-seed samples is byte-identical before and after (e02a7331).
* fix(api-extractor): resolve the code-review findings on the PR1 core
Channel types read defaulted trailing arguments (Effect<A, E>, Layer<S, E>):
corpus 1.1.0 declares each optional channel's default. Aliases reached through
type-parameter defaults and constraints expand. Exports sharing a name (a value
beside a type) pair by kind, and serialise in kind order. Class heritage keeps
extends and implements apart. The corpus gate refuses equal-specificity ties
and the reserved unclassified-change id.
Schema laws come from effect-schema-vite (flake tarball): TypeExpr, Member and
ApiItem declare recursion budgets at their recursion points, and the
hand-written ruleOfSchemas registrations it supersedes are removed. The model
barrel publishes the union members and KeywordName as a value.
Every behavioural fix has a property test that fails on 8da33d7.
* test(api-extractor): move PR1's suite onto the family test idiom
Root ruling 2026-10-10: migrate inside PR1.
- Decision and serialiser behaviour are it.prop laws over the production
schemas, with the constant-impostor gate on.
- Known-answer tables are generator-body example tests through the public
surface, and every corpus reason code now has a row (review finding #12).
- The locale test is an e2e it.prop in apps/api-extractor-e2e. It spawns
processes, so the test-layer gate puts it outside the package. It drives
only the public surface, and host-digest moved there with it.
Drawing from the ApiModel schema turned up models that repeat an enum member
name or an entry-point path. The diff of such a model against itself was not
empty. The schema now refuses them (uniqueBy, with a generation hint), so
API_MODEL_SCHEMA_VERSION is 2.
The hand-mirrored arbitraries and fast-check are gone (DEL1).
Plan 0517 supersedes plan 0314.
* ci: upload the hidden .sfs-deps directory, and fail the job when nothing uploads
upload-artifact v4+ skips hidden paths unless include-hidden-files is set, and
if-no-files-found: warn let the sfs-deps job pass with no artifact, so every
downstream job failed on download instead.
* docs(solutions): keyed uniqueness is a schema invariant only for identities
ce-compound learning from PR1: repeated export names are a diff pairing rule
(declaration merging), entry-point paths and enum member names are schema
refinements carrying the uniqueBy generation hint.
* docs(agents): read docs/solutions before planning or changing code
Sub-conductor ruling 2026-10-10: the learnings store is the first read.
* fix(api-extractor): pair same-name same-kind exports independent of storage order
Resolves the ce-code-review findings on 8da33d7..1f31aaf:
- compareNamed paired same-kind items under one name by stored position, so
two byte-identical models storing them in opposite orders diffed as changed.
Equal items now pair first and the rest pair in canonical-key order. Two
it.prop laws under "verdict on exports sharing a name and a kind" fail on the
old pairing and pass now.
- The cross-kind guard in compareItem was unreachable (groups are per kind)
and is gone.
- The cell refuses a repeated entry-point path and a repeated enum member name
with SurfaceRejected; example rows pin both refusals.
- The change-kind table takes model pairs and has a row for each of the 11
corpus reason codes that lacked one, so every code has a row as the plan
ruling requires.
- The keyed-uniqueness solution doc records the storage-order defect.1 parent 11e027b commit 623b686
48 files changed
Lines changed: 5557 additions & 0 deletions
File tree
- .compound-engineering
- .github/workflows
- apps/api-extractor-e2e
- docs
- plans
- solutions/design-patterns
- packages/api-extractor
- src
- diff
- model
- rules
- tests
- __fixtures__
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
0 commit comments