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.
3.4 KiB
3.4 KiB
id, title, group
| id | title | group |
|---|---|---|
| 3951 | Reachable Lint Rules and a Non-Destructive Quick-Task Append | v1.7.0 Features |
Purpose: Make two ESLint rules cover the code they were written to govern, and stop
quick-tasks-append from overwriting curated progress.* values on a body-only write.
What changed:
local/no-adhoc-markdown-parsingreaches its whole registered surface. The rule short-circuited unless a file's path matched a flatsrc/*.ctspattern, so it self-gated on its own filename. Two consequences: 28.ctsfiles insrc/subdirectories sat inside thesrc/**/*.ctsglob it was registered on and were silently skipped, and the rule could not be extended by configuration at all — widening the glob alone left it inert. Both halves now move together, and a test pins that the gate and the registration agree in both directions.- The rule now also covers
tests/**andscripts/**, which surfaced 80 hand-rolled markdown parses across 43 test files. Seventy are routed through the existingmarkdown-sectionizerandmarkdown-tableseams; ten are suppressed with a stated reason (six of those are a shell-pipe detector whose regex merely resembles a table). local/no-adhoc-regex-escapesees property access. Its unsafe-new RegExparm examined only bare identifiers, sonew RegExp(obj['key'])— the shape runtime data actually arrives in — was invisible. That is why it never fired on a known ReDoS. It now inspectsMemberExpression, with an exemption keyed strictly on the property beingsource(18 safe sites), plus provenance exemptions for_SOURCEconstants reached through a required module (3 sites).quick-tasks-appendcan write the canonical row. Optional--quick-id,--slugand--directorylet a caller that has a real quick task emit the same row/msd-quickrenders. Omit them — asfast.mddoes, having neither an id nor a directory — and the row is byte-identical to before.- A body-only append no longer re-derives progress. The route was the only body-only STATE.md
writer not passing
{ resync: false }, so appending one row triggered a full re-derive of the disk-derivedprogress.*frontmatter and replaced curated values. Reproduced: a project with two real phase directories and a curatedtotal_phases: 25collapsed to2on append.
Found by the widening: tests/config-field-docs.test.cjs asserted that
workflow.subagent_timeout's documented default is not 600 — but read the Type column instead
of Default, so it compared 'number' against '600' and could never fail. The guard against
regressing to the old seconds-based default had been inert. It is now row-scoped and real.
Known limits:
- #3426 and #3239 are not closed by this. Their hand-rolled scans in
tests/package-legitimacy-gate.test.cjsare built from line filters andsplit('|'), not the regex-literal fingerprints this rule detects — measured at zero violations even with the gate bypassed. They need new detectors, which is a separate design. - The 10 suppressions are suppressions, not fixes. Each names why the raw markdown text is the subject of that assertion.
- The
src/subdirectory hole was latent — zero violations existed there when it was fixed. It is closed because "no violations today" is not a property that keeps holding, not because it was hiding anything.