Skip to content

Commit 91e8fa1

Browse files
docs(trigger-schedule): re-anchor the dead tracker citations to the commits that decided them (#20775)
Part of #20596 Clause-②: no ## What changed This is the twelfth stage of the `domain:services` lane of the dead-citation sweep. It covers `packages/triggers/trigger-schedule/src/**` and nothing else. By the seat's claim (`5903462246`), it is the largest package in the lane that no in-flight work holds, now that #20599's PR #20746 (which edited `time-relative-trigger.ts`) has landed. Later stages cover the other packages, so this PR says `Part of` and the card stays open. Every comment or docblock site in scope that cited a tracker number answering 404 has been rewritten in ruling C+D's form C (comment 5749154545 on #19123), by the method of stages 1 to 11 (PR #20609 as `422db788a`, PR #20626 as `b80ab579d`, PR #20634 as `4d04b6be3`, PR #20658 as `9a4b2bb38`, PR #20693 as `0e9ad74fb`, PR #20708 as `9b384f63a`, PR #20717 as `cbaf04c1f`, PR #20729 as `d2820876f`, PR #20737 as `4dfff176b`, PR #20742 as `697845d19`, PR #20757 as `cba417a8f`). That is **32 sites on 32 lines in 6 files, covering 2 numbers**: - 18 census sites (every census site this package has); - 14 sites in test comments, which the census defers; - no site the gate's grammar cannot see (the package has none, see Acceptance notes). Each rewritten line now cites the commit in `origin/main` history that decided what the line describes, and says in its own words what was decided: **2 distinct shas**. Neither number has an ADR or ruling record of its own (a grep of `docs/adr/`, `scripts/adr-anchors/` and the rest of `docs/` for both numbers finds nothing, and no ADR records the acting-organization decision or the driver-memory per-call refusal), so both anchors are commits, per ruling C's order. No number was dropped. Only comments changed. Every touched source file keeps its line count (32 lines out, 32 in, over 6 files), so no line citation into these files moves. Every one of the 32 changed lines carried a dead citation; there is no reflow line. No code token moves (see the guard below). **No citation number is added.** The only tracker number on an added line is the live `#8844`, on the line it already stood on. Added minus removed is negative for the two dead numbers and zero for every other number, and no number is new to the diff. No PR number is the citation on an added line. 4 dead sites are left on purpose: three `describe` titles, and one comment that quotes one of those titles verbatim (see the list below). One more file: a `patch` changeset for `@objectstack/trigger-schedule`, because the rewritten prose ships (see Changeset below). ## Census: `trigger-schedule`, before and after **Instrument (A1).** The gate's own `node scripts/check-issue-citations.mjs --census --json`, read-only and unchanged. The count below is its `allocated-but-absent` findings under `packages/triggers/trigger-schedule/`. Each run counts as a reading only because its board frontier equals the newest issue or pull-request number, read by a separate request just before and just after the run. | reading | tree | board | whole-repo `allocated-but-absent` | trigger-schedule sites | lines | files | numbers | |---|---|---|---|---|---|---|---| | before | base `cba417a8f`, run 2026-09-30T03:30:14Z to 03:33:24Z | enumerated, 186 pages, frontier #20769 (newest #20769 before and after) | 823 | **18** | 18 | 2 | 2 | | after | head `226be8050`, run 03:37:59Z to 03:41:09Z | enumerated, 186 pages, frontier #20769 (newest #20769 before and after) | 805 | **0** | 0 | 0 | 0 | The before count matches the seat's census and A1 (18 sites: `#16659` ×17 and `#16589` ×1, in `schedule-trigger.ts` ×5 and `time-relative-trigger.ts` ×13). A1 noted that PR #20746 edited `time-relative-trigger.ts` today; the before count above is taken on the base that already holds that edit. The whole-repo drop is 18, exactly this diff's census sites. The `resolves` tally is 33,038 in both runs, and `resolves-as-pull-request` (1,984) and `cross-repo-unjudged` (995) did not move either. The after run was taken on `226be8050`; the head `14314f49c` adds only the changeset. No run was truncated or discarded: both enumerations read 186 pages at the newest frontier. **Supplementary instrument, the whole scope.** The census does not read test files or strings, and this stage's scope includes test comments. So a second reading runs the gate's own exported `extractCitations` (whole-file and comment-prose projections) and `namesThisRepository` over every `.ts` file under `trigger-schedule/src` (14 files). It takes its verdicts from the before census's own board reading rather than from a second enumeration: a number is dead when that census reported it `allocated-but-absent`, and alive when that census judged it on this board anywhere (its `--list` extraction, 36,840 rows) and did not report it. Every number this package cites is covered by one or the other, so no number needed a separate read to be judged; the two dead numbers were also read one by one on the issues endpoint, and each answers 404. | reading | citations | dead | src comment | test comment | src string | test string | |---|---|---|---|---|---|---| | before, `cba417a8f` | 159 | **36** | 18 | 15 | 0 | 3 | | after, `226be8050` | 127 | **4** | 0 | 1 | 0 | 3 | Its src-comment column equals the census's 18, which is the control on the second instrument. The 123 live citations are the same in both readings, and the drop of 32 citations is exactly the rewritten sites. A third, raw reading (every `#` followed by 2 to 6 digits, whatever surrounds it) finds 162 occurrences and 36 dead before, 130 and 4 after. Beyond the gate's grammar it sees 3 tokens, none a tracker reference: the maintainer decision-batch ordinals `batch #13`, `#116` and `#118`, which the gate's `NON_CITATION_HEADS` excuses by design. ## Per-number table Sites and files count every dead occurrence in scope at the base (comments and strings, tests included). `rewritten / left` counts the sites rewritten and the sites left. Each anchor was read in its message and diff, not only its subject, and `git blame` at the base puts every rewritten line in its anchor commit or in a later commit that descends from it (21 lines blame to the anchor itself; for the other 11, `merge-base --is-ancestor` of anchor and blamed commit exits 0). | number | sites / files | rewritten / left | anchor: what it decided | |---|---|---|---| | `#16659` | 34/6 | 30/4 | `ecdfc9411` (PR #17334): a time-triggered flow (`schedule` or `time_relative`) declares its acting organization on its start node as `config.organization`; the engine lifts it onto the binding; both time triggers refuse to bind a flow that declares none, naming it at `error` and THROWING so the engine records the refusal instead of reporting the flow bound; the run carries the declared organization as `tenantId`; and the time-relative sweep's own query carries it too, so the sweep SELECTS inside that organization (the review finding F2 its diff names), with a store that cannot honour the scope reported at `error` and an object the engine exempts from scoping disclosed at bind. Its body names `#16659` twice (the three consequences pinned on both drivers, and the proof registered), and its diff names it on 65 added lines. The anchor the spec stage (`0f6dcac5e`) and the lint stage (`f29c83db1`) already give the same number | | `#16589` | 2/2 | 2/0 | `555a89cbd` (PR #17005): `driver-memory` gains a third seam, `assertCallNotTenantScoped`, called first in every driver door that accepts `DriverOptions`, which REFUSES a call the engine tenant-scoped instead of discarding the scope and answering every organization's rows; row-level isolation is deliberately not implemented. Its message does not carry the number, but its own diff writes the mechanism the two lines describe and names `#16589` 30 times (the `[#16589] Seam 3` markers and the guard's docblock), so it is the commit that decided it. New to the sweep | Every cited sha matches exactly one commit (`git rev-parse --disambiguate`, count 1 for each of the 2), and both are ancestors of the base (`merge-base --is-ancestor`, exit 0 for both; control leg: stage 1's landing `422db788a` exit 0; reverse leg, base against `ecdfc9411`, exit 1; the history is complete, `--is-shallow-repository` false, 15,160 commits; each anchor lies deeper than the control, 1,616 and 1,814 commits behind the base). Each of the 2 numbers answers 404 on the issues endpoint, which serves pull requests too. Independently, the package's own shipped `CHANGELOG.md` pairs `ecdfc94` with `#16659` (line 149) and `assertCallNotTenantScoped` with `#16589` (line 238). ## Wordings to check - **Tag swaps in brackets or parentheses.** 「[#16659]」 became 「[commit ecdfc94]」 on 18 lines, 「(#16659)」 became 「(commit ecdfc94)」 at `schedule-trigger.ts:251`, `:372` and `time-relative-trigger.ts:50`, and 「(#16589)」 became 「(commit 555a89c)」 at `time-relative-trigger.ts:615` and `time-relative-trigger.test.ts:988`. - **Section rules.** `schedule-trigger.test.ts:327`, `time-relative-trigger.test.ts:794` and `:862`: the 16-character phrase replaces the 6-character number and the trailing rule loses 10 characters, so each line keeps its width exactly. The `:862` heading keeps 「F2」 beside the sha; F2 is the selection finding `ecdfc9411`'s own diff names. - **「before #16659」** at `time-relative-trigger.ts:365` and `:543` became 「before commit ecdfc94」: before that commit the sweep queried with `isSystem` alone, which is the unscoped selection both sentences describe. - **「the #16659 defect」** at `time-relative-trigger.ts:561` and `time-relative-trigger.test.ts:1371` became 「the defect commit ecdfc94 fixed」: a commit fixes a defect, it is not one, and the widening both sentences name is the selection half that commit closed. - **`schedule-trigger.test.ts:512`.** 「the exact defect #16659's own refusal was shaped to avoid」 became 「the exact defect commit ecdfc94's own refusal was shaped to avoid」: the defect is a refusal that logs and arms anyway, and that commit is where the refusal became a throw so the engine records it. - **`schedule-trigger.test.ts:588`.** 「(the #16659 suite above)」 became 「(commit ecdfc94's refusal suite above)」, so the pointer still lands on the refusal suite at `:337`. ## The 4 sites left - **Test strings, 3 sites on 3 lines**, all `describe` titles, left as stages 1 to 11 left theirs: `schedule-trigger.test.ts:337` and `:462`, `time-relative-trigger.test.ts:805` (all `#16659`). - **One comment that quotes a kept title verbatim:** `schedule-trigger.test.ts:71` points the reader at 「`ScheduleTrigger — the acting-organization refusal (#16659)` below」, the exact text of the `describe` title at `:337`. The number there belongs to the quotation, so it stays with the title it quotes: rewriting it would point at a title that does not exist. It moves when the title does. - No source string, operator log string, assertion message, quoted maintainer ruling or generated file in this package carries a dead number. - Outside `src`, the package's `CHANGELOG.md` names `#16659` on 6 lines and `#16589` on 2 (lines 149, 153, 238, 273, 297, 300, 302, 304). It is release-owned and deliberately not edited here (see Acceptance notes). The package `README.md`, which also ships, names neither number. ## Mechanical guard: no code token moves The guard compares, base `cba417a8f` against head, over all 6 touched `.ts` files: - **Reading 1**, the TypeScript parser's leaf nodes (a `forEachChild` walk, so comments are trivia and JSDoc nodes are never visited). String and template literals are therefore read in full. - **Reading 2**, the full token stream in parser context (a `getChildren` walk, so punctuation and keywords are included; JSDoc nodes skipped). Results: - Real run: 10,192 base leaf tokens, **0 files with a token change** on either reading (exit 0). - Comment control in `schedule-trigger.ts` (「the same way `schedule` is.」 to 「the same way as `schedule`.」): 0 files changed, as expected (exit 0). - Positive control, a code token added in `time-relative-trigger.ts` (`resolveBindingOrganization(binding)` given `as FlowTriggerBinding`): DIFFER, 1,215 to 1,216 leaf tokens and 2,760 to 2,762 full tokens (exit 1). - Positive control, one digit changed inside a kept test title (`schedule-trigger.test.ts:462`, `#16659` to `#16658`): DIFFER on the string literal (exit 1). Every mutation went through `scripts/ablation-replace.mjs` (wrap mode) under a shell trap that restores by absolute path, and each landed (anchor 1 to 0, blob changed). Each restore was proven byte-identical to the HEAD blob (`651170483856`, `c85aadbd168d`, `78a5dea4a463`), with `git diff HEAD` empty and a clean tree afterwards. A first version of reading 2 used TypeScript's context-free scanner and was discarded before any control ran: it opened template tokens on backticks it could not place and swallowed comment text into them, so it reported comment edits as token changes (4 files) while reading 1 read 0. The parser-context stream replaced it, and every figure above is from the replacement. ## Changeset This change ships bytes, so a `patch` changeset for `@objectstack/trigger-schedule` (`.changeset/20596-trigger-schedule-provenance-anchors.md`) is included. Its body is stage 11's, word for word, with the package name changed. Measured on the built package (A3): `files[]` is `dist`, `README.md` and `CHANGELOG.md`, and the package is not private. After the build: - `ecdfc9411` appears 3 times in each of `dist/index.js` and `dist/index.mjs`: the inline comments at `schedule-trigger.ts:777` and `time-relative-trigger.ts:585` and `:702`, which the bundle keeps. - It appears twice in each of `dist/index.d.ts` and `dist/index.d.mts`: the `FlowTriggerBinding.organization` docblock (`schedule-trigger.ts:32`) and the sweep-context docblock (`time-relative-trigger.ts:50`). - `555a89cbd` appears once in each JS entry (`time-relative-trigger.ts:615`). - Positive controls, one unchanged line beside each shipped rewrite, land exactly where their neighbours do: four neighbours once in each JS file and 0 in the declaration files, and two once in each declaration file and 0 in the JS files. - A never-written negative phrase appears nowhere in `dist`. - Neither dead number is left in `dist`. ## Gates (head `14314f49c`) - **Citation judging, as CI runs it:** `pnpm check:issue-citations` exits 0. `node scripts/check-issue-citations.mjs` exits 0: the diff-scoped run judged 1 added citation across 2 files, the live `#8844`, and it resolves. - **Doc authoring:** `pnpm check:doc-authoring` exits 0 (the sibling-package prose-id baseline holds, no growth). - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at `14314f49c` (after a fresh fetch) derived 59 commands. They are all 53 derived at dispatch, plus `check:engine-double-contract`, `check:objectql-double-limit`, `check:query-options-erasure`, `check:type-check-coverage`, `check:type-check-debt` and `check:where-matcher`. - Each ran with its exit code captured before any pipe, and all 59 exit 0. - `--ran`, fed each command with its exit code, reports 59 run, 0 NOT MEASURED (a derived zero), 0 unrun, and exits 0. - A full `turbo run build` of `./packages/*` and `./packages/*/*` ran first under the shared verify lock (71 of 71 tasks, exit 0), so no gate hit an unbuilt workspace. - **Roster families the derivation lists outside its commands** (their rosters sit in directories this diff touches): `node scripts/check-changeset-fixed.mjs`, `pnpm check:authz-resolver`, `pnpm check:error-code-casing` and `pnpm check:filter-alias-parity`, each exit 0. - **Tests and typecheck, under the verify lock:** - `pnpm --filter @objectstack/trigger-schedule test`: 8 files pass and 170 tests pass. `vitest list --filesOnly` names 8 files, all the tracked test files, the 4 touched ones included. - `pnpm --filter @objectstack/trigger-schedule typecheck` exits 0, and `tsc --listFiles` holds all 14 files under `src/`, the 6 touched ones included. - **Lint, as a proven narrowing:** eslint with inline config disabled, over the 6 touched `.ts` files, gives 6 files, 0 errors and 0 warnings (its `--format json` output). All 6 are in eslint's own population (`isPathIgnored` is false for each; a `dist` file, as the control, is ignored). `eslint.config.mjs` never enables type-aware linting (no `parserOptions.project`, as its own lines 327-328 state), so a comment edit here cannot move the verdict on any untouched file. The repo-wide `pnpm lint` is CI's run. - **Control bytes:** `pnpm check:nul-bytes` exits 0, and a raw scan of the 7 changed files for control bytes finds none. ## Acceptance notes - **The gate-invisible spellings, grepped as the claim asked.** `CITATION_RE` refuses a hyphen after the digits and a `/` before the `#` (#20636), and `NON_CITATION_HEADS` excuses a number after the word 「option」. In this package: `#N-word` none, `#A/#B` none, `option #N` none, at the base and at the head, which is the claim's 0 / 0 / 0. The two `pre-#10220` spellings in `time-relative-trigger.test.ts` are extracted by the gate as this repository's `#10220`, which the census judges live. - **`CHANGELOG.md` is left.** `packages/triggers/trigger-schedule/CHANGELOG.md` names `#16659` and `#16589` on 8 lines. It is release-owned (AGENTS.md, Documentation Guardrails), a deferred surface of the citation gate, and ⛔ not part of this stage. - **「The card」 phrases are left.** 8 comment lines in 5 files of this package speak of 「this card」, 「that card」 or 「the card」. They carry no number and neither instrument sees them. The one beside a rewritten line, `schedule-trigger.test.ts:329` (「the card's consequence (3)」), sits under the heading `:327` that now names `ecdfc9411`, whose own message pins those three consequences, so it keeps a referent. The rest are unchanged, as in stages 8 to 11. - **The census instrument did not truncate in this stage.** Both enumerations read 186 pages at the newest frontier. - **Anchors the next stages can reuse**, each checked here: `#16589` → `555a89cbd` is new to the sweep; `driver-memory`'s own `src` still names `#16589` on 29 lines in 4 files (26 of them comments; corrected by the seat from the dev report, which measured it), all outside this lane's stage surface. `#16659` → `ecdfc9411` reuses the spec and lint stages' anchor. - **Base.** The branch is on `main` at `cba417a8f`. `main` has since moved three commits (`0d9349fea`, `7053333e1`, `f284ab26d`). Their 9 files are one changeset, ADR-0053, and sources and tests under `service-analytics` and `service-automation`. They touch nothing under `trigger-schedule`, nor `scripts/check-issue-citations.mjs`, `.changeset/config.json` or the `doc-authoring-prose-id` baseline. `service-automation` is a dev dependency of this package, but this diff moves no code token, so nothing here can interact with it. No merge was taken; the merge queue rebuilds on the merged generation. --- _Generated by [Claude Code](https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent f7c6d65 commit 91e8fa1

7 files changed

Lines changed: 42 additions & 32 deletions
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@objectstack/trigger-schedule': patch
3+
---
4+
5+
Provenance comments in `trigger-schedule` were re-anchored
6+
7+
Comment and docblock lines under `src/` that cited tracker numbers which no
8+
longer resolve on GitHub now cite the commit in this repository's history that
9+
decided the matter, and say in their own words what was decided. Comments
10+
only: no type, schema, export, log or refusal text, or runtime behaviour changes.

‎packages/triggers/trigger-schedule/src/schedule-dispatch-claim.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const JOB = `flow-schedule:${FLOW}`;
4343
const CRON: FlowTriggerBinding = {
4444
flowName: FLOW,
4545
schedule: { type: 'cron', expression: '0 1 * * *', timezone: 'UTC' },
46-
// [#16659] the acting organization every tick of this flow runs as.
46+
// [commit ecdfc9411] the acting organization every tick of this flow runs as.
4747
organization: 'org_2mtx1w9d0k4bqf7v',
4848
};
4949

‎packages/triggers/trigger-schedule/src/schedule-runas-e2e.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function scheduledDataFlow(name: string, runAs?: 'system' | 'user') {
5959
type: 'schedule',
6060
...(runAs ? { runAs } : {}),
6161
nodes: [
62-
// [#16659] The acting organization a time-triggered flow declares. The
62+
// [commit ecdfc9411] The acting organization a time-triggered flow declares. The
6363
// engine lifts it onto the binding and the trigger threads it onto the
6464
// run as `tenantId`; a flow without it is refused at bind.
6565
{ id: 'start', type: 'start', label: 'Start', config: { schedule: { type: 'interval', intervalMs: 1000 }, organization: 'org_2mtx1w9d0k4bqf7v' } },

‎packages/triggers/trigger-schedule/src/schedule-trigger.test.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function binding(overrides: Partial<FlowTriggerBinding> = {}): FlowTriggerBindin
6666
return {
6767
flowName: 'nightly_health_sweep',
6868
schedule: { type: 'cron', expression: '0 1 * * *', timezone: 'UTC' },
69-
// [#16659] A time-triggered binding carries its acting organization; a
69+
// [commit ecdfc9411] A time-triggered binding carries its acting organization; a
7070
// binding without one is refused — see
7171
// `ScheduleTrigger — the acting-organization refusal (#16659)` below.
7272
organization: 'org_2mtx1w9d0k4bqf7v',
@@ -324,7 +324,7 @@ describe('ScheduleTriggerPlugin', () => {
324324
});
325325
});
326326

327-
// ─── The acting-organization refusal (#16659) ───────────────────────
327+
// ─── The acting-organization refusal (commit ecdfc9411) ─────────────
328328
//
329329
// The unit half of the card's consequence (3): a time-triggered flow that
330330
// declares no acting organization is REFUSED at bind, and the refusal reaches
@@ -509,7 +509,7 @@ describe('resolveBindingOrganization (#16659)', () => {
509509
//
510510
// Three states, three suites, and each one asserts what BINDS rather than only
511511
// what is logged: a refusal that logs correctly and arms the job anyway is the
512-
// exact defect #16659's own refusal was shaped to avoid.
512+
// exact defect commit ecdfc9411's own refusal was shaped to avoid.
513513
describe('ScheduleTrigger — the deployment switch is OFF (#17396)', () => {
514514
withScheduledWorkOff();
515515

@@ -585,7 +585,7 @@ describe('ScheduleTrigger — switched ON under `single` (#17396)', () => {
585585
const trigger = new ScheduleTrigger(() => job.service, silentLogger());
586586

587587
// ⭐ The widening the whole card turns on: this exact binding is
588-
// REFUSED under a wall (the #16659 suite above) and armed here.
588+
// REFUSED under a wall (commit ecdfc9411's refusal suite above) and armed here.
589589
trigger.start(orgLess(), async () => {});
590590
expect(job.jobs.size).toBe(1);
591591
});

‎packages/triggers/trigger-schedule/src/schedule-trigger.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export interface FlowTriggerBinding {
2929
readonly condition?: string | { dialect?: string; source?: string; ast?: unknown };
3030
readonly schedule?: unknown;
3131
/**
32-
* [#16659] The ACTING ORGANIZATION a time-triggered flow declares on its
32+
* [commit ecdfc9411] The ACTING ORGANIZATION a time-triggered flow declares on its
3333
* start node (`config.organization`), lifted onto the binding by the
3434
* engine's `resolveTriggerBinding` the same way `schedule` is.
3535
*
@@ -248,7 +248,7 @@ export interface TriggerLogger {
248248
const JOB_PREFIX = 'flow-schedule';
249249

250250
/**
251-
* Resolve the acting organization of a time-triggered binding (#16659), or
251+
* Resolve the acting organization of a time-triggered binding (commit ecdfc9411), or
252252
* `null` when the flow declared none.
253253
*
254254
* Reads the binding's lifted `organization` first and the raw start-node
@@ -369,7 +369,7 @@ export function refuseScheduledWorkDisabled(
369369

370370
/**
371371
* Refuse to bind a time-triggered flow that declares no acting organization
372-
* (#16659): say why at `error`, then THROW so the engine records the refusal.
372+
* (commit ecdfc9411): say why at `error`, then THROW so the engine records the refusal.
373373
*
374374
* ## When this fires, after #17396 and #18378
375375
*
@@ -700,7 +700,7 @@ export class ScheduleTrigger implements FlowTrigger {
700700
return;
701701
}
702702

703-
// [#16659] The acting organization is part of the BINDING, so it is
703+
// [commit ecdfc9411] The acting organization is part of the BINDING, so it is
704704
// checked before the job service is even resolved: a flow that cannot
705705
// legally run must not be reported as "not scheduled because the job
706706
// service is missing", which is a different defect with a different
@@ -774,7 +774,7 @@ export class ScheduleTrigger implements FlowTrigger {
774774
try {
775775
const ctx: AutomationContext = {
776776
event: 'schedule',
777-
// [#16659] When the flow declares one, the run executes AS
777+
// [commit ecdfc9411] When the flow declares one, the run executes AS
778778
// that organization: `tenantId` is the acting run's
779779
// organization, and every consumer already reads it —
780780
// `notify-node.ts` threads it onto the notification it

‎packages/triggers/trigger-schedule/src/time-relative-trigger.test.ts‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ function fakeDataEngine(rows: Row[], knownObjects: string[] = ['contracts']) {
7777
}
7878

7979
/**
80-
* [#16659] A fake ObjectQL surface that HONOURS `context.tenantId`, so the
80+
* [commit ecdfc9411] A fake ObjectQL surface that HONOURS `context.tenantId`, so the
8181
* differential control can put matching rows in two organizations and observe
8282
* which ones come back.
8383
*
@@ -134,7 +134,7 @@ function silentLogger(): TriggerLogger {
134134
const NOW = () => new Date('2026-07-18T12:00:00.000Z');
135135

136136
/**
137-
* [#16659] The organization every fixture binding declares. Named rather than
137+
* [commit ecdfc9411] The organization every fixture binding declares. Named rather than
138138
* inlined because it is now asserted from two directions — the sweep's query
139139
* scope and the launched run's identity — and a literal repeated at both ends
140140
* of that pair can drift into agreeing with itself.
@@ -146,7 +146,7 @@ function binding(timeRelative: unknown, overrides: Partial<FlowTriggerBinding> =
146146
flowName: 'renewal_alert',
147147
object: 'contracts',
148148
config: { timeRelative },
149-
// [#16659] see the schedule trigger's fixture note.
149+
// [commit ecdfc9411] see the schedule trigger's fixture note.
150150
organization: TEST_ORG,
151151
...overrides,
152152
};
@@ -275,7 +275,7 @@ describe('TimeRelativeTrigger', () => {
275275
expect(seen[0]).toMatchObject({ object: 'contracts', event: 'time_relative' });
276276
expect(seen[0].record).toBe(seen[0].params);
277277
// The sweep queries as a system op (sees all rows, RLS-bypassing) AND
278-
// inside its declared organization. [#16659] This assertion used to
278+
// inside its declared organization. [commit ecdfc9411] This assertion used to
279279
// read `{ isSystem: true }` and it was pinning the defect: `isSystem`
280280
// is AUTHORIZATION and `tenantId` is TENANCY, and a sweep carrying only
281281
// the first selects across every tenant while its runs act as one.
@@ -791,7 +791,7 @@ describe('TimeRelativeTriggerPlugin', () => {
791791
});
792792
});
793793

794-
// ─── The acting-organization refusal (#16659) ───────────────────────
794+
// ─── The acting-organization refusal (commit ecdfc9411) ─────────────
795795
//
796796
// The time-relative sweep is NOT the weaker case for carrying an organization,
797797
// it is the stronger one: it runs ELEVATED on purpose (`isSystem` — a
@@ -859,7 +859,7 @@ describe('TimeRelativeTrigger — the acting-organization refusal (#16659)', ()
859859
expect(job.jobs.size).toBe(0);
860860
});
861861

862-
// ── the SELECTION half (#16659, F2) ───────────────────────────────────
862+
// ── the SELECTION half (commit ecdfc9411, F2) ─────────────────────────
863863
//
864864
// Declaring an organization bounded the RUN and left the QUERY unbounded,
865865
// so a sweep declared for A matched rows in every tenant and launched runs
@@ -985,7 +985,7 @@ describe('TimeRelativeTrigger — the acting-organization refusal (#16659)', ()
985985
});
986986

987987
it('a store that CANNOT honour the scope is reported at `error`, never answered unscoped', async () => {
988-
// `driver-memory` refuses any call handed a tenant scope (#16589). A
988+
// `driver-memory` refuses any call handed a tenant scope (commit 555a89cbd). A
989989
// sweep required to stay inside one organization, talking to a store
990990
// that cannot keep it there, must be LOUD — "selected nothing this
991991
// tick" and "cannot select at all" are different facts.
@@ -1368,7 +1368,7 @@ describe('TimeRelativeTrigger — switched ON under `group` (#18378)', () => {
13681368
it('a DECLARED organization still outranks the record — declaring narrows, it does not widen', async () => {
13691369
// A declaration bounds SELECTION as well as identity, so honouring the
13701370
// record over it would silently widen a flow the author scoped — the
1371-
// #16659 defect. Declaration wins, and the sweep sees one plant only.
1371+
// defect commit ecdfc9411 fixed. Declaration wins, and the sweep sees one plant only.
13721372
const job = fakeJobService();
13731373
const base = tenantScopedDataEngine(twoPlants());
13741374
const engine = {

‎packages/triggers/trigger-schedule/src/time-relative-trigger.ts‎

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export interface TimeRelativeDataEngine {
4747
limit?: number;
4848
/**
4949
* The sweep's execution context. Two INDEPENDENT axes, and this
50-
* sweep sets both (#16659):
50+
* sweep sets both (commit ecdfc9411):
5151
*
5252
* - `isSystem` is AUTHORIZATION — a background sweep must see
5353
* every row the organization holds, not the RLS-scoped subset
@@ -215,7 +215,7 @@ export function buildWindowWhere(desc: TimeRelativeDescriptor, window: DateWindo
215215
}
216216

217217
/**
218-
* [#16659] Why the engine will DROP this sweep's tenant scope for `schema`, or
218+
* [commit ecdfc9411] Why the engine will DROP this sweep's tenant scope for `schema`, or
219219
* `null` when it will apply it.
220220
*
221221
* `Engine.buildDriverOptions` scopes a read by `context.tenantId` unless the
@@ -343,7 +343,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
343343
}
344344
const desc = parsed.data;
345345

346-
// [#16659] A time-relative sweep launches from a clock, exactly as a
346+
// [commit ecdfc9411] A time-relative sweep launches from a clock, exactly as a
347347
// plain schedule flow does, so it owes the same declaration and takes
348348
// the same refusal. It is NOT the weaker case for carrying an
349349
// organization, it is the stronger one: the sweep runs ELEVATED
@@ -362,7 +362,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
362362
// elevation argument above is why the `single` case is still safe: an
363363
// unscoped `isSystem` read on a one-organization install selects that
364364
// organization's rows and the platform's NULL-tenant rows, which is
365-
// exactly what it selected before #16659 and what the #8844 guard
365+
// exactly what it selected before commit ecdfc9411 and what the #8844 guard
366366
// resolves beneath it.
367367
const organization = resolveBindingOrganization(binding);
368368
if (policy.requiresActingOrganization && organization === null) {
@@ -415,7 +415,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
415415
// author never made.
416416
const inertBecause = organization !== null ? organizationScopeIsInertFor(known) : null;
417417
if (inertBecause) {
418-
// [#16659] ⛔ A DISCLOSURE, never a narrowing. The sweep
418+
// [commit ecdfc9411] ⛔ A DISCLOSURE, never a narrowing. The sweep
419419
// passes `context.tenantId` unconditionally and the ENGINE
420420
// decides whether it applies; this branch re-reads the two
421421
// declarations the engine documents as its exemptions
@@ -460,7 +460,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
460460
// Error isolation: a sweep failure must not crash the job
461461
// runner / ticker. Log and swallow.
462462
//
463-
// [#16659] At `error` when the logger has one, for the reason
463+
// [commit ecdfc9411] At `error` when the logger has one, for the reason
464464
// {@link TriggerLogger.error} already states: the CLI's
465465
// boot-quiet window swallows stdout, so a `warn` here can be
466466
// the whole of what a broken sweep says and still be invisible.
@@ -484,7 +484,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
484484
const mode = desc.offsetDays
485485
? `offsets [${desc.offsetDays.join(', ')}]d`
486486
: `within ${desc.withinDays}d`;
487-
// [#16659] The organization is on the BIND line, not only in
487+
// [commit ecdfc9411] The organization is on the BIND line, not only in
488488
// the refusal: it is now the sweep's selection scope as well as
489489
// the run's identity, so "which rows can this flow ever see" is
490490
// answerable from the boot log instead of from the metadata.
@@ -524,7 +524,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
524524
desc: TimeRelativeDescriptor,
525525
maxRecords: number,
526526
/**
527-
* [#16659] The declared organization, or `null`.
527+
* [commit ecdfc9411] The declared organization, or `null`.
528528
*
529529
* When declared it bounds this sweep TWICE, and both halves are
530530
* load-bearing:
@@ -540,7 +540,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
540540
* second organization to cross to there (plugin-auth's org-create
541541
* posture gate refuses one), so an
542542
* unscoped sweep is not the cross-organization task the ruling forbids
543-
* — it is the shape a single-organization install had before #16659.
543+
* — it is the shape a single-organization install had before commit ecdfc9411.
544544
* Under `isolated` `start()` still refuses an undeclared binding, and
545545
* with the switch off nothing binds, so `null` cannot arrive from
546546
* either.
@@ -558,7 +558,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
558558
* Only `'per-record'` changes behaviour here, and only while
559559
* `organization === null`: an explicit declaration outranks it, because
560560
* a declaration bounds SELECTION as well as identity and silently
561-
* widening a flow the author scoped would be the #16659 defect again.
561+
* widening a flow the author scoped would be the defect commit ecdfc9411 fixed, again.
562562
*/
563563
ownership: ScheduledRunOwnership,
564564
callback: (ctx: AutomationContext) => Promise<void>,
@@ -582,7 +582,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
582582
(await engine.find(desc.object, {
583583
where,
584584
limit: maxRecords,
585-
// [#16659] SELECTION is scoped to the declared organization,
585+
// [commit ecdfc9411] SELECTION is scoped to the declared organization,
586586
// not just the run that follows it.
587587
//
588588
// `isSystem` alone was the whole context here, and it made
@@ -612,7 +612,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
612612
// (`tenancy.enabled: false`, ADR-0066; federated, ADR-0015),
613613
// and every driver that CAN isolate then scopes, while
614614
// `driver-memory` — which cannot — refuses the call by name
615-
// (#16589). Refusal is the correct answer for a sweep that
615+
// (commit 555a89cbd). Refusal is the correct answer for a sweep that
616616
// is required to stay inside one organization and is talking
617617
// to a store that cannot keep it there, and it arrives as a
618618
// logged sweep failure rather than as silence.
@@ -699,7 +699,7 @@ export class TimeRelativeTrigger implements FlowTrigger {
699699
record,
700700
object: desc.object,
701701
event: 'time_relative',
702-
// [#16659] The acting organization — the same key a
702+
// [commit ecdfc9411] The acting organization — the same key a
703703
// record-change run inherits from its triggering session,
704704
// and the one `notify-node.ts` and the run-history writer
705705
// already read.

0 commit comments

Comments
 (0)