rvlib-shipkit 0.22.0 → 0.22.1
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 +4 -0
- package/package.json +1 -1
- package/src/core/check-suite.ts +18 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.22.1
|
|
4
|
+
|
|
5
|
+
- **Fix: the cache stamp is baked in at RUN time, replays print it verbatim.** 0.22.0 annotated only the REPLAY, so a fresh run and a cache hit rendered different strings and STATUS.md still diffed on every alternation (his catch, the second one on this line). A TTL clean pass now writes "(cached at <stamp> until <stamp>)" into the line once, live output and every replay are byte-identical, and the line changes only when a re-validation happens. Proven: fresh-then-cached runs produce a zero-diff STATUS body.
|
|
6
|
+
|
|
3
7
|
## 0.22.0
|
|
4
8
|
|
|
5
9
|
- **Fix: the machine-row auto-commit could not see STATUS.md.** The git helper trims its whole output, so the FIRST porcelain line loses its leading space and the old column-3 slice read "TATUS.md", making the preflight silently decline the exact dirt it was built to eat. `dirtyPathList` parses status prefixes robustly now (renames and quoted paths included, regression-tested on the trimmed-first-line case), and a decline is never silent: the preflight names the non-machine paths it refused.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rvlib-shipkit",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.1",
|
|
4
4
|
"description": "All-in-one repo companion: ci gate (task DAG), auto-discovered health checks, release-contract fulfillness, asks queue, md-wiki tools, asset atelier, live tui",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/core/check-suite.ts
CHANGED
|
@@ -143,13 +143,14 @@ export class CheckSuite {
|
|
|
143
143
|
&& entry != null && entry.version === r.version && entry.key === key
|
|
144
144
|
&& this.now() - entry.at < r.ttlMs && this.now() >= entry.at
|
|
145
145
|
if (fresh) {
|
|
146
|
-
//
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
// when
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
146
|
+
// the stamp was baked in when the check RAN (below): a replay
|
|
147
|
+
// prints the stored lines VERBATIM, so the live run and every
|
|
148
|
+
// later replay render the same string, and the line changes
|
|
149
|
+
// only when a re-validation happens (his call 2026-08-05,
|
|
150
|
+
// second round: annotating replays but not live runs still
|
|
151
|
+
// diffed on every fresh-vs-cached alternation)
|
|
152
|
+
out.push(...entry.lines)
|
|
153
|
+
this.onResult?.(r.name, { lines: entry.lines, status: 'pass', cached: true }) // only clean passes are cached
|
|
153
154
|
continue
|
|
154
155
|
}
|
|
155
156
|
const t = new CheckCtx(this.toolPaths)
|
|
@@ -160,14 +161,18 @@ export class CheckSuite {
|
|
|
160
161
|
else if (e instanceof ToolUnresolved) t.note(`${r.name} skipped (${e.message})`)
|
|
161
162
|
else t.fail(`${r.name} errored (${String(e).slice(0, 200)}) — network down, or a bug in this check`)
|
|
162
163
|
}
|
|
163
|
-
|
|
164
|
-
|
|
164
|
+
// a skip line is an UNKNOWN, not a clean pass — replaying
|
|
165
|
+
// "registry unreachable" for a TTL asserts a dead network as
|
|
166
|
+
// fact long after it recovered
|
|
167
|
+
const cacheable = r.ttlMs > 0 && !t.failed && !t.warned && !t.lines.some((l) => l.kind === 'skip')
|
|
168
|
+
const lines = cacheable
|
|
169
|
+
? t.lines.map((l, i): Line => (i === 0 ? { ...l, text: `${l.text} (cached at ${fmtStamp(this.now())} until ${fmtStamp(this.now() + r.ttlMs)})` } : l))
|
|
170
|
+
: t.lines
|
|
171
|
+
out.push(...lines)
|
|
172
|
+
this.onResult?.(r.name, { lines, status: t.failed ? 'fail' : t.warned ? 'warn' : 'pass', cached: false })
|
|
165
173
|
if (t.failed) anyFail = true
|
|
166
174
|
if (r.ttlMs > 0) {
|
|
167
|
-
|
|
168
|
-
// "registry unreachable" for a TTL asserts a dead network as
|
|
169
|
-
// fact long after it recovered
|
|
170
|
-
if (!t.failed && !t.warned && !t.lines.some((l) => l.kind === 'skip')) { cache[r.name] = { version: r.version, key, at: this.now(), lines: t.lines }; cacheDirty = true }
|
|
175
|
+
if (cacheable) { cache[r.name] = { version: r.version, key, at: this.now(), lines }; cacheDirty = true }
|
|
171
176
|
// a WARN/FAIL evicts the stale pass — a later run must re-probe,
|
|
172
177
|
// not replay an ok recorded before the breakage
|
|
173
178
|
else if (entry != null) { delete cache[r.name]; cacheDirty = true }
|