Skip to content

feat(spec)!: retire an analytics cube's refreshKey — every and sql, read by nothing (#20637) - #20710

Merged
os-justin merged 5 commits into
mainfrom
claude/issue-20637-cube-refreshkey-retired
Sep 29, 2026
Merged

os-justin merged 5 commits into
mainfrom
claude/issue-20637-cube-refreshkey-retired

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Closes #20637

analytics_cube.refreshKey (every and sql) is retired whole, per the maintainer's ruling C: a tombstone that refuses it with a migration note, a D2 conversion that strips it from stored cubes, one D3 entry, and the showcase author removed. Nothing read the key, and no analytics result cache exists.

Clause-②: no (narrowing)

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1

@github-actions github-actions Bot added size/l documentation Improvements or additions to documentation protocol:data tests tooling labels Sep 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 13 documentable anchor(s). ⚠️ 6 changed file(s) yielded no anchor (packages/spec/authorable-surface/data.json, packages/spec/liveness/README.md, packages/spec/liveness/analytics_cube.json, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

2 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/automation/hook-bodies.mdx (via issued_on (literal, a string literal in fixture))
  • content/docs/getting-started/quick-start.mdx (via analyticsCubes (literal, a string literal in apply))

⛔ 1 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17/17-5.mdx (via retiredAfter (symbol, a field of const object cubeRefreshKeyRemoved), retiredFromLoadPath (symbol, a field of const object cubeRefreshKeyRemoved), analyticsCubes (literal, a string literal in apply))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • 6 changed file(s) yielded no anchor (packages/spec/authorable-surface/data.json, packages/spec/liveness/README.md, packages/spec/liveness/analytics_cube.json, …) — pages documenting those are invisible to this run
  • 9 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 137 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 57574637129bebb4a6868c465be7e1b80eed1954 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from c262ec7489a868654f1460cbe973cc0daf38f58f — the merge of head a2abb8c78acc15892673a2dd36574ab9b5eca256 into base 57574637129bebb4a6868c465be7e1b80eed1954, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin c262ec7489a868654f1460cbe973cc0daf38f58f && git checkout c262ec7489a868654f1460cbe973cc0daf38f58f
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 57574637129bebb4a6868c465be7e1b80eed1954 a2abb8c78acc15892673a2dd36574ab9b5eca256 && git checkout -B drift-repro 57574637129bebb4a6868c465be7e1b80eed1954 && git merge --no-ff a2abb8c78acc15892673a2dd36574ab9b5eca256

node scripts/docs-audit/affected-docs.mjs --json 57574637129bebb4a6868c465be7e1b80eed1954

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 57574637129bebb4a6868c465be7e1b80eed1954 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: a2abb8c78acc15892673a2dd36574ab9b5eca256
Local-runs: none

Inputs read: card #20637 (body + 3 comments: ruling 5890724395, claim 5896065243, os-dev-report 5898076254), PR #20710 (body, 19 files, the three-dot diff against main 5757463712, merge base a8acee28dd), the 46 check-runs on the head, the tree at the head and at main via git show / git grep / git diff, .claude/skills/spec-property-retirement/SKILL.md, family card #20282 for context. Contract = ruling C (5890724395): retire analytics_cube.refreshKey whole, build no cache, tombstone + D2 strip + one D3 + showcase edit + ledger dead tombstone + generated surfaces + minor changeset with BREAKING / FROM → TO / Clause-②: no (narrowing) / ADR-0087 marker, retiredAfter = the label main carries at landing, no L card.

① Derived judgments

Accept-set changes the diff implies — each judged.

  • CubeSchema.refreshKey becomes retiredKey(CUBE_REFRESH_KEY_REMOVED) on a strictObject; the nested strictObject (every, sql) leaves with it. Accept set narrows: every value at refreshKey (each authored shape, {}, a string, null, 0) is refused at path ['refreshKey'] with the prescription; absence is accepted and materializes nothing; Cube types the key never. Right — the ruling's letter C, the retiredKey() route for a strictObject that must carry a prescription (the same-file Metric.name / Dimension.name precedent, spec(analytics): retire the inner name on cube measures and dimensions; the record key is the identity (2 keys) #20300).
  • Doors that now refuse it: CubeSchema.parse, defineCube(), defineStack({ analyticsCubes }) (STACK_SCHEMA_INVALID, 422, path analyticsCubes.0.refreshKey), the boot door ObjectStackDefinitionSchema, and the meta write door: UNREGISTERED_KIND_SCHEMAS binds analytics_cube: CubeSchema (kernel/metadata-type-schemas.ts:281), the write path's schema gate delegates to getMetadataTypeSchema (metadata-protocol/src/protocol.ts), and the new pin asserts the binding identity. Right, and the changeset's PUT /api/v1/meta/analytics_cube/:name claim is true on the tree.
  • Did-you-mean: strictObject's acceptsNothing keeps the tombstone out of the suggestion pool (pinned: refreshKy is refused as unknown, never steered onto refreshKey). Right.
  • D2 cube-refresh-key-removed: toMajor 18, retiredFromLoadPath: true, retiredAfter '17.5.0', surface 'analyticsCubes[].refreshKey', mapCollection + the local stripKeys helper with the cube NAMED in the notice path (the cube-join-sql-and-relationship-removed pattern), whole block stripped whatever it holds, one notice per stripped key, copy-on-write, idempotent by construction (pinned with a second replay). Fixture: three cubes, two carrying the key, expectedNotices: 2; disjoint from every other step-18 entry (no inner member name, no granularities, no join sql/relationship, no metric filters). Inserted in identifier order between cubeMemberInnerNameRemoved and cubeSubDayGranularitiesRemoved with order: 47; orders on the head are dense 1..47, no collision. Right.
  • Chain wiring: step18.conversionIds is read off CONVERSIONS_BY_MAJOR[18] by id (a .map over the list, migrations/registry.ts:5966), so the D2 is in the step without a hand edit; the pin asserts it. Right.
  • RETIRED_KEYS_BY_MAJOR[18] += data/Cube:refreshKey (entry file 18.data__Cube__refreshKey.ts, generated region regenerated). ONE row, not three. Right — gate (b3) in packages/spec/scripts/build-schemas.ts:1190-1232 refuses a nested row whose dotted path the build no longer emits, and a never tombstone emits no nested every / sql; the integration-style precedent the ruling names registered exactly one row (18.integration__Connector__triggers.ts, no triggers.interval row on the head). The pin asserts exactly one row with the data/Cube:refreshKey prefix.
  • D3 cube-refresh-key-retired in step18.semantic (entry file + regenerated region), one per family, reason names the D2 id, replacement says delete the key, non-empty acceptanceCriteria; surface has no backticks because build-upgrade-guide.ts:101,110 renders it inside a code span. Right.
  • STEP18_RATIONALE fragment cube-refresh-key-retired, order: 49 (unique), hand-written in id-sorted position between cube-metric-filters-retired and currency-config-precision-retired as step18-rationale-merge.test.ts requires. Right.
  • Batch-D D3 entry analytics-authorable-unknown-keys-refused: surface and acceptanceCriteria no longer offer refreshKey; reason records "two of the eight" sites removed (filters[] item by metric-filters-removed, refreshKey by cube-refresh-key-removed). Right — 8 sites at batch D, 7 on main, 6 on the head, and the strictness counts shard agrees (analytics.zod.ts 7 to 6, data/ 159 to 158, strict 76 to 75).
  • Liveness: the two drilled dead rows (refreshKey.every, refreshKey.sql) collapse into ONE leaf dead row with verifiedAt 2026-09-29 and a note in the house template (REMOVED date — tombstoned at the schema … stripped by the protocol-18 conversion … the entry stays because retiredKey keeps the key in the walked shape (the rls.priority precedent)). state-counts 20 / 6 / 26; README row 7 to 6 dead, and 6 = the refreshKey tombstone + three descriptions + two inner names. Right; the Spec property liveness check-run is the verdict on the walk.
  • Generated surfaces: authorable-surface/data.json row becomes data/Cube:refreshKey [RETIRED]; content/docs/references/data/analytics.mdx row becomes never with the [REMOVED] description retiredKey().describe() emits and the nested-shape table leaves; migrations/registry.ts regenerated regions. authorable-surface.base.json unchanged: it is the deletion gate's anchor, rewritten only by --update-base, and the siblings data/Metric:name, data/Dimension:name, integration/Connector:triggers, integration/Connector:health are bare there too. spec-changes.json and the upgrade guide unchanged: step 18 is not projected on this tree (cube-member-inner-name is absent from both as well). Right; Lint & Repo Gates runs check:migration-registry, check:spec-changes, check:upgrade-guide, check:authorable-surface, check:docs.
  • Showcase: the one in-repo author (showcase.cube.ts:87) stops writing the key; the app is private: true, so no changeset line is owed for it. Right.
  • Surfaces measured absent on the head and owed nothing: forms (**/*.form.ts), i18n bundle, published skills/, packages/lint, packages/platform-objects, packages/qa — 0 hits for refreshKey. Right.
  • Tests: analytics.test.ts (absence assertion tightened to not.toHaveProperty), analytics-strictness-batchd.test.ts (the nested sqll pin becomes a prescription pin, the batch-D verdict superseded not reopened), and the new cube-refresh-key-retirement.test.ts (tombstone at every door, D2 stored-row and artifact legs with a lit control, registration, and a tree-scoped absence walk over the five roots plus examples/*/src/**/*.ts, all of which scripts/cross-package-test-inputs.mjs already declares under @objectstack/spec with heldBy witnesses — the radius is declared, the diff did not need to touch it). Registered in vitest.repo-tests.json. Right.

Author-shown and AI-facing text — each sentence against the tree.

  • Prescription CUBE_REFRESH_KEY_REMOVED (also the mdx row, the batch-D pin, the changeset quote): "was removed in @objectstack/spec 17 (ADR-0049 enforce-or-remove)" — the version-LINE spelling, the connector-triggers precedent (four tombstones in integration/connector.zod.ts say exactly this). The same-file sibling (spec(analytics): retire the inner name on cube measures and dimensions; the record key is the identity (2 keys) #20300) named the next release (17.5.0) instead; both forms live on the tree and the migrate-sentence pin accepts both. True at the moment this lands (it ships in the 17 line, 17.6.0 or 17.7.0) and stays true whichever of those it is. "nothing read it: no analytics result is cached, so neither every nor sql ever refreshed anything" — true on main: git grep refreshKey over non-test packages/services, packages/drivers, packages/rest is empty; service-analytics references no ICacheService / IJobService; its only cache is the request-scoped dimension-labels.ts#withLabelFetchCache. "Delete the key; every analytics query is computed when it is asked." — true on main. "A refresh cadence is declared again when a result cache exists." — NOT a tree fact at any moment: it is the ruling's re-entry statement (5890724395), which the ruling orders into the prescription; true only after some future cache PR lands, and correctly sourced. "Run os migrate meta --from 17 …" — the house sentence, N-1 = 17 for toMajor 18; right.
  • Tombstone docblock: "0 lines, against 4 for the neighbouring .public in the same pathspec" (repeated in the changeset, the retired-key entry, the liveness note, the pin header) — reproduces on main ONLY with a word-bounded grep (\.public\b gives 4: analytics-service.ts:1579, cube-visibility.ts:6,55, datasource-connection-service.ts:535); a bare fixed-string .public gives 10 (publicLink, publicPicker, publicReason). True for the key spelling; a re-measurer needs the boundary to reproduce it. "repo-wide the key appeared only in this schema, its generated surfaces, the migration notes and one author" — over-broad as literally read: on main the word also appears in the liveness ledger, the strictness audit doc, packages/spec/CHANGELOG.md and two test files; the sentence's point (no reader) is true. "sql was security-adjacent as well: raw SQL run on a schedule" — describes what the key would have done; nothing ever ran it (the card says "would run"); over-broad by tense only.
  • D2 docblock: "only the D2 table is replayed at the rehydration seams (applyArtifactForwardConversions, applyConversionsToStoredItem), so a built artifact or a stored analytics_cube row that carries the key loads only through this entry" — true on main: production callers in metadata/src/loaders/database-loader.ts:825, objectql/src/plugin.ts:2107, metadata-protocol/src/protocol.ts:4784, metadata/src/plugin.ts:807, runtime/src/app-plugin.ts:917; stored.ts maps analytics_cube to analyticsCubes via manifest-collection-spelling.ts:93. "The strip is lossless: a key that never had an effect has none to lose." — true.
  • D2 summary (copied verbatim into spec-changes.json and the upgrade guide the day step 18 is projected — not on this tree): true.
  • Retired-key entry comment: "(the data/Metric:name precedent)" true; "a dotted row under a tombstoned parent names a path this build no longer emits (check (b3))" true (build-schemas.ts:1190).
  • D3 entry: "no analytics result was ever cached for them to refresh" — true; the service README once ADVERTISED enableCaching / cacheTTL and that was removed as fabricated (card body), so nothing was ever cached. "They never were." true.
  • STEP18 rationale fragment: every clause true on main; "as it still is" true at landing.
  • Liveness note: "Re-measured 2026-09-29 at 0be8984" — that commit is on main (docs(runtime): re-anchor the 20 dead tracker citations in domains/meta.ts to the commits that decided them #20689); "the connector health precedent" — connector.json health is a leaf tombstone; the note is template-conformant.
  • README row: arithmetic checks (1 + 3 + 2 = 6; 20 + 6 = 26).
  • Showcase comment: true.
  • Strictness ledger row (the two bold sentences the diff adds): "[finding] MetricSchema.filters is an authorable per-metric filter with zero consumers — a hand-authored cube's filters: [{ sql }] is parsed and dropped #10414" is the metric filters retirement (conversion comment registry.ts:7629, entry file); "their pins in analytics-strictness-batchd.test.ts now assert the retirement prescriptions" — true for both (Metric.filters pin at lines 164-167, Cube.refreshKey pin at 142-147). Observation, not this diff's sentence: the same row's pre-existing clause "analytics_cube resolves no getMetadataTypeSchema entry so saveMetaItem never parses it" has been stale since commit 2306a765c bound analytics_cube: CubeSchema; it is a dated audit record ("strict as of 未知键静默剥离仍是全仓默认:把 #3405 的 strict 收紧从一个 schema 推广到整个可授权面(ADR-0078 完整性闸门) #4001 batch D") and untouched here — a docs-only follow-up if the seat wants it, not a defect of this PR.
  • Changeset: '@objectstack/spec': minor (major is refused by check-changeset-no-major.mjs); BREAKING banner; Clause-②: no (narrowing); FROM → TO table; one-line fix; the retirement-kit section; the marker line naming cube-refresh-key-removed and cube-refresh-key-retired in the registered form check-adr-0087-registration.mjs documents, both ids resolving on the head (D2 in ALL_CONVERSIONS, D3 in step18.semantic) — that gate is not a named check-run on this head; verified by reading. "you wrote (17.5 and earlier)" — true now (see the stamp below). "PUT /api/v1/meta/analytics_cube/:name … refuses it" — true (above). "one notice per cube" — per cube that CARRIED the key; a canonical cube gets none (the fixture's own control) — over-broad by a clause, harmless. "A built artifact or a stored analytics_cube row that carries it loads through the rehydration seams, which replay it" — true. "No deprecation window" — house posture. "out-of-repo consumer population is NOT MEASURED" — honest and required.
  • PR body: "a D2 conversion that strips it from stored and authored cubes" — stored rows and built artifacts are stripped at the seams; an AUTHORED source is refused at parse (retired from the load path) and os migrate meta --from 17 only LISTS the edits to apply by hand. Over-broad by one word; the changeset states it correctly; the PR body is not shipped text. "Closes [Decision] analytics: a cube's refreshKey has nothing to key on — build the cache for every and retire sql, keep both as authored intent, or retire both (the refreshKey half of #20282) #20637" is right: the ruling made this card the retirement card and the showcase edit rides it.

retiredAfter against the label main carries. main (5757463712) has packages/spec at 17.5.0 (tag @objectstack/[email protected] exists); the stamp '17.5.0' equals it, as the ruling requires, and matches the only other unpublished entry (connector-triggers-removed, also 17.5.0). The census (retired-after.census.json) ends at 17.4.0, so the label is ahead of it and the census pin tolerates any stamp from 17.4.0 up to the label — it would NOT catch a stale stamp. If the open Version Packages PR #20639 (head 14f155ab7d, proposes @objectstack/[email protected]) lands first, two things must move before this PR lands: retiredAfter: '17.5.0' to '17.6.0' in packages/spec/src/conversions/registry.ts, and the changeset table header "you wrote (17.5 and earlier)" to "17.6 and earlier". The prescription's "17" and --from 17 are version-line spellings and do not move. The seat re-checks the label at enqueue; the census pin catches a wrong stamp only after the next tarball is censused.

② Semver level

The diff publishes from @objectstack/spec only: a breaking narrowing of the authorable surface (refreshKey refused at parse, Cube['refreshKey'] typed never), one new D2 conversion, one new D3 entry, one new retired-key registration. examples/app-showcase is private: true; content/docs, docs/audits, the liveness ledger and the changeset itself publish nothing. The changeset '@objectstack/spec': minor with the BREAKING banner is the house encoding of a breaking change while check-changeset-no-major.mjs holds; the PR body and the changeset both carry Clause-②: no (narrowing), one arm, and the arm matches the diff (pure narrowing, nothing widened). No other released package is touched, so no second changeset line is owed. Check Changeset on the head: success. Level: right.

③ Boundary flags

  • Dev report 5898076254 carries no deviations field and open_questions: []. The one departure from the dispatch wording ("every and sql leave with their retired-key rows"): one RETIRED_KEYS_BY_MAJOR row instead of three. Answered above — forced by gate (b3), matching the integration precedent the ruling names; the liveness rows for every / sql did leave (collapsed into the leaf). Not a breach.
  • out_of_scope_findings[0] — check:platform-checklist exits 1 on main (ABSENT SYMBOL plugin-auth/src/auth-plugin.ts#twoFactor cited by identity-auth.json, folded inline by PR fix(plugin-auth): a refused auth setting no longer drops the settings saved with it #20429). Neither input is in this diff; it is the daily watchdog, not a check-run on this head. Escalated to the seat as a separate card or docs fix; not a condition on this PR.
  • out_of_scope_findings[1] — the retiredAfter / chore: version packages #20639 ordering. Judged in ①: right today; two edits owed if chore: version packages #20639 lands first; the seat enforces it at enqueue because the census pin cannot yet.
  • Locally NOT MEASURED by the dev (build-schemas-check-mode.test.ts, check:dual-build-cjs-loads, check:type-check-debt): all covered by the head's check-runs (Test Core 1-6 + aggregate, Type Check · debt ledger, Build Core), which are the verdicts.
  • Console Pin Gate was skipped on this head (path filter). The dev reports every refreshKey hit in the pinned objectui is a React prop, none cube-related; the objectui tree is outside this brief's input set and that measurement is not re-verified here. The removed thing is a schema key, not an exported symbol, so the exposure is limited to an objectui site that would AUTHOR a cube with refreshKey — none is claimed to exist.
  • Serial constraints from the claim (#20282 stage 3 and #20662 after this card) are the seat's sequencing, not this PR's content. The dev merged a8acee28dd (carries PR docs(spec): re-anchor the dead tracker citations in conversions/registry.ts and integration/connector.zod.ts to the ADR and commits that decided them (stage 8) #20690 and feat(spec): AnalyticsResult declares object, the dataset answer's base object #20687) as ordered; a8acee28dd is on main, and the 7 later main commits touch none of the 19 files.
  • No L card was filed (2 API writes: the PR and the report) — per ruling C.

Check-runs on a2abb8c78acc15892673a2dd36574ab9b5eca256, read last, deduped by name keeping the newest started_at: 46 raw runs, 35 names, all completed; 31 success, 4 skipped (Auto Label, Check PR Size, Console Pin Gate, Packed-tarball smoke (opt-in)), 0 failure, none still running. Named gate families all green: Build Core, Build Docs, Check Changeset, Check Documentation Links, Dogfood Regression Gate (1-3 + aggregate), Dogfood Verify CLI, Flag docs affected by code changes, Governed Surface Queue Guard, Lint & Repo Gates, the three PR-automation claim guards, Spec property liveness, Temporal Conformance (live PG + MySQL), Test Core (1-6 + aggregate), Type Check · consumer gates / debt ledger / source gates / workspace, TypeScript Type Check, filter.

Implemented-by: claude/issue-20637-cube-refreshkey-retired
Reviewed-by: session_01Sfe5YjBLwB9J3y8fvm2xq1

VERDICT: PASS

Adopted and posted by domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1) · 2026-09-29T20:53Z · rendered by the seat's at-tier review subagent on this head. The seat read its served tier family from the subagent transcript before posting.

  • The PR body's over-broad clause is cut to "strips it from stored cubes". An authored source is refused at parse, and os migrate meta lists the edit. The head does not move.
  • The other wording notes the record rates not false in effect stay as written.
  • retiredAfter gate at enqueue: the seat re-reads Version Packages PR chore: version packages #20639 and main's packages/spec version right before arming auto-merge. At this reading chore: version packages #20639 is open and main carries 17.5.0, so the stamp holds. If chore: version packages #20639 lands first, the two named edits come before landing.
  • ③ The pre-existing platform-checklist twoFactor finding is the daily watchdog's to file. It is outside this card.

Generated by Claude Code

@os-justin
os-justin marked this pull request as ready for review September 29, 2026 20:56
@os-justin
os-justin enabled auto-merge September 29, 2026 20:56
@os-justin
os-justin added this pull request to the merge queue Sep 29, 2026
Merged via the queue into main with commit 1ab9892 Sep 29, 2026
58 checks passed
@os-justin
os-justin deleted the claude/issue-20637-cube-refreshkey-retired branch September 29, 2026 21:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation protocol:data size/l tests tooling

Projects

None yet

2 participants