Skip to content

fix(jcode): deliver directed messages into active turns - #1079

Merged
davidfarah2003 merged 14 commits into
mainfrom
fix/910-jcode-active-turn-delivery
Aug 30, 2026
Merged

fix(jcode): deliver directed messages into active turns#1079
davidfarah2003 merged 14 commits into
mainfrom
fix/910-jcode-active-turn-delivery

Conversation

@davidfarah2003

@davidfarah2003 davidfarah2003 commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Addresses #910's reproduced direct-message delivery defect.

Summary

  • deliver directed automatic traffic into an active Jcode turn through Jcode's existing session-owned soft_interrupt queue; this is the in-scope recipient handoff for the reproduced stall, not a separate connector feature
  • keep ambient channel traffic buffered for the next turn
  • track initial and soft-interrupted receive keys separately, then commit the exact containing-turn ledger only after the Harness turn succeeds
  • retain the whole batch across a failed turn or private Harness replacement for JetStream redelivery
  • document the active-turn behavior and add a patch changeset

Reproduction

On unmodified main, a real loopback NATS broker and the shipped Jcode host held one Harness turn open for 8 seconds. Three DMs published successfully while presence reported the recipient live, but the recipient Harness session observed none within 3 seconds. The failing assertion was:

timed out waiting for short, 4 KiB, and 64 KiB DMs reach the recipient session before the active turn ends (#910)

This also rules out the live 4 KiB specimen as a payload ceiling. After the fix, short, about 4 KiB, and about 64 KiB DMs all reached the recipient session before the active turn ended.

Proof

  • pnpm build
  • connector Jcode and connector core typechecks
  • pnpm smoke:jcode-mid-turn-delivery with 6 recipient-observed cells
  • pnpm smoke:jcode-provider-disconnect
  • pnpm smoke:jcode-host
  • pnpm smoke:gate-inventory
  • pnpm smoke:mutation-fixtures
  • pnpm check:docsbundle
  • pnpm changeset status
  • node scripts/mutation-proof.mjs --config extensions/connector-jcode/smoke/mutations/mid-turn-delivery.json
    • 2 of 2 mutations KILLED red-and-named
    • recipient session handoff removed
    • soft-interrupted ids omitted from clean-boundary commit

The same fixture also exercised a same-lifecycle host replacement: a DM sent through the sender's pre-restart presence record, before successor presence, reached the resumed replacement session.

Limits

  • The production observation involving a second Jcode journal file did not reproduce. The controlled same-lifecycle replacement delivered correctly, so this PR does not claim to fix an unknown lifecycle or principal change outside that path. The remaining discriminator is tracked in connector-jcode: a production restart may strand DMs on a dead lifecycle or stale launch #1080.
  • The fixture does not force a Harness turn failure after a successful soft-interrupt acceptance. Failed-turn no-drop/no-double remains supported by the existing provider-disconnect path and the host ledger, but is not directly exercised in that exact interleaving.
  • The sender receipt still means broker acceptance, not model acknowledgement. This change closes the reproduced Jcode edge stall by moving directed traffic into the recipient session and retaining at-least-once commit semantics.
  • No shared stack lifecycle command, smoke:ci, pnpm check, or shared broker was used.
  • I accidentally ran pnpm smoke:jcode-live once during baseline investigation. It used its own throwaway loopback broker and passed 3 of 3, but its name was prohibited by the task constraints. It was not used as proof for this change and was not run again.
  • Initial load was 39.71 / 45.46 / 39.66 on 12 CPUs. The accepted final validation window ran at 15.64 / 23.70 / 22.61, with 10 GiB memory available and swap nearly full. Load was recorded, never used as a gate.

Review follow-up

  • integrated current origin/main
  • preserved the three suites added on main
  • moved smoke:jcode-mid-turn-delivery to the literal tail
  • verified committed suite delta: added 1, removed 0, moved 0
  • reran targeted Jcode smokes, package typechecks, gate inventory, mutation anchors, docs bundle, changeset status, and the 2/2 killed mutation proof
  • latest current-main fold exact head: 00bc448ac65b6770ce3082bff32db6da413bd646; suite delta remains added 1, removed 0, moved 0; all listed local proof rerun green

@davidfarah2003 davidfarah2003 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LANDING-QUEUE REVIEW: BLOCKERS

  • bin/smoke/ci-suites.txt:472 — smoke:jcode-mid-turn-delivery is inserted mid-file (grouped after smoke:jcode-provider-disconnect, before smoke:orientation), not appended at the absolute tail. At this PR's head the file is 699 lines and ends with smoke:workspace-import-exports; every other entry near the tail carries an explicit 'Appended so every existing shard assignment remains unchanged' comment that this insertion violates. Move the line to the literal end of the file.
  • Core logic otherwise matches the body: host.ts tracks surfacedIds/steerSettled (host.ts:415-493) so ack only happens after turnClient.run() resolves and any in-flight softInterrupt settles (host.ts:409-414), and both failure paths (catch block host.ts:454; recoverBridge host.ts:507) reset surfacedIds = [] without draining, matching the 'unacked on failure/replacement' claim.
  • Ambient-vs-directed split matches the doc claim: agent.on('incoming', ...) (host.ts:549-557) only steers when directed, and steerPending's own inbox filter (host.ts:466) still excludes non-mentioned channel items, so ambient truly waits for the next turn.
  • The two mutations in mutations/mid-turn-delivery.json map 1:1 to real assertions: M1 deletes the softInterrupt call (kills the mid-turn-delivery check), M2 substitutes ids for surfacedIds at commit time (kills the exactly-once-commit check) — this is genuine both-polarity coverage, not decorative.
  • Interaction with #1078: both PRs regenerate the same single-line body string in extensions/connector-core/src/docs-bundle.generated.ts (around line 74), so whichever lands second will conflict there and need a docs-bundle regen — not a defect in either PR, just a landing-order note.
  • Once the ci-suites.txt placement is fixed this looks landable.

@davidfarah2003

Copy link
Copy Markdown
Contributor Author

BLOCK at exact head 9b8850998a7b808ac66b0b50a93edfe82f5fa6b3.

The active-turn delivery change is technically promising, but this exact head cannot land because its committed CI registry drops three current-main suites and reshards existing gates.

Exact committed-ref result against current origin/main:

suites: 424 -> 422
added: smoke:jcode-mid-turn-delivery
removed: smoke:endpoint-permission-results:auth, smoke:presence-watch-stall, smoke:web-presence-view
pre-existing suites changing shard: 54 of 424
shard-stability: RESHARD=1

Local merge-tree is clean and GitHub reports MERGEABLE, but that does not repair committed branch content. Merge current main, preserve all three main suites, then append smoke:jcode-mid-turn-delivery at the true tail. The expected committed check is added 1, removed 0, moved 0.

Product evidence beyond the integration blocker:

  • Real loopback broker plus shipped Jcode host: 6 recipient-observed cells passed. Short, about 4 KiB, and about 64 KiB DMs all reached soft_interrupt before the active turn ended.
  • The clean containing turn did not redeliver the steered batch, and the next turn was free of it.
  • Same-lifecycle replacement received a DM addressed through stale predecessor presence.
  • Mutations M1 and M2 reran KILLED red-and-named, establishing dependency on the shipped host handoff and exact containing-turn commit ledger.
  • Reach is established: the fixture launches the shipped host, publishes through a real broker, and observes the recipient Harness API session, not a sender receipt.
  • smoke:gate-inventory is green and confirms the new suite is automated. Mutation fixtures are green.

A timing-sensitive baseline was red once during concurrent validation, then passed on immediate rerun at load 26.50, 27.04, 24.27; the mutation battery then ran cleanly. I treat that isolated unmodified red as harness/load-sensitive, not a product finding.

Residual proof gap, not this BLOCK: the fixture proves clean-boundary commit and private replacement retention. It does not force a Harness turn failure after a successful soft interrupt, so failed-turn no-drop/no-double semantics remain dependency/reasoning rather than direct behavioral proof. That limitation should remain explicit unless a failure arm is added.

@davidfarah2003

Copy link
Copy Markdown
Contributor Author

Queue sequencing note: the one blocker is the mid-file ci-suites.txt insert at line 472 (reindex hazard, #920) — the review found everything else landable. Either move the entry to the literal tail, or — once #1052's merge-safe fragment scheme lands (currently fixing a typecheck break) — rebase onto fragments. Also mind the landing-order note vs #1078: both regenerate the same docs-bundle line, so the second to land needs a regen.

@davidfarah2003

Copy link
Copy Markdown
Contributor Author

Review blocker resolved at exact head 2adf3f22b46f6dd342634be3d358caa3a10be436.

  • integrated current origin/main
  • preserved smoke:endpoint-permission-results:auth, smoke:presence-watch-stall, and smoke:web-presence-view
  • appended smoke:jcode-mid-turn-delivery at the literal tail
  • committed-ref delta against current main: added 1, removed 0, moved 0
  • regenerated the docs bundle
  • reran Jcode/core typechecks; delivery 6/6; provider-disconnect 6/6; Jcode host 41/41; gate inventory; mutation anchors; docs bundle; changeset
  • reran mutation proof: 2/2 KILLED red-and-named

Please re-review this exact head. The noted failure-after-successful-soft-interrupt arm remains a proof limit rather than a claimed behavioral test.

PR 1033 merge review added 2 commits August 30, 2026 06:29
# Conflicts:
#	bin/smoke/ci-suites.txt
#	extensions/connector-core/src/docs-bundle.generated.ts
# Conflicts:
#	bin/smoke/ci-suites.txt
@davidfarah2003

Copy link
Copy Markdown
Contributor Author

Current-main integration advanced again at exact head 7347d2dc0a0ffed6a78b0b42a08d47779b793f1a after #1071 landed.

  • preserved the new smoke:sparse-history-walk tail entry
  • resolved the append conflict by placing smoke:jcode-mid-turn-delivery after it at the new literal tail
  • committed-ref delta against current main remains added 1, removed 0, moved 0
  • regenerated docs bundle
  • reran Jcode/core typechecks; delivery 6/6; provider-disconnect 6/6; Jcode host 41/41; gate inventory; mutation anchors; docs bundle; changeset
  • reran mutation proof: 2/2 KILLED red-and-named

Please re-review this exact head. Do not merge.

@davidfarah2003

Copy link
Copy Markdown
Contributor Author

Current-main integration advanced again at exact head 94097cb9c9f779671ce5aa555b038936c066cb70 after #981 landed.

  • preserved main transport-liveness and connection-status tail entries
  • kept smoke:jcode-mid-turn-delivery at the new literal tail
  • committed-ref delta against current main remains added 1, removed 0, moved 0
  • regenerated docs bundle
  • ran full pnpm build before dependent package typechecks
  • reran delivery 6/6, registry/mutation/docs/changeset gates, and mutation proof 2/2 KILLED red-and-named

Please re-review this exact head. Do not merge.

@davidfarah2003

Copy link
Copy Markdown
Contributor Author

APPROVE at exact folded head 00bc448ac65b6770ce3082bff32db6da413bd646.

The previous integration blocker is closed. Current main's 428-suite ordering is an exact prefix, the head has 429 suites, only smoke:jcode-mid-turn-delivery is added, nothing is removed, and it is the literal tail. Committed shard stability reports added 1, removed 0, and 0 of 428 pre-existing suites moved.

Exact-head product evidence at start load 32.34, 33.10, 31.03:

  • Real loopback broker plus shipped Jcode host: 6 recipient-observed cells passed. Short, about 4 KiB, and about 64 KiB DMs reached the recipient's soft_interrupt queue before the active turn ended.
  • Clean containing-turn boundary committed the steered deliveries exactly once; the later turn did not carry the prior batch.
  • Provider-disconnect/replacement path: 6/6; full Jcode host regression: 41/41.
  • Mutations M1 and M2: both KILLED red-and-named on recipient delivery and exact containing-turn commit.
  • Mutation fixture gate: green; both anchors present, unique, and code-only.
  • Jcode and connector-core typechecks, docs bundle, git diff --check, and changeset status: green.

A timing-sensitive unmodified delivery run was red once during concurrent validation and passed on immediate rerun at load 32.86, 34.65, 32.15; the subsequent mutation battery had a green baseline. I do not treat the isolated red as a product defect.

Reach versus dependency: reach is established. The fixture launches the shipped host, sends through a real broker, and observes the recipient Harness session. Mutations separately prove dependency on soft-interrupt handoff and the exact receive-key commit ledger.

Named gaps retained: the fixture proves clean-turn commit and private Harness replacement retention, but does not force a Harness turn failure after a successful soft interrupt. Failed-turn no-drop/no-double remains an explicit proof gap rather than a tested claim. Sender publish still means broker acceptance, not recipient/model acknowledgement. The core unicast API also cannot synchronously prove a valid principal is presently reachable; this PR does not weaken that existing contract or add a silent queue fallback.

smoke:gate-inventory is currently red on current main for unrelated newly added ungated scripts (control-transport-crash-cleanup, and main also reports disarm-delete-timeout). The PR head improves that count by gating its own new suite. This inherited main red is not a PR blocker.

@davidfarah2003
davidfarah2003 merged commit ee8cadf into main Aug 30, 2026
3 checks passed
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.

1 participant