Skip to content

feat(spec)!: ListView.userActions.editInline defaults to true on the v18 line; editInline: false is the opt-out (#22605, spec half) - #22629

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-22605-edit-inline-default-on
Oct 10, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-22605-edit-inline-default-on

Conversation

@objectstack-fleet

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

Copy link
Copy Markdown
Contributor

Part of #22605
Clause-②: no

The spec half of #22605: ListView.userActions.editInline defaults to true on the v18 line, and userActions: { editInline: false } is the opt-out. The skills/** paragraph the card also asks for is a separate pull request (Tier H), so this one is Part of, not Fixes.

The ruling

Maintainer, 2026-10-10, verbatim (filed by the director seat on the card): 「乙 v18 把 spec 默认翻成 true,editInline: false 变成关法。」 A list view is editable in place by default, under the permission gate that already exists. The rule of objectui#5144 stands (one vocabulary, the inlineEdit fold, declared = enforced); only the default's value changes. Not taken: declaring editInline: true on every existing view (objectstack-ai/hotcrm#2048 and #22604 are superseded by the ruling, and stay open here — this PR does not act on either), and an app-level default. The permission gate is untouched. The consumer half is objectui's, objectstack-ai/objectui#12086; in the window the console at the pinned objectui still reads an absent key as off, so nothing regresses against today.

What changed

  • packages/spec/src/ui/view.zod.ts — UserActionsConfigSchema.editInline is z.boolean().default(true), describe rewritten (on by default; a user who may update the object edits a cell in place with the field's type-aware widget, under the permission gate; declare editInline: false to make the list read-only in place). The schema docblock records the ruling beside the group/hideFields/rowColor asymmetry it already explains.
  • packages/spec/scripts/lib/default-changes.ts — DEFAULT_CHANGES_BY_MAJOR[17] gains ui/UserActionsConfig:editInline false → true with its reason. This is what lets check:authorable-surface accept the moved fingerprint; CURRENT_MAJOR is the package major (17) until the version pass takes the group to 18. The build printed 📌 1 declared default change(s) accepted (#4666): ui/UserActionsConfig:editInline: false → true.
  • packages/spec/src/migrations/entries/semantic/18.list-view-edit-inline-default-on.ts — the D3 semantic entry (protocol 18), concatenated into registry.ts by gen:migration-registry.
  • packages/spec/authorable-defaults/ui.json — regenerated by the build: ui/UserActionsConfig:editInline = true.
  • content/docs/references/ui/view.mdx (3 rows), content/docs/references/ui/page.mdx (1 row) — regenerated by gen:docs: optional (default: true) with the new describe.
  • .changeset/22605-spec-list-view-edit-inline-default-on.md — @objectstack/spec: minor, Clause-②: no (a moved default changes no accept set; the breaking signal is the banner and the ADR-0087 marker), the launch-window BREAKING banner naming the author who relied on the documented default for a read-only list and the remedy editInline: false, the FROM → TO table, the measured reach, and the ADR-0087 marker registered list-view-edit-inline-default-on. minor because the launch-window convention ships a breaking change as minor (check-changeset-no-major), and the fixed group already carries the pending major that opens the v18 line, so the level moves no version on its own.
  • packages/spec/src/ui/view.test.ts — the defaults pin flips to true, plus four pins: an absent key parses to true (on UserActionsConfigSchema and through ListViewSchema), an explicit false stays false, an explicit true stays true, and the view-level inlineEdit: true still parses as before with no userActions block materialised (the fold is the renderer's; the spec keeps both spellings as declared).

Measured first (the PM's mechanism assumptions)

  1. Other sites stating the old default. view.zod.ts:1535 read .default(false) with the "Off by default" describe — corrected. The four reference rows regenerate. Nothing else in the tree states the old default: content/docs/ui/views.mdx lists the view-level inlineEdit with no default; content/docs/protocol/objectui/layout-dsl.mdx:667 is about record:details' own inlineEdit (a different key, renderer default on); packages/spec/src/data/object.zod.ts retired-key guidance says only that editInline is a view key; object-strictness-batch20.test.ts lists key names. Left as they are, with reasons: .changeset/console-20c6d351ad74.md describes the console at pin 20c6d351ad74, which still reads an absent key as off until objectui#12086 lands and the pin moves (true of that build); CHANGELOG.md:1677 and packages/spec/CHANGELOG.md are release-owned history.
  2. ADR-0087 disposition. check:adr-0087-registration demands a marker on a declared-breaking changeset; not-required (no-migration-prescription) is refused when the body carries a prescription, and this one prescribes editInline: false. The honest disposition is registered: a D3 semantic entry at step 18, the same class as view-pagination-page-size-default-50 and protocol 12's rest-requireauth-default-flip. No key is removed (no tombstone, no RETIRED_KEYS_BY_MAJOR row) and no D2 conversion exists — a mechanical pass writing editInline: false into every silent view would preserve the old posture and defeat the ruling. The registry regenerated byte-exact after merging origin/main (which brought the sibling entry page-slots-details-beside-tabs-refused, not adjacent in id order; check:migration-registry green). A second ledger also applies: the authorable-defaults ratchet refuses an undeclared default move, so DEFAULT_CHANGES_BY_MAJOR carries the hop.
  3. Reach of the remedy, at e11ef3a7bd (git grep, tests and changelogs excluded): 0 editInline: false and 0 editInline: true across examples/** and packages/** metadata. Views that declare nothing and now gain the toggle: 38 list-kind views with an explicit type across 10 example *.view.ts files (entries with no type are grid by default and count the same way), 12 interfaceConfig page lists across 5 showcase page files (11 declare a userActions block, none naming editInline), 105 list-kind views across 40 platform *.object.ts files in packages/**. One view declares the view-level inlineEdit: true (the showcase task grid saved view) and keeps opening in edit mode. The only test that asserted the old default is view.test.ts (expect(config.editInline).toBe(false)), flipped here; no other package's tests read the view-level userActions default (consumer tests on userActions are the object-level CRUD block). The card's readings outside this repository (cloud sys-package.page.ts:105 declares editInline: false; HotCRM's 41 undeclared views) were not re-measured here.
  4. The skill file skills/objectstack-ui/rules/list-views.md is hand-written: the only generated lifts inside skills/** are references/_index.md and references/react-blocks.md (GENERATED_SURFACE_EXCEPTIONS). Its paragraph is PR 2.

Tests (post-merge head 24d9bdcbf0, shared-box readings under the verify lock)

  • pnpm --filter @objectstack/spec build — green; check:generated — ✓ All 15 generated artifacts are up to date.
  • pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2 (the package's test script) — Test Files 642 passed (642) · Tests 19150 passed | 1 todo (19151).
  • Targeted, before and after the merge: src/ui/view.test.ts src/ui/page.test.ts src/migrations/migrations.test.ts src/migrations/semantic-relevance.test.ts — 4 passed · 740 passed; the repo-project files scripts/step18-rationale-merge.test.ts scripts/authorable-defaults.test.ts scripts/build-schemas-check-mode.test.ts — 4 passed · 146 passed (with semantic-relevance).
  • pnpm --filter @objectstack/spec typecheck — tsc --noEmit, check:scripts-typecheck and check:test-typecheck green (52 file(s) / 246 error(s) / 135 pinned signature(s) held, the shrink-only debt ledger unchanged).
  • test:repo beyond those three files is declared to CI (Test Core).

Ablation (reverse verification)

node scripts/ablation-replace.mjs --file packages/spec/src/ui/view.zod.ts --anchor 'editInline: z.boolean().default(true)' --replacement 'editInline: z.boolean().default(false)' -- pnpm --filter @objectstack/spec exec vitest run --project local --maxWorkers=2 src/ui/view.test.ts, at head 24d9bdcbf0, after the fix was committed. Mutation proved on disk: anchor 1 → 0, replacement 0 → 1, blob 6979ade6158a → e0e02cd7f858. Direction observed: red, exactly the two default pins — should apply default values and an absent key parses to true (expected false to be true), 2 failed | 462 passed (464). Restore proved: blob after restore 6979ade6158a == blob at HEAD, git diff HEAD empty, tree clean. Resolution path: the pin imports the schema from the package's own src (no dist in the path), so no rebuild sits between the mutation and the reading.

Gates (local, at 24d9bdcbf0)

Derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths; the tool reads the change set off the merge base): 115 families. Reconciled with --ran: 115 derived, 114 run, 0 NOT-MEASURED, 1 UNRUN — the UNRUN is pnpm check:dual-build-cjs-loads, declared NOT MEASURED by the dispatch (it needs a whole-workspace build). Every other derived family exited 0, after building the prerequisites some of them load (@objectstack/formula, lint, client, client-react, objectql), except pnpm check:dts-closure, which exited 1 for a missing dist/ under plugin-approvals and plugin-dev: it reads every package's built declarations, so without the whole-workspace build it is NOT MEASURED, not red (CI's Build Core covers it). The artifact-roster block (49 families): 46 run, every one exit 0 except pnpm check:published-readme-exports, exit 3 (44 unbuilt packages, NOT MEASURED for the same reason); the three PR-context guards (check-closing-target-claim, check-partof-closing-keyword, check-single-claim-paths) run once this PR has a number, and their readings go in the report comment on the card. Staleness note the tool prints: the derivation tree is two commits behind origin/main 83b8b80728, and the one derivation input that moved is scripts/platform-object-tenancy-census.json (the tenancy-census roster); that family ran green on the older copy, and no path of this diff overlaps those two commits.

Lint, as a proven narrowing rather than the CI-owned pnpm lint: pnpm exec eslint --no-inline-config --format json over the .ts/.mjs files in the two-point diff — 24 files linted, 0 errors, 0 warnings (the count is from the JSON output; the set is wider than this PR's own 9 files (233 insertions, 7 deletions off the merge base e22315238f) because the two-point diff includes the merged sibling commits). Population, read from eslint.config.mjs: **/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs} minus its ignores, so the .md, .mdx and .json files of this diff are outside it (eslint reports them "ignored because no matching configuration"). Invariance: the config declares no parserOptions.project and no typed @typescript-eslint rules, so this diff cannot move the verdict of any file it does not touch.

Acceptance notes


Generated by Claude Code

…18 line; editInline: false is the opt-out

Maintainer ruling 2026-10-10, verbatim: 「乙 v18 把 spec 默认翻成 true,editInline: false 变成关法。」
A list view is editable in place by default under the permission gate that already exists.
The declared default of UserActionsConfigSchema.editInline moves false -> true with the
describe rewritten; the declared default change is ledgered at major 17 and the D3 semantic
entry list-view-edit-inline-default-on is added at protocol 18. Pins: an absent key parses
to true, an explicit false stays false, the view-level inlineEdit still parses as before.

Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF
Co-authored-by: Claude <noreply@anthropic.com>
…ages for the editInline default; add the changeset

gen:migration-registry concatenates the D3 entry into registry.ts; the spec build moved
ui/UserActionsConfig:editInline to true in authorable-defaults/ui.json under the declared
chain; gen:docs rewrote the four editInline rows in references/ui/view.mdx and page.mdx.
spec-changes.json and docs/protocol-upgrade-guide.md are not regenerated here: the PR-stage
check projects the registry in memory and compares no committed copy, and the committed copies
on origin/main already carry sibling drift this diff does not own.

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

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

2 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. ⚠️ 1 changed file(s) yielded no anchor (packages/spec/authorable-defaults/ui.json), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/authorable-defaults/ui.json) — pages documenting those are invisible to this run
  • 4 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 f368b7e980d3df201620098be965523b50d6df19 → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json f368b7e980d3df201620098be965523b50d6df19

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

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 24d9bdcbf008e79365002ffb56616f8d1e4b3b74
Local-runs: none

Read-only: the card body and its four comments (triage 6093968052, claim 6094254055, dev report 6094863892, ACCEPT 6094884470), the PR body and file list, the net diff against the merge-base e22315238f (9 files, +233 / −7, identical to the three-dot diff against origin/main), and the head's check-runs. The branch is at the brief's sha. Nothing built, run or re-run.

① Derived judgments

  • The default and its describe. UserActionsConfigSchema.editInline is z.boolean().default(true); the describe says on by default, a user who may update the object edits a cell in place with the field's type-aware widget under the permission gate, and editInline: false makes the list read-only in place — the card's three sentences. The schema docblock records the ruling verbatim. Held.
  • DEFAULT_CHANGES_BY_MAJOR[17]. The row is ui/UserActionsConfig:editInline, from: 'false', to: 'true', inside the 17: [ block (lines 218–621 at head) beside the ui/PaginationConfig:pageSize row. 17 is the only key that can authorise anything: CURRENT_MAJOR is parseInt(SPEC_VERSION) with @objectstack/spec at 17.7.0, and the ratchet's rule 4 is that only the current major authorises. authorable-defaults/ui.json moves exactly one line (= false → = true), matching both fingerprints. Held.
  • The D3 entry list-view-edit-inline-default-on. One file, entries/semantic/18.list-view-edit-inline-default-on.ts, protocol 18 — the same step as view-pagination-page-size-default-50. surface names the OMITTED key on both carriers of the one schema (a list view's userActions, a page's interfaceConfig.userActions) and carries no backtick, as the build-upgrade-guide note demands; replacement is "nothing" plus the opt-out; reason quotes the ruling and says why no D2 exists (a pass writing false everywhere would preserve the old posture and defeat the ruling); acceptanceCriteria matches the card's acceptance. No tombstone, no RETIRED_KEYS_BY_MAJOR row, no D2 — right, nothing is removed. The registry.ts hunk is the entry byte-for-byte inside step18. Held. One observation, not a finding: the reason string carries objectui#5144; 12 of the 414 semantic entries on origin/main already carry an objectui#N in prose, so it is precedented, and check:doc-authoring rule 2 scans a different surface.
  • Regenerated references. Four rows — view.mdx ×3, page.mdx ×1 — now read optional (default: \true`)with the new describe. At head,git grepfor the old describe text ("Off by default: the list") hits only this PR's own changeset quoting it; no rendered row survives.TypeScript Type Check(the job that runs every spec artifact gate,check:docsandcheck:authorable-surfaceincluded) concludedsuccess` on this head, which is the CI reading that the JSON-schema and docs artifacts are current.
  • Accept set unchanged, only the parsed default moves. editInline stays z.boolean(); .default() alone moves; the inferred type is boolean on both sides, which is why check:api-surface has nothing to say. The five pins hold the contract: absent parses to true on the schema and through ListViewSchema; explicit false and true keep their values; the view-level inlineEdit: true still parses with no userActions block materialised (the fold is the renderer's). The dev's ablation (.default(false) back) reads as exactly the two default pins red, blob-equal restore — consistent with the diff; not re-run here.
  • Every other place that still states the old default, at head: .changeset/console-20c6d351ad74.md lines 24 and 71 say the console at pin 20c6d351ad74 reads an absent key with the spec's default, off — true of that build until objectui#12086 lands and the pin moves; carrier named in ③. Root CHANGELOG.md:1677 is release-owned history and stays. content/docs/ui/views.mdx:111 lists the view-level inlineEdit with no default; layout-dsl.mdx:667 is record:details' own inlineEdit, a different key; object.zod.ts:2043 says only that editInline is a view key. No example and no skills/** file in this repository states the old default; no in-repo metadata declares editInline at all. The permission gate and objectui are untouched, as the card requires.

② Semver level

  • minor is right; major is not, even though pre mode would admit it. check-changeset-no-major.mjs ships breaking changes as minor for the launch window (end condition: GA, not reached); its RC exemption lets a major through while .changeset/pre.json reads mode: pre, tag next, so major was available — but the repository's own default-flip precedents on this line all took minor: view-pagination-page-size-default-50 (8ecbe0f, under ### Minor Changes), approval-escalation-enabled-default-flip ("shipped as minor under the repo's launch-window convention"), audience-posture-default-invite-only (same words). Protocol 12's rest-requireauth-default-flip (7c09621) sits under ### Major Changes, but that was before the window and is not the rule now. The fixed group already carries the pending major that opens the v18 line (22080-v18-line-opens.md, 22130-protocol-18.md), so this minor moves no version and rides the 18.0.0-next.N train. The BREAKING banner is present and is the only breaking signal the ADR-0087 gate reads here (no major, no bang on the changeset's first line, no narrowing arm); the marker registered list-view-edit-inline-default-on resolves at head and is new in this diff; the FROM → TO table and the one-line fix are there. Held.
  • The Clause-② arm is NOT right, and this is the one finding of record. The line answers 「本卡放宽接受集或扩大公开面吗」, and the ruled definition (pr-automation.yml WHICH LEVEL, the maintainer's ruling on finding(changeset): two independent contract reviews read the repo's own history to opposite bumps for "add an exported symbol to a published index" #15294) is "a purely additive widening of a published package's public surface (a new exported symbol on an index, a new accepted key or value)". This diff adds no export, no key and no value; the changeset itself says "The accept set is unchanged" and declares the act BREAKING, and the ADR-0087 gate's own docblock says "A widening is not a break". One act cannot be a purely additive widening and a break at once. A moved default is neither a widening nor a narrowing of the accept set, so the truthful declaration is Clause-②: no with no arm, breaking-ness carried where the window puts it — the banner and the marker. The card's parenthetical ("a view declaring nothing gains an affordance it did not have") reads the console's behaviour, not the package's surface. Origin: the card and the dispatch claim 6094254055; the dev copied the line as os-dev.md requires (照抄, ⛔ 不自造), so the correction is the seat's — on the claim, then on the PR body (line 2) and .changeset/22605-spec-list-view-edit-inline-default-on.md:13. It matters because the line ships verbatim into packages/spec/CHANGELOG.md (416 Clause-② lines there today) and is what every later census reads. No gate moves on the correction: the level axis reads no as not-declared and exits 0 with minor untouched; the ADR-0087 gate still reads BREAKING from the banner and still finds the marker. The pm-dispatch instrument-discipline reference assigns the direction to this review (Clause-② 的方向由达档复核裁), so it is ruled here: no.

③ Boundary flags

Implemented-by: claude/issue-22605-edit-inline-default-on
Reviewed-by: session_01KNKBCRDJCu5tGy3TEbvtrF

VERDICT: FAIL


Generated by Claude Code

…set declares Clause-②: no

Patch round on the contract review (a moved default neither widens nor narrows the accept
set; the banner and the ADR-0087 marker carry the breaking signal) and the Test Core red it
found: packages/cli/test/migrate-meta-engine-guidance.test.ts refuses a tracker id in printed
guidance. The entry's reason now says "the one-vocabulary rule objectui ruled for the fold";
the citation moves to the file's leading comment, as the other entries do; the
DEFAULT_CHANGES_BY_MAJOR[17] reason is rewritten the same way; registry.ts regenerated.

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

Copy link
Copy Markdown
Contributor Author

Contract review

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

Round 2, scoped: what moved since the round-1 head 24d9bdcbf0 (record 6095058376, FAIL), and whether that record's FAIL items are cured. Read-only: the card body and its comments through the dev's patch report 6095196973 (the seat's patch order 6095101276 included), the PR body and file list, the two-point diff 24d9bdcbf0..fc3733b971, the net diff against the merge-base e22315238f (unchanged since round 1), and the head's check-runs. Nothing built, run or re-run; the dev's local readings are reported here as the dev's, never adopted as a gate's.

What moved. git diff --name-only 24d9bdcbf0 fc3733b971 is exactly the four files the patch report names — the changeset, packages/spec/scripts/lib/default-changes.ts, entries/semantic/18.list-view-edit-inline-default-on.ts, registry.ts — 4 files, +15 / −7, one commit, 24d9bdcbf0 an ancestor of the head. The net diff against the merge-base is still the PR's 9 files (+241 / −7: round 1's +233 plus this hop), identical to the three-dot diff against origin/main 1b99388505. main is seven commits past the merge-base; none touches a path of this diff, and none has touched src/migrations, default-changes.ts, authorable-defaults/ or the two projections since the round-1 merge, so no regen-merge was owed. Everything round 1 held in view.zod.ts, view.test.ts, ui.json and the two reference pages is untouched by this hop and stays held.

① Derived judgments

  • The D3 entry — right. id, surface, replacement and acceptanceCriteria are byte-identical to the round-1 head, compared field by field. reason moves in one line: "the one-vocabulary rule of objectui#5144 stands" is now "the one-vocabulary rule objectui ruled for the fold stands". Scanned with the pin's own shape (# plus four or five digits, word-bounded) over every non-comment line of the entry: no hit. The only #5144 left in the file sits in the leading // comment, which now also says why it lives there ("the citation lives here, not in the printed guidance, which carries no tracker number"). That is the right home: os migrate meta prints surface, replacement, reason and acceptanceCriteria and never the comment, and the tracker ids main's other entries carry all sit comment-side. Round 1 read "12 of 414 entries carry an objectui#N" as precedent for a printed string; that was wrong — they are comments — and the pin said so on the round-1 head.
  • The registry.ts hunk — right, the generator's copy. The 52-line block inside step18 is the entry's leading comment and literal rendered exactly as renderRegion renders them (build-migration-registry.ts): every comment line indented four spaces, the declaration line as {, the closing }; as },, every literal line indented four — compared line for line against the entry file at this head, no difference. It sits in id order, before list-view-navigation-view-retired. The hunk's +6 / −2 against the round-1 head is the comment run growing by four lines plus the one reason line, which is what the generator copies by design; the dev's deviation note on this is answered. The CI reading of generator identity is check:migration-registry, a step of Lint & Repo Gates, named under ③.
  • The DEFAULT_CHANGES_BY_MAJOR[17] row — right. key, from, to unchanged; the row still sits under 17: [, the only major that authorises a hop (CURRENT_MAJOR is the package major), and still names the D3 entry by id. Its reason takes the same one-sentence rewrite; scanned with the same shape: no hit. No gate demanded this one — the pin reads the registry, not this ledger, and main's own ledger still carries tracker ids in four of its earlier reason strings — but the row's reason is printed into the build log on every run (build-schemas.ts, the "declared default change(s) accepted" block), so the rewrite follows the rule that text an author is shown carries the lesson and not the number, and it loses nothing. check:authorable-surface accepted the moved fingerprint on this head (Type Check · source gates concluded success), as on the round-1 head.
  • The changeset's Clause-②: line — right at no, judged under ②. Nothing else in the changeset moved: the **BREAKING** banner, the FROM → TO table, the one-line fix, the measured reach and the adr-0087 marker registered list-view-edit-inline-default-on are byte-identical to the round-1 head, and the marker still resolves to the entry at this head.

② Semver level

  • minor — held from round 1, unchanged on this head: the launch-window convention ships a breaking change as minor (check-changeset-no-major), the three default-flip precedents on this line took minor, and the fixed group already carries the pending major that opens the v18 line, so the level moves no version on its own.
  • Clause-②: no — right, and round 1's one finding of record is cured. The line answers 「本卡放宽接受集或扩大公开面吗」, and the ruled definition of a widening (pr-automation.yml WHICH LEVEL, the maintainer's ruling on finding(changeset): two independent contract reviews read the repo's own history to opposite bumps for "add an exported symbol to a published index" #15294) is "a purely additive widening of a published package's public surface (a new exported symbol on an index, a new accepted key or value)". This diff adds no export, no key and no value — editInline is still z.boolean(), only .default() moves, and the changeset itself says "The accept set is unchanged". A moved default narrows nothing either, so no arm: no (narrowing) would declare an accept-set shrink that does not exist, and no (widening) is the malformed pair. Breaking-ness rides where the window puts it: the **BREAKING** banner, which check-adr-0087-registration's breakingDeclaration reads as a signal of its own with no help from the arm (its self-test pins a bare Clause-②: no as NOT a breaking signal and the banner as one), plus the registered marker, which resolves. The level axis of check-changeset-no-major reads no as not-declared and stands down with minor untouched. Check Changeset, the job that runs both gates against the merge-base, concluded success on this head — the gate reading for both.
  • The PR body's line 2 agrees: Clause-②: no, bare, on a line of its own, which readClause2Line returns as declared / no / no arm. The correction chain round 1 asked for is complete on every machine-read carrier: the claim 6094254055 (corrected by the seat), the PR body's line 2 (the seat), the changeset's line 7 (the dev). One residue, named in ③. Round 1 and the patch order both numbered the changeset's declaration "line 13"; it is line 7, and the dev edited the right line — the misnumbering was round 1's.

③ Boundary flags

  • Round 1's FAIL items, each. (1) The Clause-② arm: cured, above. (2) Test Core (4/6) red on 24d9bdcbf0 — confirmed by that head's check-runs (Test Core (4/6) failure, the Test Core fan-in failure), the failing assertion being migrate-meta-engine-guidance.test.ts's "the printed guidance cites a tracker id" on this PR's entry. Cured on this head by its own check-run: Test Core (4/6) concluded success, and the required Test Core fan-in with it (both named below). The diff-side reading is that the head's printed fields are clean under the pin's own regex; the dev reports red reproduced before the patch and green after it, with the CLI closure build between the registry change and the reading on both legs (the pin resolves @objectstack/spec/migrations through the built dist), a shape consistent with the diff and not re-run here.
  • The dev's deviations, each answered. Line 7, not 13: the right line moved, above. Worktree recreated at 24d9bdcbf0 with no merge of origin/main: right — nothing on main since touches a path of this diff or a registry input, and the queue rebuilds onto current main. The changeset's prose still citing objectui#5144 and objectui#12086: not owed a change. The pin's surface is the printed migrate-meta guidance, the registry's four fields; check:doc-authoring's roots are .claude, docs, skills and content, not .changeset/, and its tracker rule is for runtime strings and refusal prose. A changeset ships to packages/spec/CHANGELOG.md, where 304 lines on main already cite an objectui#N and 59 of the 259 .md files under .changeset/ carry a #NNNN: a changelog citing the sibling repository's ruling record is this repository's norm, and here the citation is the provenance of the rule the changeset says still stands. The same holds for the objectui#5144 in the view.zod.ts docblock and the view.test.ts comment, both held from round 1 and neither printed. The registry hunk carrying the comment run: by design, above.
  • One residue on the PR body, owed to the seat, non-blocking. Line 17 of the body (the "What changed" bullet for the changeset) still describes the changeset as carrying Clause-②: yes (widening) and argues minor from "Clause-②: yes takes at least minor". No gate reads it: the declaration reader takes the first key-initial line (line 2) and keeps a mid-line backticked mention only as a residue to quote when no declaration exists, which is why Check Changeset and the claim guard are green on this head. It ships nowhere — a PR body is not a changelog. But it contradicts line 2 of the same body and the changeset it describes, so the seat corrects that bullet (and may note the citation move in the D3 bullet) in the act that enqueues; a body edit moves no head and asks for no re-review.
  • The landing-order window round 1 escalated is now open, and this PR is its only remedy. PR docs(skills): a list view edits in place by default; a read-only list declares editInline: false (#22605, skill half) #22630 landed first by the maintainer's hand (f368b7e980; the seat's reopen note 6095085980): the published skill on main teaches that a list edits in place by default, while view.zod.ts on main still reads .default(false) and the published spec is unchanged. The seat's order calls the patch urgent for that reason, rightly; the window closes when this head lands, and nothing else in this diff is asked to move. The seat enqueues on this record once every required context is green.
  • Carriers held from round 1, unchanged: the console pin changeset's "spec default false" line (carrier: the next pin bump), the README / AGENTS.md regenerate-table drift (spec(changes): delete the committed spec-changes per-major projection and the upgrade guide copy, with their two merge=os-regen routes, once generation at publish has landed (#22449 B′) #22485), spec-changes.json and the upgrade guide not regenerated (right, since [Decision] generated protocol-change records (spec-changes.json per-major section, docs/protocol-upgrade-guide.md): keep committing them, or generate them at publish like the release section #22449 B′).
  • CI on this head, read at 2026-10-10T07:55Z. Required (the ruleset's seven): TypeScript Type Check success (Type Check · source gates, · workspace, · debt ledger, · consumer gates all success beneath it), Build Core success, Dogfood Regression Gate success, Temporal Conformance (live PG + MySQL) success, Governed Surface Queue Guard success, Lint & Repo Gates success (the job that runs check:migration-registry — the generator-identity reading for the registry hunk — and check:doc-authoring), Test Core success with every shard success, Test Core (4/6) among them. The last three concluded while this record was being written and were read again before it was posted: 35 check-runs on the head, none open, none red. Advisory: every concluded check success or skipped (Check Changeset, the three PR-context guards, Spec property liveness, Check PR Size, Console Pin Gate skipped, the packed-tarball smoke skipped); no advisory red.
  • State of the PR: draft, needs:contract-review carried, no auto-merge, no governed path in the file list — the review is owed by the claim's own term, not by Tier S.

Implemented-by: claude/issue-22605-edit-inline-default-on
Reviewed-by: session_01KNKBCRDJCu5tGy3TEbvtrF

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Landing pre-checks at fc3733b971, by the owning seat: every check green, queued

domain:spec seat 3 (#18883) · zhuangjianguo · session session_01KNKBCRDJCu5tGy3TEbvtrF · 2026-10-10T07:59Z · holder of claim 6094254055 on #22605.

needs:contract-review comes off; pr_ready and automerge_enable follow.


Generated by Claude Code

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:ui size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants