You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(spec): ActionEngineFacade.delete declares the id array the runtime already accepts, and says which convention is the contract (#17608)
* fix(spec): declare ActionEngineFacade.delete's id array, and say which convention is the contract
`ActionEngineFacade.delete` declared `id: string` while the runtime facade has
always accepted `string | string[]`, iterating one `ql.delete` per id. The
declaration is now `string | string[]`, and the member's doc comment states
what the runtime comment used to record as an accident of two handler suites:
both spellings are contract, the array form is a convenience over the same
per-row path, and it is neither bulk nor atomic.
Two consumers follow from the declaration:
- `packages/runtime`'s "tolerant of both conventions" comment is retired (a
comment correction only; the arm's behaviour is untouched).
- `examples/app-todo/src/actions/task.handlers.ts` drops the hand-rolled
`ActionContext` copy of the facade — which existed because the published
type could not express its array call, and which had already drifted on
`find` — for the published `ActionHandlerContext`.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
* chore(changeset): patch for the ActionEngineFacade.delete declaration (#15117)
The level is measured, not assumed: nothing is removed and nothing narrows,
no runtime behaviour changes, and the sibling re-declaration of the neighbouring
member (`find`, #14175) shipped as a patch from the same interface. What ships
is a published type that finally describes behaviour that was already served.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
* docs(spec): cite the runtime delete arm by symbol, not by line number (#15117)
`check:spec-docblock-symbol-anchors` refuses a line number as an anchor form,
and the citation added with the widening (`:1471`) was one — a NEW finding, not
one of the seven day-one residuals. It is now the symbol anchor
`packages/runtime/src/action-execution.ts#buildActionEngineFacade`, which is
also the more honest citation: this card exists partly because the line numbers
the issue quoted had already drifted by three hundred lines.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
* fix(spec): grade the delete widening as minor, and re-verify the flagged docs page (#15117)
Contract review returned FAIL with two must-fixes.
1. The changeset is `minor`, not `patch`. The written rule
(`.github/workflows/pr-automation.yml`, maintainer ruling 2026-09-04 batch
#35) is that a purely additive widening of a published package's public
surface takes at least `minor`, and a commit type may raise a bump but never
lower it below what the act requires. The PR's own `Clause-②: yes` line says
this widens the accept set, in those words. The `find` precedent it leaned on
does not reach: that was a NARROWING, it landed the day the rule was ruled,
and the rule disclaims pre-rule `patch` precedents.
How the wrong level survived local verification is the more useful half:
`check-changeset-no-major` reads the clause-② declaration from the event
payload and nothing else, so a local run without `--event` cannot exercise
the level axis at all. Its exit 0 was recorded as a reading when the
instrument could not have come back the other way.
2. `content/docs/ui/actions.mdx` — the page the repo's own Docs Drift Check
flagged on this PR — is re-verified against the rewritten example. Its
handler snippet still annotated `ctx: ActionContext`, a type that file no
longer declares; it now imports and annotates the published
`ActionHandlerContext`. The same snippet also wrote `completed_date`, which
is `readonly` on `todo_task` and stamped by the object's `beforeUpdate` hook:
copying it made the action refuse itself against `completed_date_required`.
Both facts are verified against `task.object.ts` and `task.hook.ts`. The page
now states the `delete` convention beside where it already states `find`'s.
Folded in: the example's comment attributed to the contract a request the
contract does not make. The contract asks for `ActionHandler`; it says so, and
says why a file of function declarations annotates `ActionHandlerContext`
instead. Comment-only — 11 changed lines, all comments or blank.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
* docs(ui): state the true reason a handler must not name a server-owned field (#15117)
The previous push removed `completed_date` from the handler snippet, which was
right, and then explained it with a mechanism that is false. Re-measured:
- A handler's `ctx.engine` runs ELEVATED — `buildActionExecutionContext` returns
`{ ...base, isSystem: true }` (`packages/runtime/src/action-execution.ts`) —
and the read-only strip is gated `if (!opCtx.context?.isSystem)`
(`packages/objectql/src/engine.ts`). Nothing is stripped on that path, so
"stripped from the payload before the record is validated" never happens.
- The refusal does not exist either, for any caller. The hook's stamp is
unconditional on the transition and its own docblock says that is precisely so
a caller-supplied value is overwritten and survives the strip; a live test
asserts it — "a caller that still sends `completed_date` is not punished for
it — the hook value wins". The REJECTED row whose mechanism the page described
is labelled "Measured before the fix".
The true reason is close to the inverse, and is now what the page says: the
write is not stripped, it LANDS, and on a write that is not a completion
transition the hook does not stamp, so the handler's "now" silently replaces the
real completion timestamp.
I read the #7036 history at the three sites I cited and wrote it in the present
tense, without reading the four sites the conclusion depended on. A citation
that exists is not a citation that entails.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments