Commit Graph

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
acb3cc974b fix(#4197): dedup the update-context fast path against the selected global dir (#4413)
* fix(#4197): dedup the update-context fast path against the selected global candidate

The preferredConfigDir fast path derived scope from a cwd-relative match
alone, so a global install reported LOCAL whenever the shell sat in
$HOME — and run_update then drove the installer through its --local arm
(settings.local.json + the #338 relocation) against a global install.

Extract resolveGlobalCandidate (env candidates first, then $HOME-relative,
first hasInstall hit wins) and use it in BOTH paths: the fast path now
answers LOCAL only for a cwd-relative match that is not the selected
global dir, which is the same dedup the cascade applies at its isLocal
check. A preferred dir that is also the env-directed global now answers
GLOBAL on both paths (the cascade's answer), pinned by a parity test.

The discriminator is the selected global candidate, not the $HOME
pathname: with CLAUDE_CONFIG_DIR directing the global elsewhere,
$HOME/.claude probed from cwd === $HOME is a genuine local install, and
a pathname check would re-break parity (regression-pinned).

* chore(#4197): add changeset

* chore(#4197): backfill PR number in changeset

---------

Co-authored-by: agent-4197 <agent-4197@gsd.local>
2026-09-06 14:09:32 -04:00
Dennis Alexis Valin Dittrich
e8800287d5 enhance(#4153): fail closed unresolved update targets (#4237)
* test(#4153): cover unresolved update target

* fix(#4153): fail closed unresolved update target

* test(#4153): require a concrete recovery installer

* fix(#4153): use concrete unresolved recovery command

* chore(#4153): bind changeset to fork PR

* test(#4153): cover portable update diagnostics

* fix(#4153): keep update diagnostics portable

* fix(#4153): harden update version diagnostics

* test(#4153): reject jq in update version checks

* test(#4153): expose step-local parser gap

* fix(#4153): keep JSON parsing step-local

* docs(#4153): align update target guidance

* test(#4153): expose workflow runtime fallback

* test(#4153): expose resolver runtime fallback

* fix(#4153): leave unknown workflow runtime empty

* fix(#4153): stop inferring Claude for unknown targets

* test(#4153): preserve Claude workflow targeting

* test(#4153): preserve known runtime directory identity

* fix(#4153): recognize Claude workflow paths

* fix(#4153): reuse known runtime directory identities

* chore(#4153): acknowledge emitted workflow growth

The fail-closed diagnostic and known-runtime preservation deliberately add 48 emitted bytes.

Emitted-Drift-Ack-Growth: update.md — explicit unresolved-target diagnostics and known-runtime preservation

* test(#4153): expose missing Windsurf workflow contract

* docs(#4153): document Windsurf update targets

* chore(#4153): bind changeset to upstream PR

* fix(#4153): gate unresolved-target exit before the VERSION-missing fallback

The VERSION-missing bullet in get_installed_version sat before the
UPDATE_TARGET_UNRESOLVED exit and shared its trigger condition (version
0.0.0). An LLM agent reading the workflow top-to-bottom could satisfy
"proceed to install" without ever reaching the fail-closed exit this
PR adds, reopening the ill-defined mutating path #4153 closes. Reorder
so the unresolved-target gate runs first and scope the VERSION-missing
bullet to require an already-resolved target.

Also drop two vacuous mutationSpies entries: they checked '--sync'/
'--reapply' (commands/gsd/update.md content) against `step`, a slice of
workflows/update.md — always -1 regardless of correctness. Those routes
bypass get_installed_version entirely and are already covered by
install.test.cjs, reapply-patches.test.cjs, and
skill-frontmatter-contract.test.cjs.

* chore(#4153): point changeset pr field at fork PR #10 for fork CI

* test(#4153): guard RUNTIME_DIRS/update.md table parity, confirm narrowing intent

Nit 1: update.md's PREFERRED_RUNTIME prose and RUNTIME_DIRS
(src/update-context.cts) are two independently maintained copies of the
same runtime->dir mapping with no parity check; add one so a future
edit to either surface without the other fails loudly instead of
silently drifting.

Nit 2: call out in the changeset that a custom --config-dir matching no
known runtime, marker file, or env var now resolves unresolved instead
of silently defaulting to claude -- this narrowing is intentional, it's
the fail-closed behavior #4153 asks for.

* fix(#4153): drop dead $UC fallback in check_latest_version's uc_field, cover unresolved-runtime fast path

agy (gemini-3.8-flash-high) adversarial review of the full PR:

1. check_latest_version's uc_field() copy-pasted get_installed_version's
   `${2:-$UC}` fallback, but every call site here passes $2 explicitly and
   $UC does not exist in this step's scope -- dead, misleading reference.
   Use $2 directly.
2. No unit test covered resolveUpdateContext's preferredConfigDir fast path
   returning runtime: '' for a custom --config-dir matching no RUNTIME_DIRS
   suffix, marker file, or env var (the exact fail-closed case #4153 adds).
   Added.

A third finding (update.md:90 using /gsd:update vs docs using /gsd-update)
was investigated and rejected: /gsd:update is the actual registered
Claude Code command name (commands/gsd/update.md name: gsd:update) and is
locked by this PR's own test (tests/update-workflow.test.cjs); /gsd-update
is a separate, pre-existing, intentional prose convention used in
audience-facing docs (README/INVENTORY/FEATURES). Not a defect.

* chore(#4153): backfill changeset pr field to upstream PR #4237

---------

Co-authored-by: CI Rebase Check <ci@gsd-redux>
Co-authored-by: Test <test@test.com>
Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
2026-09-05 04:17:21 -04:00
Tom Boucher
4a0b5e26b4 test(#3338): fold the verify/validate & workflow-text issue-* cluster — Wave 6 (#3383)
* test(#3338): fold the verify/validate & workflow-text issue-* cluster — Wave 6

Folds 10 legacy issue-*.test.cjs regression files (75 test() blocks) into
their module's main suite, per H3 (#3315) of the test-hygiene epic (#3053).
Third of 4 issue-* waves.

- issue-2701-nul-corrupted-validators.test.cjs (9) + issue-429-comment-
  text-gate.test.cjs (31, incl. fast-check property tests): both target
  verify.cjs/validate.cjs via different calling styles (CLI vs direct-
  require) — merged jointly into verify.test.cjs, 0 dropped.
- issue-2762-plan-reviews-chunked.test.cjs (3) merged into
  plan-phase-drift-guard.test.cjs.
- issue-2771-advisor-subagent-type.test.cjs (1) + issue-2772-discuss-
  phase-text-inconsistencies.test.cjs (6) merged jointly into
  discuss-phase-power.test.cjs.
- issue-498-update-backup-runtime-dir.test.cjs (3, rename basis) +
  issue-815-update-next-channel.test.cjs (7, merged in): both concern
  update.md workflow-text contracts, now update-workflow.test.cjs.
- issue-498-update-context.test.cjs (13): pure rename to
  update-context.test.cjs, sole comprehensive suite for its module.
- issue-2765-brace-expansion-lockfile.test.cjs (1, rename basis) +
  issue-3238-js-yaml-lockfile.test.cjs (1, merged in): two distinct CVE
  regression pins against package-lock.json, now lockfile-cve-audit.test.cjs,
  shared ROOT/npmLs helpers deduped instead of double-declared.

Ratchet upkeep to keep this wave's own gates green: pruned 3 stale
allow-test-rule allowlist entries, cited 2 previously-uncited comments
that surfaced in the folded content (#3338), tightened the exemption-file
ceiling 305 -> 297. Fixed one stale filename reference in production code
(src/init.cts) plus one in docs/reference/workflow-fragments.md.

Zero net test-coverage loss. No production code BEHAVIOR changed.

* test(#3338): fix orthogonal-review findings — Wave 6 fold

Standards-axis review found a real structural defect in two files, both
the same root cause and both fixed here:

- tests/update-workflow.test.cjs: the folded:issue-815-update-next-channel
  wrapper's closing brace was placed after the file's pre-existing tail
  instead of before it, making the already-established folded:bug-2470
  and folded:bug-3130 wrappers CHILDREN of issue-815's block in the test
  hierarchy instead of independent siblings — confirmed via an actual
  node --test run showing the mislabeled TAP nesting. Moved the closing
  brace to the correct position; all three fold wrappers are now
  top-level siblings again (verified via node --test, TAP hierarchy
  correct, 10/10 tests, 5 suites, identical count before and after).
- tests/plan-phase-drift-guard.test.cjs: same mistake in the other
  direction — folded:issue-2762-plan-reviews-chunked was spliced inside
  the pre-existing folded:bug-2492-context-coverage-gate wrapper instead
  of after it. Fixed the same way (227/227 tests, 38 suites, identical
  count before and after).
- Reverted unnecessary 815-suffixed local renames (assert815/fs815/etc.)
  introduced by the fold — the wrapper is genuinely block-scoped once
  correctly closed, so no collision existed (same class as Wave 4's
  __foldSetNested finding).

No test() count changed in either file. No production code touched.

---------

Co-authored-by: sim <sim@local>
2026-08-12 00:51:19 -04:00