Repository navigation
Commit ae6dcf6
fix(service-automation): a notify node reports the recipients it addressed, so a zero-delivery run stops reading like a successful one (#17339)
* fix(service-automation): notify reports the recipients it addressed
A notify node whose delivery came back zero contributed `acted: 0` and
nothing else, so a run that notified nobody folded to
`selected: 0, acted: 0, unmeasured: 0` -- the same triple a run with no
notify node at all reports, and one the broken-sweep filter cannot match
because its first clause is `selected > 0`.
Report `selected` (the recipient entries addressed) on every path that
reaches a recipient list. `acted` / `unmeasuredEffect` keep their rules,
so a delivering run's reading is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
* test(service-automation): differential control for notify zero-delivery
Same flow, same recipients, both trigger families (the cron tick context
ScheduleTrigger really builds, and the REST trigger's session context),
on both drivers (memory and better-sqlite3), over the real
MessagingService + outbox + inbox channel.
Three-way comparison: the zero-delivery run, the delivering run, and a
run that genuinely had nothing to notify about -- the first two of which
used to be told apart only by a token on the OTHER row, and the first
and third of which were the same triple.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
* test(service-automation): migrate the second backend off the frozen memory driver
`pnpm check:driver-memory-census` refuses a new binding to
@objectstack/driver-memory and says in as many words that adding a
ledger entry to silence it is not the author's call: the consumer set is
a maintainer ruling. Take the migrate route instead -- the matrix is now
sqlite-wasm x sqlite-native, two real storage implementations.
Admitting a memory arm needs that ruling; noted on the PR.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
* test(service-automation): take the second arm without a maintainer-only widening
check:type-source-resolution refuses @objectstack/driver-sqlite-wasm and
@objectstack/platform-objects as new dist-resolved type imports, says
widening its shrink-only registry is not the fix, and names `paths` as
the measured-wrong tool for a package whose rootDir is `src` (TS6059).
Its own remedy for that case is to not take the dependency.
So: object fixtures are declared locally, and the non-SQL arm is an
in-process IDataEngine rather than the frozen mingo driver. Declared as a
deviation in the file header; the real memory arm needs a ruling.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
* chore: drop the lockfile residue from the reverted dev dependencies
Two devDependencies were added and then taken back out (the frozen memory
driver, then the wasm one); the manifest returned to its original state
but the lockfile kept the entry. Restored to origin/main and re-verified
with a full `pnpm install`, which rewrote nothing.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
* test(service-automation): pin the published summary lines verbatim
The three rows the PR publishes are now assertions rather than prose, so
the table is a measurement anyone can re-run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
* test(service-automation): route the in-process engine double's findOne through the producer predicate
The zero-delivery differential control's second arm is an in-process
IDataEngine standing in for the frozen mingo driver. Its findOne read an
absent filter as "match everything", which is looser than ObjectQL.findOne
— the exact shape check:engine-double-contract pins, and the shape that
turns a green suite into no suite at all.
Open it with assertEngineFindOnePredicate(object, query), imported from
@objectstack/metadata-core — the predicate's home, and already a declared
dependency of this package, so no new dependency edge and no objectql
reverse edge. The RETAINED ledger learns the new row through the gate's
own --write; the shrink-only baseline is untouched, byte for byte.
All nine cases of the differential control still pass unchanged: no
assertion was loosened to accommodate the predicate.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
* test(service-automation): hold the caller's bound and refuse the combinators this double does not implement
Two further gates were RED on this same in-process engine double before this
branch's last head, and neither had run in CI: the lint job executes its gates
sequentially under `bash -e`, so check:engine-double-contract's exit 1 halted
the job and masked every step behind it. Both are the same defect class as the
finding that halted it — a test double looser than the engine it stands in for
— in the same literal, and both gates state their baseline never grows, so the
mechanical fix each prints is the only route.
check:where-matcher — `matches` read a combinator as a FIELD NAME. No row
carries a column called `$or`, so such a clause silently drops every row and
this arm would report "nobody was reached" for a reason that is not the one
under test, in the very file written to make that distinction visible. The
store answers scalar equality, so it now refuses a combinator loudly rather
than answering wrongly.
check:objectql-double-limit — `find` applied the caller's bound by truthiness,
so `limit: 0` returned every row: the one call that asked for none. Applied by
presence now, after the filter.
Neither baseline gained a file ("no files added", both gates). No assertion and
no case was touched: the diff contains zero `expect(`/`it(`/`describe(` lines,
and all nine cases of the differential control still pass on both arms,
CONTROLs included — the in-process arm still genuinely delivers.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zTkyNHJ7TkuN2oXtP5x37
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 54b3d1d commit ae6dcf6
5 files changed
Lines changed: 629 additions & 3 deletions
File tree
- .changeset
- content/docs/automation
- packages/services/service-automation/src/builtin
- scripts
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1060 | 1060 | | |
1061 | 1061 | | |
1062 | 1062 | | |
| 1063 | + | |
1063 | 1064 | | |
1064 | 1065 | | |
1065 | 1066 | | |
| |||
1071 | 1072 | | |
1072 | 1073 | | |
1073 | 1074 | | |
| 1075 | + | |
| 1076 | + | |
| 1077 | + | |
| 1078 | + | |
| 1079 | + | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
1074 | 1086 | | |
1075 | 1087 | | |
1076 | 1088 | | |
| |||
Lines changed: 48 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
321 | 321 | | |
322 | 322 | | |
323 | 323 | | |
324 | | - | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
325 | 331 | | |
326 | 332 | | |
327 | 333 | | |
| |||
439 | 445 | | |
440 | 446 | | |
441 | 447 | | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
442 | 487 | | |
443 | | - | |
444 | | - | |
| 488 | + | |
| 489 | + | |
445 | 490 | | |
446 | 491 | | |
447 | 492 | | |
| |||
0 commit comments