@vantageos/backend-doctor 0.1.11 → 0.1.12
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,9 +150,29 @@ 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*\(/;
|
|
@@ -166,6 +186,15 @@ const INDEPENDENCE_STATED = /no\s+invariant\s+spans|invariant\s+spans\s+no|write
|
|
|
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
|
const GATE_CALLEE = /\b(require|assert|ensure|bind)\w*/i;
|
|
189
|
+
// Shape (3) narrows the gate stems: `ensure*` is the standard prefix for an UPSERT
|
|
190
|
+
// WRITE helper (ensureUser/ensureWorkspace/ensureRow), so on the reingest shape — whose
|
|
191
|
+
// FIRST runMutation is the gate — accepting `ensure*` lets a first WRITE renamed the
|
|
192
|
+
// usual way (e.g. _insertImportedMemory -> ensureImportedMemory) masquerade as the gate
|
|
193
|
+
// and buy the exemption, removing a real violation from the #1250 prod gate (Eta REVISE
|
|
194
|
+
// #27, probe B). `bind` STAYS (bindOrAssertStorageOwnership is kb.ts's real gate, the
|
|
195
|
+
// case this shape exists for); `require`/`assert` are unambiguous. Shapes 1/2 keep the
|
|
196
|
+
// broader GATE_CALLEE.
|
|
197
|
+
const GATE_CALLEE_REINGEST = /\b(require|assert|bind)\w*/i;
|
|
169
198
|
export function scanR29(files) {
|
|
170
199
|
const scan = emptyScan();
|
|
171
200
|
for (const f of files) {
|
|
@@ -187,11 +216,20 @@ export function scanR29(files) {
|
|
|
187
216
|
// Shape (1) is honoured ONLY as exactly two runMutations whose first is a
|
|
188
217
|
// gate call; shape (2) only when the loop is named and independence stated.
|
|
189
218
|
const shapeGate = count === 2 && GATE_CALLEE.test(firstMutCallee);
|
|
219
|
+
// Shape (3) sub-conditions: a leading gate runMutation, a supersede/dedup on
|
|
220
|
+
// a stable namespace, a re-insert loop, AND an explicit convergence statement.
|
|
221
|
+
const shapeReingest = GATE_CALLEE_REINGEST.test(firstMutCallee) &&
|
|
222
|
+
REINGEST_SUPERSEDE.test(region) &&
|
|
223
|
+
STABLE_KEY.test(region) &&
|
|
224
|
+
LOOP_NAMED.test(region) &&
|
|
225
|
+
CONVERGENCE_STATED.test(region);
|
|
190
226
|
const shapeComplete = shape === SHAPE_PER_ITEM_LOOP
|
|
191
227
|
? LOOP_NAMED.test(region) && INDEPENDENCE_STATED.test(region)
|
|
192
228
|
: shape === SHAPE_PRE_IO_GATE
|
|
193
229
|
? shapeGate
|
|
194
|
-
:
|
|
230
|
+
: shape === SHAPE_GATE_REINGEST
|
|
231
|
+
? shapeReingest
|
|
232
|
+
: false;
|
|
195
233
|
if (shape && shapeComplete) {
|
|
196
234
|
// COND 1: a well-formed marker yields COULD-NOT-JUDGE, never conform —
|
|
197
235
|
// the claim is deferred to the reviewer, who verifies it per site.
|
|
@@ -200,7 +238,26 @@ export function scanR29(files) {
|
|
|
200
238
|
n: firstMut || openLine,
|
|
201
239
|
note: `action ${inAction} issues ${count} ctx.runMutation calls AND carries an atomicity-exception marker claiming shape "${shape}" — ${shape === SHAPE_PER_ITEM_LOOP
|
|
202
240
|
? "the region names its loop and states the per-item writes are independently atomic (no invariant spans two)"
|
|
203
|
-
:
|
|
241
|
+
: shape === SHAPE_GATE_REINGEST
|
|
242
|
+
? "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"
|
|
243
|
+
: "exactly two runMutations, the first a gate (require*/assert*/ensure*/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)`,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
else if (shape === SHAPE_GATE_REINGEST) {
|
|
247
|
+
// Shape (3) claimed but a sub-condition is absent — an incomplete claim does
|
|
248
|
+
// NOT buy could-not-judge (Eta: a shape names a checkable sub-condition, or
|
|
249
|
+
// the carve-out becomes a vocabulary).
|
|
250
|
+
const missing = [
|
|
251
|
+
!GATE_CALLEE_REINGEST.test(firstMutCallee) && "a leading gate runMutation (require*/assert*/bind* — ensure* is an upsert-write stem, excluded here)",
|
|
252
|
+
!REINGEST_SUPERSEDE.test(region) && "a supersede/dedup call",
|
|
253
|
+
!STABLE_KEY.test(region) && "a stable namespace key (namespace/docId/contentHash)",
|
|
254
|
+
!LOOP_NAMED.test(region) && "a re-insert loop (for/for-of/.forEach/.map)",
|
|
255
|
+
!CONVERGENCE_STATED.test(region) && "an explicit convergence statement (converges on one current set / re-ingest / self-heals)",
|
|
256
|
+
].filter(Boolean).join("; ");
|
|
257
|
+
scan.violate.push({
|
|
258
|
+
rel: f.rel,
|
|
259
|
+
n: firstMut || openLine,
|
|
260
|
+
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
261
|
});
|
|
205
262
|
}
|
|
206
263
|
else if (shape === SHAPE_PRE_IO_GATE) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vantageos/backend-doctor",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
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",
|