Skip to content

fix(lint): one-line fix lines for 15 author-time rule ids; os explain RULE_ID carries what they enumerated - #22878

Merged
objectstack-fleet[bot] merged 12 commits into
mainfrom
claude/issue-22161-s2-lint-slice-11-hints
Oct 11, 2026
Merged

objectstack-fleet[bot] merged 12 commits into
mainfrom
claude/issue-22161-s2-lint-slice-11-hints

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Part of #22161
Clause-②: no

Stage 2 of the card, slice 11: the over-long fix: lines, item 3 of slice 10's landing record as triage routed it. Each finding's hint (the CLI's fix: line, the runtime issue's hint) of 15 packages/lint rule ids is now one remedy sentence of at most 200 characters, and what the lines used to enumerate is each id's RULE_EXPLANATIONS entry behind os explain RULE_ID. The card stays open: 107 author-time ids still carry a hint over 200 characters (below).

What changes

  • One remedy line per finding. The 15 ids, the longest hint the lint suite fires, before → after:
rule id file lint suite: hints · range, before → after runtime door
sharing-rule-runtime-variable-condition validate-sharing-rule-enforceability.ts 1 · 2,280 → 1 · 195 CLI only
sharing-rule-unlowerable-condition same 3 · 387–968 → 3 · 172–199 CLI only
approval-approvers-may-resolve-empty validate-approval-approvers.ts 2 · 440–2,243 → 2 · 198–200 flow write, 2xx advisory
rls-predicate-unenforceable validate-rls-predicate-enforceability.ts 27 · 191–1,056 → 27 · 62–191 permission write, 422
rls-predicate-over-budget same 3 · 1,037–1,044 → 1 · 197 permission write, 422
rls-predicate-unknown-field same 5 · 651–766 → 1 · 154 permission write, 422
filter-empty-combinator validate-empty-combinators.ts 3 · 647–764 → 3 · 125–154 flow / report write, 422
permission-retired-lifecycle-residue validate-retired-permission-residue.ts 2 · 573–681 → 1 · 14 permission write, 2xx advisory
visibility-predicate-over-budget validate-visibility-predicates.ts 2 · 645–651 → 2 · 177–179 view write, 422
hook-api-update-readonly-field validate-readonly-hook-writes.ts 8 · 604–647 → 8 · 153–182 CLI only
react-chart-aggregate-invalid validate-react-page-props.ts 3 · 111–363 → 3 · 113–191 CLI only
react-chart-drilldown-invalid same 2 · 114–128 → 2 · 128–181 CLI only
flow-time-relative-descriptor-invalid validate-flow-trigger-readiness.ts 1 · 342 → 1 · 176 flow write, 422
component-type-unknown validate-component-types.ts 16 · 32–229 → 16 · 32–158 CLI only
field-no-consumers validate-field-consumers.ts 15 · 68–189 → 16 · 68–175 (showcase os validate: 24 · 68–624 → 24 · 68–199) CLI only

A count that falls is several old hints that differed only in what the new line no longer lists (the over-budget bound's name, the object's field list, the retired key's name). The drill-down hint grows: it carried a pointer, and now carries the remedy.

  • The named five (slice 8's four, plus slice 10's).
    • sharing-rule-runtime-variable-condition (2,280): the hint was the whole mechanism essay. It is now "keep only the record's own properties in condition and name the audience in sharedWith; what replaces current_user depends on the object's sharingModel". ⛔ The one-line hint recommends no RLS at all, because an RLS policy narrows only public_read / public_read_write and grants nothing on private. The model-qualified split, the AND-composition, the ADR-0057 D1 depth scopes, the position over-broad-grant trap and the record-relative gap are the explanation's, with the The sharing-rule-runtime-variable-condition fix-hint sends authors to RLS to widen a private object, but the layers are AND-composed — the advice cannot work on the case that most needs it #14234 wording legs moved there (an RLS sentence must name the models it holds for) and a new leg that holds the hint to naming no RLS.
    • Slice 5's three "above" hints, which pointed at verdict text slice 5 cut: react-chart-drilldown-invalid and react-chart-aggregate-invalid ("the rejection above carries the fix") now say "use the rename it suggests, or delete / move a key real on another surface / one layer out"; flow-time-relative-descriptor-invalid ("satisfies each message above") now says to start with the key the verdict names and re-run until the schema accepts it.
    • component-type-unknown's "Apply the prescription above": the retired arm now carries the prescription's own "Delete the …" sentence, cut (never rewritten) by retiredTypeRemedy() from RETIRED_PAGE_COMPONENT_TYPES, at its first dash only when the sentence would pass 200 (for element:form: "Delete the element:form component and use the object-bound object-form block instead").
    • approval-approvers-may-resolve-empty's manager arm (2,243 on main after feat(plugin-approvals): an empty admin_rescue slate opens on the organization's administrators; retire the unstaffed arm #22850): "Set every submitter's sys_user.manager_id (Setup → Users → Set Manager, or the admin user import), or add an approver that cannot resolve empty". MANAGER_ONLY_REMEDY / MANAGER_ONLY_ROUTES move, verbatim and under the same names, into the id's explanation; the rule file keeps the measurement docblock behind each graded route. The group arm (463) is one line too.
    • field-no-consumers' carrier list (629 printed, 624 as the hint): the first carrier site and (and N more), the shape its verdict's same-name clause already uses.
  • Enumerations cut to the first item and a count, elsewhere. rls-predicate-unenforceable rewrites the first faulty site and counts the rest; for a bare current_user it names the key slot instead of listing every kernel key. rls-predicate-unknown-field drops the object's field list (the verdict's "Did you mean" names the nearest column). permission-retired-lifecycle-residue carries the tombstone prescription's "Delete the key" sentence, cut by retiredKeyRemedy() (the clause after its dash, on what stays denied, goes to the explanation), never retyped.
  • The explanations gain paragraphs; no entry is added or removed. The lowerable subset and its traps, the comparison classes with their types (a new shared CROSS_CLASS_LISTING paragraph, held equal to CROSS_FIELD_CLASS_LISTING by both rules' cross-class tests), the rule each current_user holding breaks, the null-comparand rewrites, the four ways to shrink an RLS predicate (with the top-level && warning kept on the one-line hint as well), the declared match-nothing filter spelling, the drop-the-field alternatives for a readonly hook write, and what deleting a retired permission key leaves. CROSS_CLASS_REMEDY (module export, not on the barrel) is gone; each rule's line names its own alternatives.
  • Nothing else moves. Every message, rule id, severity and path, and what each rule accepts or refuses, is unchanged: every hunk in the 11 rule files is a hint expression, a comment, a hint constant, or a string-in / string-out cut helper (retiredTypeRemedy, retiredKeyRemedy, firstPathAndCount, firstAndCount); typeFaultRewrite keeps one rewrite per site and kernelKeysHolding (which fed only the removed alternatives) is deleted. No condition, branch, skip or dedupe moved.
  • .changeset/22161-lint-slice-11-one-line-fix.md: @objectstack/lint patch, Clause-②: no, naming every door that prints fix: and the runtime hint FROM → TO.

The runtime wire (Zone 2 item 4)

Measured at the door with runRuntimeAuthoringRules on the base dist and on the rebuilt one (scratch probe):

  • a flow write: flow-time-relative-descriptor-invalid (422 issues[].hint, 342 → 176), filter-empty-combinator (422, 647 / 764 → 134 / 154), approval-approvers-may-resolve-empty (2xx advisories[].hint and the [Protocol] authoring advisory log line, 2,243 / 440 → 198 / 200);
  • a permission write: rls-predicate-unenforceable (422, 912 / 312 → 186 / 121), rls-predicate-unknown-field (422, 708 → 154), permission-retired-lifecycle-residue (2xx advisory, 573 / 681 → 14); rls-predicate-over-budget runs on that write but fires only once the platform CEL bounds refuse (the suite holds it with atGa), so the probe drew no finding either side;
  • a view write: visibility-predicate-over-budget (422, 651 → 179);
  • a hook write runs none of the 15; the sharing-rule, component-type, react-chart, field-no-consumers and hook-api-update-readonly-field ids are CLI only.

Readers of hint, measured read-only against objectui main at dca25af (git grep, no edit): Studio's saveAdvisoryToast.ts formatFinding renders [rule] where — message hint for every 2xx advisory, and DraftChangesPanel.tsx renders p.hint || p.message for the in-browser security-posture lint (none of the 15). metadata-client.ts readSaveAdvisories checks only that hint is a string. The 422 issues renderers (ResourceEditPage.tsx) read path and message. REST (PUT /api/v1/meta, SaveMetaItemResponseSchema.advisories, the error envelope's issues) forwards the array as JSON; packages/mcp has no metadata write tool, so an MCP or AI author reaches the gate through REST. No reader in this repository or in objectui matches on hint text; the one text match in this repository's sources (check-yaml-examples.ts) reads an unrelated object.

check:watch-hint-literal guards something else of the same name: that every *_WATCH_HINTS population declaration in a gate script is a literal array (a computed one drops out of dispatch-gates). It ran green before the gate set (72 declarations across 4 rostered names) and inside it.

Census (taken first, before any edit, at the base 31b5a5f7f5)

Method: slices 4 to 10's scratch preload (NODE_OPTIONS=--import, never committed), patching Array.prototype.push to record every finding-shaped object, here deduped by (rule, hint) per process, with its push site. Lengths are the hint alone. Runs, each before and after:

  • packages/lint suite (137 files, 6,455 tests at the base): 240 ids fire; 144 carry a hint over 200: 21 of the 26 fenced ids, 3 repo-gate ids (lint-startup-registry-verdict.ts), and 120 author-time ids. The named five's 7 ids and the 8 longest others (excluding the two lint-flow-patterns.ts ids, below) are this slice's 15.
  • Runtime publish gate, the whole @objectstack/metadata-protocol suite reading @objectstack/lint from its built dist (base dist before, rebuilt after): fires rls-predicate-unenforceable (300 → 139) and permission-retired-lifecycle-residue (573–681 → 14) of the 15.
  • packages/cli unit tier (281 files): fires hook-api-update-readonly-field (622 → 175) and field-no-consumers' unchanged inert line (68).
  • os validate (the built CLI) on app-crm, app-todo, app-showcase, app-multi-package, exit 0 each, before and after: field-no-consumers crm 68–336 → 68–179, todo 263–339 → 168–196, showcase 68–624 → 68–199, multi-package 68 → 68; approval-approvers-may-resolve-empty fires on the showcase, 440–2,243 → 198–200 (FROM measured on main after feat(plugin-approvals): an empty admin_rescue slate opens on the organization's administrators; retire the unstaffed arm #22850). Each app prints the same number of rule: lines before and after (9 / 7 / 70 / 3).

Tests

Every heavy run went through scripts/pm/os-verify-lock.sh; its VERDICT lines are in the report.

  • Each rule's own suite pins the new shape. Every touched suite records what its cases fire; a new last block per id holds every recorded fix: line of the converted ids to one line of at most 200 characters behind a coverage control (each arm fired: the three unlowerable arms across the main file and its two siblings; both empty-slate arms; the shape, type-fault and null arms; all three combinator shapes; both retired keys; both readonly-hook verbs; every retired component type and the own-namespace arm; the counted carrier arm), plus exact pins per arm and a pin per id that explainRule(id) holds what the line stopped saying. Pins that read the old hint text moved to the explanation, text-only; the four sibling files' bounds are scoped to the converted ids (the anchor and unknown-user-variable / unparseable ids keep longer hints).

  • Lint suite at the final head: Test Files 137 passed (137), Tests 6,496 passed (6,496); VERDICT command-exit 0.

  • Lint build + typecheck: pnpm --filter @objectstack/lint build (check-dts-emitted 6/6) and run typecheck (check:test-typecheck OK, 2 files / 6 errors / 2 pinned signatures held), VERDICT command-exit 0. The rebuilt dist carries the new text (Staff at least one target 1 hit in each of index.js, index.cjs, runtime.js, runtime.cjs; Apply the prescription above 0).

  • CLI unit tier on the rebuilt dist: Test Files 281 passed (281), Tests 4,196 passed (4,196); VERDICT command-exit 0. No packages/cli or packages/metadata-protocol test asserts these ids' hint text, so the declared rider went unused; the runtime-gate test that reads the residue hint asserts its length over 10 (Delete the key is 14).

  • Runtime gate: the whole @objectstack/metadata-protocol suite, after: Test Files 225 passed, 3 skipped (228), Tests 28,131 passed, 19 skipped; VERDICT command-exit 0.

  • Corpus pins over packages/lint/src: pnpm --filter @objectstack/spec test:repo: Test Files 55 passed (55), Tests 971 passed (971); VERDICT command-exit 0. No new text carries an os migrate meta --from sentence (the residue explanation names os migrate meta without one), and no tracker id is in a printed hint or explanation (citations stay in comments and test names).

  • Ablation (one-shot, from the committed head b4cf329ada, through scripts/ablation-replace.mjs under the lock, with a shell trap restoring HEAD by absolute path). The rule suites import the rule source, so there is no dist leg. permission-retired-lifecycle-residue's pre-slice line was restored: hint: retiredKeyRemedy(prescription), → hint: prescription, (anchor x1 → x0, blob 52140529de29 → c568d4a53e68). Predicted before the run: exactly the exact-remedy case and the new bound pin go red. Observed: src/validate-retired-permission-residue.test.ts Tests 2 failed, 21 passed (23), exactly those two; the bound pin read 573. Restored: blob 52140529de29 == HEAD, git diff HEAD empty, git status --porcelain empty.

  • ESLint, narrowed: npx eslint --no-inline-config --format json over the 28 changed .ts files: 28 files in the report, 0 errors, 0 warnings. The population is eslint.config.mjs's **/*.{ts,…} block plus its packages/** blocks; the config never enables type-aware linting (no parserOptions.project), so no untouched file's verdict can move. A control-character scan of every changed file found no match.

  • Gates: two merges of origin/main through scripts/pm/os-regen-merge.sh (to 12b9daf749, then 55382dc02a; neither touched a line this slice edits, and the branch edits no generated artifact). node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack with no paths at the final head b4cf329ada derived 62 commands; 60 ran, each exit code captured before any pipe, all 0. NOT MEASURED, as dispatched: check:dual-build-cjs-loads (needs every package's dist) and check:type-check-debt (its script is --re-measure; check:type-check-coverage ran). --ran: Run reconciliation — 62 derived, 60 run, 2 NOT-MEASURED, 0 UNRUN. The artifact-roster block (51 families): the 48 that need no pull request exited 0 at b4cf329ada, check:published-readme-exports after building its four missing dists (client-react, embedder-openai, knowledge-ragflow, organizations) under the lock; the three PR-context guards run against this PR and report on the card.

  • Round 2 (seat order 6111995055):

Remaining for this card

Acceptance notes

  • A long name can still lengthen a line. The bound holds on every variant the suites and the four example apps fire; the names in a hint (object, field, carrier path, rewritten predicate) are the author's. The closest measured case is field-no-consumers on showcase_project_membership.allocation_percent at 199, whose first carrier path is 80 characters.
  • field-no-consumers' carrier list beyond the first now prints nowhere on the CLI. The finding object still holds every site in carriers for a programmatic caller, but os validate --json carries an advisory as one where: message string and os lint --json maps the finding to fix without carriers. The card's "Asked for" names no carrier list at all; the first site plus the count is the dispatch's route.
  • The spec's pointer moved with the remedy (round 2, the seat-authorized rider, order 6111995055). ApproverType's .describe() (packages/spec/src/automation/approval.zod.ts) now points at os explain approval-approvers-may-resolve-empty, and its comment names rule-explanations.ts as the carrier. The reference page content/docs/references/automation/approval.mdx is regenerated, and .changeset/22161-spec-approver-type-describe.md (@objectstack/spec patch, Clause-②: no) carries it. This PR now publishes @objectstack/lint patch and @objectstack/spec patch.
  • rls-predicate-unknown-field's old hint said a missing column is "an outage in one position and an open door in the other", which the explanation's own history note records as no longer true (the compiled-predicate guard fails closed everywhere). The sentence is not carried into the explanation.

Generated by Claude Code

…ations move to os explain

WIP: hint text and RULE_EXPLANATIONS data only; tests updated text-only.

Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF
Co-authored-by: Claude <noreply@anthropic.com>
…rrier example verbatim

Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF
Co-authored-by: Claude <noreply@anthropic.com>
…-lint-slice-11-hints

# Conflicts:
#	packages/lint/src/rule-explanations.ts
#	packages/lint/src/validate-approval-approvers.ts
…s and explanation to #22824's administrators' slate

Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF
Co-authored-by: Claude <noreply@anthropic.com>
…approvers-may-resolve-empty

Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/xl documentation Improvements or additions to documentation tests tooling labels Oct 11, 2026
@github-actions

github-actions Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/lint, @objectstack/spec, touching 43 documentable anchor(s).

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

  • content/docs/automation/approvals.mdx (via ApproverType (symbol, a top-level const object), idp_provisioned (literal, a string literal in MANAGER_ONLY_ROUTES), org_membership_level (literal, a string literal in GROUP_ONLY_FIX; a string literal in MANAGER_ONLY_FIX; a string literal in validateApprovalApprovers), /api/v1/auth/admin/import-users (route, a path literal in MANAGER_ONLY_ROUTES), /api/v1/auth/admin/set-user-manager (route, a path literal in MANAGER_ONLY_REMEDY))
  • content/docs/automation/hooks.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/automation/index.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/automation/workflows.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/capabilities/approvals.mdx (via /api/v1/auth/admin/set-user-manager (route, a path literal in MANAGER_ONLY_REMEDY))
  • content/docs/concepts/architecture.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/data-modeling/analytics.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/data-modeling/seed-data.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/data-modeling/validation.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/deployment/validating-metadata.mdx (via validateRlsPredicateEnforceability (symbol, a top-level function), validateSharingRuleEnforceability (symbol, a top-level function))
  • content/docs/permissions/authentication.mdx (via /api/v1/auth/admin/import-users (route, a path literal in MANAGER_ONLY_ROUTES))
  • content/docs/plugins/packages.mdx (via org_membership_level (literal, a string literal in GROUP_ONLY_FIX; a string literal in MANAGER_ONLY_FIX; a string literal in validateApprovalApprovers))
  • content/docs/protocol/objectql/state-machine.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))
  • content/docs/protocol/objectui/concept.mdx (via closed_won (literal, a string literal in RUNTIME_VARIABLE_REMEDY))

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

  • content/docs/releases/v14.mdx (via org_membership_level (literal, a string literal in GROUP_ONLY_FIX; a string literal in MANAGER_ONLY_FIX; a string literal in validateApprovalApprovers), /api/v1/auth/admin/import-users (route, a path literal in MANAGER_ONLY_ROUTES))
  • content/docs/releases/v16.mdx (via ApproverType (symbol, a top-level const object), org_membership_level (literal, a string literal in GROUP_ONLY_FIX; a string literal in MANAGER_ONLY_FIX; a string literal in validateApprovalApprovers), /api/v1/auth/admin/import-users (route, a path literal in MANAGER_ONLY_ROUTES))
  • content/docs/releases/v17/17-5.mdx (via /api/v1/auth/admin/set-user-manager (route, a path literal in MANAGER_ONLY_REMEDY))
  • content/docs/releases/v17/17-7.mdx (via org_membership_level (literal, a string literal in GROUP_ONLY_FIX; a string literal in MANAGER_ONLY_FIX; a string literal in validateApprovalApprovers))

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
  • 1 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 — 139 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 72b26ed4f5dcdf32b4b167764fa1ecc71121f181 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 54bc8794e32097fe1b6d2656cb3d3d4df294aed2 — the merge of head 6e2c2f068ce1cbd146cecabcfee138e04b11a4ec into base 72b26ed4f5dcdf32b4b167764fa1ecc71121f181, 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 54bc8794e32097fe1b6d2656cb3d3d4df294aed2 && git checkout 54bc8794e32097fe1b6d2656cb3d3d4df294aed2
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 72b26ed4f5dcdf32b4b167764fa1ecc71121f181 6e2c2f068ce1cbd146cecabcfee138e04b11a4ec && git checkout -B drift-repro 72b26ed4f5dcdf32b4b167764fa1ecc71121f181 && git merge --no-ff 6e2c2f068ce1cbd146cecabcfee138e04b11a4ec

node scripts/docs-audit/affected-docs.mjs --json 72b26ed4f5dcdf32b4b167764fa1ecc71121f181

⚠️ 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 72b26ed4f5dcdf32b4b167764fa1ecc71121f181 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

… re-pointed description

Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF
Co-authored-by: Claude <noreply@anthropic.com>
… main after the administrators' slate landed

The slice changeset's FROM figures for approval-approvers-may-resolve-empty
were measured before the merge that brought in the administrators' slate:
main's hints are now 2,243 (manager arm) and 440 (group arm) characters,
and the group arm's one-line fix is 200 characters after it was restated
in that verdict's words. The spec changeset now says plainly that the
describe's "the request waits" clause names the onEmptyApprovers policy,
and that the default policy opens the request on the organization's
administrators.

Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Landing pre-checks at 6e2c2f068c, by the owning seat: all green, queued

domain:spec seat 3 (#18883) · zhuangjianguo · session session_01KNKBCRDJCu5tGy3TEbvtrF · 2026-10-11T19:47Z · holder of claim 6109573368 on #22161.

  • The review: the seat's ACCEPT 6112984677 on this head.
    • Hint prose, RULE_EXPLANATIONS data and one ApproverType description (@objectstack/lint patch and @objectstack/spec patch, both Clause-②: no).
    • No pending changeset of another card is edited, so no contract review is owed.
    • The PR body was corrected by the seat to the round-2 figures (one issue_patch, read back identical).
  • CI: 42 check-runs, 38 success and 4 skipped, including the re-runs the body edit started. check-expected-skips --pr 22878 reads all four in the roster.
  • Governed: check-governed-merges --pr objectstack-ai/objectstack#22878 reads NOT governed: +1,235 / −423, under the human-merge threshold.
  • Closing keywords: the body opens Part of #22161 and carries no closing keyword, and neither does any commit message. The card stays open for its later slices.
  • main drift since the merge base f9ebb7dd31: main (now b1d701b60a) moved none of the PR's paths. git merge-tree against it exits 0 (clean). GitHub reports mergeable: true, clean.

pr_ready and automerge_enable follow.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 11, 2026 19:47
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 11, 2026 19:48
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 11, 2026
Merged via the queue into main with commit 2e11d90 Oct 11, 2026
44 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-22161-s2-lint-slice-11-hints branch October 11, 2026 20:17
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 size/xl tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants