Commit 2bb0614
docs(platform-objects): widen sys_email.error description to cover pre-delivery rejections (#15276)
* fix(runtime): type the packages-domain `protocol` service handle so undeclared request keys are compile errors (#15215)
* wip(runtime): type the packages-domain protocol service handle
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
* wip(runtime): add the packages-domain protocol handle typing pin
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
* chore(changeset): patch note for the packages-domain protocol handle typing
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
* docs(permissions): re-anchor the system-context census rows moved by the typing block
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
* docs(permissions): regenerate the system-context census from the merged tree
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(objectql): publish the record's organization on every DataEvent (#15220)
* fix(objectql): publish the record's organization on every DataEvent (#14970)
`DataEventSchema.organizationId` was declared and published by the spec half
but populated by nothing, so every `data.record.*` event went out with the key
absent — which the contract requires a consumer to read as "this record is
behind no organization wall". `publishDataEvent` now resolves it from the row
itself: the written record on `created`, the post-state on `updated`, and the
by-id branch's already-read pre-image on `deleted`, so no per-event read is
bought.
The record's organization, never `ExecutionContext.tenantId` — that is the
caller's active org, and the two diverge on exactly the system/unscoped write
this key most needs to label correctly. Absence keeps one spelling: the key is
omitted, never `''` (which the schema refuses outright, dropping the whole
event) and never an explicit `undefined` (which survives `parse` as a present
key).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
* docs(permissions): re-anchor the system-context census after the engine line shift
Mechanical repair by `node scripts/check-system-context-census.mjs --fix`, the
only correct writer for this table. Pure line rot: the `eventOrganizationId`
helper and its threading shifted every later line in `packages/objectql/src/engine.ts`,
so 14 anchors (15 citation sites — one source line is cited twice) pointed at
the wrong lines.
No population and no classification change: still 106 elevation read sites in
20 packages across 45 files, all anchored; 140 anchors resolve, 27 declared
non-read — the same figures as before the shift. `--fix` did not refuse, and
the diff is digits and nothing else (12 lines added, 12 removed, identical once
digits are stripped).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
---------
Co-authored-by: Claude <noreply@anthropic.com>
* ci(reaper): arm the merged-branch reaper for scheduled deletion of claude/ branches (#15224)
* ci(reaper): arm the merged-branch reaper for scheduled deletion of claude/ branches
Flips .github/workflows/merged-branch-reaper.yml from report-only to the
scheduled weekly deletion the maintainer ruled on 2026-09-04 (issue #12771,
decision batch #30), reaffirming the 2026-08-31 ruling under the base-ref
guard PR #15144 landed.
Deletion is a SEPARATE job (`reap`), because `permissions:` is scoped per
job. `sweep` keeps `contents: read` + `pull-requests: read` and remains
structurally incapable of deleting a ref; `reap` holds the only
`contents: write` in the file, consumes the `reapable` list `sweep`
publishes as a job output, and computes no classification of its own.
Fences:
- `reap` never runs on `pull_request` — the self-exercising run stays a dry
run — and its `if:` is an allowlist of `schedule` plus a
`workflow_dispatch` on which the operator explicitly set `dry_run: false`.
- the new `dry_run` workflow_dispatch input defaults to true, so the manual
path is fail-closed.
- the base-ref guard, `PREFIX`, `BASE_REF`, the grace window, the schedule
and the `is-ancestor` prohibition are all untouched.
- the whole deletion list is printed to the run log before the first delete.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
* test(reaper): pin the deletion hand-off and fence the delete job structurally
The contract harness drives the `sweep` classifier and can say nothing about
the job that deletes — deletion deliberately lives outside the extracted
script, so what the harness judges stays a classification rather than an
action. Two additions close that gap.
1. The hand-off. `sweep` now publishes `reapable_branches`, the
machine-readable half of the list it prints, and `reap` consumes that and
nothing else. Scenarios G1/G2/R1 pin that the list EQUALS the reapable
bucket — same members, same order — over a population carrying one branch
in every bucket, and mutations M13/M14 drive both directions red (held
branches leaking in; the list not published at all).
2. The fence. `reapFenceFailures()` parses the shipped YAML and asserts the
delete job's structure: its `if:` excludes `pull_request` and gates
`workflow_dispatch` on `inputs.dry_run == false`; it declares
`contents: write` and is the ONLY job in the file that does; the top-level
grant stays `contents: read`; it still `needs: sweep`. New self-test
battery 6 drives six mutations of the workflow text to red, each asserting
its anchor was present first.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
* ci(reaper): put every excluded bucket on the run-log audit line
The maintainer's ruling names the run log as the audit trail, and the notice
line named three of the seven buckets — reapable, mergedElsewhere, noPr. The
other four (open, closedUnmerged, grace, protectedBranch) lived only in the
step summary and the uploaded artifact, so the log alone could not answer
"what did it hold back, and why".
Also retires two strings that stopped being true when the reaper was armed:
the summary heading said "DRY RUN. Nothing was deleted." of a run that may
now delete in a later job, and the notice said "Nothing was deleted" of the
whole run rather than of this job. Both now speak for the `sweep` job only,
which is the thing they were ever really asserting — its token grant is
`contents: read` and that has not changed.
No classification changed: the buckets, the guard, the grace window and the
step outputs are byte-identical.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
---------
Co-authored-by: Claude <noreply@anthropic.com>
* fix(service-automation): compile the test layer with tsc, and repair the TS2341 x3 it hid (#15152)
* wip: onboard service-automation typecheck, fix TS2341 residue
* wip: onboarding gate registry entry + changeset
* fix(scripts): re-measure this entry's provenance totals on the merged tree
The `service-knowledge` onboarding landed on `main` between this entry's first
reading and this merge, so every absolute in its provenance block (programs,
pairs, packages, clean count) was a number about a tree that no longer exists.
Re-taken with `--list` on the merge commit itself, all four rows plus the
before/after pair, by varying only what the `typecheck` script names:
no `typecheck` script absent 120 programs / 293 pairs
names tsconfig.json absent 120 programs / 293 pairs
names tsconfig.test PRESENT 121 programs / 302 pairs
names both (the card) PRESENT 121 programs / 302 pairs
before 59 of 78 packages, 120 programs, 293 pairs, 19 clean
after 60 of 78 packages, 121 programs, 302 pairs, 18 clean
The deltas this block actually claims (+1 package, +1 program, +9 pairs, one
per dep) are unchanged; only the absolutes moved, and the block now says which
merge moved them. The sibling entries' own blocks keep their own historical
readings untouched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XpTx2tbq3pZRYAdoGt6E6Y
---------
Co-authored-by: Claude <noreply@anthropic.com>
* docs(platform-objects): widen sys_email.error description to cover pre-delivery rejections
`sys_email.error` was declared as "Transport error message when status=failed",
but since #14371 EmailService.recordRejectedMessage also writes status=failed
rows for messages rejected by normalizeMessage before they reach a transport
(prefixed "rejected before delivery: ..."). The declared field help was
narrower than what the column actually holds.
Widen the description (wording settled in triage, issue comment 5504375428)
and regenerate the platform-objects i18n bundle with its own tooling
(node scripts/check-i18n-bundles.mjs --write) rather than hand-editing the
generated file.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
* chore(platform-objects): add changeset for sys_email.error description widening
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
---------
Co-authored-by: Litant Ying <litant.dev@proton.me>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: os-sales <sales@objectstack.ai>1 parent fbecffe commit 2bb0614
3 files changed
Lines changed: 25 additions & 2 deletions
File tree
- .changeset
- packages/platform-objects/src
- apps/translations
- audit
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2476 | 2476 | | |
2477 | 2477 | | |
2478 | 2478 | | |
2479 | | - | |
| 2479 | + | |
2480 | 2480 | | |
2481 | 2481 | | |
2482 | 2482 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
192 | 192 | | |
193 | 193 | | |
194 | 194 | | |
195 | | - | |
| 195 | + | |
| 196 | + | |
196 | 197 | | |
197 | 198 | | |
198 | 199 | | |
| |||
0 commit comments