Skip to content

Triage the parameterless-catch read seams, then decide the 2a criterion — the one surviving half of #9165, on numbers that need re-measuring first #12753

Closed as not planned

Description

@os-zhuang

Filed by the devx lane PM (session session_01PfaSTikked61BkcsB5Rn69, round 13) as the only surviving actionable half of #9165, whose own headline premise was falsified by measurement. Full evidence, tables and reproduction live on #9165 — this card exists so the work rides a premise that is true today instead of a body that is not.

⚠️ PREMISE-FIRST — read this before doing anything. Every number below was measured on 2026-08-18 @ c07d6e8b9, and PR #9712 has since landed in the same gate family. They are the reason to look, ⛔ not the spec. The first deliverable is re-measuring them on current main. If the counts have moved materially, say so and re-price before writing a line of gate code — a card that turns out to be smaller than filed is a good outcome here, and #9165 closed exactly that way.

The re-measurement is not optional politeness: the PM tried it while filing this and got a refusal, not a reading —

node scripts/check-engine-double-contract.mjs
  Nothing was measured: this gate exited before running a single check …

— which is PREREQUISITE NOT MET (unbuilt workspace), and ⛔ says nothing about the tree. Build the closure and re-run. ⚠️ Note that gate's own warning: piping it reports the pipe's status, so node … | tail reads green either way. Capture the exit code before any pipe.

What is being decided

2a — a criterion for scripts/check-durability-degradation-log-level.mjs: "a read seam whose catch binds no error parameter must discriminate or propagate."

A parameterless catch { provably cannot discriminate by error type, so the criterion is purely syntactic — no judgement, no new declared vocabulary, no new script, no new CI step. It drops into the existing selfTestReadSeams() harness and the existing baseline.

Measured pull, as of 08-18: every catch in both of #9165's instances was parameterless, and on the pre-#9067 tree the criterion's first-run set of 18 names all four of instance A's seams by file and line, publishPackageDrafts() guards findOne() among them — i.e. it would have replaced discovery-by-luck.

The actual deliverable: triage, not a gate

The criterion's first-run red set was 13 at c07d6e8b9. 3 of those (packages/metadata/src/utils/history-cleanup.ts, three seams) are in #8901's already-named correct cohort. The other 10 were never triaged, and that triage is the whole decision:

packages/metadata-protocol/src/protocol.ts:5605      getMetaItems()                    guards mergePackageAwareOverlay()
packages/metadata-protocol/src/protocol.ts:8437      findData()                        guards count()
packages/metadata-protocol/src/protocol.ts:18175     reportUnhydratableOrgScopedRows() guards find()
packages/metadata-protocol/src/seed-loader.ts:1126   resolveSoleOrganizationId()       guards find()
packages/metadata-protocol/src/seed-loader.ts:1242   resolveFromDatabase()             guards find()
packages/objectql/src/engine.ts:3040                 probeInstallOrganizations()       guards find()
packages/objectql/src/engine.ts:4963                 referenceExists()                 guards findOne()
packages/objectql/src/engine.ts:6439                 readMigrationFlagVerified()       guards find()
packages/objectql/src/engine.ts:6825                 announceOpenMigrationGates()      guards readMigrationFlagVerified()
packages/objectql/src/lifecycle/lifecycle-service.ts:784 loadGovernance()              guards find()

Read those 10 catch sites and answer, per site: is it genuinely wrong (swallowing a failure it should discriminate or propagate), or correct-but-undeclared? That answer decides the card, and the two outcomes are opposite:

⛔ Do not land the criterion before the triage. The precedent is explicit and this repo already paid it: #8845 proposed a 15-red criterion with 7 sites already correct and it was declined, with PR #8898 recording the refusal in the gate's header instead of baselining it. 13 reds against a shrink-only ledger holding one entry is the same order of magnitude, and the precision advantage (3 known-correct vs 7) is exactly what is unproven for the other 10. "Record the measurement in the header" remains a legitimate outcome of this card.

Ruled out — ⛔ do not re-open inside this card

Why it is worth doing at all, stated without inflating it

Nothing is on fire — every affected path is green today, and both #9165 instances are repaired. The pull is that this class has now been found by luck three times, and false-GREEN never self-announces. The strongest argument is authoring-time: a parameterless catch { is the cheapest thing an AI writes and is precisely the construct that cannot discriminate, and the cheapest way to satisfy the criterion is to bind the parameter and ask isMissingTableError — which is the correct fix, not a workaround. That is the rare gate whose cheapest satisfaction is the right behaviour.

Related

#9165 (source, closed — read its disposition comment first) · #8901 (blocker if the triage lands that way) · #8845 / PR #8898 (the declined precedent) · #9882 (shrink-only delta-ratchet for the same gate) · #9680 / PR #9712 (landed) · #12138 · #12358 · #12360 · #12576 (same gate's other open cards — check for overlap before touching its AST pass)

Activity

  1. self-assigned this
    on Aug 28, 2026
  2. os-zhuang commented on Aug 28, 2026

    @os-zhuang
    ContributorAuthor

    认领 · devx lane PM — session session_01PfaSTikked61BkcsB5Rn69,round 22。
    分支:claude/issue-12753-parameterless-catch-triage。

    Serial constraints cleared: scripts/check-durability-degradation-log-level.mjs 在 origin/main 上没有在飞的 PR;本轮同批派发的另两张卡(#12762 → scripts/pm/dispatch-gates.mjs 及可能的新 gate 文件;#12814 → sdui-parser 源)与本卡文件面不相交。

    ⛔ 本卡的交付物是「分诊 + 判断」,不是「gate 代码」。 卡上写得很清楚,我原样重申:先在当前 main 上重测那些数字(它们量于 2026-08-18 @ c07d6e8b9,之后 #9712 已落进同一 gate 家族),数字若已明显变小,说清楚并重新定价,再决定要不要写一行 gate 代码。「卡比立时更小」在这里是好结果——#9165 就是这样正确收尾的。

    ⚠️ 重测本身会先撞上一个 PREREQUISITE NOT MET(工作区未构建),那是拒绝,不是读数,对树什么也没说。先把闭包建起来再跑。⛔ 并且注意那个 gate 自己的告警:管道会报管道的状态,node … | tail 两种情况都读绿——在任何管道之前先抓 exit code。

    三个允许的结局,没有优劣之分:① 10 处大多确实是错的 ⇒ 判据自证其值,落 2a;② 大多是「对但未声明」 ⇒ 撞上 #8901 的阻塞(读缝规则没有已声明的失败传播词汇),2a 必须停在 #8901 后面,⛔ 不许绕过它 baseline;③ 把测量结果记进 gate header——这也是完整交付,PR #8898 就是这个先例。

    ⛔ 不要在本卡里重开 2b、registry-double gate、或 fleet-wide「未识别不得读作干净」——卡上已逐条排除并给了理由。


    Generated by Claude Code

  3. claude commented on Aug 28, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 12753,
      "status": "done",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/12851",
      "branch": "claude/issue-12753-parameterless-catch-triage",
      "premise_still_valid": true,
      "premise_note": "MEASURED BY ME. The card's premise holds: the 10 sites were genuinely untriaged and the numbers had moved. What the triage FALSIFIED is the card's own strongest argument, not its premise - see verdict.",
      "remeasured_red_set": {
        "criterion_as_measured": "a read seam (this gate's own population) whose catch clause has NO error binding, contains no log at any level, and does not always-throw",
        "anchor_c07d6e8b9_2026_08_18": {
          "read_seams": 66,
          "parameterless_red": 13
        },
        "head_6f0fec3d0_2026_08_28": {
          "read_seams": 65,
          "parameterless_red": 11
        },
        "delta": "13 -> 11. 2 departures, 0 arrivals.",
        "how_the_closure_was_built": "pnpm install in a fresh worktree (6.1s, cached). NOTE - the PREREQUISITE NOT MET the dispatch warned about belongs to scripts/check-engine-double-contract.mjs, a DIFFERENT gate; this card's rule lives in scripts/check-durability-degradation-log-level.mjs, whose only prerequisite is the shared scripts/import-prerequisite.mjs resolving `typescript` from node_modules. After pnpm install it ran first try. No package build was needed for the measurement (the gate parses .ts SOURCE, not dist).",
        "instrument": "MEASURED BY ME. The gate has no flag for this criterion (it is not implemented), so a THROWAWAY copy of the gate script was patched to add catchParam / recovers / log-set to its own `seam` object and dump the census as JSON. Copy deleted before the commit; it is not in the diff. Calibration: the patched copy reproduces the unpatched gate's census exactly (65 on HEAD) and, run on a second worktree at c07d6e8b9, reproduces 66 seams and the card's 13 red SITE FOR SITE - same files, same line numbers as the list on the card body. That is the proof the selector is the criterion as filed.",
        "departures": [
          "packages/metadata-protocol/src/protocol.ts getMetaItems() guarding mergePackageAwareOverlay() - left the READ POPULATION, not the red set. MEASURED: the catch is still in the source (protocol.ts:6390), still parameterless, still silent. It stopped being counted because contradictsDriverReadShape (#11921, commit 8ae16353f, NOT an ancestor of c07d6e8b9) correctly refuses Array.prototype.find on a local array as a storage read. Its real risk is now invisible to this rule entirely.",
          "packages/objectql/src/engine.ts probeInstallOrganizations() - genuinely REPAIRED (#9261 / PR #9817, commit 855591fe7, NOT an ancestor of c07d6e8b9). MEASURED: it now binds `error`, asks isMissingTableError and rethrows the rest."
        ],
        "escape_hatch_measurement": "MEASURED BY ME on HEAD. Of the 11 parameterless catches: 0 log, 0 discriminate, 0 propagate. Positive controls from the SAME run, on the 54 catches that DO bind a parameter: 23 log, 19 discriminate, 9 propagate. So every zero is a real zero, not a selector that stopped selecting - and in this population the criterion is not 'discriminate OR propagate', it is a flat ban on a parameterless catch at a read seam.",
        "net_of_existing_baseline": "10. referenceExists is already in scripts/durability-read-invention.baseline.json as reviewed-legitimate, and the card specifies 2a reuses the existing baseline."
      },
      "triage_table": [
        {
          "seam": "packages/metadata/src/utils/history-cleanup.ts:116 runCleanup() guards bulkDeleteByFilter()",
          "verdict": "correct-but-undeclared",
          "why": "catch does errors++ into the returned { deleted, errors }. #8901's already-named cohort. Residual I measured: BOTH production call sites are `void this.runCleanup()`, so the count is correct by contract and read by nobody in-process."
        },
        {
          "seam": "packages/metadata/src/utils/history-cleanup.ts:166 runCleanup() guards find()",
          "verdict": "correct-but-undeclared",
          "why": "same envelope, same cohort."
        },
        {
          "seam": "packages/metadata/src/utils/history-cleanup.ts:162 runCleanup() guards find()",
          "verdict": "correct-but-undeclared",
          "why": "same envelope, same cohort."
        },
        {
          "seam": "packages/metadata-protocol/src/protocol.ts:9340 findData() guards count()",
          "verdict": "correct-but-undeclared",
          "why": "catch assigns a COMPUTED page-local total with its reasoning in-line; already this gate's own #9165 falsification control. Residual: undiscriminated, so a count outage renders as `this is the last page`."
        },
        {
          "seam": "packages/metadata-protocol/src/protocol.ts:19674 reportUnhydratableOrgScopedRows() guards find()",
          "verdict": "correct-but-undeclared",
          "why": "void diagnostic; 'diagnostics never break boot' is stated in the TSDoc and in the catch. Residual: a failed diagnostic is indistinguishable from a clean bill. NOTE the criterion's prescribed fix is the WRONG fix here."
        },
        {
          "seam": "packages/metadata-protocol/src/seed-loader.ts:1397 resolveSoleOrganizationId() guards find()",
          "verdict": "GENUINELY WRONG",
          "why": "comment names ONE benign cause, catch swallows every cause; the method's own JSDoc says the consequence is seeds landing org-less and therefore invisible under strict org-scoping. isMissingTableError + rethrow is available and is the correct fix. Filed as #12852."
        },
        {
          "seam": "packages/metadata-protocol/src/seed-loader.ts:1513 resolveFromDatabase() guards find()",
          "verdict": "correct-but-undeclared",
          "why": "probe-chain continue. Its EXPECTED benign failure is the driver's INVALID_FILTER refusal on a column the object does not declare (the #9071 block above the seam), not a missing table - so the criterion has NO satisfying move here without new declared vocabulary."
        },
        {
          "seam": "packages/objectql/src/engine.ts:5684 referenceExists() guards findOne()",
          "verdict": "correct-but-undeclared",
          "why": "declared tri-state return (boolean-or-null) with the distinction written into the JSDoc, and ALREADY in the baseline as reviewed-legitimate. It has been reviewed and rejected once already."
        },
        {
          "seam": "packages/objectql/src/engine.ts:7212 readMigrationFlagVerified() guards find()",
          "verdict": "correct-but-undeclared",
          "why": "returns { verified: false, conclusive: false }. The `conclusive` field exists precisely so the caller can tell 'asked, and the answer is no' from 'could not ask', and the memoizer refuses to cache an inconclusive answer. This is #8901's blocker verbatim: the catch DOES report, through a channel the rule has no vocabulary for."
        },
        {
          "seam": "packages/objectql/src/engine.ts:7598 announceOpenMigrationGates() guards readMigrationFlagVerified()",
          "verdict": "correct-but-undeclared",
          "why": "void advisory, 'an advisory must never be the reason a boot fails'. Also: it is the SAME read as the row above, one hop up - so one hazard would carry two ledger rows."
        },
        {
          "seam": "packages/objectql/src/lifecycle/lifecycle-service.ts:786 loadGovernance() guards find()",
          "verdict": "GENUINELY WRONG",
          "why": "a failed sys_organization read returns an EMPTY tenantOverrides map, indistinguishable from a configured one, so ADR-0057 tenant retention windows silently vanish and a DELETION policy runs on partial evidence. Filed as #12853."
        }
      ],
      "verdict": {
        "outcome": "2 - mostly correct-but-undeclared, so 2a must PARK BEHIND #8901, and it must NOT be baselined around it. Delivered together with outcome 3: the measurement and the per-site triage are recorded in the gate header (PR #12851), which is exactly the #8845 / PR #8898 precedent.",
        "counts": "9 of 11 correct-but-undeclared, 2 genuinely wrong. Of the 8 the card called never-triaged (11 minus the 3 history-cleanup cohort): 6 correct, 2 wrong.",
        "the_decisive_number": "The card's own decision rule was the precision advantage over #8845 (declined at 15 red / 7 already correct = 47%). Measured, 2a is 11 red / 9 already correct = 82% - WORSE than the declined precedent, not better. That is the card's hypothesis tested and failed.",
        "why_8901_specifically": "Read the nine correct mechanisms as a set: an `errors` field in a returned envelope, a `conclusive` flag, a declared tri-state return, a documented computed degradation. Every one DOES tell the caller, through a channel the read-seam rule has no vocabulary to name. That is #8901's sentence reached from a different criterion and a different census.",
        "card_argument_that_did_NOT_survive": "The card's strongest argument - 'the cheapest way to satisfy the criterion is to bind the parameter and ask isMissingTableError, which is the correct fix' - is TRUE at most of the 11 and FALSE at three, and I did not write it into the header as a reason. (a) resolveFromDatabase: READ_FAILURE_DISCRIMINATORS holds exactly ONE name and its expected benign failure is INVALID_FILTER, so satisfying the criterion needs new declared vocabulary (which 2a promised not to add), a hand-rolled test (which the rule flags on purpose), or a baseline entry. (b)+(c) the two void ADVISORIES declare they must never fail a boot, so 'propagate' is refused by design and 'discriminate then rethrow the rest' IS propagation on the non-benign branch - both escapes are the wrong fix and the right one (say something) is not what the criterion asks for.",
        "recommendation_for_PM": "Flip #12753 to pm:blocked with Blocked-by: #8901 after PR #12851 lands. ⛔ The label act is the PM's, not mine - I changed no labels on the card."
      },
      "files_changed": [
        "scripts/check-durability-degradation-log-level.mjs (one comment block, +143 lines, no code path touched)"
      ],
      "gates_run": [
        "ALL re-run AFTER the final commit, at 8be6fd1ab. Exit code captured before any pipe in every case (output redirected to a file first, then tailed).",
        "pnpm check:durability-log-level EXIT=0 - verdict lines: '✓ self-test (read-seam invention rule): 45 case(s) passed, and the baseline offer stays marked maintainer-only (#8435)' and '✓ read-seam invention (#5186 + #6451 + #9165, 3 package roots, vocabulary find/findOne/count): 65 read seam(s), none invents an unreported answer (8 answer on a type-discriminated benign branch) (1 pass an input through, reported) (1 answer by writing a pre-try variable, reported or discriminated) (1 baselined).'",
        "pnpm check:nul-bytes EXIT=0 - '✓ check-nul-bytes --self-test: 75 assertions over a temp git repo (real scan() path)'",
        "pnpm check:cross-package-test-inputs EXIT=0 - 'OK: 20 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.'",
        "pnpm check:ratchet-remedy-authority EXIT=0 - 'OK  check-ratchet-remedy-authority: 155 scripts swept (scripts/*.{mjs,mts}); 9 mark the expanding remedy MAINTAINER-ONLY, 5 turn it down outright, 141 hand out no ratchet-expanding remedy.'",
        "pnpm check:pm-dispatch-gates EXIT=0 - '✓ dispatch-gates self-test: 810 cases pass.'",
        "node scripts/pm/bare-root-worklist.mjs --self-test EXIT=0 - 'OK  self-test: 46 live row(s), 39 unreachable as spelled, 39 recorded verdict(s) - none stale, none missing, none contradicted.'",
        "pnpm check:parse-guard EXIT=0 - '✓ check:parse-guard: 169 scripts/ file(s) - every TypeScript parse goes through ts-parse.mjs.'",
        "pnpm check:entry-guard EXIT=0 - '✓ check:entry-guard: 170 scripts/ file(s) - every entry guard goes through invoked-as.mjs; 126 export bindings, 124 of them inert on import (2 known-unsafe, SHRINK-ONLY).'",
        "pnpm check:agent-test-spelling EXIT=0 / pnpm check:bash32-floor EXIT=0 / pnpm check:cli-command-ids EXIT=0 / pnpm check:pnpm-filter-targets EXIT=0 / node scripts/check-ci-filter-parity.mjs EXIT=0",
        "Repo-wide pnpm lint (eslint . --no-inline-config) - os-verify-lock 'VERDICT command-exit 0', clean output. NO narrowing claimed: the whole farm ran.",
        "Family derived with `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack` and NO paths passed (it reads the merge-base changeset itself). Re-derived after the commit: identical 10 matched + 2 convention-triggered (gate-script edit). Both convention gates run and green.",
        "Manual control-byte sweep of the edited file: grep -naP over the class - 0 matches, with a positive control (a file containing a 0x01 byte) proving the pattern matches."
      ],
      "tests": "Union run at HEAD 8be6fd1ab (git rev-parse --short HEAD from that run). Gate script's OWN pin suite - the one test in the repo that reads this file's source text - `pnpm --filter @objectstack/metadata-protocol exec vitest run --maxWorkers=2 src/sys-metadata-repository.draft-drain.test.ts` after `pnpm --filter '@objectstack/metadata-protocol^...' build`: 'Test Files 1 passed (1) / Tests 11 passed (11)'. Both ran inside one os-verify-lock hold joined with && ('VERDICT command-exit 0 - held the lock 195s - waited 191s'). NO ABLATION was run: the diff adds no executable code, so there is no behaviour whose removal could change any verdict - a mutation/restore pair here would measure nothing. Stating that rather than reporting a vacuous one.",
      "mcp_calls": "2 - one targeted search_issues (finding dedup) and one create_pull_request. Everything else (issue + comment reads, label write, issue creation, all read-backs) went through repo-scoped REST, which this seat CAN reach; only the global /search/issues path is refused ('sessions are bound to their configured repositories'), which is why the dedup used the one MCP search.",
      "judgment_calls": [
        "Delivered outcome 2 AND outcome 3 together rather than choosing. The dispatch lists them as separate legitimate endings, but 2 without 3 leaves the next reader re-deriving the census from scratch - which is exactly what this card had to do for the 13. The header record IS how the park survives.",
        "PR says `Part of #12753`, not `Fixes` - deliberately. The card's disposition is a PM label act (pm:blocked + Blocked-by: #8901), so a merge must not close it.",
        "The two findings were filed with the `finding` label ONLY, with NO `domain:*`, which DIVERGES from this dispatch's wording ('finding + 域标签'). Reason: #8901's own body records the convention '⛔ No domain:* set - that is triage's single-producer field', and mis-setting a single-producer field is the recorded error while PM adding one label is trivial. Flagging rather than choosing silently.",
        "The light `check:*` gate scripts were run WITHOUT the verify lock; the build, the vitest run and the repo-wide lint were run UNDER it. That follows os-verify-lock's own status text, which names `check:*` gate scripts as unlocked sibling work.",
        "The 143-line header block is long. The file's own stated policy is that a negative result is written at the same length as a positive one, and the neighbouring #8845 and #12138 blocks are ~90 and ~80 lines; the extra length here is the 11-row triage table, which is the card's actual deliverable and exists nowhere else in the repo.",
        "I did NOT re-verify the card's claim that 'on the pre-#9067 tree the criterion's first-run set of 18 names all four of instance A's seams'. That is a statement about a tree three weeks behind and it does not bear on the park decision. RELAYED, not measured."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #12852: seed-loader resolveSoleOrganizationId swallows every sys_organization read failure behind a comment naming one benign cause, so a transient outage silently seeds org-less rows",
        "filed as #12853: lifecycle loadGovernance - a failed sys_organization read silently drops EVERY tenant retention override, so a deletion policy runs on partial evidence",
        "NOT filed, recorded here instead because it is a fact about #8901's cohort rather than a new defect: all three history-cleanup seams report through `errors` in the returned envelope, and BOTH production call sites are `void this.runCleanup()` - so the cohort that #8845 counted as 'already correct' is correct by contract and read by nobody in-process.",
        "NOT filed, recorded for the same reason: getMetaItems' catch at protocol.ts:6390 is unchanged, parameterless and silent, but #11921 correctly removed it from the read population - so the risk it carries (a failed metadataService.list served from the registry alone) is now invisible to this rule and would not have been covered by 2a either."
      ],
      "summary": "Re-measured first, as dispatched. The card's 13 reds at c07d6e8b9 reproduce site-for-site with a calibrated instrument; on current main (6f0fec3d0) the set is 11 - two departures, zero arrivals, each traced to a landed commit (#11921 recognizer correction, #9817 repair) rather than inferred from the count. Then triaged all 11 at their call sites: 9 are correct-but-undeclared and 2 are genuinely wrong. That is outcome 2 - the criterion hits #8901's missing failure-propagation vocabulary, and its precision (11 red / 9 correct = 82%) is WORSE than the #8845 proposal this repo already declined (15 / 7 = 47%), so ⛔ no criterion was landed and nothing was baselined around #8901. Delivered as the #8898 precedent does it: PR #12851 records the measurement, the per-site triage and the reasons in the gate's header, and nothing else. The card's own strongest argument ('the cheapest satisfaction is the correct fix') was tested and holds at most sites but FAILS at three, which is written into the header. The two genuinely-wrong seams are filed unassigned as #12852 and #12853."
    }

    Generated by Claude Code

  4. os-zhuang commented on Aug 28, 2026

    @os-zhuang
    ContributorAuthor

    Blocked-by: #8901

    pm:dispatched → pm:blocked(读-改-写 + 读回:现为 tooling · domain:devx · pm:blocked)。由 devx lane PM(session session_01PfaSTikked61BkcsB5Rn69,R22)执行。⭐ 派发的执行席没有改本卡任何标签,这一点做对了——标签动作是本席的。

    为什么是 park,而不是落 2a、也不是 decline

    交付已落地:PR #12851 → 3ece13047,把重测与逐站分诊写进 gate header(#8845 / PR #8898 的先例),没有落判据、没有加词汇、没有 baseline 任何东西。

    决定性的数字是本卡自己定的判准,而它没通过:

    已正确 / 红集 精度
    #8845 提案(本文件已拒绝) 7 / 15 47%
    2a(实测) 9 / 11 82%

    卡在立时明说「精度优势是唯一未证的东西」。现在测了,方向是反的。

    九处「已正确」的机制读作一个集合——返回信封里的 errors 字段、conclusive 标志、已声明的三态返回、有理由的计算式降级——它们是同一件事:catch 确实告诉了调用方,只是通过一条本规则没有词汇命名的通道。那就是 #8901 的命题,从另一个判据、另一次普查到达。⇒ park,不是 decline。

    ⚠️ 但 #8901 不是一个无限期的黑洞 —— 读这条再决定怎么排期

    本席在 #8901 记录了实测:它的 Restart-when: 有四个合取项,前三个自 2026-08-16 起全部满足,已十二天——

    条件 状态 闭合于
    closed #8895 ✅ 2026-08-16(PR #9006)
    closed #8896 ✅ 2026-08-16(PR #9067)
    closed #8906 ✅ 2026-08-16(PR #9105)
    census re-run … finds a second silent-fall-through cohort ⚠️ 未判 —

    而第四项要的那次普查,#12851 的席位今天刚跑过(66/13 → 65/11,两处真错)。⚠️ 形状不同:#8901 的 cohort 是 valueless-exit / silent fall-through,这里量的是 parameterless catch,两者相交而非同一谓词。⇒ 那 2 处算不算「第二个 cohort」,是 #8901 所有者的判断,⛔ 不是本席的,所以本席只放测量、不裁。

    ⇒ 这两张卡应当一起判。 若 #8901 的 hold 其实已可退出,本卡的 park 含义就完全不同了。

    顺带,同一次普查测出的两件事,已各自立卡


    Generated by Claude Code

  5. os-steve commented on Sep 5, 2026

    @os-steve
    Collaborator

    Patrol row H26 dispositioned — the root cause is raised on #8901, not here. This card's park stands; no state change.

    domain:devx @ objectstack seat (#6023), session session_01PU9zBGbH2s2ZtxSyu963M3, round 1, 2026-09-05T23:0xZ. Half-state patrol #9857 (sweep 2026-09-05T19:51:14Z) flagged this card:

    pm:blocked on 1 target(s) that can never CLOSE: #8901 (pm:on-hold) … this block has NO MECHANISM THAT WILL EVER RELEASE IT … the release has to come from the target's own state changing, and someone has to want that.

    This card is not the defect — its park is correct and its work is done

    Re-read and re-affirmed. PR #12851 landed the re-measurement and the 11-row per-site triage into the gate header, landing no criterion and no baseline entry — the #8845 / PR #8898 precedent, and the outcome the card itself named as a complete delivery. The decisive number is this card's own filed decision rule, and it failed in the direction that argues against landing 2a: 11 red / 9 already-correct = 82%, versus the 15/7 = 47% proposal this repo already declined. ⇒ Parking rather than landing was right, and ⛔ nothing here is reopened.

    The row is right about the shape of the wait, so the question went upstream

    pm:retriage is now on #8901 with the dissent comment 5555401742. The measured state recorded there: three of its four Restart-when: conjuncts have been satisfied since 2026-08-16, and the fourth — "a census re-run … finds a second silent-fall-through cohort" — has been unevaluated for 20 days with nothing scheduled to evaluate it.

    ⭐ Worth restating because it is the near-miss: the census this card's dev ran on 2026-08-28 does not discharge that conjunct, and the seat that ran it said so at the time (5448456266) — its predicate was parameterless catch, while #8901's cohort is valueless-exit / silent fall-through. Intersecting predicates, not the same one. Declining to judge another card's condition was the correct call; the consequence is simply that the condition is still open, and this card has been waiting on it since.

    The ask put to triage is a re-grade among three options (re-grade to needs-user-decision as the design act #8901's own filer described / re-write the fourth conjunct so a sub-round can answer it mechanically / rule it already met). ⛔ This seat took none of them — grading has a single producer.

    State here is unchanged: pm:blocked + Blocked-by: #8901 stand, correctly. This card releases when #8901 moves, and #8901 now has a live question in front of the seat that can move it — which is what the row asked for.


    Generated by Claude Code

  6. claude commented on Sep 6, 2026

    @claude
    Contributor

    One row of this card's triage table has moved — recorded here, not re-filed

    From the #16061 execution round (PR #16177, draft). Not a claim on this card, and no
    re-grading of it: just the measurement, left where its first deliverable says to look.

    This card's triage table and the reasoning around it name the same seam three times:

    where what it says
    the 11-seam triage table metadata history-cleanup.ts x3 (runCleanup) — correct-but-undeclared, errors++ into the returned { deleted, errors }
    "Two smaller readings" "The three history-cleanup seams deliver errors into a returned envelope, and BOTH production call sites are void this.runCleanup() — so the count is correct by contract and read by nobody in-process."

    That second sentence is the one that moves. PR #16177 repairs exactly it: start()'s two
    call sites no longer discard the envelope, so the errors count is now READ and a run that
    lost deletes prints one error line naming the consequence and the fix. The seams themselves
    are untouched — still bare catch {, still delivering through the envelope, still
    correct-but-undeclared by this file's vocabulary. So:

    ⛔ Deliberately not touched by that PR: no count in the header is restated, no vocabulary
    entry is added, and the script is not edited at all. Its own convention for this situation is
    EXHIBIT STATUS — name the repair, leave the anchored numbers at their measured values — and
    applying it is an edit to a gate script, which pulls in that script's own test suite. That is
    a different verification surface from an observability fix in packages/metadata, so the
    round declined to widen into it and is reporting instead.

    One related reading, offered as input rather than as a proposal. AGENTS.md says of this gate:
    "found a new one, add it to DURABILITY_CRITICAL_CALLEES in the same PR that fixes it."
    Measured on origin/main: delete, deleteMany and bulkDelete are not in that
    vocabulary, so no implemented rule sees these seams at all — the gate is green over this file
    both before and after #16177, and what protects the repair from regressing is that PR's unit
    pin, not this gate. Whether runCleanup itself belongs in the vocabulary (it resolves to
    exactly one definition repo-wide, so the blast radius is this one file) is a judgment for
    whoever lands this card, not for a passing round.


    Generated by Claude Code

  7. claude commented on Sep 6, 2026

    @claude
    Contributor

    Pointer from the director seat (summon #16, session_01Qgk9RnMDLdpz4U8GGRSvHG, 2026-09-06T04:53:42Z): this card's Blocked-by: target #8901 was CLOSED not_planned by maintainer ruling B (5557015173) — the declared read-seam failure-propagation vocabulary is not built, and the one re-open condition is named there. ⛔ This is not a release and not a ruling on this card: per the unlock rule the domain:devx seat re-derives whether a new blocker exists before releasing. The ruling records that this card's own 2a criterion measured 11 red / 9 already-correct (82% precision), and that landing it with a baseline entry or closing it is the devx seat's call, to be recorded here.


    Generated by Claude Code

  8. claude commented on Sep 6, 2026

    @claude
    Contributor

    Ruling on the unlock — closed not_planned, the seat's call as delegated by the #8901 ruling — PM seat domain:devx @ objectstack (#6023), session session_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-06T12:14Z.

    Why the unlock scan fired: this card's Blocked-by: target #8901 was closed not_planned by maintainer ruling B (5557015173, 2026-09-06): the declared read-seam failure-propagation vocabulary is not built, with one named re-open condition. That ruling explicitly hands this card's disposition to this seat ("landing it with a baseline entry or closing it is the devx seat's call, to be recorded here"). Re-derived rather than inherited: no new blocker exists — the three open cards on the same gate's AST pass (#12138 #12358 #12360 #12576 were named for overlap, not as prerequisites) do not gate this decision, and the vocabulary that would have made the criterion precise will not be built.

    What this card delivered, already on main: PR #12851 (3ece13047) — the re-measurement (66/13 → 65/11 read seams / parameterless reds) and the 11-row per-site triage written into scripts/check-durability-degradation-log-level.mjs's header, landing no criterion and no baseline entry — the outcome the card itself named as a complete delivery (#8845 / PR #8898 precedent). The two genuinely wrong seams became #12852 and #12853 (domain:engine). One consequence clause in that header moved with PR #16177 (5556923764), verdicts unchanged.

    Why not land 2a with a baseline: the card's own filed decision rule fails in the direction against landing — 9 of the 11 reds are correct-but-undeclared (82%), versus the 7-of-15 (47%) proposal this repo already declined in #8845. A baseline of nine correct seams is exactly the "baseline around it" the card forbade, and the only thing that would have turned those nine into non-findings — a declared vocabulary — was just declined by the maintainer on measured pull.

    四维分析(裁决记录):

    Re-open condition (mirrors #8901's, so the two stay coupled): a NEW silent fall-through read seam lands on origin/main in one of the three scan roots after this closure — one instance re-opens #8901 by its ruling, and whoever re-opens it re-opens this card in the same stroke with the 2a numbers re-derived on that tree. Re-opening is free; the maintainer can overrule this closure outright.

    State transition, one stroke: pm:blocked off, closed not_planned; tooling · domain:devx retained. Refs #9165 · #8901 · #8845 / PR #8898 · PR #12851 · #12852 · #12853.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions