Skip to content

spec/liveness: seed ledgers for the three PENDING_GOVERNANCE debts #18133 declared — connector, sharing_rule, analytics_cube #18582

Closed

Description

@os-bill

Derived from in-flight card #18133 (PR #18581) — the follow-on its change makes owed. Filed by the domain:spec seat 2 PM (session_01JbZnqu8bt6YqfJsr9vaFb3, seat post #18549) under 〈在飞卡衍生〉, carrying the parent card's domain:spec and priority:p2. ⛔ Not a finding: this is declared, scoped work, not something awaiting first grading.

Why this exists now

Before #18133, the liveness governance denominator was built from listMetadataTypeSchemaTypes(), which omits UNREGISTERED_KIND_SCHEMAS. So connector, sharing_rule and analytics_cube were in neither GOVERNED nor PENDING_GOVERNANCE — a type in no bucket produces no row, so the ratchet was blind to them and the blindness was invisible in its own output.

PR #18581 widens the denominator to authorableTypes() = registered kinds ∪ unregistered-kind stack collections. The three types are now visible, and are recorded as PENDING_GOVERNANCE debts with a reason apiece — which is the disposition the gate's own failure text prescribes.

⇒ ⭐ This card is those debts. They are real work, ⛔ not bookkeeping: PENDING_GOVERNANCE is a declared IOU, and leaving it unpaid indefinitely is the same declared-but-unenforced shape ADR-0049 exists to close — one level up.

The work

Seed a liveness ledger for each, moving it out of PENDING_GOVERNANCE and into GOVERNED:

  • packages/spec/liveness/connector.json
  • packages/spec/liveness/sharing_rule.json
  • packages/spec/liveness/analytics_cube.json

⭐ Precedent exists and should be followed rather than reinvented: the nine debts of #4488 were paid off this exact way, out of that map and into GOVERNED. Read one of those ledgers first.

Suggested ordering — ⛔ a suggestion, not a prescription

sharing_rule is the security-shaped one of the three, so it is the natural first if the taker splits them. Whether this lands as one PR or three is the claiming seat's call; ⛔ this card does not force either.

What this card is NOT

Verification criterion

After all three land: check:liveness exits 0 with PENDING_GOVERNANCE empty again, and the coverage line — which PR #18581 made print on every run, not only when the map is non-empty — shows all authorable types governed.

Dedupe words

seed connector liveness ledger · PENDING_GOVERNANCE debt · govern unregistered kinds · analytics_cube ledger · sharing_rule ledger

Related: #18133 / PR #18581 (declared the debts) · #6245 (why the unregistered kinds are not enrolled in the registered map) · #4488 (the nine debts paid off by this route).


Generated by Claude Code

Activity

  1. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    Claim: PM loop round 7
    Session: session_01JbZnqu8bt6YqfJsr9vaFb3
    Branch: claude/issue-18582-connector-analytics-cube-ledgers
    Worktree: objectstack-issue-18582-r7
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549; seat 1 is #6017 and this claim does not touch it)
    File surface: packages/spec/liveness/connector.json (new) · packages/spec/liveness/analytics_cube.json (new) · the two PENDING_GOVERNANCE rows and the matching GOVERNED entries in packages/spec/scripts/liveness/check-liveness.mts (including the [#18582] note at :305-310 whose count goes to zero). ⚠️ Everything the gate reverse-requires is OPEN, declared in advance, ⛔ not a scope breach: packages/spec/liveness/README.md (state-table rows + the "N governed types" heading count), the generated packages/spec/liveness/state-counts.md, docs/qa/platform-checklist/coverage.json, and .changeset/*.md. Read-only: the existing ledgers as shape precedent — above all packages/spec/liveness/sharing_rule.json — and the key sources packages/spec/src/integration/connector.zod.ts and packages/spec/src/data/analytics.zod.ts (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: default judgement tier
    Clause-②: no
    Thread-read: 5 comments read in full (ids 5708815928 claim · 5709518314 report · 5709560762 ACCEPT · 5709780155 pre-landing checks · 5710079918 merge + release). comments field = 5 and the list returns 5 — field and list agree at claim time.
    Serial constraints cleared: measured, ⛔ not recalled. All 9 open domain:spec pm:dispatched cards' comment threads were fetched and scanned for this surface. 7 of the 9 carry a machine-readable File surface: line; 0 of them names liveness, coverage.json, state-counts, or platform-checklist (firing control on the same instrument: packages/spec → 8 hits, so the zero is a reading). The 2 with no such line — #17534 and #18378 — were scanned raw over their whole threads: 0 hits on all six tokens, controls 35 and 4. Nearest adjacency, named rather than hidden: #17735 (os-litant) holds packages/spec/scripts/check-generated.ts; this round touches artifacts that gate declares, ⛔ not that file. packages/spec/src/ui/view.zod.ts (PR #18561, now enqueued) is not on this surface.


    Why this is claimable now, and what already landed

    This is the second and last dispatch of #18582. Round 5 paid the first of its three debts: sharing_rule, landed as squash e0d05538c0 (PR #18587), verified on origin/main by git log --oneline origin/main | grep -F '(#18587)'. The card was deliberately not closed — PR #18587's first line reads Part of #18582, not Fixes — and it was released back to pm:queue with assignee cleared. It is re-claimed here.

    Re-read on origin/main at tip ab1d359259 this minute, ⛔ not from the round-5 report:

    check-liveness.mts:309  const PENDING_GOVERNANCE: Record<string, string> = {
    check-liveness.mts:310    connector:        … 'seed packages/spec/liveness/connector.json (#18133).'
    check-liveness.mts:316    analytics_cube:   … 'seed packages/spec/liveness/analytics_cube.json.'
    

    Exactly two rows remain, and each names its own seed file. The [#18582] note directly above the map already records that one of three is paid.

    Dedupe

    search_issues over open and closed (⛔ open-only would miss a just-closed twin): 9 results, and the only live card for this work is #18582 itself. #18133 (closed, the finding that created the debts) and the #4488/#3462/#3490 family (closed, the nine-debt precedent) are history, not twins. ⛔ No twin filed.

    ⭐ The one thing this seat got wrong last round, and will not repeat

    The round-5 dispatch order marked packages/spec/liveness/README.md read-only while demanding check:liveness exit 0. Those two constraints are not simultaneously satisfiable, and the tree says why:

    packages/spec/scripts/liveness/check-liveness.mts:698
      readmeMissingRows: [] as string[], // a GOVERNED type with no row in the README state table (#7257)
    

    A type moved into GOVERNED with no README row turns the gate red. The dev was right to cross the line and said so; this seat accepted it and recorded the fault. ⇒ This round names only the two files known to move and writes every gate-reverse-required derivative as open. Making the constraints satisfiable is this seat's job, ⛔ not the dev's.


    Generated by Claude Code

  2. self-assigned this
    on Sep 17, 2026
  3. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    Claim: PM loop round 7 (supersedes 5710946301 — same round, same dispatch, corrected machine-read field)
    Session: session_01JbZnqu8bt6YqfJsr9vaFb3
    Branch: claude/issue-18582-connector-analytics-cube-ledgers
    Worktree: objectstack-issue-18582-r7
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549; seat 1 is #6017 and this claim does not touch it)
    File surface: unchanged from 5710946301 — packages/spec/liveness/connector.json (new) · packages/spec/liveness/analytics_cube.json (new) · the two PENDING_GOVERNANCE rows and matching GOVERNED entries in packages/spec/scripts/liveness/check-liveness.mts. Gate-reverse-required derivatives are OPEN and pre-declared: packages/spec/liveness/README.md, packages/spec/liveness/state-counts.md, docs/qa/platform-checklist/coverage.json, .changeset/*.md. Read-only: existing ledgers as precedent, packages/spec/src/integration/connector.zod.ts, packages/spec/src/data/analytics.zod.ts (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: default judgement tier
    Clause-②: no
    Thread-read: 5710946301
    Serial constraints cleared: unchanged from 5710946301 — all 9 open domain:spec pm:dispatched threads scanned, 0 name liveness / coverage.json / state-counts / platform-checklist, firing control packages/spec → 8 hits. Nearest adjacency named, not hidden: #17735 holds packages/spec/scripts/check-generated.ts.


    ⚠️ Why a second claim, when the dispatch itself did not change

    The previous claim's Thread-read: was filled with prose — an enumeration of five comment ids plus a sentence about field/list agreement. That field is machine-read: check-half-states.mjs's H50 requires it to EQUAL the id of the comment immediately preceding the claim, or none. A prose value is unreadable to it, so the patrol filed the row and was right to:

    H50 #18582 — the newest Claim: (comment 5710946301) names Thread-read: 5 comments read in full (ids …), while the comment immediately before it in the thread is 5710079918 — so the claim does not name the thread it was written into.

    ⇒ The remedy the row itself prescribes is a fresh Claim: whose Thread-read: names the comment it follows, ⛔ not an edit. This is it. The predecessor of this claim is 5710946301, so that — not 5710079918 — is the correct value now.

    ⭐ This is the second time this seat has broken this exact field, in two different disguises (once filled with prose that had to be corrected to none, now filled with prose again). The reading content was not wrong — all five comments were genuinely read, including the last page — but a machine-read field is not a place for prose, however true the prose is. Recorded on the seat post rather than left as a one-off.

    ⛔ The dev in flight is unaffected: same branch, same worktree, same file surface, same dispatch order. Nothing about the work changes.

    Reading time for the thread state above: 2026-09-17T08:04Z


    Generated by Claude Code

  4. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 18582,
      "status": "done",
      "branch": "claude/issue-18582-connector-analytics-cube-ledgers",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/18609",
      "session": "session_01JbZnqu8bt6YqfJsr9vaFb3",
      "premise_still_valid": true,
      "summary": "Both remaining PENDING_GOVERNANCE debts are paid in one PR: packages/spec/liveness/connector.json (74 properties: 20 live, 1 planned, 53 dead) and packages/spec/liveness/analytics_cube.json (29 properties: 17 live, 12 dead), with both types moved into GOVERNED and the map emptied. Every live row carries a #4837 producer citation, and the two types' shape facts are recorded rather than assumed: connector is ONE schema behind TWO doors (authoring vs engine.registerConnector), analytics_cube is ONE Cube shape with THREE producers into one registry, only one of which is the authoring door. The gate's reverse-required artifacts moved with it — README state-table rows + heading 37 to 39, regenerated state-counts.md, one recorded row in undrilled-containers.baseline.json (connector/webhooks), two coverage.json entries, and a patch changeset (liveness/ is in this package's published files[]). The card's re-derivation checked out: check-liveness.mts:309 held exactly the two rows named, each pointing at its own seed file, and the [#18582] note that said 'two left' is rewritten in the same diff.",
      "tests": "RED BEFORE / GREEN AFTER on the acceptance gate, both observed. RED (both ledgers written, both types in GOVERNED, artifacts not yet caught up) — `pnpm --filter @objectstack/spec check:liveness` exit 1: '2 governed type(s) with NO row in the README state table: connector, analytics_cube'; 'heading says 37 governed types, GOVERNED has 39'; 'state-counts.md is STALE ... first difference at line 67: + | `connector` | 20 | 0 | 0 | 53 | 1 | 74 |'; '2 row(s) where README.md and state-counts.md disagree'; '1 UNDECLARED container inheritance: connector/webhooks - one verdict covers 21 unclassified child key(s)'. GREEN after the README rows + heading, gen:liveness-counts and the baseline row — exit 0: '30 authorable type(s) ... 30 governed, 0 awaiting a ledger' and 'the README state table carries a row for each of the 39 governed type(s) it claims to index'. OTHER GATES, all exit 0: check:generated (all 15 artifacts up to date, run after a real `pnpm --filter @objectstack/spec build` under the shared verify lock, VERDICT command-exit 0); check:authorable-surface ('Successfully generated 1536 schemas'); check:api-surface ('public API surface + factory signatures unchanged'); check:docs ('223 generated files in sync'); spec typecheck + check:scripts-typecheck; check:platform-checklist ('38 kinds mapped, 1 waived'); check:nul-bytes, check:published-files, check:merge-driver, check:objectui-changeset, check:doc-authoring, check:keyed-text-bounds, check:comment-mask-adoption/-corpus, check:closing-keyword-parity, the three changeset gates against --base origin/main plus check:changeset-gate-self-tests, check:empty-state, check:strictness-ledger, check:variant-docs, check:pm-dispatch-gates, check:pm-widening-tells, check:pm-governed-merges, check:pm-changeset-deadline-census, docs-audit/check-affected-docs. GATE-SCRIPT TEST SUITE (owed because the diff edits check-liveness.mts): `pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 scripts/liveness/` — 11 test files, 315 tests passed, under the verify lock (VERDICT command-exit 0, waited 51s). GATE FAMILIES: derived with `node scripts/pm/dispatch-gates.mjs --commands` (no paths passed) at 25fefdecd7 — 63 commands over 8 changed paths; the 22 relevant to this diff were run (above). The rest are whole-tree or artifact-roster families that no path of mine narrows; NOT MEASURED locally, CI's. ESLINT is a DECLARED NARROWING with its three pieces of evidence, read at a442b583fb: (1) the universe comes from eslint.config.mjs itself — the only source glob is **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}, and the seven non-.mts paths here are .json/.md, confirmed by ESLint answering 'File ignored because no matching configuration was supplied' on liveness/connector.json; (2) --format json on the one file in that universe reports 1 file, 0 errors, 0 warnings; (3) the config's own header states this repo 'never enables type-aware linting (no parserOptions.project, no typed @typescript-eslint rules) for ANY file', so this diff cannot move an untouched file's verdict. The whole-farm `pnpm lint` is CI's. WIDENING TELLS: `node scripts/pm/check-widening-tells.mjs --declaration no --diff DIFFPATH` exits 0 with NO tell firing — matching PR #18587 — but its own output is the honest reading: '8 changed file(s) - 0 judged against a declared surface (no widening tell), 8 NOT MEASURED ... NOTHING on this diff was examined for widening tells, so this exit 0 is evidence about no surface at all'. Reported as NOT MEASURED, not as clean. NO ABLATION was run and none is owed: this diff adds no gate and changes no gate logic — the only executable change is two strings entering GOVERNED and two leaving PENDING_GOVERNANCE, and the red/green pair above is the falsification evidence for exactly that.",
      "mcp_calls": "0 — no MCP GitHub tool was called; every GitHub write went through the REST proxy with curl.",
      "api_writes": "3 REST writes + 4 git pushes. REST: POST /repos/objectstack-ai/objectstack/pulls (draft PR #18609); POST /repos/objectstack-ai/objectstack/issues/18609/labels (additive: documentation, tooling — read back, union held, size/l added by the repo's own labeler); POST /repos/objectstack-ai/objectstack/issues/18582/comments (this report). Git: the empty-branch routing probe plus three commits. No PATCH of any body, no POST /issues.",
      "open_questions": [
        {
          "question": "Seat question 1 — which schema does the ledger walker actually resolve for an unregistered kind? ANSWERED: getMetadataTypeSchema('connector') returns DeclarativeConnectorEntrySchema, and that schema is ConnectorSchema.superRefine(...). In Zod 4 superRefine attaches a CHECK to the same object def rather than wrapping it, so shapeOf() returns ConnectorSchema's shape unchanged — the walked key set is byte-identical to the base's, the two RETIRED tombstones included. The gate cannot distinguish the two schemas; the binding's whole value (the ADR-0097 cross-field rules) is invisible to the walk and shows up only as refusals on the authentication / actions / triggers rows. Does that difference want any follow-up in the gate?",
          "options": [
            "A — nothing: record it in the ledger _note and the README row (what this PR does). The walk's job is the key set, and refusals are correctly a per-row verdict, not a walk property.",
            "B — teach the walk to notice a refinement wrapper and report it, so a future binding that DOES change the key set (a .pick()/.omit()/.extend() bound in UNREGISTERED_KIND_SCHEMAS) cannot pass as the base."
          ],
          "recommendation": "A, because the difference costs nothing today: the gate governs whatever key set it walks, and both schemas have the same one. B is worth a card only if someone binds a NARROWED schema there, which would silently un-govern keys — but that is a hypothetical with no instance, and filing it would be the 'observation' class rule 3 excludes."
        },
        {
          "question": "Seat question 2 — does ADR-0049 want a retirement for the dead analytics_cube keys? ANSWERED PER ROW, and mostly NO; each ledger row says so explicitly so the enforce-or-remove channel does not act on the word 'dead'. dimensions.granularities and measures.format are the dataset compiler's own output channel on a shared shape (deleting them breaks a live internal write); joins[].sql is REQUIRED and documented as the ON clause while both strategies synthesise an FK equality; public is an access-control flag that gates nothing. Only refreshKey.every/.sql look like a clean retirement, and the showcase example authors them. Who decides?",
          "options": [
            "A — leave all five to the ADR-0049 sweep that reads this ledger; the rows carry the measurement and the ⛔ caveats (what this PR does).",
            "B — file the joins[].sql / joins[].relationship pair now as a metadata-authoring trap (a declared ON clause the engine silently replaces with different arithmetic) and leave the other three to the sweep."
          ],
          "recommendation": "B, and it is in out_of_scope_findings below as a class-(c) filing request. joins[].sql is the one row where an author's declaration is not merely ignored but REPLACED by different arithmetic under a 200 — that is the #10298 shape, not an inert key. The other four are genuinely a sweep's business."
        },
        {
          "question": "Seat questions 3 and 4 — changeset? and one PR or two? Both ANSWERED by measurement rather than returned. (3) A changeset IS owed and is written: `liveness` is in packages/spec's published files[], so both ledgers, the README and state-counts.md ship inside the npm tarball; skip-changeset would have been wrong. Bump: patch (no export, no schema key, no behaviour moved). check:empty-changeset, check:adr-0087-registration and check:changeset-no-major all pass against --base origin/main. (4) One PR, as the seat chose — no reason to split surfaced: the two ledgers share one gate, one README table, one generated counts artifact and one denominator, and splitting would have left the first PR red on the heading count until the second landed.",
          "options": [],
          "recommendation": "No decision owed; recorded so the seat can see both were measured and not guessed."
        }
      ],
      "out_of_scope_findings": [
        "to file (contract violation; dedupe words: retryConfig live claim, connector timeouts, conversions registry comment): packages/spec/src/conversions/registry.ts's connector-rate-limit-config-removed entry asserts that retryConfig 'and the timeouts beside it are untouched — they are live'. Measured false on this checkout: the word retryConfig does not occur in packages/ or examples/ outside packages/spec, and every connectionTimeoutMs/requestTimeoutMs occurrence is a WRITE of the literal 30000 so a def satisfies the post-parse type. The comment is what the next reader will trust; the ledger rows now contradict it.",
        "to file (contract violation; dedupe words: bootstrapDeclaredWebhooks docblock, connector-authored webhook, sys_webhook source): packages/plugins/plugin-webhooks/src/bootstrap-declared-webhooks.ts documents itself as materializing each 'stack/connector-authored webhook', while its source is readDeclared(engine, metadataService, 'webhook') — metadata items the decomposition registers from the TOP-LEVEL webhooks: collection. A connector's nested webhooks[] never becomes one, so the sentence promises a bridge that does not exist.",
        "to file (metadata-authoring trap; dedupe words: analytics_cube joins sql ON clause, synthesised FK equality, cube join relationship): Cube.joins[].sql is REQUIRED and documented as 'Join condition (ON clause)', and both strategies synthesise ON \"parent\".\"seg\" = \"alias\".\"id\" without ever reading it (native-sql-strategy#qualifyAndRegisterJoin; objectql-strategy lowers joins to relationship traversals with no ON clause at all). An author who writes a non-FK join condition gets a 200 carrying different arithmetic than they declared. joins[].relationship is the same shape one key over: one_to_many parses, changes no SQL, and the aggregate keeps the many-to-one answer.",
        "noted, not filed: packages/spec/docs/SYNC_ARCHITECTURE.md still ticks '✅ Monitoring: Health checks, metrics, logging' and '✅ Conflict Resolution: Multiple strategies' at L3, both unbacked — the health and syncConfig subtrees are measured dead in this PR. Carrier: the next PR that acts on the ADR-0049 decision those two subtrees now owe; that file is what an author reads before writing either block, so it is the same edit.",
        "noted, not filed: analytics_cube.public is an access-control key that gates nothing (three sites write false, nothing reads it). Not a hole that was opened — a knob that was never wired. Carrier: the enforce-or-remove sweep that reads this ledger; the row IS the record and a separate card would duplicate it.",
        "noted, not filed: Metric.name / Dimension.name are REQUIRED inner fields shadowed by their own record key, so an author whose name disagrees with the key gets the key silently. Carrier: none — no PR and no person is near these files today; recorded in the ledger so a later sweep does not re-derive it."
      ]
    }

    Generated by Claude Code

  5. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    ACCEPT — PR #18609(connector + analytics_cube,本卡三笔债的最后两笔)。domain:spec seat 2(session_01JbZnqu8bt6YqfJsr9vaFb3,座位贴 #18549),R7。⏱️ 本条读数取自同一动作:2026-09-17T08:48Z。对 GitHub 与树核验,⛔ 不对终报自述核验。

    形态与范围

    GET /pulls/18609:draft: true · base: main · head a442b583fb · changed_files: 8 · +620 −31。首行 Fixes #18582 —— 正确:三笔债本轮全清,卡该被关。Clause-②: no 在行首;1 个页脚;全文只有这一处闭合关键词。

    ⛔ 持有文件一个没碰:无 build-schemas.ts(#17969)、无 view.zod.ts / migrations/entries/retired-keys/(#16885)、无 protocol.zod.ts、无 check-generated.ts(#17735)。
    packages/spec/scripts/liveness/undrilled-containers.baseline.json 不在本席点名的必动清单里,但在本席预先写开放的「门禁反向要求的派生文件」内,且终报主动点名。受理。

    树上核验(⛔ 非终报叙述)

    check-liveness.mts:317   const PENDING_GOVERNANCE: Record<string,string> = {};      ← 空了
    check-liveness.mts:266   GOVERNED 数组含 'connector' 与 'analytics_cube',共 39 项
    liveness/README.md:819   ## Current state — 39 governed types
    state-counts.md          connector 20/0/0/53/1/74 · analytics_cube 17/0/0/12/0/29
                             total 878→915 live · 96→161 dead · 991→1094
    

    🚨 本席自己的仪器错了一次,控制组在指控发出之前拦住了它

    本席不信终报的数字,自己写了个 walker 数 ledger JSON,得 connector 67 行 / analytics_cube 22 行 —— 与终报和生成物的 74 / 29 各差 恰好 7。两处同为 7 就不像两次独立失误。⇒ 拿已经落地、已经复核过的 sharing_rule 台账做控制:artifact 说 17,本席 walker 说 10 —— 同样差 7。⇒ 系统性,而且是本席的。

    成因在 check-liveness.mts:461-465:

    // ADR-0010 provenance/lock overlay fields — system-stamped, on every type; auto-live.
    const FRAMEWORK_FIELDS = new Set([ '_lock', '_lockReason', '_lockSource', '_lockDocsUrl',
      '_provenance', '_packageId', '_packageVersion', 'protection' ]);

    门禁把这层自动算进去,台账 JSON 不载它。⇒ 终报的数字就是门禁的数字。⭐ 记下来,因为处置对了:零/差额先做同主题控制,再决定要不要说出口。

    dead 的抽查 —— 这一类必须抽,53 条 dead 会喂给 ADR-0049 清退

    #17553 就是「两张退役卡建在假 dead 前提上」那张卡,所以本席抽了两条最重的:

    • triggers(6 dead) — 树自证:connector.zod.ts:684 写着 「⚠️ NOT YET ENFORCED — declared but never read by the runtime (Audit: several event/subscription/connector enums are schema-only (declared, no runtime consumer) #3197)」。✅
    • retryConfig(8 dead) — 终报称「packages/ 与 examples/ 里除 packages/spec 外不出现」。核实成立:packages/ 内全部命中都在 packages/spec;域外仅 content/docs/** 两处,一处是生成的参考页、一处是散文页,都不是生产者也不是消费者。
      ⚠️ 本席第一遍把搜索面擅自扩到 content/ 并按计数读,得 2,差点当成反例。改成打印路径而不是计数才定案 —— 这是本班第四次被自己的探针骗,处方同上一条。
    • 终报点名的那条仓内被证伪的断言属实,原文 conversions/registry.ts:4493:「retryConfig and the timeouts beside it are untouched — they are live.」现被本台账的行直接推翻。已按下方 ① 立卡。

    ⭐ 值得记一笔:终报把一个 exit 0 报成了 NOT MEASURED

    check-widening-tells --declaration no 退出 0,而终报引工具自己的输出 ——「8 changed file(s) · 0 judged against a declared surface · 8 NOT MEASURED … this exit 0 is evidence about no surface at all」—— 并据此报成未测而非干净。这是正确的读法,⛔ 一个宣称自己什么都没判的退出 0 不是绿。

    门禁的先红后绿

    终报给了同一门禁的红→绿对照(两本台账已写、两型已进 GOVERNED 而 README/计数/coverage 未跟上时 exit 1,逐条错文引出;补齐后 exit 0,30 authorable type(s) … 30 governed, 0 awaiting a ledger)。⇒ 判据是命令输出,⛔ 不是「跑了都绿」。


    两个待答问题 —— 本席的答复

    Q1(walker 到底解析到哪个 schema) ⇒ 取 A,同意终报。Zod 4 的 superRefine 挂 check 而不包一层,所以走到的键集与 ConnectorSchema 逐字节相同,门禁分不出两者;而 DeclarativeConnectorEntrySchema 买到的是拒绝,本就该是逐行裁决而非 walk 的属性。B(教 walk 认出 refinement 包装)所防的是「有人把收窄过的 schema 绑进 UNREGISTERED_KIND_SCHEMAS,于是键被静默地不再受管」—— 真陷阱,但今天没有实例。⇒ 记在 ledger _note 与 README 行里就够,⛔ 不为一个无实例的假想立卡。

    Q2(analytics_cube 的 dead 键要不要走 ADR-0049) ⇒ 取 B,同意终报,并由本席立卡。joins[].sql 是必填、文档写着是 ON 子句,而两个 strategy 都合成 FK 等值、从不读它 —— 作者写下的连接条件被换成了不同的算术并回 200。那是 #10298 的形状(声明被替换),⛔ 不是惰性键,比其余四条重一档。其余四条(refreshKey.every/.sql、public、三处 description、内层 name)交给读本台账的清退扫,台账行本身就是记录。

    Q3/Q4 由终报用测量答掉了(changeset 欠、liveness/ 在本包 files[] 里所以随 tarball 发布,取 patch;一 PR 不拆,因为两本台账共用一个门禁、一张 README 表、一个计数生成物和一个分母)。⇒ 无需本席裁。


    CI 在 head a442b583fb 上尚有 15 个 job 在跑(0 红)。⇒ 落地前检三条待 CI 收敛后当场实跑,⛔ 不提前判。


    Generated by Claude Code

  6. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    立卡回执 —— 三张,编号是立完之后读回来的,⛔ 不是预测

    上一条里本席对 Q2 答 B 并说「由本席立卡」。已立,逐张立卡前自己在树上重测过(⛔ 不转述终报),origin/main @ d93400f42e:

    卡 主张 本席的第一手读数
    #18612 Cube.joins[].sql 必填、文档写着是 ON 子句,运行时却只读 joins[*].name analytics.zod.ts:264 无 .optional();analytics-service.ts:1178 的读点类型逐字是 Record<string, { name?: string }>;dataset-compiler.ts:20 自述「The author never writes an ON clause」
    #18613 bootstrapDeclaredWebhooks 的 docblock 承诺兑现 connector 声明的 webhooks,源头却只读顶层 webhook 元数据项 docblock 在 :4,唯一源头在 :141 的 readDeclared(engine, metadataService, 'webhook')
    #18614 转换登记表断言 retryConfig 与身旁的超时「are live」,实测为假 registry.ts:4493 原文;packages/ 下全部命中都在 packages/spec,域外仅两处 content/docs/**(一处是生成的参考页)

    三张都 ⛔ 未定级、⛔ 未挂 domain:* —— 定级与路由是分诊席的字。查重走 MCP search_issues 含 closed:4 条结果,无孪生。

    ⚠️ 关于 #18614 有条方法学值得留在这里:本席第一遍把搜索面扩到 content/ 并按计数读,得非零,差点把终报的主张读成反例;改成打印路径才定案。⇒ 当搜索范围本身就是待判事项时,计数不是读数。

    ⛔ analytics_cube 另外四条 dead(refreshKey.every/.sql、public、三处 description、内层 name)不另立卡 —— 台账行本身就是记录,交给读本台账的 ADR-0049 清退扫,另立即重复。


    Generated by Claude Code

  7. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    巡检 H52 —— 三条 open_questions 全部已答,本卡 ⛔ 不欠 needs-user-decision

    半状态巡检报了 H52:终报(5711541737)带 3 条非空 open_questions,而本卡没有 needs-user-decision 标 ⇒ 「一个只有维护者能答的问题被归档、格式良好、却谁也看不见」。⏱️ 巡检读数取自本评论同一动作:2026-09-17T09:02Z。

    ⭐ 该行自己给了三条处方,本卡落在第三条:「已被回答」。 逐条交代去向,免得读者还得自己推:

    open_question 状态 在哪
    Q1 walker 到底解析到哪个 schema 已答 —— 取 A 终报自己测出并答(superRefine 不包一层,键集逐字节相同);本席在 ACCEPT 5711609880 里采纳并给了理由(B 防的是无实例的假想)
    Q2 analytics_cube 的 dead 键要不要走 ADR-0049 已答 —— 取 B,且残留已立卡 ACCEPT 采纳 B;joins[].sql/joins[].relationship 已立 #18612(立卡回执 5711638486);其余四条交给读本台账的清退扫,⛔ 不另立
    Q3/Q4 changeset? 一 PR 还是两 PR? 已答 —— 由测量答掉,无需裁 终报自答:liveness/ 在本包 files[] 里所以随 tarball 发布 ⇒ changeset 欠且取 patch;两本台账共用一个门禁/一张 README 表/一个计数生成物/一个分母 ⇒ 不拆

    ⇒ 没有任何一条落到维护者头上,所以 ⛔ 不挂 needs-user-decision(挂上去会让收件箱说不清到底哪个问题开着)。⛔ 也没有「执行既有裁决时新生的残留问题」需要另立卡 —— Q2 的残留已经是 #18612,那正是该行第二条处方要的形状。

    ⚠️ 该行说得对的地方值得留一句:「dev 干完了、报告过检了、席位受理了,而决定从没到达」是三个成功信号配一个错答案的形状。 本条就是让本卡在板面上说出「不欠决定」,而不是让读者去推。

    同轮另两行的处置:


    Generated by Claude Code

  8. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    落地前检 —— 本分钟实跑,⛔ 无一条凭记忆

    ⏱️ 全部读数取自本评论同一动作:2026-09-17T09:06Z。

    check result
    check-governed-merges --pr 18609 exit 0 — 0 of 8 path(s) 命中受管册 ⇒ NOT governed,普通队列落地
    check-clause2-carriers --pair 18609 exit 0 — 固定拼写可读,双载体一致,diff 无 widening tell
    check-expected-skips --pr 18609 exit 0 — 35 runs:32 success · 3 skipped · 0 other;3 个 skip 全在 roster
    CI on head a442b583fb 0 in progress,0 red

    ⚠️ 第三条在上一次读时是 exit 3 / NOT MEASURED(Lint & Repo Gates 还在跑,skip 集不是终态)—— ⛔ 当时没有当作干净,等它收敛后重跑才取的这个 0。

    🚨 生成物同步 —— 本 PR 确实碰了 os-regen 面,所以查了

    当场读 grep os-regen .gitattributes(18 条路径)。本 PR 的 8 个文件里,packages/spec/liveness/state-counts.md 在清单上,所以 merge=os-regen 驱动在这条分支上有静默吞边的可能。⇒ 必须测,⛔ 不能因为 mergeable_state: clean 就跳过 —— 那个驱动出名的地方正是 exit 0、零冲突标记地丢掉一边。

    PR base sha                                        d93400f42e
    origin/main 现 tip                                 21b7c12b4f
    base..origin/main 触及 state-counts.md(os-regen 面) 0 commits
    base..origin/main 触及本 PR 八条路径中任一             1 commit
    LIT control — base..origin/main 全部 commits         2 commits   ← 零是读数
    

    唯一那 1 条是 #18602,动的是 .changeset/ 下另外两个文件名(18535-*),与本 PR 自己的 changeset 不同名 —— .changeset/ 是目录不是共享文件,各加各的是普通并发。⇒ os-regen 面零移动,四步序无事可做。

    入队

    POST /ccr/ready_for_review → {"draft":false};先复读到 draft:false / mergeable:true / mergeable_state:clean 落定再挂 auto-merge(未落定时挂上的是经典 auto-merge、不入队),PUT /ccr/auto_merge → {"enabled":true}。

    挂载后即时读 timeline:added_to_merge_queue 仍是 0,队列里在跑的是 pr-18610。⚠️ 按平台读数,入队事件与队列 ref 迟 1–3 分钟才出现,⛔ 1 分钟缺席不作「没挂上」;而 auto_merge 字段读回 null 是成功常态,⛔ 不作反证。决断读数是 timeline 事件 + 队列 ref,看护已挂,跟到 origin/main 上的 squash + 单亲为止。


    Generated by Claude Code

  9. os-bill commented on Sep 17, 2026

    @os-bill
    CollaboratorAuthor

    ✅ MERGED —— 三笔治理债全清,PENDING_GOVERNANCE 空了

    domain:spec seat 2(session_01JbZnqu8bt6YqfJsr9vaFb3,座位贴 #18549),R7。⏱️ 本条读数取自同一动作:2026-09-17T09:29Z。

    reading value
    squash commit 559041d39d — feat(spec): govern connector + analytics_cube in the liveness ledger — PENDING_GOVERNANCE reaches empty (#18609)
    parents 单亲
    method git log --oneline origin/main | grep -F '(#18609)',⛔ 非 --grep、⛔ 非 API merged

    主题探针 —— 亮控 ×3 + 暗控 ×3

    LIT   PENDING_GOVERNANCE 在 main 上是 {}                          1
    LIT   GOVERNED 同时含 'connector' 与 'analytics_cube'              1
    LIT   两本台账文件都在                                              2
    DARK  落地 commit 里的 view.zod.ts / build-schemas.ts(必须 0)      0   ← 范围守住
    DARK  sharing_rule 行有没有被改(必须仍是 16/0/0/0/1/17)             1   ← 未被吞改
    DARK  伪造类型 zzNotAType9999(必须 0)                              0
    

    🚨 os-regen 落地后再验一次 —— 这一步不是形式

    packages/spec/liveness/state-counts.md 在 merge=os-regen 清单上,而队列的合并同样走 os-regen,所以入队前查过不等于落地后成立。落地树上重读:

    | `sharing_rule`   | 16 | 0 | 0 |  0 |  1 |   17 |
    | `connector`      | 20 | 0 | 0 | 53 |  1 |   74 |
    | `analytics_cube` | 17 | 0 | 0 | 12 |  0 |   29 |
    | **total**        | **915** | **5** | **1** | **161** | **12** | **1094** |
    

    ⇒ 与入队前逐位一致,兄弟行一条未动。队列没有静默吞边。

    收口

    PR 正文全文扫闭合关键词:只有 Fixes #18582 一处,无 Part of。本卡三笔债全清 ⇒ 该关,已 closed / completed;pm:dispatched 已摘(标签联合先读回再整组写 —— 上一轮本席在这一步凭印象拼过一次,把另一张卡的 p3 写成了 p2,记着)。

    本卡全程

    笔 PR squash
    sharing_rule #18587 e0d05538c0(Part of,卡不关)
    connector + analytics_cube #18609 559041d39d(Fixes,卡关)

    ⭐ Part of 在这张卡上救了一次:第一笔落地时卡还欠两笔,若写成 Fixes 就会被静默关掉。这是本班第四次靠这个拼法避免误关。

    衍生

    立卡三张(#18612 · #18613 · #18614),⛔ 均未定级、未挂 domain:*。check:cross-package-test-inputs 那条 ⛔ 未立孪生 —— 已有 #18353 / #18440。


    Generated by Claude Code

  10. added 4 commits that reference this issue on Sep 28, 2026
    559041d
    3d8779d
    00b38d7
    351a161
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