@massu/core 2.5.1 → 2.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +240 -0
- package/agents/massu-output-scorer.md +2 -2
- package/agents/massu-plan-auditor.md +1 -1
- package/commands/_shared-references/test-first-protocol.md +4 -4
- package/commands/_shared-references/verification-table.md +5 -5
- package/commands/massu-audit-deps.md +2 -2
- package/commands/massu-batch.md +3 -3
- package/commands/massu-checkpoint.md +7 -7
- package/commands/massu-ci-fix.md +1 -1
- package/commands/massu-cleanup.md +16 -16
- package/commands/massu-commit.md +7 -7
- package/commands/massu-create-plan.md +7 -7
- package/commands/massu-dead-code.md +3 -3
- package/commands/massu-debug/references/common-shortcuts.md +1 -1
- package/commands/massu-debug/references/investigation-phases.md +4 -4
- package/commands/massu-debug/references/report-format.md +2 -2
- package/commands/massu-deploy.md +1 -1
- package/commands/massu-deps.md +5 -5
- package/commands/massu-doc-gen.md +3 -3
- package/commands/massu-docs.md +6 -6
- package/commands/massu-estimate.md +3 -3
- package/commands/massu-golden-path/references/competitive-mode.md +2 -2
- package/commands/massu-golden-path/references/phase-1-plan-creation.md +1 -1
- package/commands/massu-golden-path/references/phase-2-implementation.md +2 -2
- package/commands/massu-golden-path/references/phase-4-commit.md +3 -3
- package/commands/massu-golden-path/references/phase-5-push.md +5 -5
- package/commands/massu-guide.md +3 -3
- package/commands/massu-hotfix.md +14 -14
- package/commands/massu-loop/references/checkpoint-audit.md +3 -3
- package/commands/massu-loop/references/iteration-structure.md +3 -3
- package/commands/massu-loop/references/loop-controller.md +5 -5
- package/commands/massu-loop/references/plan-extraction.md +4 -4
- package/commands/massu-loop/references/vr-plan-spec.md +3 -3
- package/commands/massu-loop-playwright.md +5 -5
- package/commands/massu-loop.md +1 -1
- package/commands/massu-new-feature.md +6 -24
- package/commands/massu-perf.md +1 -1
- package/commands/massu-plan.md +21 -21
- package/commands/massu-push-light.md +9 -9
- package/commands/massu-recap.md +1 -1
- package/commands/massu-refactor.md +8 -8
- package/commands/massu-release.md +3 -3
- package/commands/massu-review.md +1 -1
- package/commands/massu-rollback.md +6 -6
- package/commands/massu-scaffold-page.md +1 -1
- package/commands/massu-scaffold-router.md +1 -1
- package/commands/massu-status.md +9 -9
- package/commands/massu-tdd.md +2 -2
- package/commands/massu-test.md +13 -13
- package/commands/massu-verify-playwright.md +1 -1
- package/commands/massu-verify.md +20 -20
- package/dist/cli.js +1731 -976
- package/dist/hooks/auto-learning-pipeline.js +745 -87
- package/dist/hooks/classify-failure.js +747 -45
- package/dist/hooks/cost-tracker.js +89 -28
- package/dist/hooks/fix-detector.js +536 -48
- package/dist/hooks/incident-pipeline.js +96 -29
- package/dist/hooks/intent-suggester.js +89 -28
- package/dist/hooks/memory-recall.js +89 -28
- package/dist/hooks/post-edit-context.js +137 -29
- package/dist/hooks/post-tool-use.js +95 -30
- package/dist/hooks/pre-compact.js +89 -28
- package/dist/hooks/pre-delete-check.js +137 -31
- package/dist/hooks/pre-tool-use-gate.js +271 -43
- package/dist/hooks/quality-event.js +89 -28
- package/dist/hooks/rule-enforcement-pipeline.js +89 -28
- package/dist/hooks/security-gate.js +219 -39
- package/dist/hooks/session-end.js +92 -28
- package/dist/hooks/session-start.js +140 -62
- package/dist/hooks/user-prompt.js +89 -28
- package/fragments/feature-components.md +15 -0
- package/fragments/feature-components.python.md +15 -0
- package/fragments/feature-components.typescript.md +15 -0
- package/package.json +6 -5
- package/patterns/testing-patterns.md +8 -8
- package/protocols/plan-implementation.md +2 -2
- package/protocols/verification.md +4 -4
- package/reference/lessons-learned.md +4 -4
- package/reference/vr-verification-reference.md +9 -9
- package/templates/aspnet/massu.config.yaml +2 -0
- package/templates/go-chi/massu.config.yaml +2 -0
- package/templates/multi-runtime/massu.config.yaml +4 -2
- package/templates/phoenix/massu.config.yaml +2 -0
- package/templates/python-django/massu.config.yaml +3 -1
- package/templates/python-fastapi/massu.config.yaml +3 -1
- package/templates/python-flask/massu.config.yaml +3 -1
- package/templates/rails/massu.config.yaml +4 -2
- package/templates/rust-actix/massu.config.yaml +2 -0
- package/templates/spring/massu.config.yaml +2 -0
- package/templates/swift-ios/massu.config.yaml +3 -1
- package/templates/ts-nestjs/massu.config.yaml +2 -0
- package/templates/ts-nextjs/massu.config.yaml +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,246 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
10
10
|
> redistributed under the **Apache License 2.0**. Full license + NOTICE:
|
|
11
11
|
> `packages/core/assets/embedder/MODEL-LICENSE`.
|
|
12
12
|
|
|
13
|
+
## [2.5.3] - 2026-11-08
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **Installed commands and agents now match your stack, not massu's own.** massu detected a
|
|
18
|
+
project's stack correctly and then installed the same TypeScript-shaped command set into every
|
|
19
|
+
repository, so a Python project's checks ran `npm test` and `npx tsc --noEmit` against a tree
|
|
20
|
+
that has neither, found nothing, and reported clean. The shipped assets now render the
|
|
21
|
+
toolchain from `massu.config.yaml`: measured on a python-fastapi fixture, the 83 `npm test`
|
|
22
|
+
references became `pytest`, and `npx tsc --noEmit` became `mypy`. Stack capabilities are
|
|
23
|
+
resolved once and all 13 shipped templates are held to that contract.
|
|
24
|
+
- **`paths.tests` config key.** About 25 assets told every project its tests belong in massu's
|
|
25
|
+
own `packages/core/src/__tests__/`. The test directory is now a config property. It is
|
|
26
|
+
optional, so every existing config keeps working.
|
|
27
|
+
- **`{{> name}}` fragments in templates.** Block-level, stack-specific content (for example the
|
|
28
|
+
"where a new feature goes" section of `/massu-new-feature`) now lives in one shared body with a
|
|
29
|
+
per-stack fragment, instead of telling a FastAPI user to edit `tools.ts`.
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- **`massu show-template` printed the raw template while the installer wrote rendered bytes.**
|
|
34
|
+
The diff the installer suggests (`diff <target> <(npx massu show-template <base>)`) therefore
|
|
35
|
+
reported differences that did not exist. It now prints what would be installed.
|
|
36
|
+
- **The template-syntax README was silently dropped from every install since 1.3.0.** It
|
|
37
|
+
documents `{{variable.path}}` literally, the renderer tried to resolve it, and the error was
|
|
38
|
+
counted as "skipped" with exit 0. Documentation is no longer rendered.
|
|
39
|
+
- **The knowledge index read about half of a project's canonical rules.** The CR-table parser's
|
|
40
|
+
`[^|]+` matched newlines, so in a three-column table each row consumed the next: 21 of 41
|
|
41
|
+
rules were indexed in this repository, for the life of the feature. Every row is now read.
|
|
42
|
+
- **The fix detector cried wolf on English.** `auth`, `lock` and `rate.limit` matched inside
|
|
43
|
+
"author", "blocked" and "corporate_limits". Every heuristic is now word-bounded,
|
|
44
|
+
`method_name_correction` (which fired on any two differently named method calls) is retired,
|
|
45
|
+
and a numbered Markdown heading is no longer read as an incident title.
|
|
46
|
+
- **The security gate flagged its own documentation.** `os.system() — shell injection risk`
|
|
47
|
+
fired on a comment quoting the call and on a test fixture holding it as a string. Python
|
|
48
|
+
content is now judged on code, not on prose that mentions the pattern.
|
|
49
|
+
- **`corrections.md` has one owner.** Its filename, path and placement were rebuilt in five
|
|
50
|
+
places. One module now owns them, so a hook and the indexer cannot disagree about where it is.
|
|
51
|
+
- **`zod` moves to 4 (GHSA-mrhx-c7xc-m3w5, high, covers every zod 3 release).** Config parsing is
|
|
52
|
+
unchanged. zod 4's `.default()` no longer parses its value, so every object-level config default
|
|
53
|
+
now uses `.prefault()`; without that, a section left out of `massu.config.yaml` would have come
|
|
54
|
+
back empty instead of filled with its defaults.
|
|
55
|
+
- **Dependency advisories cleared** (`smol-toml` ^1.8.0, `vitest` ^4.1.12).
|
|
56
|
+
- **The auto-learning Stop hook no longer counts keywords inside strings and comments, and no
|
|
57
|
+
longer repeats itself.** It matched fix keywords (`try`, `catch`, `raise`, …) against raw diff
|
|
58
|
+
text, so `"The catch"` in a Python string counted as error handling, and it re-read the working
|
|
59
|
+
tree on every Stop with no record of what it had already shown. One false positive repeated
|
|
60
|
+
after every reply until the file was committed. Added lines are now scored on their CODE spans by
|
|
61
|
+
a per-language lexer (`hooks/lib/code-spans.ts`: escapes, triple quotes, template literals,
|
|
62
|
+
block comments, regex literals), which the per-edit fix detector now shares. Languages without a
|
|
63
|
+
lexer are judged as before and named in the hook's debug output. The hook keeps a per-session
|
|
64
|
+
record of the matched lines it has shown and speaks again only when a new one appears. Diff file
|
|
65
|
+
headers (`--- a/src/error.ts`) are no longer scored as removed lines.
|
|
66
|
+
|
|
67
|
+
- **The release ceremony contained a step it could not reach.** CR-64 makes a published
|
|
68
|
+
version immutable: once `X.Y.Z` is on npm, HEAD must be exactly the `vX.Y.Z` tag, so any
|
|
69
|
+
further commit at that version cannot be pushed. The ceremony nonetheless listed the
|
|
70
|
+
`.mcp.json` pin update (step 8) and the master-plan row (step 10) *after* `npm publish`
|
|
71
|
+
(step 6) — two commits at a version that forbids commits. Unreachable by construction, and
|
|
72
|
+
only visible at the moment someone tried to perform them.
|
|
73
|
+
|
|
74
|
+
The step order now matches what has always actually worked: every repository commit lands
|
|
75
|
+
first, the tag is placed at the final tip, and publishing happens last. Nothing about the
|
|
76
|
+
invariant changed; the written order was wrong.
|
|
77
|
+
|
|
78
|
+
- **`.mcp.json` pin drift is now caught on the commit that causes it, not at the next
|
|
79
|
+
release.** A drive-by edit in an unrelated commit had replaced the pin with a machine-local
|
|
80
|
+
path and a stale version, breaking the publish path for two days while every commit, push
|
|
81
|
+
and CI run stayed green — the only check that catches it runs at publish time.
|
|
82
|
+
|
|
83
|
+
## [2.5.2] - 2026-08-14
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- **The code-intelligence index was empty, and an empty index looked exactly like a project
|
|
88
|
+
with no imports.** Ten places across seven modules each answered "where does this project's
|
|
89
|
+
source live?" with the literal `src/`. In any layout that is not single-package every one of
|
|
90
|
+
them matched nothing: the import index consumed **0 of 1266** indexed files, the page index
|
|
91
|
+
found **0 of 69** real pages, cross-domain analysis saw one package of four, and two hooks
|
|
92
|
+
exited silently on every edit and every deletion. Nothing reported it, because a builder that
|
|
93
|
+
reads no rows returns `0` and the caller prints that as a normal result.
|
|
94
|
+
|
|
95
|
+
The layout now declares itself in `massu.config.yaml` and every consumer asks one module.
|
|
96
|
+
Everything is derived from declarations that already existed — `paths.source`,
|
|
97
|
+
`paths.monorepo_roots`, `framework.languages.*.source_dirs`, `paths.pages`,
|
|
98
|
+
`paths.components` — and one definition feeds both the SQL predicates and the in-JS path
|
|
99
|
+
guards, so widening a query cannot leave its recursion guard behind. A builder whose declared
|
|
100
|
+
source dirs match **0 rows of a non-empty** file table now raises an error naming the
|
|
101
|
+
denominator, the declaration, and the prefixes actually present. The contract is `0-of-N`,
|
|
102
|
+
never `0`: a repo with an empty or not-yet-built index legitimately matches nothing and must
|
|
103
|
+
not trip it.
|
|
104
|
+
|
|
105
|
+
Measured after, on the same corpus: 1128 of 1266 files consumed, 1096 import edges where the
|
|
106
|
+
table had been empty, 69 pages indexed, and every downstream read site non-empty.
|
|
107
|
+
|
|
108
|
+
- **A failed knowledge re-index was indistinguishable from a successful one.** The helper that
|
|
109
|
+
refreshes the markdown corpus caught every exception without binding it and returned a boolean
|
|
110
|
+
the only call site discarded. A corrupt database, a permissions error and a search-index
|
|
111
|
+
failure therefore produced byte-identical output to a healthy rebuild: the tool answered from
|
|
112
|
+
whatever the index held before and said nothing.
|
|
113
|
+
|
|
114
|
+
The error is now bound and recorded, and a failed refresh prepends a notice to the response so
|
|
115
|
+
the caller knows the answer may be stale. Loud is not fatal — the tool still answers from the
|
|
116
|
+
index it has, because turning a degradation into an outage for all twelve knowledge tools is
|
|
117
|
+
what the "degrade gracefully" contract exists to avoid.
|
|
118
|
+
|
|
119
|
+
The rebuild itself is no longer a side effect of dispatching. It cost 677 documents / 11,954
|
|
120
|
+
chunks on any file-modification under four scanned roots, and no caller had asked for it;
|
|
121
|
+
callers now state their intent explicitly, with no default, so an unrequested full rebuild
|
|
122
|
+
cannot happen by omission.
|
|
123
|
+
|
|
124
|
+
- **The session-end fix reminder fired on other sessions' work, and could not be discharged.**
|
|
125
|
+
Three defects compounded. Documentation was excluded from two of the three git reads but not
|
|
126
|
+
from the one whose text is actually scored, so the exclusion held only when a diff was
|
|
127
|
+
documentation-only — change any code file and prose was scored as code again. The diff was
|
|
128
|
+
read over the whole working tree with no notion of who made the changes, so on a machine where
|
|
129
|
+
several sessions hold one repository at once the reminder routinely demanded an artifact for
|
|
130
|
+
work the blocked session had not done. And the `autoLearning.fixDetection.enabled` switch,
|
|
131
|
+
which reads as the control for fix detection, never reached this reminder at all.
|
|
132
|
+
|
|
133
|
+
All three git reads now carry the documentation exclusion; the scan is intersected with files
|
|
134
|
+
the acting session actually touched, including the body read and not merely the gate; and the
|
|
135
|
+
switch gates both halves. When the actor cannot be established the reminder stays **silent** —
|
|
136
|
+
a demand that no legal action can discharge is one people route around, after which nothing is
|
|
137
|
+
enforced. The verdict carries a reason and a scanned-file count, so a negative result is never
|
|
138
|
+
an unexplained silence.
|
|
139
|
+
|
|
140
|
+
- **The reality gate's hook check was red forever, and the only way to green it was to
|
|
141
|
+
destroy its own evidence.** R-3 failed on the LIFETIME row count of
|
|
142
|
+
`.massu/hook-failures.jsonl`, an append-only log retained on purpose. From the first
|
|
143
|
+
failure ever recorded the gate stayed red permanently — at 11,116 rows it had long since
|
|
144
|
+
stopped carrying information, and a gate whose sole remedy is deleting its input is one
|
|
145
|
+
people learn to route around.
|
|
146
|
+
|
|
147
|
+
The predicate is now RECENCY: the check fails when a failure lies inside a bounded window
|
|
148
|
+
(default 24h, `MASSU_HOOK_FAILURE_WINDOW_HOURS`) and names the offending row's timestamp
|
|
149
|
+
and hook, while the historical backlog is reported as context and never truncated. The
|
|
150
|
+
denominator prints on every run, so "scanned 0 rows, found 0 failures" can never be
|
|
151
|
+
mistaken for a clean log.
|
|
152
|
+
|
|
153
|
+
An absent log is no longer collapsed into either answer. It is corroborated against the
|
|
154
|
+
independent `hook_health` table the same writer populates: rows there prove failures were
|
|
155
|
+
recorded in this checkout, so a missing file means the evidence was destroyed and the gate
|
|
156
|
+
fails; no rows means there is nothing to measure and the check skips with the reason
|
|
157
|
+
named. Treating absence as an error — as originally specified — would have made the
|
|
158
|
+
nightly gate permanently red in CI, where the log is gitignored, and on every fresh
|
|
159
|
+
install, where it is created lazily on first failure.
|
|
160
|
+
|
|
161
|
+
Not a package change: `scripts/` is not in the published `files` array.
|
|
162
|
+
Plan `plan-2026-08-11-hook-failure-signal-truthfulness`.
|
|
163
|
+
|
|
164
|
+
- **The release verifier reported FAIL on a publish that had fully succeeded.** It slept two
|
|
165
|
+
seconds, read the npm registry once, and treated "the replica has not caught up" and "the
|
|
166
|
+
publish did not land" as the same answer. npm is read-after-write eventually consistent, so
|
|
167
|
+
both states produce the identical value.
|
|
168
|
+
|
|
169
|
+
This is the blind-gate law with the polarity flipped: usually absence reads as PASS, here it
|
|
170
|
+
read as FAIL — the same defect, a check that cannot distinguish *not yet* from *not ever*.
|
|
171
|
+
The flipped polarity is what makes it dangerous, because a false FAIL on a release tool
|
|
172
|
+
invites a re-publish or a version bump against a registry where versions are immutable.
|
|
173
|
+
|
|
174
|
+
Replaced with a deadline-bounded poll (90s, 3s interval, overridable) that reports how long
|
|
175
|
+
it waited and, on failure, states plainly that the absence is not propagation lag. The
|
|
176
|
+
demand itself was correct and is unchanged — `+ @massu/core@x.y.z` on stdout is not a
|
|
177
|
+
receipt; only the timeout was wrong.
|
|
178
|
+
|
|
179
|
+
Not a package change: `scripts/` is not in the published `files` array.
|
|
180
|
+
|
|
181
|
+
- **`require()` of a TypeScript specifier held CI red in both repos for two days.** A
|
|
182
|
+
`require()` is resolved by whatever loader is running — not by `tsc`, and not by the vitest
|
|
183
|
+
transform. Node only gained require-of-TypeScript in 22.18; `packages/core` declares
|
|
184
|
+
`engines.node >= 22.16.0` and CI pins exactly that floor, so three such calls in
|
|
185
|
+
`hooks-stdout-convention.test.ts` passed on a Node 26 dev machine and threw
|
|
186
|
+
`SyntaxError: Unexpected identifier 'as'` on every runner. Replaced with a static ESM import
|
|
187
|
+
and guarded by a new drift-guard, which is a static property of the source and so goes red on
|
|
188
|
+
any Node version. A fourth call site in production code was found by enumerating the tree
|
|
189
|
+
rather than the failure, and stays: `require()` defers evaluation while a static import is
|
|
190
|
+
eager, and that laziness is what keeps a database load failure from silencing the hook-failure
|
|
191
|
+
signal it records.
|
|
192
|
+
|
|
193
|
+
- **Publication to the public mirror now goes through a pull request.** A direct push to the
|
|
194
|
+
mirror's `main` cannot be gated by its required status checks — checks have not run on a
|
|
195
|
+
commit that does not exist yet — so every sync reported `Bypassed rule violations` and landed
|
|
196
|
+
regardless. That is what hid the above for two days. `scripts/ops/publish-public-mirror.sh`
|
|
197
|
+
derives the required contexts from the live ruleset, polls each to a deadline, treats a
|
|
198
|
+
cancelled or missing verdict as *not* a pass, and merges by rebase only when every one is
|
|
199
|
+
SUCCESS. It enforces the verdict itself rather than relying on the ruleset, because the
|
|
200
|
+
ruleset grants the pushing account a standing bypass.
|
|
201
|
+
|
|
202
|
+
- **A bcrypt cost factor was a wall-clock budget in disguise.** `generateApiKey()` hashes at
|
|
203
|
+
cost 12 — ~350ms of deliberate CPU — in three tests that do not test hashing, which blew
|
|
204
|
+
vitest's 5000ms timeout under the concurrent coverage run while passing in isolation. Lowering
|
|
205
|
+
the cost factor would have been a security regression with nothing in the tree to catch it, so
|
|
206
|
+
`BCRYPT_COST` is now named and the property is asserted directly: the configured cost reaches
|
|
207
|
+
bcrypt, with the full key and never the plaintext-stored prefix.
|
|
208
|
+
|
|
209
|
+
- **Importing any of 18 hook modules executed the hook.** A bare `main()` at module scope means
|
|
210
|
+
importing the module reads stdin, does its work, and exits the host process. Enumerating the
|
|
211
|
+
tree found 15 with no guard and 2 more guarded by a filename suffix — invisible to a sweep for
|
|
212
|
+
"unguarded", and disarmed silently by a rename. All 18 now share one
|
|
213
|
+
`isDirectInvocation(import.meta.url)` helper, proven behaviourally against the built bundles.
|
|
214
|
+
|
|
215
|
+
- **A live destructive-path defect was hiding behind a permanently-red CI job.** Three sites in a
|
|
216
|
+
test harness widened to the filesystem root when a variable was empty, one of them under the
|
|
217
|
+
memory-store tree. The guard had been reporting it correctly on every run for long enough that
|
|
218
|
+
its redness stopped carrying information. Destructive paths there now go through a chokepoint
|
|
219
|
+
that cannot express the unsafe form. (Plan
|
|
220
|
+
`plan-2026-08-08-incident-coverage-range-discharge`: the CR-62 linkage ratchet shipped
|
|
221
|
+
2026-08-09 gains its real-history differential, which shows all 10 post-ratchet obligated
|
|
222
|
+
commits discharging via containment or citation and none via the legacy fallback.)
|
|
223
|
+
|
|
224
|
+
None of these are package changes: `scripts/` and `__tests__/` are not in the published
|
|
225
|
+
`files` array, and `website/` is not published.
|
|
226
|
+
|
|
227
|
+
- **`massu watch` could start a file watcher that was dead for its entire lifetime.** chokidar
|
|
228
|
+
can return a watcher that emits `ready`, emits no `error`, and then delivers nothing, ever.
|
|
229
|
+
Interleaved A/B in a single load window: fsevents **8 of 60** dead against **0 of 60** for the
|
|
230
|
+
same directories with polling (Fisher's exact ≈ 0.006). The consequence for a user is silent
|
|
231
|
+
staleness — `.claude/` stops refreshing, `massu watch --status` looks healthy, and nothing is
|
|
232
|
+
logged. Nothing in the daemon would ever have noticed: its only reconcile trigger was a tick
|
|
233
|
+
gap over 30s, whose predicate is *"did the clock jump?"* while the property is *"might we have
|
|
234
|
+
missed events?"*, and a watcher dead from birth produces no tick gap at all.
|
|
235
|
+
|
|
236
|
+
The tick now writes a sentinel the watcher itself must echo back. Silence is treated as death:
|
|
237
|
+
log loudly, reconcile, and after two consecutive dead intervals close and re-watch. Escalation
|
|
238
|
+
fires on powers of two of the dead streak, so a permanently dead watcher cannot trade a
|
|
239
|
+
silent-staleness bug for a full refresh plus a watcher rebuild every ten seconds forever.
|
|
240
|
+
Polling was rejected as the fix — it trades a correctness bug for a battery-life bug.
|
|
241
|
+
|
|
242
|
+
Two constants here are claims about the outside world and were measured rather than assumed.
|
|
243
|
+
The canary shares ONE recursive FSEvents stream with the watched source directories (verified
|
|
244
|
+
by recording the paths streams are actually opened on — a canary on its own stream could have
|
|
245
|
+
been alive while the source watcher was dead), and its grace floor is set from measured echo
|
|
246
|
+
latency: ~48ms median, but a tail to 941ms under contention.
|
|
247
|
+
`scripts/ops/measure-canary-echo-latency.mjs` ships so the number can be re-checked instead of
|
|
248
|
+
trusted. Plan `plan-2026-08-12-watch-daemon-silent-dead-watcher`.
|
|
249
|
+
|
|
250
|
+
This one IS a package change: `packages/core/src/watch/daemon.ts` and the new
|
|
251
|
+
`packages/core/src/watch/canary.ts` are published.
|
|
252
|
+
|
|
13
253
|
## [2.5.1] - 2026-08-09
|
|
14
254
|
|
|
15
255
|
### Fixed
|
|
@@ -73,7 +73,7 @@ Input: List of files changed, plan document path, feature description.
|
|
|
73
73
|
#### Dimension 5: Test Coverage
|
|
74
74
|
- Check: test files exist for new features
|
|
75
75
|
- Check: critical paths have test coverage
|
|
76
|
-
- Run `
|
|
76
|
+
- Run `{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}}` to verify passing
|
|
77
77
|
- 1=no tests, 3=basic tests pass, 5=comprehensive coverage
|
|
78
78
|
|
|
79
79
|
### Step 3: Generate Scorecard
|
|
@@ -86,7 +86,7 @@ Input: List of files changed, plan document path, feature description.
|
|
|
86
86
|
| Pattern Compliance | X/5 | pattern-scanner exit code | |
|
|
87
87
|
| Error Handling | X/5 | [grep results for error states] | |
|
|
88
88
|
| UX Quality | X/5 | [responsive/a11y checks] | |
|
|
89
|
-
| Test Coverage | X/5 |
|
|
89
|
+
| Test Coverage | X/5 | {{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} result | |
|
|
90
90
|
|
|
91
91
|
### Summary
|
|
92
92
|
- Average: X.X/5
|
|
@@ -129,7 +129,7 @@ grep -rn "[old-pattern]" src/
|
|
|
129
129
|
### Step 7: Pattern Compliance
|
|
130
130
|
```bash
|
|
131
131
|
./scripts/pattern-scanner.sh
|
|
132
|
-
|
|
132
|
+
{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
### Step 8: Generate Structured Audit Report
|
|
@@ -40,7 +40,7 @@ it('should serialize BigInt fields to Number', () => {
|
|
|
40
40
|
Run the test and confirm it fails for the expected reason:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
|
|
43
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} -- -t "should serialize BigInt"
|
|
44
44
|
# Expected: FAIL with the specific assertion error
|
|
45
45
|
# Note: This project uses Vitest. Use -t (--testNamePattern) for filtering, NOT --grep.
|
|
46
46
|
```
|
|
@@ -57,14 +57,14 @@ Now fix the source code. The fix should be minimal and targeted.
|
|
|
57
57
|
### Step 4: Verify Test Passes
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
|
-
|
|
60
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} -- -t "should serialize BigInt"
|
|
61
61
|
# Expected: PASS
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
Run the full test suite to check for regressions:
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
|
|
67
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}}
|
|
68
68
|
# Expected: ALL pass
|
|
69
69
|
```
|
|
70
70
|
|
|
@@ -77,7 +77,7 @@ TEST-FIRST PROTOCOL for: [finding description]
|
|
|
77
77
|
Step 1: Test written → [file:line]
|
|
78
78
|
Step 2: Test fails → [error message confirming the bug]
|
|
79
79
|
Step 3: Fix applied → [file:line, description]
|
|
80
|
-
Step 4: Test passes → [
|
|
80
|
+
Step 4: Test passes → [{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} output showing pass]
|
|
81
81
|
TEST_FIRST_GATE: PASS
|
|
82
82
|
```
|
|
83
83
|
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
| Type | Command | Expected | Use When |
|
|
12
12
|
|------|---------|----------|----------|
|
|
13
|
-
| VR-BUILD | `
|
|
14
|
-
| VR-TYPE | `
|
|
15
|
-
| VR-TEST | `
|
|
13
|
+
| VR-BUILD | `{{verify.build | default("(this stack declares no build step)")}}` | Exit 0 | Claiming production ready |
|
|
14
|
+
| VR-TYPE | `{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}` | 0 errors | Claiming type safety |
|
|
15
|
+
| VR-TEST | `{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}}` | ALL pass (MANDATORY) | ALWAYS before claiming complete |
|
|
16
16
|
| VR-SCHEMA-PRE | `SELECT column_name FROM information_schema.columns WHERE table_name = 'X'` | All columns exist | BEFORE writing ANY query |
|
|
17
17
|
| VR-NEGATIVE | `grep -rn "[old]" src/` | 0 matches | Claiming removal |
|
|
18
18
|
| VR-GREP | `grep "[pattern]" [file]` | Match found | Claiming code added |
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
| Gate | Command | Must |
|
|
36
36
|
|------|---------|------|
|
|
37
37
|
| 1. Pattern Scanner | `./scripts/pattern-scanner.sh` | Exit 0 |
|
|
38
|
-
| 2. Type Safety | `
|
|
39
|
-
| 3. Build | `
|
|
38
|
+
| 2. Type Safety | `{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}` | 0 errors |
|
|
39
|
+
| 3. Build | `{{verify.build | default("(this stack declares no build step)")}}` | Exit 0 |
|
|
40
40
|
| 4. Lint | `npm run lint` | Exit 0 |
|
|
41
41
|
| 5. Schema | `npx prisma validate` | Exit 0 |
|
|
42
42
|
| 6. Secrets Staged | `git diff --cached --name-only \| grep -E '\.(env\|pem\|key\|secret)'` | 0 files |
|
|
@@ -144,8 +144,8 @@ cat package.json | node -e "
|
|
|
144
144
|
```bash
|
|
145
145
|
# Check if each dependency is actually imported in source
|
|
146
146
|
for dep in $(node -e "const p=require('./package.json'); Object.keys(p.dependencies||{}).forEach(d=>console.log(d))"); do
|
|
147
|
-
count=$(grep -rn "from ['\"]$dep"
|
|
148
|
-
count2=$(grep -rn "require(['\"]$dep"
|
|
147
|
+
count=$(grep -rn "from ['\"]$dep" {{paths.source}}/ --include="*.ts" 2>/dev/null | wc -l | tr -d ' ')
|
|
148
|
+
count2=$(grep -rn "require(['\"]$dep" {{paths.source}}/ --include="*.ts" 2>/dev/null | wc -l | tr -d ' ')
|
|
149
149
|
total=$((count + count2))
|
|
150
150
|
if [ "$total" -eq 0 ]; then
|
|
151
151
|
echo "UNUSED: $dep (0 imports found)"
|
package/commands/massu-batch.md
CHANGED
|
@@ -191,7 +191,7 @@ FOR each batch (IN PARALLEL):
|
|
|
191
191
|
After ALL files are modified:
|
|
192
192
|
7. Run: ./scripts/pattern-scanner.sh --single-file [file] for each changed file
|
|
193
193
|
8. If pattern-scanner finds violations, fix them
|
|
194
|
-
9. Run: NODE_OPTIONS='--max-old-space-size=8192'
|
|
194
|
+
9. Run: NODE_OPTIONS='--max-old-space-size=8192' {{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}
|
|
195
195
|
10. If tsc finds errors in your changed files, fix them
|
|
196
196
|
|
|
197
197
|
## Output Format (MANDATORY)
|
|
@@ -240,10 +240,10 @@ Run on the consolidated result:
|
|
|
240
240
|
./scripts/pattern-scanner.sh
|
|
241
241
|
|
|
242
242
|
# Full type check
|
|
243
|
-
NODE_OPTIONS="--max-old-space-size=8192"
|
|
243
|
+
NODE_OPTIONS="--max-old-space-size=8192" {{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}
|
|
244
244
|
|
|
245
245
|
# Build check
|
|
246
|
-
|
|
246
|
+
{{verify.build | default("(this stack declares no build step)")}}
|
|
247
247
|
```
|
|
248
248
|
|
|
249
249
|
### Step 8: Output Structured Result
|
|
@@ -265,16 +265,16 @@ Then manual checks (all expect 0):
|
|
|
265
265
|
### Step 6: RUN Build Verification (VR-BUILD)
|
|
266
266
|
|
|
267
267
|
```bash
|
|
268
|
-
|
|
268
|
+
{{verify.build | default("(this stack declares no build step)")}}
|
|
269
269
|
```
|
|
270
270
|
|
|
271
271
|
### Step 6.5: Additional Verification Gates
|
|
272
272
|
|
|
273
273
|
```bash
|
|
274
|
-
|
|
274
|
+
{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}} # VR-TYPE: 0 errors
|
|
275
275
|
npm run lint # VR-LINT: Exit 0
|
|
276
276
|
npx prisma validate # VR-SCHEMA-VALIDATE: Exit 0
|
|
277
|
-
|
|
277
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} # VR-TEST: MANDATORY, ALL pass
|
|
278
278
|
./scripts/pre-deploy-check.sh 2>/dev/null || echo "No pre-deploy script"
|
|
279
279
|
```
|
|
280
280
|
|
|
@@ -282,10 +282,10 @@ npm test # VR-TEST: MANDATORY, ALL pass
|
|
|
282
282
|
### Additional Gates
|
|
283
283
|
| Gate | Command | Result | Status |
|
|
284
284
|
|------|---------|--------|--------|
|
|
285
|
-
| Type Safety |
|
|
285
|
+
| Type Safety | {{verify.type | default("declare verification.LANG.type in massu.config.yaml")}} | 0 errors | PASS/FAIL |
|
|
286
286
|
| Lint | npm run lint | Exit 0 | PASS/FAIL |
|
|
287
287
|
| Prisma Validate | npx prisma validate | Valid | PASS/FAIL |
|
|
288
|
-
| Tests |
|
|
288
|
+
| Tests | {{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} | ALL Pass | PASS/FAIL |
|
|
289
289
|
| Pre-deploy | pre-deploy-check.sh | Pass/N/A | PASS/FAIL/N/A |
|
|
290
290
|
```
|
|
291
291
|
|
|
@@ -566,9 +566,9 @@ Checkpoint MUST abort if: pattern scanner fails, security violation detected, bu
|
|
|
566
566
|
## PARALLEL EXECUTION
|
|
567
567
|
|
|
568
568
|
Independent checks can run simultaneously via Task agents:
|
|
569
|
-
- Agent 1: `
|
|
569
|
+
- Agent 1: `{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}`
|
|
570
570
|
- Agent 2: `./scripts/pattern-scanner.sh`
|
|
571
|
-
- Agent 3: `
|
|
571
|
+
- Agent 3: `{{verify.build | default("(this stack declares no build step)")}}`
|
|
572
572
|
- Agent 4: `npm run test:run`
|
|
573
573
|
|
|
574
574
|
---
|
package/commands/massu-ci-fix.md
CHANGED
|
@@ -59,7 +59,7 @@ Map the failure to a known pattern:
|
|
|
59
59
|
2. Run the same check locally to verify:
|
|
60
60
|
```bash
|
|
61
61
|
# Run the specific check that failed
|
|
62
|
-
|
|
62
|
+
{{verify.build | default("(this stack declares no build step)")}} # or whatever CI step failed
|
|
63
63
|
```
|
|
64
64
|
3. Verify fix passes locally
|
|
65
65
|
|
|
@@ -48,7 +48,7 @@ Capture the behavioral baseline BEFORE making any changes:
|
|
|
48
48
|
### 1a. Test Baseline
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
|
|
51
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} 2>&1
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
Record:
|
|
@@ -64,7 +64,7 @@ Record:
|
|
|
64
64
|
### 1b. Type Check Baseline
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
-
|
|
67
|
+
{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}} 2>&1
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
Record:
|
|
@@ -90,20 +90,20 @@ Scan all categories in parallel. Do NOT remove anything yet.
|
|
|
90
90
|
|
|
91
91
|
```bash
|
|
92
92
|
# TypeScript unused imports (ts error 6133)
|
|
93
|
-
|
|
93
|
+
{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}} 2>&1 | grep "is declared but"
|
|
94
94
|
|
|
95
95
|
# ESLint-style: imports never referenced in file body
|
|
96
|
-
grep -rn "^import"
|
|
96
|
+
grep -rn "^import" {{paths.source}}/ --include="*.ts" | head -50
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
### 2b. Dead Exports
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
102
|
# Exported symbols with zero external references
|
|
103
|
-
grep -rn "^export "
|
|
103
|
+
grep -rn "^export " {{paths.source}}/ --include="*.ts" | grep -v "__tests__" | while IFS=: read file line content; do
|
|
104
104
|
name=$(echo "$content" | grep -oP '(?<=export (function|const|class|type|interface|enum) )\w+' | head -1)
|
|
105
105
|
if [ -n "$name" ]; then
|
|
106
|
-
count=$(grep -rn "$name"
|
|
106
|
+
count=$(grep -rn "$name" {{paths.source}}/ --include="*.ts" | grep -v "^$file:" | grep -v "__tests__" | wc -l)
|
|
107
107
|
if [ "$count" -eq 0 ]; then
|
|
108
108
|
echo "DEAD EXPORT: $name in $file"
|
|
109
109
|
fi
|
|
@@ -121,7 +121,7 @@ for f in packages/core/src/*.ts; do
|
|
|
121
121
|
if [[ "$base" == "server" || "$base" == "index" || "$f" == *"__tests__"* ]]; then
|
|
122
122
|
continue
|
|
123
123
|
fi
|
|
124
|
-
count=$(grep -rn "from.*['\"]\./${base}"
|
|
124
|
+
count=$(grep -rn "from.*['\"]\./${base}" {{paths.source}}/ --include="*.ts" | grep -v "__tests__" | wc -l)
|
|
125
125
|
if [ "$count" -eq 0 ]; then
|
|
126
126
|
echo "POSSIBLY ORPHANED: $f"
|
|
127
127
|
fi
|
|
@@ -135,15 +135,15 @@ done
|
|
|
135
135
|
cat packages/core/package.json | grep -A 50 '"dependencies"'
|
|
136
136
|
|
|
137
137
|
# Check each dependency usage
|
|
138
|
-
grep -rn "from.*'better-sqlite3'\|require.*better-sqlite3"
|
|
139
|
-
grep -rn "from.*'yaml'\|require.*yaml"
|
|
138
|
+
grep -rn "from.*'better-sqlite3'\|require.*better-sqlite3" {{paths.source}}/ --include="*.ts" | wc -l
|
|
139
|
+
grep -rn "from.*'yaml'\|require.*yaml" {{paths.source}}/ --include="*.ts" | wc -l
|
|
140
140
|
```
|
|
141
141
|
|
|
142
142
|
### 2e. TODO/FIXME/HACK Comments
|
|
143
143
|
|
|
144
144
|
```bash
|
|
145
145
|
# Enumerate all stale markers — informational only (no auto-removal)
|
|
146
|
-
grep -rn "TODO\|FIXME\|HACK\|XXX\|DEPRECATED"
|
|
146
|
+
grep -rn "TODO\|FIXME\|HACK\|XXX\|DEPRECATED" {{paths.source}}/ --include="*.ts" | grep -v "__tests__"
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
---
|
|
@@ -180,9 +180,9 @@ CLEANUP LOOP:
|
|
|
180
180
|
1. Select all REMOVE items in this category
|
|
181
181
|
2. Apply removals
|
|
182
182
|
3. Run type check:
|
|
183
|
-
|
|
183
|
+
{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}} 2>&1
|
|
184
184
|
4. Run tests:
|
|
185
|
-
|
|
185
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} 2>&1
|
|
186
186
|
5. Compare against baseline:
|
|
187
187
|
- Type errors must be <= baseline
|
|
188
188
|
- Passing tests must be >= baseline
|
|
@@ -218,11 +218,11 @@ For every removed item, confirm it is gone:
|
|
|
218
218
|
|
|
219
219
|
```bash
|
|
220
220
|
# Unused import removed
|
|
221
|
-
grep -rn "[import_name]"
|
|
221
|
+
grep -rn "[import_name]" {{paths.source}}/ --include="*.ts"
|
|
222
222
|
# MUST return 0 matches (or only in unrelated contexts)
|
|
223
223
|
|
|
224
224
|
# Dead export removed
|
|
225
|
-
grep -rn "export.*[export_name]"
|
|
225
|
+
grep -rn "export.*[export_name]" {{paths.source}}/ --include="*.ts"
|
|
226
226
|
# MUST return 0 matches
|
|
227
227
|
|
|
228
228
|
# Orphaned file removed
|
|
@@ -253,13 +253,13 @@ bash scripts/massu-pattern-scanner.sh
|
|
|
253
253
|
|
|
254
254
|
### Gate 2: Type Check (VR-TYPE)
|
|
255
255
|
```bash
|
|
256
|
-
|
|
256
|
+
{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}
|
|
257
257
|
# MUST show 0 errors (or <= baseline)
|
|
258
258
|
```
|
|
259
259
|
|
|
260
260
|
### Gate 3: All Tests (VR-TEST)
|
|
261
261
|
```bash
|
|
262
|
-
|
|
262
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}}
|
|
263
263
|
# MUST exit 0, all tests pass
|
|
264
264
|
```
|
|
265
265
|
|
package/commands/massu-commit.md
CHANGED
|
@@ -64,7 +64,7 @@ grep -n "name:" packages/core/src/[module]-tools.ts
|
|
|
64
64
|
grep -n "case " packages/core/src/[module]-tools.ts
|
|
65
65
|
|
|
66
66
|
# Verify config keys match getConfig() usage
|
|
67
|
-
grep -rn "getConfig()"
|
|
67
|
+
grep -rn "getConfig()" {{paths.source}}/ | head -20
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
---
|
|
@@ -276,13 +276,13 @@ bash scripts/massu-pattern-scanner.sh
|
|
|
276
276
|
|
|
277
277
|
### Gate 2: Type Safety (VR-TYPE)
|
|
278
278
|
```bash
|
|
279
|
-
|
|
279
|
+
{{verify.type | default("declare verification.LANG.type in massu.config.yaml")}}
|
|
280
280
|
# MUST show 0 errors
|
|
281
281
|
```
|
|
282
282
|
|
|
283
283
|
### Gate 3: All Tests Pass (VR-TEST)
|
|
284
284
|
```bash
|
|
285
|
-
|
|
285
|
+
{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}}
|
|
286
286
|
# MUST exit 0, all vitest tests pass
|
|
287
287
|
```
|
|
288
288
|
|
|
@@ -306,9 +306,9 @@ echo "PASS: No secrets staged"
|
|
|
306
306
|
|
|
307
307
|
### Gate 7: Security - No Credentials in Code
|
|
308
308
|
```bash
|
|
309
|
-
# Check
|
|
309
|
+
# Check {{paths.source}}/ for hardcoded credentials
|
|
310
310
|
grep -rn 'sk-[a-zA-Z0-9]\{20,\}\|password.*=.*["\x27][^"\x27]\{8,\}' --include="*.ts" --include="*.tsx" \
|
|
311
|
-
|
|
311
|
+
{{paths.source}}/ 2>/dev/null \
|
|
312
312
|
| grep -v "process.env" \
|
|
313
313
|
| grep -v 'RegExp\|regex\|REDACT\|redact\|sanitize\|mask' \
|
|
314
314
|
| grep -v '\.test\.ts:' \
|
|
@@ -355,7 +355,7 @@ npm audit --audit-level=high # 0 high/critical vulnerabilities
|
|
|
355
355
|
|------|---------|--------|--------|
|
|
356
356
|
| 1. Pattern Scanner | massu-pattern-scanner.sh | Exit [X] | PASS/FAIL |
|
|
357
357
|
| 2. Type Safety | tsc --noEmit | [X] errors | PASS/FAIL |
|
|
358
|
-
| 3. Tests |
|
|
358
|
+
| 3. Tests | {{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} | [X] pass, [X] fail | PASS/FAIL |
|
|
359
359
|
| 4. Hook Build | build:hooks | Exit [X] | PASS/FAIL |
|
|
360
360
|
| 5. Generalization | massu-generalization-scanner.sh | Exit [X] | PASS/FAIL |
|
|
361
361
|
| 6. No Secrets Staged | git diff --cached check | [result] | PASS/FAIL |
|
|
@@ -465,7 +465,7 @@ Analyze `git diff --cached --name-only` to determine scope:
|
|
|
465
465
|
|
|
466
466
|
| Changed Files Location | Suggested Scope |
|
|
467
467
|
|------------------------|-----------------|
|
|
468
|
-
| All in `
|
|
468
|
+
| All in `{{paths.source}}/` | `core` |
|
|
469
469
|
| All in `website/` | `website` |
|
|
470
470
|
| All in `.claude/commands/` | `commands` |
|
|
471
471
|
| All in `scripts/` | `tooling` |
|
|
@@ -330,13 +330,13 @@ Proceed directly to PHASE 1 (Feature Understanding) as normal. Not every request
|
|
|
330
330
|
|
|
331
331
|
```bash
|
|
332
332
|
# Search for similar features in codebase
|
|
333
|
-
grep -rn "[feature_keyword]"
|
|
333
|
+
grep -rn "[feature_keyword]" {{paths.source}}/ --include="*.ts" | head -20
|
|
334
334
|
|
|
335
335
|
# Find similar tool modules
|
|
336
336
|
ls -la packages/core/src/*-tools.ts
|
|
337
337
|
|
|
338
338
|
# Find similar tests
|
|
339
|
-
ls -la
|
|
339
|
+
ls -la {{paths.tests | default("tests")}}/
|
|
340
340
|
```
|
|
341
341
|
|
|
342
342
|
**Document findings:**
|
|
@@ -429,7 +429,7 @@ ls packages/core/src/__tests__/*.test.ts | wc -l
|
|
|
429
429
|
|
|
430
430
|
```bash
|
|
431
431
|
# Check if target directories exist
|
|
432
|
-
ls -la
|
|
432
|
+
ls -la {{paths.source}}/
|
|
433
433
|
|
|
434
434
|
# Check if files to modify exist
|
|
435
435
|
ls -la [file_path]
|
|
@@ -692,7 +692,7 @@ Update coverage map: mark D6, D7, D8, D10 as `done`.
|
|
|
692
692
|
- **File**: packages/core/src/__tests__/[module].test.ts
|
|
693
693
|
- **Action**: CREATE
|
|
694
694
|
- **Covers**: Tool definitions, handlers, edge cases
|
|
695
|
-
- **Verification**: VR-TEST (
|
|
695
|
+
- **Verification**: VR-TEST ({{verify.test | default("declare verification.LANG.test in massu.config.yaml")}})
|
|
696
696
|
|
|
697
697
|
---
|
|
698
698
|
|
|
@@ -713,7 +713,7 @@ Update coverage map: mark D6, D7, D8, D10 as `done`.
|
|
|
713
713
|
|------|------|---------------------|
|
|
714
714
|
| P1-001 | MODULE | `ls -la packages/core/src/[module].ts` |
|
|
715
715
|
| P1-002 | TOOL_WIRE | `grep "getXToolDefinitions" packages/core/src/tools.ts` |
|
|
716
|
-
| P2-001 | TEST | `
|
|
716
|
+
| P2-001 | TEST | `{{verify.test | default("declare verification.LANG.test in massu.config.yaml")}}` |
|
|
717
717
|
| P3-001 | CONFIG | Parse config without error |
|
|
718
718
|
|
|
719
719
|
---
|
|
@@ -780,8 +780,8 @@ Update coverage map: mark D6, D7, D8, D10 as `done`.
|
|
|
780
780
|
#### Build Feasibility
|
|
781
781
|
| Check | Command | Result | Status |
|
|
782
782
|
|-------|---------|--------|--------|
|
|
783
|
-
| TypeScript compiles |
|
|
784
|
-
| Tests pass |
|
|
783
|
+
| TypeScript compiles | {{verify.type | default("declare verification.LANG.type in massu.config.yaml")}} | 0 errors | PASS/FAIL |
|
|
784
|
+
| Tests pass | {{verify.test | default("declare verification.LANG.test in massu.config.yaml")}} | All pass | PASS/FAIL |
|
|
785
785
|
| Hooks compile | cd packages/core && npm run build:hooks | Exit 0 | PASS/FAIL |
|
|
786
786
|
|
|
787
787
|
**FEASIBILITY GATE: PASS / FAIL**
|