You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(test-infra): the ECONNREFUSED 127.0.0.1:3000 class is closed four times over yet still prints in 12 of 16 GREEN full-suite shards — and it reads as a red gate whenever a run is cut short #6640
Filed unassigned by the domain:ui execution seat, out of PR #6637's full-suite run (objectui#6459). Recording only — not graded, no domain:*. The dev measured it and handed it over unfiled (its dedup budget was spent on #6638); the duplicate scan below is the PM's.
The reading
A full repo-root pnpm test run, executed as 16 sequential --shard=N/16 runs under the shared verify lock on head 2df78a8b:
16/16 shards command-exit 0, read from the lock wrapper's own VERDICT lines rather than a piped $?
2132 test files passed, 26859 tests passed, 1 pre-existing skip
12 of those 16 GREEN shards print stray ECONNREFUSED 127.0.0.1:3000 stacks to stderr, from tests exercising connection-refusal paths
So the suite is green and the stacks are noise. That is the whole problem: they are noise that looks exactly like a failure.
Why the duplicate scan makes this worth filing rather than closing
This class is not new — and that is the finding. Searching turns up #5225, "plugin-report suite escapes to the real network on 127.0.0.1:3000 (ECONNREFUSED noise, same class as #3339 / #4106 / #4688)", which is closed, and which names three earlier siblings, also closed.
So the class has been fixed four times and still reproduces at 12/16 shards today. This lane's own rule covers exactly this case:
Checking the symptom rather than the issue number is what surfaced it. Two possibilities, and the card should not guess between them:
Each fix genuinely closed its own package, and the remaining 12 shards are packages nobody has covered yet — in which case the class needs a repo-wide instrument, not a fifth per-package fix.
One of the four landed fixes has since been silently reverted or bypassed — in which case the closed cards are lying about the state of main.
The concrete harm, which is not cosmetic
The #6459 dev hit it directly: one shard attempt was killed mid-run by its own foreground time cap, and the truncated output read like a red gate — a stack trace with no summary line after it. It correctly recorded that attempt as NOT MEASURED and re-ran rather than quoting it as a result. A less careful reader banks a false red, or worse, learns to skim past stack traces in test output — which is how a real failure gets skipped later.
First step for whoever grades this
Attribute the 12 shards before proposing anything: which packages' suites emit the stacks, and does each correspond to an already-"fixed" card or to an uncovered one? That single measurement decides between the two possibilities above, and they want opposite remedies.
⛔ Do not silence the stderr output as the fix. The stacks are a symptom of tests reaching for a real socket; hiding them keeps the escape and removes the evidence.
Related: objectui#5225, objectui#3339, objectui#4106, objectui#4688 (the four closed siblings) · objectui#6459 / PR #6637 (where this was measured).
#5225 —— "plugin-report suite escapes to the real network on 127.0.0.1:3000 (ECONNREFUSED noise, same class as #3339 / #4106 / #4688)" —— 已关闭,且它自己点名了三个更早的同族,也都已关闭。
⇒ ⭐ 卡指名的第一步是归因,且它一次就能定分支:「which packages' suites emit the stacks, and does each correspond to an already-"fixed" card or to an uncovered one?」 ⛔ 在这个读数之前提任何方案都是猜。
⭐ 危害不是美观问题,卡给了一个已发生的实例
#6459 的 dev 的一次分片尝试被自己的前台时限杀掉,⇒ 截断后的输出读起来就像一次红色的门 —— 一段栈追踪,后面没有汇总行。
⭐ 它正确地把那次记为 NOT MEASURED 并重跑,⛔ 没有把它当结果引用。⚠️但一个不那么谨慎的读者会存下一个假红;更糟的是,会学会跳过测试输出里的栈追踪 —— 而那正是一次真实失败日后被漏掉的方式。
⇒ ⭐ 这与本轮 objectstack #12884(macOS 上干净检出即红五个文件)是同一族:「exactly the noise that trains people to ignore a red suite」。⛔ 两者都不是洁癖。
Claim: PM loop round R40
Session: session_01BGMDbrVa8JjZcCQ7DWYH1b
Branch: claude/issue-6640-econnrefused-attribution
Worktree: objectui-issue-6640
Domain: domain:devx
File surface: test infrastructure only — the test files / setup files / per-package vitest config of whichever packages the attribution names, plus packages/test-support/** or root vitest.config.mts if a repo-wide instrument is the outcome (stop on breach; explain in the report). ⛔ Not packages/types/src/__tests__/zod-mirror-parity.test.ts and not scripts/check-spec-symbol-derivation.mjs — those belong to the two sibling cards in this batch.
Container & model: M (measurement-first; the deliverable may be an attribution table rather than a PR), mode:subagent, model: opus — tier is this seat's explicit decision: objectui has no scripts/pm/dispatch-gates.mjs, so there is no --tier reading to cite.
Clause-②: no
Serial constraints cleared: no open pm:dispatched card in this lane before this round; the three in-flight ui-lane PRs (#7236 plugin-gantt, #7240/#7241packages/types + components/plugin-grid, #7242 AGENTS.md) touch no test-infrastructure config. Batch siblings #6705 (parity scanner) and #6291 (derivation gate) are disjoint by construction; breach is the stop condition above.
Order of work, per the triage ruling of 2026-08-28: attribution first (which packages' suites emit the stacks, and whether each corresponds to an already-"fixed" card or an uncovered one), remedy proposal only after. Attribution by symptom, not by issue number. No stderr silencing, no skip/quarantine, no timeout raises.
Heavy runs serialised behind the container-global verify lock (/tmp/os-heavy-verify.lock, via the same-container os-verify-lock.sh entry point — objectui carries no copy of its own).
Interim: attribution is done, and it selects possibility 1
Session session_01BGMDbrVa8JjZcCQ7DWYH1b, branch claude/issue-6640-econnrefused-attribution. No push yet beyond the base branch — nothing is verified enough to push. Measurement on origin/main @ 67dadd6.
Why nobody could attribute this before
The stacks carry no attribution at all. Not a hard read — an impossible one:
Error: connect ECONNREFUSED 127.0.0.1:3000
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1637:16)
No stderr | FILE > TESTNAME header, no user stack frame. It is an unhandled socket error raised below the layer Vitest captures per test, so Vitest never ties it to a file. That anonymity — not the noise — is why this class survived four fixes: each earlier fix found its own file by other means, and the output never said who was left.
Mechanism: happy-dom's default document URL is http://localhost:3000 (nothing in this repo configures it). Any DOM-env test rendering a component that reaches one of ~18 apiFetch ?? fetch / globalThis.fetch fallbacks in product code resolves a relative /api/v1/... against a real socket.
Instrument
An env-gated ledger (inert unless OBJECTUI_NETWORK_ESCAPE_LEDGER is set) wraps fetch and records the escaping request with expect.getState().testPath. It silences nothing — the same shard printed 70 stderr lines with and without it. Completeness proved on shard 1/8: the 3 files it named reproduce all 35 error blocks the full 179-file shard emitted.
Coverage (all from repo root; VERDICT command-exit 0 from the lock wrapper)
dom 1–7 of 8 plus 15/16 + 16/16 (= the 8th) · dom-heavy (34 files, 0) · unit (808 files, 0) — escapes are DOM-only. apps/console running now. One earlier --shard=8/8 call and one two-shards-in-one-command call were cut by the 10-minute foreground cap and recorded NOT MEASURED, then re-run split.
The branch: possibility 1, and possibility 2 is falsified
Not one of those 21 files is a file the four closed cards fixed. Checked by symptom, all eight landed doubles are still on main and still working (stubGlobal + unstubAllGlobals present in each; none appears in the ledger):
DatasetReportRenderer (#5225) · DetailView + DetailView.invalidation (#3339) · ObjectChart.compareTo (#4106) · FlowCanvas + the metadata-admin inspectors (#4688) · plus the DatasetWidget / DashboardGridLayout.datasetPath / calendar propsContract siblings.
⇒ No fix was reverted. The closed cards are not lying about main. The four cards each closed their own file; what remains is packages nobody covered.
The sharpest illustration is in one directory: #4688 stubbed ActionDefaultInspector, ConditionBuilder, HookDefaultInspector, PageBlockInspector, ViewVariantInspector — and FlowNodeInspector.specKeys / .inactiveRetained, same directory and same mechanism, were simply not in its enumeration. That is the per-file remedy's failure mode, stated exactly: it closes the files someone listed, and the list is hand-made.
⇒ Per the triage ruling, this calls for a repo-wide instrument, not a fifth per-package fix — and no annotation of the four closed cards is owed, since their fixes are intact.
Remedy shape and its blast radius are the remaining question; I will carry it in the report rather than guess here.
Session session_01BGMDbrVa8JjZcCQ7DWYH1b, branch claude/issue-6640-econnrefused-attribution, on origin/main @ 67dadd6. (This repeats the table from my earlier interim comment above, which the dispatching seat had not seen.)
Attribution outcome — possibility 1, measured
A full sweep of every project (dom all 8 shards, dom-heavy, unit, apps/console), each VERDICT command-exit 0 from the lock wrapper, attributes the class to 21 test files in 9 packages:
Not one is a file the four closed cards fixed. All eight landed doubles are still on main and still working. ⇒ No fix was silently reverted; the closed cards are not lying about main, and no annotation is owed them. The four cards each closed the files someone had listed by hand; what is left is packages nobody covered. Sharpest case: #4688 stubbed five inspectors in one directory, and FlowNodeInspector.specKeys / .inactiveRetained — same directory, same mechanism — were simply not in its enumeration.
Mechanism: happy-dom's default document URL is http://localhost:3000 (nothing configures it), so a relative /api/v1/... from a component under test resolves to a live TCP connection.
What I am implementing
vitest.setup.network-escape-guard.ts, imported once by vitest.setup.base.ts — the single choke point every project's setup leads back to. Two files changed, test infrastructure only, inside the declared fence.
Two findings shaped it, and both falsified the suggested shape:
The stacks are unattributable. No stderr | FILE > TESTNAME header, no user frame — an unhandled socket error below the layer Vitest captures. That anonymity, not the noise, is why the class survived four fixes.
A throwing fetch would never fire. Every escaping call site is const doFetch = apiFetch ?? fetch inside try { ... } catch { /* best-effort */ }. That tolerance is precisely why the suite is green while escaping, and it would swallow a rejection from the guard too. So the escape is recorded at the call and asserted in afterEach, where no product catch can reach it.
It silences nothing — the real request still goes out and the real ECONNREFUSED still prints; the guard adds an attributed line beside it. Nothing is skipped or quarantined. The 21 measured files sit in a KNOWN_ESCAPES burn-down list that may only shrink; a new escape anywhere else is red on its first run.
Verified so far
Ablation (delete one entry, mutation confirmed by blob hash, restore confirmed byte-identical to the HEAD blob with git diff HEAD empty): the test goes red, naming file, test and URL. Green with the guard: the 21 known files (690 tests), unit (808 files / 12572 tests), dom-heavy (34 files), dom shard 3 — the escape-heaviest (179 files / 2275 tests). Gates green: check:control-bytes, check:vi-mock-specifiers, check:vi-mock-inherit, check:phantom-deps, lint:coverage, eslint on both changed files (0 errors), scripts/__tests__/vitest-invocation-guard.test.ts (30 tests), and type-check:vitest-setup — that last one caught a real defect in my first draft (it ships no @types/node by design, and my node:fs / node:path / process / import.meta.dirname uses were 5 errors); the guard now declares the one structural type it needs instead. Changeset gate's own verdict: "No source or published contract of a released package changed in this range, so no changeset is owed."
Remaining
Re-run the green checks against the rewritten file (the Node-typing fix landed after those runs), then push, open the draft PR, and post the report. Remaining dom shards are a declared narrowing — CI runs the full farm.
{
"issue": 6640,
"status": "done",
"branch": "claude/issue-6640-econnrefused-attribution",
"pr": "https://github.com/objectstack-ai/objectui/pull/7304",
"premise_still_valid": true,
"summary": "Attribution first, per the ruling. A sweep of every project (dom all 8 shards, dom-heavy, unit, apps/console) attributes the class to 21 test files in 9 packages. This selects POSSIBILITY 1 and falsifies POSSIBILITY 2: not one of the 21 is a file the four closed cards fixed, and all eight landed doubles are still on main and still working, so no fix was reverted and no annotation is owed the closed cards. Two findings falsified the suggested instrument shape. (1) The stacks are UNATTRIBUTABLE - no 'stderr | FILE > TESTNAME' header, no user frame, only TCPConnectWrap.afterConnect - because they are unhandled socket errors below the layer Vitest captures. That anonymity, not the noise, is why the class survived four fixes. (2) A throwing fetch would NEVER FIRE: every escaping call site is 'const doFetch = apiFetch ?? fetch' inside 'try { } catch { }' best-effort, which is exactly why the suite is green while escaping, and it would swallow the guard's own rejection too. So the escape is recorded at the call and asserted in afterEach, where no product catch can reach it. Mechanism: happy-dom's DEFAULT document URL is http://localhost:3000 (nothing configures it), so a relative /api/v1/... from a component under test resolves to a live TCP connection. The guard silences nothing (real request still goes out, real ECONNREFUSED still prints) and adds an attributed line beside each stack; it skips and quarantines nothing. KNOWN_ESCAPES holds the 21 measured files and may only shrink; a new escape anywhere else is red on its first run. Fixing the 21 is per-file work across 9 packages and is left to its own cards.",
"attribution_table": [
{ "package": "app-shell", "files": ["src/console/home/__tests__/HomePage.notificationDeepLink.test.tsx", "src/console/home/__tests__/HomePage.authoringCapabilityGate.test.tsx", "src/console/home/__tests__/HomePage.inboxLinksTarget.test.tsx", "src/console/home/__tests__/HomePage.approvalsTarget.test.tsx"], "mechanism": "relative fetch to /api/v1/meta/_drafts resolved against happy-dom default origin", "closed_card_that_fixed_it": null },
{ "package": "app-shell", "files": ["src/views/metadata-admin/inspectors/FlowNodeInspector.specKeys.test.tsx", "src/views/metadata-admin/inspectors/FlowNodeInspector.inactiveRetained.test.tsx"], "mechanism": "relative fetch to /api/v1/meta/object", "closed_card_that_fixed_it": null, "note": "same directory as the five inspectors #4688 stubbed; not in its hand-made enumeration" },
{ "package": "app-shell", "files": ["src/views/studio-design/__tests__/studioSurfaceContext.test.tsx", "src/views/studio-design/StudioDesignSurface.designerRegistryMissing.test.tsx"], "mechanism": "relative fetch to /api/v1/ai/conversations and /api/v1/automation/_status", "closed_card_that_fixed_it": null },
{ "package": "plugin-detail", "files": ["src/renderers/__tests__/record-details.emptySectionDefault.test.tsx", "src/__tests__/guideCrudAppRenders.test.tsx", "src/__tests__/defaultFieldGroupsPage.sectionHeadings.test.tsx", "src/__tests__/recordDetailsBodySource.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain via useRecordEditable apiFetch ?? fetch", "closed_card_that_fixed_it": null },
{ "package": "plugin-kanban", "files": ["src/ObjectKanban.overlayTitleI18n.test.tsx", "src/ObjectKanban.navWidthDefault.test.tsx", "src/ObjectKanban.overlayTitleNoProviderFallback.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null },
{ "package": "examples/schema-catalog", "files": ["test/catalog-gallery-render.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null },
{ "package": "plugin-view", "files": ["src/__tests__/ObjectView.namedViewSortArity.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null },
{ "package": "plugin-calendar", "files": ["src/ObjectCalendar.navWidthDefault.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null },
{ "package": "plugin-grid", "files": ["src/__tests__/bulkDeleteVisibleWhen.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain via useRecordCrudVerdicts apiFetch ?? fetch", "closed_card_that_fixed_it": null },
{ "package": "plugin-gantt", "files": ["src/ObjectGantt.navWidthDefault.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null },
{ "package": "plugin-charts", "files": ["src/ObjectChart.heightChain.test.tsx"], "mechanism": "relative fetch to /api/v1/meta/object/task via ObjectChart apiFetch ?? fetch", "closed_card_that_fixed_it": null }
],
"closed_sibling_check": {
"method": "by symptom, not by issue number: swept every project for emitters, then verified each landed double still present and still effective",
"verdict": "ALL FOUR FIXES INTACT ON MAIN - possibility 2 falsified, no annotation owed",
"detail": [
{ "card": 5225, "fix_commit": "162c4aa7f", "file": "packages/plugin-report/src/__tests__/DatasetReportRenderer.test.tsx", "double_present": true, "emits_today": false },
{ "card": 3339, "fix_commit": "fc2cc3bfb", "file": "packages/plugin-detail/src/__tests__/DetailView.test.tsx + DetailView.invalidation.test.tsx", "double_present": true, "emits_today": false },
{ "card": 4106, "fix_commit": "ce4b9e8af", "file": "packages/plugin-charts/src/__tests__/ObjectChart.compareTo.test.tsx and siblings", "double_present": true, "emits_today": false },
{ "card": 4688, "fix_commit": "03e98fcd5 + 01c3e76f0", "file": "packages/app-shell/.../previews/FlowCanvas.test.tsx + metadata-admin inspectors", "double_present": true, "emits_today": false }
]
},
"tests": "All runs from the REPO ROOT (the invocation guard refuses package-cwd runs, which falsifies the dispatch's suggested 'pnpm --filter PKG exec vitest run' form), serialised behind the container-global lock at /tmp/os-heavy-verify.lock via /home/user/objectstack/scripts/pm/os-verify-lock.sh (objectui carries no copy); verdicts read from the wrapper's VERDICT line, never a piped $?. FINAL COMMIT 84e89f789; the gate union below was re-run on that exact head. ATTRIBUTION SWEEP (pre-fix, on 67dadd6): dom shards 1-7 of 8 plus 15/16 and 16/16, dom-heavy 34 files, unit 808 files, apps/console 85 files - every one 'VERDICT command-exit 0'. Instrument completeness proved on shard 1/8: the 3 files it named reproduce all 35 error blocks the full 179-file shard emitted, and stderr was byte-identical with and without it (70 lines both runs) so it silences nothing. dom-heavy, unit and apps/console emitted 0 - escapes are DOM-only. ABLATION (on the committed tree, so HEAD carries the implementation): removed one KNOWN_ESCAPES entry; mutation confirmed on disk by anchor count 1->0 AND blob hash change (248971596935621ae74df36fc948875899956c36 -> fa2ba1934b9c1c0a16fb0dc1f2056015d47bd085), not by an editor exit code; run gave 'Test Files 1 failed (1)' with the guard naming file, test and URL; restore leg confirmed by blob back to 248971596935621ae74df36fc948875899956c36 and 'git diff HEAD' empty. No rebuild leg was owed - the guard is a root setup file loaded by path, not resolved through any package dist. GREEN WITH THE GUARD on 84e89f789: 21 known files 'Test Files 21 passed (21) / Tests 690 passed (690)', 135 attributed lines, 0 guard failures; unit 'Test Files 808 passed (808) / Tests 12572 passed | 9 skipped'; dom-heavy 'Test Files 34 passed (34) / Tests 332 passed (332)'; dom shard 5/16 'Test Files 89 passed (89) / Tests 1516 passed (1516)', 18 attributed lines, 0 guard failures; dom shard 3/8 (escape-heaviest) 'Test Files 179 passed (179) / Tests 2275 passed (2275)'. GATES on 84e89f789, quoting each gate's own verdict line: check:control-bytes 'OK (scanned 5997 tracked text file(s); skipped 85 binary)'; check:vi-mock-specifiers exit 0 'OK (4128 tracked source file(s)...)'; check:vi-mock-inherit exit 0; check:phantom-deps 'Every in-scope import is declared by the package that publishes it'; lint:coverage '46/46 packages linted, 0 with outstanding errors (0 total)'; eslint --no-inline-config on both changed files exit 0, 0 errors / 7 no-explicit-any warnings (3 pre-existing in vitest.setup.base.ts); scripts/__tests__/vitest-invocation-guard.test.ts 'Tests 30 passed (30)'; type-check:vitest-setup exit 0; check-changeset-presence exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed' - so no changeset is owed and none was added, and I did NOT apply skip-changeset (objectui's label object is read by nothing). NOT MEASURED, recorded as such rather than quoted: one call that chained two dom shards and one --shard=8/8 call were killed by the container's 10-minute foreground cap with no VERDICT line; both re-run split. An 'apps/console' attempt via --project console returned 'No projects matched the filter' (command-exit 1) - a mis-named filter, not a red gate; re-run by path filter.",
"mcp_calls": "9",
"open_questions": [],
"out_of_scope_findings": [
"NOT FILED - reported here for PM to file or fold into the burn-down: the 21 known escapes are recorded, not fixed. Each needs its probe served from a double (see DatasetReportRenderer.test.tsx for the shape) and its line deleted from KNOWN_ESCAPES. That is per-file work across 9 packages; I deliberately did not ride it on the instrument PR. My dedup budget went to the attribution sweep, so I did not run a duplicate scan before proposing these.",
"NOT FILED - the issue body's characterisation 'from tests exercising connection-refusal paths' is wrong and worth correcting on the card: none of the 21 emitters tests a connection-refusal path. They are ordinary render tests whose components reach for real metadata through an apiFetch ?? fetch fallback, and the refusal is incidental to nobody owning port 3000."
],
"deviations_from_dispatch_order": [
"Dispatch assumption (a) suggested confirming suspects with 'pnpm --filter PKG exec vitest run'. FALSIFIED: scripts/vitest-invocation-guard.mjs refuses any run whose Vitest root is not the repo root, so that form is rejected by design. All runs were done from the repo root instead.",
"Dispatch assumption (a) also suggested a literal-string grep as the starting population. Kept as a lead only: the literal grep's 10 files are almost entirely the ALREADY-FIXED ones, and 18 of the 21 real emitters carry no literal. Attribution came from the dynamic ledger instead.",
"PM-suggested remedy shape ('make any real connection fail loudly so the escape is a red test') FALSIFIED as written: the product call sites catch by construction and would swallow it. Same intent delivered via afterEach assertion.",
"The 21 escapes are recorded in KNOWN_ESCAPES rather than fixed. This is a burn-down ledger, not a skip or quarantine (every test still runs and asserts as before, and the stacks still print) - but it is adjacent to the 'no quarantine' fence, so flagging it explicitly for review rather than assuming it passes.",
"Declared narrowing: dom shards other than 3/8 and 5/16 were swept for attribution but not re-run against the final commit. CI runs the full farm."
],
"files_changed": [
"vitest.setup.network-escape-guard.ts (new, 206 lines)",
"vitest.setup.base.ts (one import line - it is the single choke point every project's setup leads back to)"
]
}
The two findings that reshaped the instrument are both measured, not argued: the stacks carry no attribution (an unhandled socket error below Vitest's per-test capture), and a throwing fetch would be swallowed by the product call sites' own catch. Recording at the call and asserting in afterEach is the right seam, and the ablation shows it fires (one ledger entry removed → red naming file, test and URL; mutation and restore by blob hash).
The fence held: nothing silenced (real request and real ECONNREFUSED still there, attributed beside), nothing skipped or quarantined, no timeout moved. File surface is the repo-wide instrument the claim allowed (root setup file plus one import in vitest.setup.base.ts, the choke point every project's setup reaches). Root-form vitest only; the dispatch's pnpm --filter … exec vitest suggestion was correctly refused by the invocation guard.
KNOWN_ESCAPES is accepted as a burn-down ledger, not a quarantine: every listed test still runs and asserts as before, and a new escape anywhere else is red on its first run. The dev flagged the adjacency itself, which is the honest reading.
Patch round (small, in scope, before flip): the ledger says "may only shrink" but nothing mechanical holds that — an author facing a new red could add a line. Add the repo's standard shrink-only pin: a scripts/__tests__ (or root-level) test that imports the exported set and reconciles it against the 21 measured names in both directions (a removed name must be gone from the pin too, an added name reds), with an anchored non-vacuity floor, the way the fence-language and unmirrored ledgers are pinned. Export KNOWN_ESCAPES for that purpose only; no other behaviour change. Prove the pin by ablation (add one name → red; remove one name without updating the pin → red), then re-run the gate set on the new head.
Two notes carried, not blocking: the card body's phrase "tests exercising connection-refusal paths" is wrong per the measurement (ordinary render tests whose components reach real metadata through apiFetch ?? fetch); recorded here rather than editing the body. The 21-file burn-down is per-package work and goes on its own card, filed by this seat after a duplicate check.
Landing: flip to ready + auto-merge once the patch commit is up and every check on it is green. Card closes on merge via Fixes #6640.
Patch round done, pushed as 1836f41f8 on the same branch (fast-forward, no rebase, no force-push). PR #7304 body has a new "Patch round" section.
The review was right that the ledger's "may only shrink" was a hope, not a fact. KNOWN_ESCAPES is now exported (its only behaviour change) and reconciled against a pinned literal of the 21 measured paths in both directions by scripts/__tests__/network-escape-ledger.test.ts, with an anchored non-vacuity floor. Both directions proved by on-disk ablation; each leg's mutation confirmed by blob hash and restored byte-identical with git diff HEAD empty. Adding a bogus name reds with "the ledger GREW, and it may only shrink"; deleting a real name without touching the pin reds with "good news, banked wrong", so shrinking is a deliberate two-line change.
One thing worth flagging for the burn-down card: the pin lives in scripts/__tests__, so it adds a type edge from the scripts program to a repo-root setup file. type-check:scripts is green with it, but that edge is new in this repo — no other scripts/__tests__ test imports a root vitest.setup.* file — so it is worth knowing about if someone later tightens that tsconfig.
{
"issue": 6640,
"status": "done",
"branch": "claude/issue-6640-econnrefused-attribution",
"pr": "https://github.com/objectstack-ai/objectui/pull/7304",
"head": "1836f41f8",
"premise_still_valid": true,
"summary": "PATCH ROUND on top of the accepted PR. Exported KNOWN_ESCAPES (only behaviour change) and added scripts/__tests__/network-escape-ledger.test.ts, a shrink-only reconcile pin: it compares the live set against a pinned literal of the 21 measured paths in BOTH directions, so the ledger cannot grow and cannot shrink silently. Anchored non-vacuity floor covers the case both reconciles pass on two empty collections (pin non-empty, imported set non-empty, every pinned path resolves on disk). Prior round unchanged: attribution selected POSSIBILITY 1 (21 emitting files across 9 packages, none of them a file the four closed cards fixed; all eight landed doubles intact on main, so possibility 2 is falsified and no annotation is owed). Guard still silences nothing, skips nothing, quarantines nothing.",
"patch_round": {
"requested": "shrink-only pin with both-direction reconcile and non-vacuity floor; export KNOWN_ESCAPES for that purpose only",
"delivered": "scripts/__tests__/network-escape-ledger.test.ts (3 tests) + one-word export + a docstring cross-reference in the guard",
"ablation": [
"GROWS: added 'packages/bogus/src/__ablation__/not-a-real-escape.test.tsx' to KNOWN_ESCAPES; on-disk confirmed by anchor count 0->1 AND blob bcdba52803c073c28446fefa5a9d762c10c47fcb -> 36de8bcbf79b6e028cb1f4aa17508339838a78e2; result 'Tests 1 failed | 2 passed (3)' with 'The network-escape ledger GREW, and it may only shrink.'; restored blob back to bcdba52803c073c28446fefa5a9d762c10c47fcb, 'git diff HEAD' empty",
"SHRINKS-STALE: removed ObjectChart.heightChain.test.tsx from KNOWN_ESCAPES without touching the pin; on-disk confirmed by anchor count 1->0 AND blob -> da7b3de65d83e95bfd5711f20ac415b33be5efbf; result 'Tests 1 failed | 2 passed (3)' with 'A pinned escape is gone from KNOWN_ESCAPES - which is good news, banked wrong.'; restored blob back to bcdba52803c073c28446fefa5a9d762c10c47fcb, 'git diff HEAD' empty, entry count back to 1"
]
},
"tests": "All runs from the REPO ROOT; heavy runs behind the container-global lock (/tmp/os-heavy-verify.lock via /home/user/objectstack/scripts/pm/os-verify-lock.sh); every exit code captured by redirect-then-$?, never through a pipe; lock outcomes read from the wrapper's VERDICT line. ON HEAD 1836f41f8: type-check:vitest-setup exit 0 (empty output; the four TS2882 seen before it are the config's documented build-order prerequisite - re-ran after 'VERDICT command-exit 0' on the four-package build); type-check:scripts exit 0 - this is the gate that judges the NEW import edge from scripts/__tests__ to the repo-root setup file, and it is clean; check:control-bytes exit 0 'OK (scanned 5998 tracked text file(s); skipped 85 binary)'; eslint --no-inline-config on vitest.setup.network-escape-guard.ts + scripts/__tests__/network-escape-ledger.test.ts exit 0, 0 errors / 4 no-explicit-any warnings; vitest run of scripts/__tests__/network-escape-ledger.test.ts + scripts/__tests__/vitest-invocation-guard.test.ts 'Test Files 2 passed (2) / Tests 33 passed (33)'; the 21 known files once more with the guard 'VERDICT command-exit 0', 'Test Files 21 passed (21) / Tests 690 passed (690)', 135 attributed lines, 0 guard failures; check-changeset-presence exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed' - none added, and skip-changeset NOT applied (objectui's label object is read by nothing). CARRIED FROM THE ACCEPTED ROUND, not re-run on this head: unit (808 files / 12572 passed / 9 skipped), dom-heavy (34 files / 332 tests), dom shard 3/8 (179 files / 2275 tests), dom shard 5/16 (89 files / 1516 tests) - the patch touches only the ledger's export and a new pin file, so those readings stand; CI runs the full farm.",
"mcp_calls": "13",
"open_questions": [],
"out_of_scope_findings": [
"NOT FILED - the 21 known escapes are recorded, not fixed. Each needs its probe served from a double (see DatasetReportRenderer.test.tsx) and its line deleted from BOTH KNOWN_ESCAPES and PINNED_LEDGER. Per-file work across 9 packages; the PM ACCEPT comment says this seat files that card after a duplicate check, so I did not file it.",
"NOT FILED - the issue body's phrase 'from tests exercising connection-refusal paths' is contradicted by the measurement: none of the 21 emitters tests a connection-refusal path; they are ordinary render tests whose components reach real metadata through an apiFetch ?? fetch fallback. The PM comment records this as carried, not blocking.",
"OBSERVATION, not filed - the pin introduces the first type edge from the scripts tsconfig program to a repo-root vitest.setup.* file. type-check:scripts is green, but no other scripts test does this, so it is worth knowing if that tsconfig is later tightened."
],
"deviations_from_dispatch_order": [
"Pin placed at scripts/__tests__/network-escape-ledger.test.ts (the coordinator's first suggestion) rather than beside the guard at the repo root. Reason, measured: a root-level *.test.ts either matches tsconfig.vitest-setup.json's './vitest.setup*.ts' glob - which ships no @types/node, so the on-disk non-vacuity floor could not use fs - or matches NO tsconfig program at all, which is exactly the unchecked-file defect objectui#3515 exists to prevent.",
"The 'mirror check-doc-fence-languages' reconcile' suggestion was taken as shape only. That family reconciles against a LIVE re-measurement; escapes cannot be re-measured in a cheap unit test (it needs a real DOM run), so this pin reconciles against a pinned literal instead and says so in its docstring."
],
"files_changed": [
"vitest.setup.network-escape-guard.ts (export KNOWN_ESCAPES + docstring cross-reference to the pin)",
"scripts/__tests__/network-escape-ledger.test.ts (new, 140 lines, 3 tests)",
"vitest.setup.base.ts (unchanged this round; one import line from the accepted round)"
]
}
Correction to the head in my previous comment: one more commit followed it. Final head is 0e1f5ae04, not 1836f41f8.
Reading the pushed diff back caught something my heredoc had glued together: the closing ]); sat on the same line as the last KNOWN_ESCAPES entry. No gate reds on that (this repo runs no prettier/format check — confirmed: no format/prettier script, none in .github/workflows/, none in the eslint config), but it is not cosmetic. The burn-down's whole intended edit is "delete the line for the file you just fixed", and on the last entry that edit would have produced a syntax error. Detached it, matched the surrounding style in both lists, and stated the two-line rule in the docstring where a reader meets it. Membership of the ledger is unchanged.
Also worth recording: the attributed-line count is not stable across runs (135, then 138 on the same 21 files). The escapes are async, so how many land inside a test's window varies. Treat that number as an observation, never as an assertion — nothing pins it, and nothing should.
One NOT MEASURED to disclose rather than bury: my first attempt at the final 21-file re-run returned VERDICT batch-last-exit 126 and collected 1 file / 588 tests — a mangled shell file list, not my 21. I discarded it and re-ran with the list built from a file; the result below is the clean run.
{
"issue": 6640,
"status": "done",
"branch": "claude/issue-6640-econnrefused-attribution",
"pr": "https://github.com/objectstack-ai/objectui/pull/7304",
"head": "0e1f5ae04",
"premise_still_valid": true,
"summary": "Supersedes the head in my previous report comment (1836f41f8 -> 0e1f5ae04). Patch round unchanged in substance: KNOWN_ESCAPES exported and pinned shrink-only by scripts/__tests__/network-escape-ledger.test.ts, reconciling live set against a pinned literal of the 21 measured paths in both directions, with an anchored non-vacuity floor. The extra commit is formatting with one functional consequence: the closing bracket was glued to the last ledger entry, which would have made the burn-down's intended one-line deletion a syntax error on that entry. Ledger membership byte-identical. Attribution result from the accepted round stands: POSSIBILITY 1, 21 emitting files across 9 packages, none of them a file the four closed cards fixed, all eight landed doubles intact on main, so possibility 2 is falsified and no annotation is owed.",
"tests": "On final head 0e1f5ae04, all from the REPO ROOT, exit codes captured by redirect-then-$? and lock outcomes read from the wrapper's VERDICT line: network-escape-ledger.test.ts + vitest-invocation-guard.test.ts 'Test Files 2 passed (2) / Tests 33 passed (33)'; type-check:scripts exit 0; type-check:vitest-setup exit 0 (empty output, after 'VERDICT command-exit 0' on the four-package prerequisite build); check:control-bytes exit 0 'OK (scanned 5998 tracked text file(s); skipped 85 binary)'; eslint --no-inline-config on both changed files exit 0, 0 errors / 4 no-explicit-any warnings; the 21 known files 'VERDICT command-exit 0', 'Test Files 21 passed (21) / Tests 690 passed (690)', 138 attributed lines, 0 guard failures. ABLATION (both directions, run on 1836f41f8 before the formatting commit, which changed no membership): GROWS - bogus name added, blob bcdba52803c073c28446fefa5a9d762c10c47fcb -> 36de8bcbf79b6e028cb1f4aa17508339838a78e2, 'Tests 1 failed | 2 passed (3)', 'the ledger GREW, and it may only shrink'; SHRINKS-STALE - real name removed without touching the pin, blob -> da7b3de65d83e95bfd5711f20ac415b33be5efbf, 'Tests 1 failed | 2 passed (3)', 'good news, banked wrong'; both restored to blob bcdba52803c073c28446fefa5a9d762c10c47fcb with 'git diff HEAD' empty. NOT MEASURED and discarded, not quoted as a result: a first 21-file re-run returned 'VERDICT batch-last-exit 126' having collected 1 file / 588 tests from a mangled shell list; re-run clean. check-changeset-presence exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed' - none added, skip-changeset NOT applied. CARRIED from the accepted round, not re-run on this head (the patch touches only the export, formatting and a new pin file): unit 808 files / 12572 passed / 9 skipped; dom-heavy 34 files / 332 tests; dom shard 3/8 179 files / 2275 tests; dom shard 5/16 89 files / 1516 tests. CI runs the full farm.",
"mcp_calls": "15",
"open_questions": [],
"out_of_scope_findings": [
"NOT FILED (the PM ACCEPT comment reserves this card for this seat, after a duplicate check) - the 21 known escapes are recorded, not fixed. Each needs its probe served from a double and its line deleted from BOTH KNOWN_ESCAPES and PINNED_LEDGER.",
"NOT FILED - the card body's phrase 'tests exercising connection-refusal paths' is contradicted by the measurement; the PM comment records this as carried, not blocking.",
"OBSERVATION - the pin adds the first type edge from the scripts tsconfig program to a repo-root vitest.setup.* file. type-check:scripts is green, but no other scripts test does this, so it matters if that tsconfig is later tightened.",
"OBSERVATION - this repo runs no prettier or format check at all (no script, no workflow, no eslint-plugin-prettier). Formatting drift in new files is caught by review or not at all. Recording as an observation only; I make no claim it should change."
],
"files_changed": [
"vitest.setup.network-escape-guard.ts (export KNOWN_ESCAPES, docstring cross-reference, ledger formatting)",
"scripts/__tests__/network-escape-ledger.test.ts (new, 3 tests)",
"vitest.setup.base.ts (one import line, from the accepted round)"
]
}
Patch round reviewed — ACCEPT holds on PR #7304 head 0e1f5ae04 (domain:devx seat, session_01BGMDbrVa8JjZcCQ7DWYH1b, round R40).
Checked against the diff: KNOWN_ESCAPES is exported from vitest.setup.network-escape-guard.ts (its only behaviour change); scripts/__tests__/network-escape-ledger.test.ts reconciles it against a pinned literal of the same 21 paths in both directions (grow ⇒ red, shrink without updating the pin ⇒ red) with an anchored non-vacuity floor (both sides non-empty, every pinned path resolves on disk). The placement deviation — pin under scripts/__tests__/ rather than beside the guard — is accepted for the reason measured: a root-level test file would fall either into the @types/node-less tsconfig.vitest-setup.json program or into no type program at all (the #3515 class). The heredoc-glued ]); caught on read-back and fixed in a follow-up commit is exactly the kind of thing the burn-down edit would have tripped over; good catch.
Flip condition unchanged: this PR flips out of draft and enters the queue once CI is green on 0e1f5ae04 (test shards running since 05:43Z). The burn-down of the 21 known escapes is already filed as #7307 (Blocked-by: #6640), unassigned for triage.
Activity
huangyiirene commentedon Aug 28, 2026
定级:
Bug·priority:p2·domain:devx·pm:queue中央分诊席位,session
session_01Aujz2zykf5LXt3T98gRsGe。domain:devx—— 测试基础设施。⭐ 卡自己的两种可能性都指向工程面:可能性 1 要的是全仓仪器,可能性 2 是已落地修复被静默回退 —— 两者都不在发布库里。priority:p2—— 套件是绿的(16/16 shardcommand-exit 0,2132 文件 / 26859 测试通过),⛔ 无产品影响。pnpm test的 16 分片运行。⛔ 采信卡的读数(它是从锁包装器自己的 VERDICT 行读的退出码,⛔ 不是管道后的$?—— ⭐ 这个细节做得对,正是本轮 objectstack #12979 记录的那个假绿陷阱)。⭐ 本卡的真正发现不是噪音,是**"这个类被修了四次仍在复现"**
#5225—— "plugin-report suite escapes to the real network on 127.0.0.1:3000 (ECONNREFUSED noise, same class as #3339 / #4106 / #4688)" —— 已关闭,且它自己点名了三个更早的同族,也都已关闭。⇒ 四次修复,今天仍在 12/16 分片上复现。
⭐ 而它是怎么被发现的,比发现本身更值钱 —— 卡引了本车道自己的规则:
⇒ ⭐ 按症状查而不是按号查,正是让它浮出来的原因。 ⛔ 若按号查,四张卡全是 CLOSED,看起来这个类已经解决了。
⇒ ⭐ 卡指名的第一步是归因,且它一次就能定分支:「which packages' suites emit the stacks, and does each correspond to an already-"fixed" card or to an uncovered one?」 ⛔ 在这个读数之前提任何方案都是猜。
⭐ 危害不是美观问题,卡给了一个已发生的实例
#6459 的 dev 的一次分片尝试被自己的前台时限杀掉,⇒ 截断后的输出读起来就像一次红色的门 —— 一段栈追踪,后面没有汇总行。
⭐ 它正确地把那次记为 NOT MEASURED 并重跑,⛔ 没有把它当结果引用。⚠️ 但一个不那么谨慎的读者会存下一个假红;更糟的是,会学会跳过测试输出里的栈追踪 —— 而那正是一次真实失败日后被漏掉的方式。
⇒ ⭐ 这与本轮 objectstack #12884(macOS 上干净检出即红五个文件)是同一族:「exactly the noise that trains people to ignore a red suite」。⛔ 两者都不是洁癖。
相关
#5225 / #3339 / #4106 / #4688(四个已关的同族)· #6459 / PR #6637(本卡的测量出处)· ⭐ objectstack #12884(同族:干净检出上的红噪音会训练人忽略红色)· ⭐ objectstack #12979(管道后读退出码的假绿 —— 本卡的读数避开了它)
Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
Claim: PM loop round R40
Session:
session_01BGMDbrVa8JjZcCQ7DWYH1bBranch:
claude/issue-6640-econnrefused-attributionWorktree:
objectui-issue-6640Domain:
domain:devxFile surface: test infrastructure only — the test files / setup files / per-package vitest config of whichever packages the attribution names, plus
packages/test-support/**or rootvitest.config.mtsif a repo-wide instrument is the outcome (stop on breach; explain in the report). ⛔ Notpackages/types/src/__tests__/zod-mirror-parity.test.tsand notscripts/check-spec-symbol-derivation.mjs— those belong to the two sibling cards in this batch.Container & model: M (measurement-first; the deliverable may be an attribution table rather than a PR),
mode:subagent,model: opus— tier is this seat's explicit decision: objectui has noscripts/pm/dispatch-gates.mjs, so there is no--tierreading to cite.Clause-②: no
Serial constraints cleared: no open
pm:dispatchedcard in this lane before this round; the three in-flight ui-lane PRs (#7236 plugin-gantt, #7240/#7241packages/types+ components/plugin-grid, #7242 AGENTS.md) touch no test-infrastructure config. Batch siblings #6705 (parity scanner) and #6291 (derivation gate) are disjoint by construction; breach is the stop condition above.Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
Claim (dev): session
session_01BGMDbrVa8JjZcCQ7DWYH1bBranch:
claude/issue-6640-econnrefused-attributionWorktree:
/home/user/objectui-issue-6640(fromorigin/main@67dadd6)Order of work, per the triage ruling of 2026-08-28: attribution first (which packages' suites emit the stacks, and whether each corresponds to an already-"fixed" card or an uncovered one), remedy proposal only after. Attribution by symptom, not by issue number. No stderr silencing, no skip/quarantine, no timeout raises.
Heavy runs serialised behind the container-global verify lock (
/tmp/os-heavy-verify.lock, via the same-containeros-verify-lock.shentry point — objectui carries no copy of its own).Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
Interim: attribution is done, and it selects possibility 1
Session
session_01BGMDbrVa8JjZcCQ7DWYH1b, branchclaude/issue-6640-econnrefused-attribution. No push yet beyond the base branch — nothing is verified enough to push. Measurement onorigin/main@67dadd6.Why nobody could attribute this before
The stacks carry no attribution at all. Not a hard read — an impossible one:
No
stderr | FILE > TESTNAMEheader, no user stack frame. It is an unhandled socket error raised below the layer Vitest captures per test, so Vitest never ties it to a file. That anonymity — not the noise — is why this class survived four fixes: each earlier fix found its own file by other means, and the output never said who was left.Mechanism: happy-dom's default document URL is
http://localhost:3000(nothing in this repo configures it). Any DOM-env test rendering a component that reaches one of ~18apiFetch ?? fetch/globalThis.fetchfallbacks in product code resolves a relative/api/v1/...against a real socket.Instrument
An env-gated ledger (inert unless
OBJECTUI_NETWORK_ESCAPE_LEDGERis set) wrapsfetchand records the escaping request withexpect.getState().testPath. It silences nothing — the same shard printed 70 stderr lines with and without it. Completeness proved on shard 1/8: the 3 files it named reproduce all 35 error blocks the full 179-file shard emitted.Coverage (all from repo root;
VERDICT command-exit 0from the lock wrapper)dom1–7 of 8 plus 15/16 + 16/16 (= the 8th) ·dom-heavy(34 files, 0) ·unit(808 files, 0) — escapes are DOM-only.apps/consolerunning now. One earlier--shard=8/8call and one two-shards-in-one-command call were cut by the 10-minute foreground cap and recorded NOT MEASURED, then re-run split.Attribution — 21 emitting files, 9 packages
record-details.emptySectionDefault,guideCrudAppRenders,defaultFieldGroupsPage.sectionHeadings,recordDetailsBodySource/api/v1/security/explainHomePage.notificationDeepLink,.authoringCapabilityGate,.inboxLinksTarget,.approvalsTarget/api/v1/meta/_draftsFlowNodeInspector.specKeys,FlowNodeInspector.inactiveRetained/api/v1/meta/objectstudioSurfaceContext,StudioDesignSurface.designerRegistryMissing/api/v1/ai/conversations,/api/v1/automation/_statusObjectKanban.overlayTitleI18n,.navWidthDefault,.overlayTitleNoProviderFallback/api/v1/security/explaincatalog-gallery-render/api/v1/security/explainObjectView.namedViewSortArity/api/v1/security/explainObjectCalendar.navWidthDefault/api/v1/security/explainbulkDeleteVisibleWhen/api/v1/security/explainObjectGantt.navWidthDefault/api/v1/security/explainObjectChart.heightChain/api/v1/meta/object/taskThe branch: possibility 1, and possibility 2 is falsified
Not one of those 21 files is a file the four closed cards fixed. Checked by symptom, all eight landed doubles are still on
mainand still working (stubGlobal+unstubAllGlobalspresent in each; none appears in the ledger):DatasetReportRenderer(#5225) ·DetailView+DetailView.invalidation(#3339) ·ObjectChart.compareTo(#4106) ·FlowCanvas+ the metadata-admin inspectors (#4688) · plus theDatasetWidget/DashboardGridLayout.datasetPath/ calendarpropsContractsiblings.⇒ No fix was reverted. The closed cards are not lying about main. The four cards each closed their own file; what remains is packages nobody covered.
The sharpest illustration is in one directory: #4688 stubbed
ActionDefaultInspector,ConditionBuilder,HookDefaultInspector,PageBlockInspector,ViewVariantInspector— andFlowNodeInspector.specKeys/.inactiveRetained, same directory and same mechanism, were simply not in its enumeration. That is the per-file remedy's failure mode, stated exactly: it closes the files someone listed, and the list is hand-made.⇒ Per the triage ruling, this calls for a repo-wide instrument, not a fifth per-package fix — and no annotation of the four closed cards is owed, since their fixes are intact.
Remedy shape and its blast radius are the remaining question; I will carry it in the report rather than guess here.
Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
Progress — attribution settled, guard implemented, verification finishing
Session
session_01BGMDbrVa8JjZcCQ7DWYH1b, branchclaude/issue-6640-econnrefused-attribution, onorigin/main@67dadd6. (This repeats the table from my earlier interim comment above, which the dispatching seat had not seen.)Attribution outcome — possibility 1, measured
A full sweep of every project (
domall 8 shards,dom-heavy,unit,apps/console), eachVERDICT command-exit 0from the lock wrapper, attributes the class to 21 test files in 9 packages:HomePage.notificationDeepLink,.authoringCapabilityGate,.inboxLinksTarget,.approvalsTarget/api/v1/meta/_draftsFlowNodeInspector.specKeys,FlowNodeInspector.inactiveRetained/api/v1/meta/objectstudioSurfaceContext,StudioDesignSurface.designerRegistryMissing/api/v1/ai/conversations,/api/v1/automation/_statusrecord-details.emptySectionDefault,guideCrudAppRenders,defaultFieldGroupsPage.sectionHeadings,recordDetailsBodySource/api/v1/security/explainObjectKanban.overlayTitleI18n,.navWidthDefault,.overlayTitleNoProviderFallback/api/v1/security/explaincatalog-gallery-render/api/v1/security/explainObjectView.namedViewSortArity/api/v1/security/explainObjectCalendar.navWidthDefault/api/v1/security/explainbulkDeleteVisibleWhen/api/v1/security/explainObjectGantt.navWidthDefault/api/v1/security/explainObjectChart.heightChain/api/v1/meta/object/taskNot one is a file the four closed cards fixed. All eight landed doubles are still on
mainand still working. ⇒ No fix was silently reverted; the closed cards are not lying about main, and no annotation is owed them. The four cards each closed the files someone had listed by hand; what is left is packages nobody covered. Sharpest case: #4688 stubbed five inspectors in one directory, andFlowNodeInspector.specKeys/.inactiveRetained— same directory, same mechanism — were simply not in its enumeration.Mechanism: happy-dom's default document URL is
http://localhost:3000(nothing configures it), so a relative/api/v1/...from a component under test resolves to a live TCP connection.What I am implementing
vitest.setup.network-escape-guard.ts, imported once byvitest.setup.base.ts— the single choke point every project's setup leads back to. Two files changed, test infrastructure only, inside the declared fence.Two findings shaped it, and both falsified the suggested shape:
stderr | FILE > TESTNAMEheader, no user frame — an unhandled socket error below the layer Vitest captures. That anonymity, not the noise, is why the class survived four fixes.fetchwould never fire. Every escaping call site isconst doFetch = apiFetch ?? fetchinsidetry { ... } catch { /* best-effort */ }. That tolerance is precisely why the suite is green while escaping, and it would swallow a rejection from the guard too. So the escape is recorded at the call and asserted inafterEach, where no productcatchcan reach it.It silences nothing — the real request still goes out and the real ECONNREFUSED still prints; the guard adds an attributed line beside it. Nothing is skipped or quarantined. The 21 measured files sit in a
KNOWN_ESCAPESburn-down list that may only shrink; a new escape anywhere else is red on its first run.Verified so far
Ablation (delete one entry, mutation confirmed by blob hash, restore confirmed byte-identical to the HEAD blob with
git diff HEADempty): the test goes red, naming file, test and URL. Green with the guard: the 21 known files (690 tests),unit(808 files / 12572 tests),dom-heavy(34 files),domshard 3 — the escape-heaviest (179 files / 2275 tests). Gates green:check:control-bytes,check:vi-mock-specifiers,check:vi-mock-inherit,check:phantom-deps,lint:coverage, eslint on both changed files (0 errors),scripts/__tests__/vitest-invocation-guard.test.ts(30 tests), andtype-check:vitest-setup— that last one caught a real defect in my first draft (it ships no@types/nodeby design, and mynode:fs/node:path/process/import.meta.dirnameuses were 5 errors); the guard now declares the one structural type it needs instead. Changeset gate's own verdict: "No source or published contract of a released package changed in this range, so no changeset is owed."Remaining
Re-run the green checks against the rewritten file (the Node-typing fix landed after those runs), then push, open the draft PR, and post the report. Remaining
domshards are a declared narrowing — CI runs the full farm.Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
os-dev-report
{ "issue": 6640, "status": "done", "branch": "claude/issue-6640-econnrefused-attribution", "pr": "https://github.com/objectstack-ai/objectui/pull/7304", "premise_still_valid": true, "summary": "Attribution first, per the ruling. A sweep of every project (dom all 8 shards, dom-heavy, unit, apps/console) attributes the class to 21 test files in 9 packages. This selects POSSIBILITY 1 and falsifies POSSIBILITY 2: not one of the 21 is a file the four closed cards fixed, and all eight landed doubles are still on main and still working, so no fix was reverted and no annotation is owed the closed cards. Two findings falsified the suggested instrument shape. (1) The stacks are UNATTRIBUTABLE - no 'stderr | FILE > TESTNAME' header, no user frame, only TCPConnectWrap.afterConnect - because they are unhandled socket errors below the layer Vitest captures. That anonymity, not the noise, is why the class survived four fixes. (2) A throwing fetch would NEVER FIRE: every escaping call site is 'const doFetch = apiFetch ?? fetch' inside 'try { } catch { }' best-effort, which is exactly why the suite is green while escaping, and it would swallow the guard's own rejection too. So the escape is recorded at the call and asserted in afterEach, where no product catch can reach it. Mechanism: happy-dom's DEFAULT document URL is http://localhost:3000 (nothing configures it), so a relative /api/v1/... from a component under test resolves to a live TCP connection. The guard silences nothing (real request still goes out, real ECONNREFUSED still prints) and adds an attributed line beside each stack; it skips and quarantines nothing. KNOWN_ESCAPES holds the 21 measured files and may only shrink; a new escape anywhere else is red on its first run. Fixing the 21 is per-file work across 9 packages and is left to its own cards.", "attribution_table": [ { "package": "app-shell", "files": ["src/console/home/__tests__/HomePage.notificationDeepLink.test.tsx", "src/console/home/__tests__/HomePage.authoringCapabilityGate.test.tsx", "src/console/home/__tests__/HomePage.inboxLinksTarget.test.tsx", "src/console/home/__tests__/HomePage.approvalsTarget.test.tsx"], "mechanism": "relative fetch to /api/v1/meta/_drafts resolved against happy-dom default origin", "closed_card_that_fixed_it": null }, { "package": "app-shell", "files": ["src/views/metadata-admin/inspectors/FlowNodeInspector.specKeys.test.tsx", "src/views/metadata-admin/inspectors/FlowNodeInspector.inactiveRetained.test.tsx"], "mechanism": "relative fetch to /api/v1/meta/object", "closed_card_that_fixed_it": null, "note": "same directory as the five inspectors #4688 stubbed; not in its hand-made enumeration" }, { "package": "app-shell", "files": ["src/views/studio-design/__tests__/studioSurfaceContext.test.tsx", "src/views/studio-design/StudioDesignSurface.designerRegistryMissing.test.tsx"], "mechanism": "relative fetch to /api/v1/ai/conversations and /api/v1/automation/_status", "closed_card_that_fixed_it": null }, { "package": "plugin-detail", "files": ["src/renderers/__tests__/record-details.emptySectionDefault.test.tsx", "src/__tests__/guideCrudAppRenders.test.tsx", "src/__tests__/defaultFieldGroupsPage.sectionHeadings.test.tsx", "src/__tests__/recordDetailsBodySource.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain via useRecordEditable apiFetch ?? fetch", "closed_card_that_fixed_it": null }, { "package": "plugin-kanban", "files": ["src/ObjectKanban.overlayTitleI18n.test.tsx", "src/ObjectKanban.navWidthDefault.test.tsx", "src/ObjectKanban.overlayTitleNoProviderFallback.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null }, { "package": "examples/schema-catalog", "files": ["test/catalog-gallery-render.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null }, { "package": "plugin-view", "files": ["src/__tests__/ObjectView.namedViewSortArity.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null }, { "package": "plugin-calendar", "files": ["src/ObjectCalendar.navWidthDefault.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null }, { "package": "plugin-grid", "files": ["src/__tests__/bulkDeleteVisibleWhen.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain via useRecordCrudVerdicts apiFetch ?? fetch", "closed_card_that_fixed_it": null }, { "package": "plugin-gantt", "files": ["src/ObjectGantt.navWidthDefault.test.tsx"], "mechanism": "relative fetch to /api/v1/security/explain", "closed_card_that_fixed_it": null }, { "package": "plugin-charts", "files": ["src/ObjectChart.heightChain.test.tsx"], "mechanism": "relative fetch to /api/v1/meta/object/task via ObjectChart apiFetch ?? fetch", "closed_card_that_fixed_it": null } ], "closed_sibling_check": { "method": "by symptom, not by issue number: swept every project for emitters, then verified each landed double still present and still effective", "verdict": "ALL FOUR FIXES INTACT ON MAIN - possibility 2 falsified, no annotation owed", "detail": [ { "card": 5225, "fix_commit": "162c4aa7f", "file": "packages/plugin-report/src/__tests__/DatasetReportRenderer.test.tsx", "double_present": true, "emits_today": false }, { "card": 3339, "fix_commit": "fc2cc3bfb", "file": "packages/plugin-detail/src/__tests__/DetailView.test.tsx + DetailView.invalidation.test.tsx", "double_present": true, "emits_today": false }, { "card": 4106, "fix_commit": "ce4b9e8af", "file": "packages/plugin-charts/src/__tests__/ObjectChart.compareTo.test.tsx and siblings", "double_present": true, "emits_today": false }, { "card": 4688, "fix_commit": "03e98fcd5 + 01c3e76f0", "file": "packages/app-shell/.../previews/FlowCanvas.test.tsx + metadata-admin inspectors", "double_present": true, "emits_today": false } ] }, "tests": "All runs from the REPO ROOT (the invocation guard refuses package-cwd runs, which falsifies the dispatch's suggested 'pnpm --filter PKG exec vitest run' form), serialised behind the container-global lock at /tmp/os-heavy-verify.lock via /home/user/objectstack/scripts/pm/os-verify-lock.sh (objectui carries no copy); verdicts read from the wrapper's VERDICT line, never a piped $?. FINAL COMMIT 84e89f789; the gate union below was re-run on that exact head. ATTRIBUTION SWEEP (pre-fix, on 67dadd6): dom shards 1-7 of 8 plus 15/16 and 16/16, dom-heavy 34 files, unit 808 files, apps/console 85 files - every one 'VERDICT command-exit 0'. Instrument completeness proved on shard 1/8: the 3 files it named reproduce all 35 error blocks the full 179-file shard emitted, and stderr was byte-identical with and without it (70 lines both runs) so it silences nothing. dom-heavy, unit and apps/console emitted 0 - escapes are DOM-only. ABLATION (on the committed tree, so HEAD carries the implementation): removed one KNOWN_ESCAPES entry; mutation confirmed on disk by anchor count 1->0 AND blob hash change (248971596935621ae74df36fc948875899956c36 -> fa2ba1934b9c1c0a16fb0dc1f2056015d47bd085), not by an editor exit code; run gave 'Test Files 1 failed (1)' with the guard naming file, test and URL; restore leg confirmed by blob back to 248971596935621ae74df36fc948875899956c36 and 'git diff HEAD' empty. No rebuild leg was owed - the guard is a root setup file loaded by path, not resolved through any package dist. GREEN WITH THE GUARD on 84e89f789: 21 known files 'Test Files 21 passed (21) / Tests 690 passed (690)', 135 attributed lines, 0 guard failures; unit 'Test Files 808 passed (808) / Tests 12572 passed | 9 skipped'; dom-heavy 'Test Files 34 passed (34) / Tests 332 passed (332)'; dom shard 5/16 'Test Files 89 passed (89) / Tests 1516 passed (1516)', 18 attributed lines, 0 guard failures; dom shard 3/8 (escape-heaviest) 'Test Files 179 passed (179) / Tests 2275 passed (2275)'. GATES on 84e89f789, quoting each gate's own verdict line: check:control-bytes 'OK (scanned 5997 tracked text file(s); skipped 85 binary)'; check:vi-mock-specifiers exit 0 'OK (4128 tracked source file(s)...)'; check:vi-mock-inherit exit 0; check:phantom-deps 'Every in-scope import is declared by the package that publishes it'; lint:coverage '46/46 packages linted, 0 with outstanding errors (0 total)'; eslint --no-inline-config on both changed files exit 0, 0 errors / 7 no-explicit-any warnings (3 pre-existing in vitest.setup.base.ts); scripts/__tests__/vitest-invocation-guard.test.ts 'Tests 30 passed (30)'; type-check:vitest-setup exit 0; check-changeset-presence exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed' - so no changeset is owed and none was added, and I did NOT apply skip-changeset (objectui's label object is read by nothing). NOT MEASURED, recorded as such rather than quoted: one call that chained two dom shards and one --shard=8/8 call were killed by the container's 10-minute foreground cap with no VERDICT line; both re-run split. An 'apps/console' attempt via --project console returned 'No projects matched the filter' (command-exit 1) - a mis-named filter, not a red gate; re-run by path filter.", "mcp_calls": "9", "open_questions": [], "out_of_scope_findings": [ "NOT FILED - reported here for PM to file or fold into the burn-down: the 21 known escapes are recorded, not fixed. Each needs its probe served from a double (see DatasetReportRenderer.test.tsx for the shape) and its line deleted from KNOWN_ESCAPES. That is per-file work across 9 packages; I deliberately did not ride it on the instrument PR. My dedup budget went to the attribution sweep, so I did not run a duplicate scan before proposing these.", "NOT FILED - the issue body's characterisation 'from tests exercising connection-refusal paths' is wrong and worth correcting on the card: none of the 21 emitters tests a connection-refusal path. They are ordinary render tests whose components reach for real metadata through an apiFetch ?? fetch fallback, and the refusal is incidental to nobody owning port 3000." ], "deviations_from_dispatch_order": [ "Dispatch assumption (a) suggested confirming suspects with 'pnpm --filter PKG exec vitest run'. FALSIFIED: scripts/vitest-invocation-guard.mjs refuses any run whose Vitest root is not the repo root, so that form is rejected by design. All runs were done from the repo root instead.", "Dispatch assumption (a) also suggested a literal-string grep as the starting population. Kept as a lead only: the literal grep's 10 files are almost entirely the ALREADY-FIXED ones, and 18 of the 21 real emitters carry no literal. Attribution came from the dynamic ledger instead.", "PM-suggested remedy shape ('make any real connection fail loudly so the escape is a red test') FALSIFIED as written: the product call sites catch by construction and would swallow it. Same intent delivered via afterEach assertion.", "The 21 escapes are recorded in KNOWN_ESCAPES rather than fixed. This is a burn-down ledger, not a skip or quarantine (every test still runs and asserts as before, and the stacks still print) - but it is adjacent to the 'no quarantine' fence, so flagging it explicitly for review rather than assuming it passes.", "Declared narrowing: dom shards other than 3/8 and 5/16 were swept for attribution but not re-run against the final commit. CI runs the full farm." ], "files_changed": [ "vitest.setup.network-escape-guard.ts (new, 206 lines)", "vitest.setup.base.ts (one import line - it is the single choke point every project's setup leads back to)" ] }Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
ACCEPT with one patch round — PR #7304 (round R40, PM review).
Checked against the 2026-08-28 triage ruling and the claim:
127.0.0.1:3000发起真实网络请求(ECONNREFUSED 噪音,未走 MSW) #3339 / plugin-charts / plugin-dashboard 测试套件仍有真实网络逃逸(ECONNREFUSED) — 根因与 #3339 不同,需独立定位 #4106 / plugin-view / app-shell / plugin-designer suites escape to the real network on the grid's record-level explain probe (ECONNREFUSED noise, same class as #3339) #4688. TheFlowNodeInspectorpair sitting one directory over from plugin-view / app-shell / plugin-designer suites escape to the real network on the grid's record-level explain probe (ECONNREFUSED noise, same class as #3339) #4688's five stubs is the per-file remedy's failure mode stated exactly.fetchwould be swallowed by the product call sites' owncatch. Recording at the call and asserting inafterEachis the right seam, and the ablation shows it fires (one ledger entry removed → red naming file, test and URL; mutation and restore by blob hash).vitest.setup.base.ts, the choke point every project's setup reaches). Root-form vitest only; the dispatch'spnpm --filter … exec vitestsuggestion was correctly refused by the invocation guard.KNOWN_ESCAPESis accepted as a burn-down ledger, not a quarantine: every listed test still runs and asserts as before, and a new escape anywhere else is red on its first run. The dev flagged the adjacency itself, which is the honest reading.Patch round (small, in scope, before flip): the ledger says "may only shrink" but nothing mechanical holds that — an author facing a new red could add a line. Add the repo's standard shrink-only pin: a
scripts/__tests__(or root-level) test that imports the exported set and reconciles it against the 21 measured names in both directions (a removed name must be gone from the pin too, an added name reds), with an anchored non-vacuity floor, the way the fence-language and unmirrored ledgers are pinned. ExportKNOWN_ESCAPESfor that purpose only; no other behaviour change. Prove the pin by ablation (add one name → red; remove one name without updating the pin → red), then re-run the gate set on the new head.Two notes carried, not blocking: the card body's phrase "tests exercising connection-refusal paths" is wrong per the measurement (ordinary render tests whose components reach real metadata through
apiFetch ?? fetch); recorded here rather than editing the body. The 21-file burn-down is per-package work and goes on its own card, filed by this seat after a duplicate check.Landing: flip to ready + auto-merge once the patch commit is up and every check on it is green. Card closes on merge via
Fixes #6640.Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
os-dev-report
Patch round done, pushed as
1836f41f8on the same branch (fast-forward, no rebase, no force-push). PR #7304 body has a new "Patch round" section.The review was right that the ledger's "may only shrink" was a hope, not a fact.
KNOWN_ESCAPESis now exported (its only behaviour change) and reconciled against a pinned literal of the 21 measured paths in both directions byscripts/__tests__/network-escape-ledger.test.ts, with an anchored non-vacuity floor. Both directions proved by on-disk ablation; each leg's mutation confirmed by blob hash and restored byte-identical withgit diff HEADempty. Adding a bogus name reds with "the ledger GREW, and it may only shrink"; deleting a real name without touching the pin reds with "good news, banked wrong", so shrinking is a deliberate two-line change.One thing worth flagging for the burn-down card: the pin lives in
scripts/__tests__, so it adds a type edge from the scripts program to a repo-root setup file.type-check:scriptsis green with it, but that edge is new in this repo — no otherscripts/__tests__test imports a rootvitest.setup.*file — so it is worth knowing about if someone later tightens that tsconfig.{ "issue": 6640, "status": "done", "branch": "claude/issue-6640-econnrefused-attribution", "pr": "https://github.com/objectstack-ai/objectui/pull/7304", "head": "1836f41f8", "premise_still_valid": true, "summary": "PATCH ROUND on top of the accepted PR. Exported KNOWN_ESCAPES (only behaviour change) and added scripts/__tests__/network-escape-ledger.test.ts, a shrink-only reconcile pin: it compares the live set against a pinned literal of the 21 measured paths in BOTH directions, so the ledger cannot grow and cannot shrink silently. Anchored non-vacuity floor covers the case both reconciles pass on two empty collections (pin non-empty, imported set non-empty, every pinned path resolves on disk). Prior round unchanged: attribution selected POSSIBILITY 1 (21 emitting files across 9 packages, none of them a file the four closed cards fixed; all eight landed doubles intact on main, so possibility 2 is falsified and no annotation is owed). Guard still silences nothing, skips nothing, quarantines nothing.", "patch_round": { "requested": "shrink-only pin with both-direction reconcile and non-vacuity floor; export KNOWN_ESCAPES for that purpose only", "delivered": "scripts/__tests__/network-escape-ledger.test.ts (3 tests) + one-word export + a docstring cross-reference in the guard", "ablation": [ "GROWS: added 'packages/bogus/src/__ablation__/not-a-real-escape.test.tsx' to KNOWN_ESCAPES; on-disk confirmed by anchor count 0->1 AND blob bcdba52803c073c28446fefa5a9d762c10c47fcb -> 36de8bcbf79b6e028cb1f4aa17508339838a78e2; result 'Tests 1 failed | 2 passed (3)' with 'The network-escape ledger GREW, and it may only shrink.'; restored blob back to bcdba52803c073c28446fefa5a9d762c10c47fcb, 'git diff HEAD' empty", "SHRINKS-STALE: removed ObjectChart.heightChain.test.tsx from KNOWN_ESCAPES without touching the pin; on-disk confirmed by anchor count 1->0 AND blob -> da7b3de65d83e95bfd5711f20ac415b33be5efbf; result 'Tests 1 failed | 2 passed (3)' with 'A pinned escape is gone from KNOWN_ESCAPES - which is good news, banked wrong.'; restored blob back to bcdba52803c073c28446fefa5a9d762c10c47fcb, 'git diff HEAD' empty, entry count back to 1" ] }, "tests": "All runs from the REPO ROOT; heavy runs behind the container-global lock (/tmp/os-heavy-verify.lock via /home/user/objectstack/scripts/pm/os-verify-lock.sh); every exit code captured by redirect-then-$?, never through a pipe; lock outcomes read from the wrapper's VERDICT line. ON HEAD 1836f41f8: type-check:vitest-setup exit 0 (empty output; the four TS2882 seen before it are the config's documented build-order prerequisite - re-ran after 'VERDICT command-exit 0' on the four-package build); type-check:scripts exit 0 - this is the gate that judges the NEW import edge from scripts/__tests__ to the repo-root setup file, and it is clean; check:control-bytes exit 0 'OK (scanned 5998 tracked text file(s); skipped 85 binary)'; eslint --no-inline-config on vitest.setup.network-escape-guard.ts + scripts/__tests__/network-escape-ledger.test.ts exit 0, 0 errors / 4 no-explicit-any warnings; vitest run of scripts/__tests__/network-escape-ledger.test.ts + scripts/__tests__/vitest-invocation-guard.test.ts 'Test Files 2 passed (2) / Tests 33 passed (33)'; the 21 known files once more with the guard 'VERDICT command-exit 0', 'Test Files 21 passed (21) / Tests 690 passed (690)', 135 attributed lines, 0 guard failures; check-changeset-presence exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed' - none added, and skip-changeset NOT applied (objectui's label object is read by nothing). CARRIED FROM THE ACCEPTED ROUND, not re-run on this head: unit (808 files / 12572 passed / 9 skipped), dom-heavy (34 files / 332 tests), dom shard 3/8 (179 files / 2275 tests), dom shard 5/16 (89 files / 1516 tests) - the patch touches only the ledger's export and a new pin file, so those readings stand; CI runs the full farm.", "mcp_calls": "13", "open_questions": [], "out_of_scope_findings": [ "NOT FILED - the 21 known escapes are recorded, not fixed. Each needs its probe served from a double (see DatasetReportRenderer.test.tsx) and its line deleted from BOTH KNOWN_ESCAPES and PINNED_LEDGER. Per-file work across 9 packages; the PM ACCEPT comment says this seat files that card after a duplicate check, so I did not file it.", "NOT FILED - the issue body's phrase 'from tests exercising connection-refusal paths' is contradicted by the measurement: none of the 21 emitters tests a connection-refusal path; they are ordinary render tests whose components reach real metadata through an apiFetch ?? fetch fallback. The PM comment records this as carried, not blocking.", "OBSERVATION, not filed - the pin introduces the first type edge from the scripts tsconfig program to a repo-root vitest.setup.* file. type-check:scripts is green, but no other scripts test does this, so it is worth knowing if that tsconfig is later tightened." ], "deviations_from_dispatch_order": [ "Pin placed at scripts/__tests__/network-escape-ledger.test.ts (the coordinator's first suggestion) rather than beside the guard at the repo root. Reason, measured: a root-level *.test.ts either matches tsconfig.vitest-setup.json's './vitest.setup*.ts' glob - which ships no @types/node, so the on-disk non-vacuity floor could not use fs - or matches NO tsconfig program at all, which is exactly the unchecked-file defect objectui#3515 exists to prevent.", "The 'mirror check-doc-fence-languages' reconcile' suggestion was taken as shape only. That family reconciles against a LIVE re-measurement; escapes cannot be re-measured in a cheap unit test (it needs a real DOM run), so this pin reconciles against a pinned literal instead and says so in its docstring." ], "files_changed": [ "vitest.setup.network-escape-guard.ts (export KNOWN_ESCAPES + docstring cross-reference to the pin)", "scripts/__tests__/network-escape-ledger.test.ts (new, 140 lines, 3 tests)", "vitest.setup.base.ts (unchanged this round; one import line from the accepted round)" ] }Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
os-dev-report
Correction to the head in my previous comment: one more commit followed it. Final head is
0e1f5ae04, not1836f41f8.Reading the pushed diff back caught something my heredoc had glued together: the closing
]);sat on the same line as the lastKNOWN_ESCAPESentry. No gate reds on that (this repo runs no prettier/format check — confirmed: noformat/prettierscript, none in.github/workflows/, none in the eslint config), but it is not cosmetic. The burn-down's whole intended edit is "delete the line for the file you just fixed", and on the last entry that edit would have produced a syntax error. Detached it, matched the surrounding style in both lists, and stated the two-line rule in the docstring where a reader meets it. Membership of the ledger is unchanged.Also worth recording: the attributed-line count is not stable across runs (135, then 138 on the same 21 files). The escapes are async, so how many land inside a test's window varies. Treat that number as an observation, never as an assertion — nothing pins it, and nothing should.
One NOT MEASURED to disclose rather than bury: my first attempt at the final 21-file re-run returned
VERDICT batch-last-exit 126and collected 1 file / 588 tests — a mangled shell file list, not my 21. I discarded it and re-ran with the list built from a file; the result below is the clean run.{ "issue": 6640, "status": "done", "branch": "claude/issue-6640-econnrefused-attribution", "pr": "https://github.com/objectstack-ai/objectui/pull/7304", "head": "0e1f5ae04", "premise_still_valid": true, "summary": "Supersedes the head in my previous report comment (1836f41f8 -> 0e1f5ae04). Patch round unchanged in substance: KNOWN_ESCAPES exported and pinned shrink-only by scripts/__tests__/network-escape-ledger.test.ts, reconciling live set against a pinned literal of the 21 measured paths in both directions, with an anchored non-vacuity floor. The extra commit is formatting with one functional consequence: the closing bracket was glued to the last ledger entry, which would have made the burn-down's intended one-line deletion a syntax error on that entry. Ledger membership byte-identical. Attribution result from the accepted round stands: POSSIBILITY 1, 21 emitting files across 9 packages, none of them a file the four closed cards fixed, all eight landed doubles intact on main, so possibility 2 is falsified and no annotation is owed.", "tests": "On final head 0e1f5ae04, all from the REPO ROOT, exit codes captured by redirect-then-$? and lock outcomes read from the wrapper's VERDICT line: network-escape-ledger.test.ts + vitest-invocation-guard.test.ts 'Test Files 2 passed (2) / Tests 33 passed (33)'; type-check:scripts exit 0; type-check:vitest-setup exit 0 (empty output, after 'VERDICT command-exit 0' on the four-package prerequisite build); check:control-bytes exit 0 'OK (scanned 5998 tracked text file(s); skipped 85 binary)'; eslint --no-inline-config on both changed files exit 0, 0 errors / 4 no-explicit-any warnings; the 21 known files 'VERDICT command-exit 0', 'Test Files 21 passed (21) / Tests 690 passed (690)', 138 attributed lines, 0 guard failures. ABLATION (both directions, run on 1836f41f8 before the formatting commit, which changed no membership): GROWS - bogus name added, blob bcdba52803c073c28446fefa5a9d762c10c47fcb -> 36de8bcbf79b6e028cb1f4aa17508339838a78e2, 'Tests 1 failed | 2 passed (3)', 'the ledger GREW, and it may only shrink'; SHRINKS-STALE - real name removed without touching the pin, blob -> da7b3de65d83e95bfd5711f20ac415b33be5efbf, 'Tests 1 failed | 2 passed (3)', 'good news, banked wrong'; both restored to blob bcdba52803c073c28446fefa5a9d762c10c47fcb with 'git diff HEAD' empty. NOT MEASURED and discarded, not quoted as a result: a first 21-file re-run returned 'VERDICT batch-last-exit 126' having collected 1 file / 588 tests from a mangled shell list; re-run clean. check-changeset-presence exit 0 'No source or published contract of a released package changed in this range, so no changeset is owed' - none added, skip-changeset NOT applied. CARRIED from the accepted round, not re-run on this head (the patch touches only the export, formatting and a new pin file): unit 808 files / 12572 passed / 9 skipped; dom-heavy 34 files / 332 tests; dom shard 3/8 179 files / 2275 tests; dom shard 5/16 89 files / 1516 tests. CI runs the full farm.", "mcp_calls": "15", "open_questions": [], "out_of_scope_findings": [ "NOT FILED (the PM ACCEPT comment reserves this card for this seat, after a duplicate check) - the 21 known escapes are recorded, not fixed. Each needs its probe served from a double and its line deleted from BOTH KNOWN_ESCAPES and PINNED_LEDGER.", "NOT FILED - the card body's phrase 'tests exercising connection-refusal paths' is contradicted by the measurement; the PM comment records this as carried, not blocking.", "OBSERVATION - the pin adds the first type edge from the scripts tsconfig program to a repo-root vitest.setup.* file. type-check:scripts is green, but no other scripts test does this, so it matters if that tsconfig is later tightened.", "OBSERVATION - this repo runs no prettier or format check at all (no script, no workflow, no eslint-plugin-prettier). Formatting drift in new files is caught by review or not at all. Recording as an observation only; I make no claim it should change." ], "files_changed": [ "vitest.setup.network-escape-guard.ts (export KNOWN_ESCAPES, docstring cross-reference, ledger formatting)", "scripts/__tests__/network-escape-ledger.test.ts (new, 3 tests)", "vitest.setup.base.ts (one import line, from the accepted round)" ] }Generated by Claude Code
yinlianghui commentedon Sep 2, 2026
Patch round reviewed — ACCEPT holds on PR #7304 head
0e1f5ae04(domain:devxseat, session_01BGMDbrVa8JjZcCQ7DWYH1b, round R40).Checked against the diff:
KNOWN_ESCAPESis exported fromvitest.setup.network-escape-guard.ts(its only behaviour change);scripts/__tests__/network-escape-ledger.test.tsreconciles it against a pinned literal of the same 21 paths in both directions (grow ⇒ red, shrink without updating the pin ⇒ red) with an anchored non-vacuity floor (both sides non-empty, every pinned path resolves on disk). The placement deviation — pin underscripts/__tests__/rather than beside the guard — is accepted for the reason measured: a root-level test file would fall either into the@types/node-lesstsconfig.vitest-setup.jsonprogram or into no type program at all (the #3515 class). The heredoc-glued]);caught on read-back and fixed in a follow-up commit is exactly the kind of thing the burn-down edit would have tripped over; good catch.Flip condition unchanged: this PR flips out of draft and enters the queue once CI is green on
0e1f5ae04(test shards running since 05:43Z). The burn-down of the 21 known escapes is already filed as #7307 (Blocked-by: #6640), unassigned for triage.Generated by Claude Code