Skip to content

docs(changeset): correct two pending changesets whose present-tense claims a later PR falsified - #8994

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-8617-pending-changeset-false-facts
Sep 10, 2026
Merged

baozhoutao merged 1 commit into
mainfrom
claude/issue-8617-pending-changeset-false-facts

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #8617

Clause-②: no

Two unreleased changesets each carried a present-tense claim that a later, separate PR has since falsified. A changeset body publishes verbatim into the CHANGELOG, so both sentences would have shipped as published false statements. This PR corrects exactly those sentences and nothing else.

1. The window — re-measured by this seat, ⛔ no reading carried from the card

Triage's own correction (comment 5619376700) closes with 取卡时请自己重跑那条 git ls-tree,⛔ 不要沿用本卡任何一次的读数. So it was re-run on a freshly fetched origin/main:

$ git fetch origin main && git ls-tree -r --name-only origin/main -- .changeset/
measured at 2026-09-10T15:56:06Z (re-confirmed unchanged at push time, 16:03Z)
origin/main tip 4d65991c5766b77bbc95b7b1ea93fb7154a8c7c7, commit date 2026-09-10T15:31:10+00:00
control — total entries under .changeset/ 1338 (1337 *.md + config.json); triage measured 1327 on 2026-09-10T13:11Z
.changeset/6794-notify-submitter-default.md present — still pending
.changeset/core-datascope-field-and-comparison-guards-7751.md present — still pending

The control moved 1327 → 1338 across those ~2h45m, so the directory is genuinely being read and the two hits are readings, not a stuck listing. The window is open: neither changeset has been consumed by a release, so both sentences are still correctable.

Neither file had been touched since it was written — git log on the two paths returns their original landing commits (21993e4a9 #6831 and 5aed9e4eb #8048) and nothing since.

2. Instance one — .changeset/6794-notify-submitter-default.md

Before (lines 30-33, verbatim):

Deliberately scoped to notifySubmitter. The sibling controller
escalation.enabled is a separate, on-hold card (objectui#6620) whose default
flips on a future spec bump; installed spec and table agree on it today, and
generalising this assertion across the block would arm that card's tripwire here.

After:

Deliberately scoped to notifySubmitter. The sibling controller
escalation.enabled is a separate card (objectui#6620) whose default flipped on
a spec bump that has since landed — installed @objectstack/spec 17.4.0 returns
enabled: true, and PR objectui#8615 has matched the table's declaration to it,
so installed spec and table agree on it today. When this was written that bump
was still ahead, and generalising this assertion across the block would have
armed that card's tripwire here.

The measurements that prove it was false

a. The spec bump is past, not future. Run against the installed package, through the @objectstack/spec/automation subpath the card names:

installed @objectstack/spec version: 17.4.0
safeParse success: true
parsed data: {"enabled":true,"timeoutHours":24,"action":"notify","notifySubmitter":true}

ApprovalEscalationSchema.safeParse({ timeoutHours: 24 }) yields enabled: true on the version this tree actually installs (17.4.0 — the card was filed against 17.3.0; it has bumped again since). ⇒ "flips on a future spec bump" is false.

b. The table has already been flipped to match. packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.ts now declares defaultValue: 'true' for escalation.enabled, and the commit that changed it is in main:

b1a14f28e082c96f36d7a2b9c9202f210814fcc6  2026-09-08T16:52:56+00:00
  fix(app-shell): declare the spec's `escalation.enabled` default in the flow-node inspector (#8615)

-  { id: 'escalation.enabled', ... defaultValue: 'false', ... }
+  { id: 'escalation.enabled', ... defaultValue: 'true',  ... }

c. objectui#6620 is not on hold. It is closed as completed, 2026-09-08T17:09:45Z, closed by PR #8615. ⇒ "on-hold card" is false, and it is false by the same event.

d. The tripwire clause. With spec true and table 'true', generalising the reconciliation assertion across the block would now simply pass — it would arm nothing. Present tense "would arm" is false today; changed to "would have armed", which is what was true when the sentence was written.

⭐ What was NOT edited, because it measures TRUE

installed spec and table agree on it today

This is the clause the card lists as false, and it is not. Measured: spec returns enabled: true (a), table declares 'true' (b) — they agree. What actually happened is that the pair went false when the spec bumped and true again when #8615 flipped the table, so the card's account of it (written before #8615 was read into the picture) does not hold. Per the fence — a sentence that is still true is reported, not edited — the clause is kept verbatim; only the surrounding false tense is repaired around it.

3. Instance two — .changeset/core-datascope-field-and-comparison-guards-7751.md

Before (line 11, verbatim):

That third case is deliberately stricter than evaluateCondition in @object-ui/permissions, which this card was filed to converge with. Reading with hasOwnProperty alone — the sibling's shape — collapses "inherited" into "absent", and absent ADMITS on a negative operator, so the sibling still returns true for { field: 'toString', operator: 'neq' } on every record (filed as objectui#8044).

After:

That third case was deliberately stricter than evaluateCondition in @object-ui/permissions as that evaluator then stood, which this card was filed to converge with. Reading with hasOwnProperty alone — the sibling's shape at the time — collapses "inherited" into "absent", and absent ADMITS on a negative operator, so the sibling returned true for { field: 'toString', operator: 'neq' } on every record (filed as objectui#8044, and fixed since by PR objectui#8669, which ported this three-case read into the sibling).

The measurements that prove it was false

a. PR #8669 is in main.

2609812d2  fix(permissions): read a condition's field in three cases, not two (#8669)

b. The sibling no longer reads with hasOwnProperty alone. packages/permissions/src/evaluator.ts now carries the identical three-case read, and its own header records it as "a port of the shape objectui#7751 landed in readField in packages/core/src/data-scope/DataScopeManager.ts":

// packages/permissions/src/evaluator.ts — readField, as it stands after #8669
  if (PROTOTYPE_FIELD_NAMES.has(field)) return { readable: false };
  if (Object.prototype.hasOwnProperty.call(record, field)) return { readable: true, value: record[field] };
  if (field in Object(record)) return { readable: false };
  return { readable: true, value: undefined };

evaluateCondition turns readable: false into return false. ⇒ { field: 'toString', operator: 'neq' } denies today; "still returns true" is false. That also falsifies the two clauses in front of it in the same sentence — core's third case is no longer stricter than the sibling, and hasOwnProperty alone is no longer the sibling's shape. All three were falsified by the one PR, so all three are put in the past tense together.

c. Runtime confirmation, not only a source read — the pin that PR #8669 shipped:

$ pnpm exec vitest run packages/permissions/src/__tests__/evaluator.prototype-guard-8044.test.ts
 Test Files  1 passed (1)
      Tests  34 passed (34)                       exit 0

It asserts admits('toString', 'neq', 'x', record) === false for every unlisted prototype member.

What was NOT edited in this file, because it measures TRUE

  • "The sibling requires typeof === 'number' on both sides" — true: gt/gte/lt/lte in evaluator.ts still test typeof value === 'number' && typeof condition.value === 'number'.
  • "the sibling already refused it" (a non-string contains value) — true: typeof condition.value === 'string'.
  • "ne / nin here versus neq / not_in in the sibling, and the sibling's is_null / is_not_null which this evaluator does not implement, remain exactly as they were" — true: DataScopeManager still spells ne/nin with no null arms; evaluator.ts still spells neq/not_in/is_null/is_not_null. PR fix(permissions): evaluateCondition reads a condition's field in three cases, not two #8669 changed the field read, not the spellings.

4. Scope

  • ⛔ Neither bump level touched — the overwrite gate reads this back for both files: declared at base: @object-ui/app-shell: patch / declares now: @object-ui/app-shell: patch, and @object-ui/core: minor / @object-ui/core: minor.
  • ⛔ Neither changeset deleted; both describe real shipped changes that owe a CHANGELOG entry.
  • ⛔ No other changeset touched (2 files changed, +7 −4, prose only).
  • ⛔ content/docs/releases/** untouched. ⛔ No release note written or re-framed.
  • ⛔ The structural half of the card — that nothing re-reads a pending changeset when a later PR falsifies it — is not addressed here and no gate for it is built here; An unreleased changeset states a fact that is now false and will publish it verbatim to the CHANGELOG (.changeset/6794-notify-submitter-default.md) #8617 remains open on that half for the PM to file separately.

5. Checks — exit codes captured before any pipe

command exit verdict line
node scripts/check-changeset-presence.mjs 0 ✅ No source or published contract of a released package changed in this range, so no changeset is owed. (2 files changed, 0 published source)
node scripts/check-changeset-fixed.mjs 0 ✅ All workspace packages are in the changeset fixed group.
node scripts/check-changeset-no-major.mjs 0 ✅ No changeset declares a major bump.
node scripts/check-changeset-overwrite.mjs 0 report-only; reports both files as modified-not-added with bump levels unchanged — case 2, "correcting a declaration on purpose"
node scripts/check-control-bytes.mjs 0 ✅ check-control-bytes: OK (scanned 7200 tracked text file(s); skipped 85 binary).
node scripts/check-new-cross-file-line-citations.mjs 0 VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0
pnpm lint:root 0 ✖ 32 problems (0 errors, 32 warnings) — all pre-existing, none in this diff
pnpm exec vitest run packages/permissions/src/__tests__/evaluator.prototype-guard-8044.test.ts 0 Test Files 1 passed (1) / Tests 34 passed (34) — evidence for §3, not a gate this diff owes

Every .changeset/**-triggered workflow (changeset-guard.yml, changeset-presence.yml) runs exactly the scripts above; all four ran locally green. ⛔ Nothing was skipped, disabled or quarantined.

⚠️ A green gate is not the acceptance evidence here — nothing in this repository parses changeset prose for truth, so every gate stays green whether or not this is fixed. The evidence is §1-§3: the corrected text read back, plus the tree measurements showing what each sentence asserted was false.

6. Fork not resolved

.changeset/6794-notify-submitter-default.md line 9 reads "the installed @objectstack/spec (17.2.0) defaults the key to true". Installed is now 17.4.0, so the parenthetical is stale — but the claim it carries (notifySubmitter defaults to true) is still true on 17.4.0, and the version reads as the provenance pin of the original measurement rather than a claim about today. Left unedited on the narrower reading; flagged so the release editor can settle it.


Generated by Claude Code

`.changeset/6794-notify-submitter-default.md` described the `escalation.enabled`
spec bump as *future* and called objectui#6620 an on-hold card. Installed
`@objectstack/spec` is 17.4.0 and `ApprovalEscalationSchema.safeParse({
timeoutHours: 24 })` returns `enabled: true`; PR objectui#8615 (b1a14f2) flipped
the table's declared default from `'false'` to `'true'` and closed objectui#6620.
The bump is past. The clause "installed spec and table agree on it today" was
re-measured and is still TRUE, so it is kept verbatim.

`.changeset/core-datascope-field-and-comparison-guards-7751.md` stated in the
present tense that `@object-ui/permissions`' `evaluateCondition` still returns
`true` for `{ field: 'toString', operator: 'neq' }`. PR objectui#8669 (2609812)
ported the three-case `readField` into that evaluator, so the read is refused and
the condition denies.

A changeset body publishes verbatim into the CHANGELOG, so both sentences would
have shipped false. Prose only: neither bump level, frontmatter nor any other
changeset is touched.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
@baozhoutao
baozhoutao marked this pull request as ready for review September 10, 2026 16:10
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 10, 2026
@claude

claude Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Armed — SQUASH, in the queue, probe written BEFORE the merge

domain:devx @ objectui PM seat (session_01FhBNJcLRZLe8M87VcUgpKr), 2026-09-10T16:11Z. Card objectui#8617, p1 on a deadline.

CI on 134077605: converged all green, 32 checks, Live E2E (informational) excluded — 16:10:10Z. Flip ready 16:10:16Z; post-flip Governed Surface Queue Guard completed/success @ 16:10:34Z; armed SQUASH; queue confirmed from the added_to_merge_queue timeline event.

The probe

Baselines on origin/main = 4d65991c5, tip committed 2026-09-10T15:31:10Z, read 16:10Z. Re-read after the merge on a re-fetched origin/main.

# leg today expected after
A 「future spec bump」 in the first changeset 1 0
B 「has since landed」 in the same file 0 1
C 「still returns」 in the second changeset 1 0
D the PR number that fixed it, named in the same file 0 ≥1

⭐ A/B and C/D are two pairs, each the same claim read from both sides. On a card whose entire subject is a false sentence publishing verbatim, a one-sided leg would be the wrong instrument: appending a correction while leaving the falsehood standing beside it is precisely the failure mode, and only the pair distinguishes a replacement from an addition.

Control: both files are present in the listing (2 of 2) at baseline, so each zero above is a reading of a file that exists, ⛔ not of a path that does not.

⚠️ ⛔ Not a probe leg: the pending-changeset total. It moved 1,327 → 1,338 in three hours on other people's work; it is a fine control for 「the directory is being read」 and a useless leg for 「this merge did what it said」.

⇒ this card closes on the merge (Fixes #8617): LANDED, then strip pm:* + assignee.


Generated by Claude Code

Merged via the queue into main with commit 35c6a34 Sep 10, 2026
34 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-8617-pending-changeset-false-facts branch September 10, 2026 16:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

An unreleased changeset states a fact that is now false and will publish it verbatim to the CHANGELOG (.changeset/6794-notify-submitter-default.md)

2 participants