@vantageos/backend-doctor 0.1.11 → 0.1.13
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.
|
@@ -150,22 +150,52 @@ const ACTION_OPEN = /export\s+const\s+(\w+)\s*=\s*action\s*\(/;
|
|
|
150
150
|
const NEXT_EXPORT = /export\s+const\s+\w+\s*=/;
|
|
151
151
|
const RUN_MUTATION = /ctx\.runMutation\s*\(/;
|
|
152
152
|
// The carve-out marker + the two shape names it may claim (COND 2).
|
|
153
|
-
const ATOMICITY_MARKER = /atomicity-exception:\s*(pre-io-gate-then-single-atomic-write|independent-per-item-loop-writes)/i;
|
|
153
|
+
const ATOMICITY_MARKER = /atomicity-exception:\s*(pre-io-gate-then-single-atomic-write|independent-per-item-loop-writes|gate-then-idempotent-reingest)/i;
|
|
154
154
|
const SHAPE_PER_ITEM_LOOP = "independent-per-item-loop-writes";
|
|
155
155
|
const SHAPE_PRE_IO_GATE = "pre-io-gate-then-single-atomic-write";
|
|
156
|
+
// Shape (3) — gate-then-idempotent-reingest (Eta ruling #26 follow-up, 2026-08-31,
|
|
157
|
+
// task k1725z23c095p08q7nxp74mkhn8dg8e2). kb.ts storeDocumentChunked is a leading
|
|
158
|
+
// gate mutation, a conditional supersede/dedup keyed on a STABLE namespace, and a
|
|
159
|
+
// per-item re-insert loop — there IS an invariant between the supersede and the loop
|
|
160
|
+
// (so it is NOT shape 2's "no invariant spans two"), but a re-ingest of the same
|
|
161
|
+
// stable key converges on exactly one current set (supersede is a no-op when already
|
|
162
|
+
// applied; the loop re-creates the full set; residue is orphaned rows, not corruption).
|
|
163
|
+
// Eta accepted this as a THIRD checkable shape, NOT an atomic-ingest task (forcing one
|
|
164
|
+
// batched mutation over an unbounded chunk set trades a self-healing transient for a
|
|
165
|
+
// transaction-limit failure on large documents). Its sub-conditions a reader can check:
|
|
166
|
+
// (a) a leading gate runMutation, (b) a supersede/dedup keyed on a stable namespace,
|
|
167
|
+
// (c) the recovering re-insert loop — AND the marker MUST STATE THE CONVERGENCE
|
|
168
|
+
// explicitly, not merely name the shape (or the carve-out becomes a vocabulary).
|
|
169
|
+
const SHAPE_GATE_REINGEST = "gate-then-idempotent-reingest";
|
|
170
|
+
const REINGEST_SUPERSEDE = /supersede|dedup|find-?or-?create|isLatest|\.unique\s*\(/i;
|
|
171
|
+
const STABLE_KEY = /namespace|docId|content-?hash|by_namespace/i;
|
|
172
|
+
// NB: deliberately EXCLUDES the bare token "reingest" — the shape name itself is
|
|
173
|
+
// "gate-then-idempotent-reingest", so matching "re-?ingest" would let the token satisfy
|
|
174
|
+
// its own convergence sub-condition. Convergence must be stated BEYOND naming the shape.
|
|
175
|
+
const CONVERGENCE_STATED = /converge|one current set|full (?:current )?set|self-?heal|no-?op when already|re-?creates the full/i;
|
|
156
176
|
// Shape-(2) sub-conditions (COND 3): the region must NAME the loop and STATE the
|
|
157
177
|
// write independence — neither is inferable, both are required of the claim.
|
|
158
178
|
const LOOP_NAMED = /\bfor\s*\(|\bfor\s+(?:const|let|var|await)\b|\.forEach\s*\(|\.map\s*\(|\bwhile\s*\(/;
|
|
159
179
|
const INDEPENDENCE_STATED = /no\s+invariant\s+spans|invariant\s+spans\s+no|writes?\s+are\s+independent|independently\s+atomic|no\s+cross-write\s+invariant/i;
|
|
160
180
|
// Shape-(1) sub-condition (Eta REVISE #26, 2026-08-31): "a pre-I/O gate mutation
|
|
161
181
|
// precedes a single atomic write" describes itself CHECKABLY — it is EXACTLY TWO
|
|
162
|
-
// ctx.runMutation calls, the FIRST a gate (require*/assert*/
|
|
182
|
+
// ctx.runMutation calls, the FIRST a gate (require*/assert*/bind*). A shape-1
|
|
163
183
|
// marker on anything else (three calls, an unbounded loop, a first call that is not a
|
|
164
184
|
// gate) is INCOMPLETE and stays non-conforming, exactly as an incomplete shape-2 does
|
|
165
185
|
// — otherwise eleven words in a comment remove a real violation from the #1250 prod
|
|
166
186
|
// gate (abstentions do not block; mechanical_violations is the sole driver), and the
|
|
167
187
|
// mechanical count that gate rests on is no longer honest.
|
|
168
|
-
|
|
188
|
+
// The gate stem excludes `ensure*` — the standard prefix for an UPSERT WRITE helper
|
|
189
|
+
// (ensureUser/ensureWorkspace/ensureRow). Both shapes whose FIRST runMutation is the gate
|
|
190
|
+
// (shape 1 pre-io-gate, shape 3 gate-then-idempotent-reingest) checked the callee NAME, so
|
|
191
|
+
// accepting `ensure*` let a first WRITE renamed the usual way (_insertImportedMemory ->
|
|
192
|
+
// ensureImportedMemory) masquerade as the gate and buy the exemption — removing a real
|
|
193
|
+
// violation from the #1250 prod gate. Fixed at the CLASS (Eta REVISE #27 probe B closed
|
|
194
|
+
// shape 3; this closes the same hole in shape 1, task k179fmje8vb7y0tbjdmxbzg78h8dhj3q):
|
|
195
|
+
// the defect was a gate sub-condition decided by a name stem that idiomatically names
|
|
196
|
+
// writes, so the fix is one narrowed stem set for every gate check. `bind` STAYS
|
|
197
|
+
// (bindOrAssertStorageOwnership is kb.ts's real gate); `require`/`assert` are unambiguous.
|
|
198
|
+
const GATE_CALLEE = /\b(require|assert|bind)\w*/i;
|
|
169
199
|
export function scanR29(files) {
|
|
170
200
|
const scan = emptyScan();
|
|
171
201
|
for (const f of files) {
|
|
@@ -187,11 +217,20 @@ export function scanR29(files) {
|
|
|
187
217
|
// Shape (1) is honoured ONLY as exactly two runMutations whose first is a
|
|
188
218
|
// gate call; shape (2) only when the loop is named and independence stated.
|
|
189
219
|
const shapeGate = count === 2 && GATE_CALLEE.test(firstMutCallee);
|
|
220
|
+
// Shape (3) sub-conditions: a leading gate runMutation, a supersede/dedup on
|
|
221
|
+
// a stable namespace, a re-insert loop, AND an explicit convergence statement.
|
|
222
|
+
const shapeReingest = GATE_CALLEE.test(firstMutCallee) &&
|
|
223
|
+
REINGEST_SUPERSEDE.test(region) &&
|
|
224
|
+
STABLE_KEY.test(region) &&
|
|
225
|
+
LOOP_NAMED.test(region) &&
|
|
226
|
+
CONVERGENCE_STATED.test(region);
|
|
190
227
|
const shapeComplete = shape === SHAPE_PER_ITEM_LOOP
|
|
191
228
|
? LOOP_NAMED.test(region) && INDEPENDENCE_STATED.test(region)
|
|
192
229
|
: shape === SHAPE_PRE_IO_GATE
|
|
193
230
|
? shapeGate
|
|
194
|
-
:
|
|
231
|
+
: shape === SHAPE_GATE_REINGEST
|
|
232
|
+
? shapeReingest
|
|
233
|
+
: false;
|
|
195
234
|
if (shape && shapeComplete) {
|
|
196
235
|
// COND 1: a well-formed marker yields COULD-NOT-JUDGE, never conform —
|
|
197
236
|
// the claim is deferred to the reviewer, who verifies it per site.
|
|
@@ -200,7 +239,26 @@ export function scanR29(files) {
|
|
|
200
239
|
n: firstMut || openLine,
|
|
201
240
|
note: `action ${inAction} issues ${count} ctx.runMutation calls AND carries an atomicity-exception marker claiming shape "${shape}" — ${shape === SHAPE_PER_ITEM_LOOP
|
|
202
241
|
? "the region names its loop and states the per-item writes are independently atomic (no invariant spans two)"
|
|
203
|
-
:
|
|
242
|
+
: shape === SHAPE_GATE_REINGEST
|
|
243
|
+
? "a leading gate runMutation, a supersede/dedup keyed on a stable namespace, and a recovering re-insert loop, with the convergence stated explicitly — a re-ingest of the same stable key converges on one current set"
|
|
244
|
+
: "exactly two runMutations, the first a gate (require*/assert*/bind*) preceding a single atomic write, which R-29's <=1 bar has no room for"}. R-29 refuses (a reviewer verifies the claim per site) — never a silent green (Eta ruling 2026-08-31)`,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
else if (shape === SHAPE_GATE_REINGEST) {
|
|
248
|
+
// Shape (3) claimed but a sub-condition is absent — an incomplete claim does
|
|
249
|
+
// NOT buy could-not-judge (Eta: a shape names a checkable sub-condition, or
|
|
250
|
+
// the carve-out becomes a vocabulary).
|
|
251
|
+
const missing = [
|
|
252
|
+
!GATE_CALLEE.test(firstMutCallee) && "a leading gate runMutation (require*/assert*/bind* — ensure* is an upsert-write stem, excluded here)",
|
|
253
|
+
!REINGEST_SUPERSEDE.test(region) && "a supersede/dedup call",
|
|
254
|
+
!STABLE_KEY.test(region) && "a stable namespace key (namespace/docId/contentHash)",
|
|
255
|
+
!LOOP_NAMED.test(region) && "a re-insert loop (for/for-of/.forEach/.map)",
|
|
256
|
+
!CONVERGENCE_STATED.test(region) && "an explicit convergence statement (converges on one current set / re-ingest / self-heals)",
|
|
257
|
+
].filter(Boolean).join("; ");
|
|
258
|
+
scan.violate.push({
|
|
259
|
+
rel: f.rel,
|
|
260
|
+
n: firstMut || openLine,
|
|
261
|
+
note: `action ${inAction} orchestrates ${count} ctx.runMutation calls with an atomicity-exception "${SHAPE_GATE_REINGEST}" marker that is INCOMPLETE — missing: ${missing}. The marker must state the convergence, not merely name the shape`,
|
|
204
262
|
});
|
|
205
263
|
}
|
|
206
264
|
else if (shape === SHAPE_PRE_IO_GATE) {
|
|
@@ -209,7 +267,7 @@ export function scanR29(files) {
|
|
|
209
267
|
scan.violate.push({
|
|
210
268
|
rel: f.rel,
|
|
211
269
|
n: firstMut || openLine,
|
|
212
|
-
note: `action ${inAction} orchestrates ${count} ctx.runMutation calls with an atomicity-exception "${SHAPE_PRE_IO_GATE}" marker that is INCOMPLETE — this shape is EXACTLY TWO runMutations whose FIRST is a gate (require*/assert*/
|
|
270
|
+
note: `action ${inAction} orchestrates ${count} ctx.runMutation calls with an atomicity-exception "${SHAPE_PRE_IO_GATE}" marker that is INCOMPLETE — this shape is EXACTLY TWO runMutations whose FIRST is a gate (require*/assert*/bind*); here ${count !== 2
|
|
213
271
|
? `there are ${count}, not two`
|
|
214
272
|
: "the first runMutation is not a gate call"}. A gate-then-single-write is checkable; a marker cannot remove a >2-call or loop site from the gate`,
|
|
215
273
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vantageos/backend-doctor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "A conformance instrument that measures the VantagePeers backend against the pinned backend standard. The THIRD doctor built ON the @vantageos/mcp-doctor engine — never a third engine. It consumes runDoctor/renderTable and adds only detectors.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cli.js",
|