4 Commits

Author SHA1 Message Date
Jakub Zych
a9a7a328e6 refactor: hard-fork GSD -> MSD (Make Software Done)
Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD
across contents and paths, upstream package/repo coordinates -> @golem15/msd-core
and golem15com/msd-core. Deep links into upstream history, sibling upstream
packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is.

Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line,
package/plugin identity, regenerated lockfile, install-tree fixtures, derived
registries and benchmark baseline; migration checksum baseline re-locked
(MSD keeps its own install state, so no install had applied the old sums);
sort-order and regex-escaped expectations in tests adjusted.
2026-10-06 01:47:40 +02:00
Tom Boucher
48789fe9a9 fix(#4355): add --merge-async to test:coverage:unit:raw (#4356)
* test(#4355): assert test:coverage:unit:raw carries --merge-async

tests/c8-merge-async-flag.test.cjs asserted the opposite based on a
disproven assumption that `--reporter none` skips c8's merge phase --
it does not (Report.run() computes the merge unconditionally before
consulting the reporter list). This is the failing-first assertion for
the fix in the next commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* fix(#4355): add --merge-async to test:coverage:unit:raw

c8's Report.run() computes the full coverage merge unconditionally,
even with --reporter none -- it only skips the final text/json output,
not the merge dispatch (verified against node_modules/c8/lib/report.js).
Without --merge-async this used the synchronous _getMergedProcessCov(),
loading every raw per-process V8 coverage dump into memory at once and
OOM-crashing release.yml's finalize-test job (run 33997057100) with a
silent exit 1 and no diagnostic ~21s after the test suite itself
finished cleanly ("# fail 0"). Same class already fixed on the other
three coverage scripts via #4068/#4172.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs(changeset): add changeset for #4355 coverage:unit:raw fix

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs(changeset): backfill PR number for #4355 fix

pr:0 -> pr:4356

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

---------

Co-authored-by: sim <sim@local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-05 20:28:51 -04:00
Tom Boucher
fa107c0461 fix(#4172): add --merge-async to test:coverage:scripts-floor (#4173)
* fix(#4172): add --merge-async to test:coverage:scripts-floor

The "Coverage gate (merged shards)" test.yml job has OOM-crashed (exit
134, SIGABRT) on every push to next since 4dfc46b. test:coverage:scripts-floor
was the only c8 coverage-merge invocation in package.json still missing
--merge-async: c8's default sync merge path (Report._getMergedProcessCov)
loads every raw V8 coverage file from the merged 3-shard coverage/tmp
directory into memory as one array before merging, instead of folding
them in one at a time, and now blows through the job's 8192 MB heap
ceiling.

This is the same bug class as #4068 (fixed in 4d70b4dc4), which added
--merge-async to test:coverage:unit and test:coverage:report -- the two
other scripts sharing this merge/report code path -- but missed this
third sibling, which reads the exact same merged coverage/tmp data in
the same job. check-coverage and report both dispatch through c8's
shared getCoverageMapFromAllCoverageFiles()/mergeAsync branch, so the
fix is identical in shape to #4068's.

Extends the existing #4068 regression guard (tests/c8-merge-async-flag.test.cjs)
to also assert test:coverage:scripts-floor carries --merge-async, closing
the coverage gap #4068 left on this sibling script.

Fixes #4172

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs(#4172): backfill changeset PR number (pr:0 -> 4173)

* fix(#4172): route scripts-floor through `c8 report`, not `check-coverage`

The prior commit (1a3d6b75e) added --merge-async to
test:coverage:scripts-floor, but the Coverage gate job still OOM-crashed
identically on PR #4173's CI run
(https://github.com/open-gsd/gsd-core/actions/runs/33587951779/job/100118358975).

Root cause of that miss: c8@11.0.0's `check-coverage` CLI subcommand
handler (node_modules/c8/lib/commands/check-coverage.js) never forwards
argv.mergeAsync into the Report constructor -- only the `report`
subcommand's handler (node_modules/c8/lib/commands/report.js) and the
default command (which also calls into report.js) do. Verified directly
by constructing Report the same way each handler does: the check-coverage
path yields report.mergeAsync === undefined even with --merge-async on
the command line, while the report path yields true.

Fix: route test:coverage:scripts-floor through `c8 report --check-coverage`
instead of `c8 check-coverage`. report.js's outputReport() calls the same
checkCoverages() threshold-checking helper when --check-coverage is
truthy, so behavior (and exit code on threshold failure) is unchanged --
only the code path taken to get there now actually honors --merge-async.

Extends the tests/c8-merge-async-flag.test.cjs regression guard with an
explicit assertion that scripts-floor invokes `c8 report`, not
`check-coverage`, so this can't silently regress back to the broken form.

Fixes #4172

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* docs(#4172): correct changeset to describe the actual root cause (check-coverage vs report subcommand gap, not just the missing flag)

---------

Co-authored-by: sim <sim@local>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 06:39:15 -04:00
Tom Boucher
4d70b4dc43 fix(#4068): add --merge-async to c8 coverage-merge invocations (#4069)
* test(#4068): failing-first regression guard for c8 --merge-async flag

Adds a config-invariant test asserting test:coverage:unit and
test:coverage:report pass --merge-async to c8, guarding against the
coverage-merge OOM (release.yml finalize dry-run, exit 134/SIGABRT)
regressing a third time (prior stopgap: #199).

Also commits the sourced research memo backing the diagnosis.

* test(#4068): rename regression test to avoid lint-test-file-count collision

coverage-merge-async-flag.test.cjs's effective prefix (coverage-merge-
async-flag) matched the unrelated gsd-core/bin/lib/coverage.cjs module's
2-file cap under lint-test-file-count.cjs's startsWith bucketing, failing
FAIL_EXCEEDS_LIMIT (confirmed via the RED gsd-test run on 7b6e6ca9e).
Renamed to c8-merge-async-flag.test.cjs -- no colliding prefix.

* fix(#4068): add --merge-async to c8 coverage-merge invocations

The `test:coverage:unit` script OOM-crashed (exit 134, SIGABRT) in the
release.yml finalize dry-run of 1.12.0: all 1785 unit tests pass, then
c8's report/merge phase crashes ~76s later against the 6144 MB heap
ceiling. Root cause (verified against this repo's pinned c8@11.0.0
source, node_modules/c8/lib/report.js): the default sync merge path,
Report._getMergedProcessCov(), loads every raw V8 coverage file for the
whole run into memory as one array before merging. This is a recurrence
of #199 (same OOM class at ~466 tests, "fixed" by raising the heap
ceiling) -- the suite outgrew 6144 MB as it grew to 1785 tests, and
test.yml's own coverage-gate job already independently hit and
stopgap-fixed the identical class once (test.yml:614-620, 4096->8192 MB).

c8 ships the upstream fix for exactly this: --merge-async (c8 v7.14.0,
already inside the pinned c8@^11.0.0 range -- no dependency bump),
which switches to Report._getMergedProcessCovAsync(), reading and
merging one raw file at a time instead of loading them all at once.
The merge arithmetic (mergeProcessCovs()) and --all's zero-coverage-file
inclusion are unchanged between the two paths, so the coverage gate's
accuracy is unaffected.

Verified empirically (not just by source inspection): against a 223 MB
synthetic raw-coverage corpus derived from this repo's actual 235
gsd-core/bin/lib/**/*.cjs files (same order of magnitude as the 358 MB
figure documented in test.yml), c8's real Report class crashes with the
same "Ineffective mark-compacts near heap limit" signature via the sync
path at a 300 MB heap ceiling, while the async path completes at a flat
~40-50 MB peak down to a 100 MB ceiling. Full repro steps and numbers:
.gsd/bug/fix-4068-coverage-merge-oom/10-diagnosis.md.

Only `test:coverage:unit` and `test:coverage:report` are changed.
`test:coverage` (line 150) is a non-CI dev-convenience script, never
invoked as a command by any workflow. `test:coverage:unit:raw` (line
153) already runs --reporter none, which skips the merge/report phase
this flag affects, entirely -- adding it there would be a no-op.

Fixes #4068

* fix(#4068): add changeset fragment for the coverage-merge OOM fix

The changeset fragment was generated locally (npm run changeset) but
never committed -- isolated code review caught the gap (no
.changeset/*.md on the branch, confirmed via git diff --name-status).

* chore(#4068): backfill changeset PR number

pr:0 -> pr:4069

---------

Co-authored-by: sim <sim@local>
2026-08-29 22:03:28 -04:00