Repository navigation
docs(ideation): actor-collection revival - six ranked, evidence-verified directions - #310
Conversation
…ied directions Adds the 2026-08-17 ideation deliverable for reviving the 2022 micro-actor branch family (manifest: sweep-2023-actor-ipc), plus the inflight pointer that makes it discoverable from docs/inflight/. The doc holds six survivors from ~55 generated candidates, each with a verified basis (direct quotes spot-checked against the repo and the 2022 branch trees by an independent verification pass), confidence/complexity, downsides, and a rejection table recording what was cut and why - including one candidate killed because its cited evidence was factually backwards, and one whose headline number was a 4x diffstat misread. Top pick: a one-day falsification pipeline (rename-script the 4 framework files, compile standalone, conformance-test the documented FILO invariant) that converts the two standing editorial verdicts on this family from opinion into measurement before any architectural decision is made. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QqHpNSXC39ANv9kG1ZvUzn
…eation doc bin/check-issue-refs.sh found 23 bare refs the previous commit missed - the pre-commit gate run was piped through tail, which both truncated the listing to its last two lines and swallowed the non-zero exit. All refs now carry their repo (astubbs# / confluentinc#); gate green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QqHpNSXC39ANv9kG1ZvUzn
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
✅ Duplicate Code ReportTwo engines run in parallel for cross-validation. Each has its own thresholds tuned to its baseline - the real safety net is the per-engine "max increase vs base" check. ✅ PMD CPD
No new clones introduced by this PR. ✅ jscpd (language-agnostic)
No new clones introduced by this PR. Powered by astubbs/duplicate-code-cross-check |
✅ SpotBugs ReportNo bugs found (new bugs only — baseline from base branch excluded). |
🧪🔒 Quarantine Lane Report
🔴 expected while the owner PR is open · 🟡🎲 flapper, pass proves nothing · 🚨 a deterministic quarantined test passing means its fix landed: delete its |
|
@claude review this |
|
Claude finished @astubbs's task in 2m 25s —— View job Review
This is a docs-only ideation deliverable (self-contained HTML + an inflight pointer note), so I reviewed it as a documentation/content change: structural fit with the repo's conventions, and accuracy of the claims and citations against the actual repo state. Blocking: unqualified issue reference will fail the PR Checklist gate
Fix: resolve which repo Verified accurate (spot-checked against repo state)
Minor, non-blocking
No code changes, no tests affected - the "N/A" checklist entries are appropriate for a pure ideation/planning doc. All automated checks (duplicate-code, SpotBugs, dependency review, quarantine lane) are unrelated to this docs-only change and are green/inapplicable. |
…nding `next-actor-revival.md` and `2026-08-17-actor-collection-revival-ideation.html` are carried by #310, open and mergeable off `docs/actor-revival-ideation`. They are not stranded, so this sweep has no business copying them - the rule this branch applies everywhere else is that a doc carried by an open PR lands when that PR does. They were classified stranded because the open-PR snapshot this sweep triaged against was taken before #310 existed. The verdict was right when it was made and wrong by the time the branch was pushed, which is the hazard of triaging a moving set: the survey is a photograph, and this one aged in under an hour. Re-checked every other extracted file against the current open PRs. The only remaining overlaps are #306 and #268, both deliberate: #306 is not scheduled to merge until after v6, so its followups note and the learnings beside it would stay invisible until then. Nothing else in this branch is duplicated, and nothing extracted here has landed on master in the meantime.
…phemeral dossier path from the footer The review flagged C1/#488 as a bare ref. Mechanically it was not one - the gate's lookbehind deliberately skips /#N, which is why local runs were green - but the convention exists for human readers, and a bare #488 in this repo is a coin flip. Also removed the footer's /tmp evidence-dossier path, which no other reader could ever resolve. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QqHpNSXC39ANv9kG1ZvUzn
|
Response to the review:
Everything else in the review needed no action (the manifest-entry timing note and the poller-bus-actor claim verification both confirm the doc's accuracy). |
…hing else Extends .claude/hooks/check-squash-subject.sh: a gh pr merge --squash whose body is overridden (--body/-b/--body-file/-F) is refused unless the body carries a line-start Co-authored-by trailer, and refused if it carries a Claude-Session line - master squash commits hold exactly one sign-off and no session link, and the sign-off kept being remembered by convention rather than enforcement. An unreadable --body-file fails open because gh itself then fails loudly. docs/merge-checklist.md now states both halves for anyone merging by hand; harness gains eight cases including trailer-must-start-a- line, verified red against the pre-change hook. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QqHpNSXC39ANv9kG1ZvUzn
…es, and the batching defect the recovery found (#312) Committed planning documents are project content even when their implementation does not exist yet. Knowledge left on a branch is invisible to any agent that does not already know the branch exists, and the branch can vanish: while this sweep was being assembled, docs/proxy-http-ideation was merged into #293 and deleted, and its note did not travel with it. That note is recovered here from the commit object alone. Every remote branch was surveyed against master's current tree rather than merge-base diffs, which over-report. Most doc paths that exist on a branch and not on master are carried by a branch with an open PR and land when it does; those were left alone. What remained was triaged by reading each note, not by bucketing it on its filename prefix - which would have been wrong in both directions. Brought over: the 2026-08-17 ideation wave, five notes plus the three HTML deliverables they only point at, since the notes are one-page summaries and the substance is in the HTML; one open design proposal, recoverable producer fencing (#225); twelve docs/solutions/ learnings, whose home is master by definition, adding the architecture-patterns, best-practices, runtime-errors and logic-errors categories; and the chaos pain suite design plan, which master's shipped phase-1 plan names in its own origin: frontmatter and cannot resolve, and which is the only definition of phases 2 and 3 that docs/inflight/test-chaos-phase2.md tracks as open. Also brought over, as a deliberate exception to the rule above: six files from #306, which is not scheduled to merge until after v6. One of them records a project-wide gap that would otherwise stay invisible through the release it could affect - there is no japicmp or revapi equivalent, so a source- or binary-breaking public API change rides through CI unflagged. Left behind as spent rather than stranded: the whole v6 documentation-ideas cluster, whose output already shipped as docs/data/roadmap.yaml, docs/data/module-maturity.yaml and the docs/features/ catalogue; the package-rename dress rehearsal, since the real rename merged as #294; and a stale outside-collaborator grant, since the grant is gone and its branch is deleted. Left with their branches: pr- notes, which the PR that resolves them tracks, and the ks-streams unit plans, which document code that exists on those branches. 2026-08-14-language-proxy-interaction-model-ideation.html is deliberately not taken. Two sessions extended it in parallel; #293 has since absorbed the HTTP half and carries none of the polyglot half, and its copy is still growing. A master copy would fork the document a third time. The note recording the collision is here instead, and the reconciliation belongs on that PR. A survey is a photograph, and this one aged inside the hour. The actor-revival pair was triaged as stranded and then removed again once #310 opened to land it. Every remaining file was re-checked against the open PRs at push time rather than at survey time. The batching ideation note carried an unreported defect, confirmed against master and filed as #311, recorded as two notes because docs/inflight/ is one item per file. The arithmetic one needs no caller error: calculateQuantityToRequest rounds up with target - modulo where filling the tail batch needs batchSize - modulo, and the variable is named extraToFillBatch. target is always a multiple of batchSize, so it fires whenever current is not, and in-flight settles near twice the configured target. The second-order effect is the one worth keeping: the inflated delta makes lastWorkRequestWasFulfilled false, which gates the adaptive load factor, so under batching the load factor stops stepping up precisely when the pool queue is low. The second note covers an absent bound on batchSize, where zero is silent on a default configuration, throws from PCModule.initDynamicLoadFactor() when a message buffer size is set, and NPEs when null. Default configurations are unaffected, batchSize defaults to 1, and there is no data-safety consequence. Searching the class found PCModule to be the only other modulo in main code, and its ceiling division is correct, so the arithmetic defect is a single site rather than a pattern. Extracted docs predate the issue-reference gate, so bare numbers below #1000 were qualified against the repo they actually mean. One document could not be: the write-up of a sweep that once rewrote a verbatim log line into a string no program ever emitted. Its remaining bare refs are the gate matcher's quoted inputs beside its quoted outputs, and qualifying them rewrites the demonstration into a false one. It carries #307's block opt-out markers around those blocks, which sit outside the quoted material so every quoted line stays byte-identical. That document is also the one file amended rather than copied. Its own recommended remedy is an inline code span, and applying it here reproduced the failure it records, because backticks are literal inside a code block. It now carries that as guidance item 8, recommending the block markers as the general answer, with a forward reference on item 2. The correction came out of this branch's own attempt to follow the document, so deferring it would have left the next reader to repeat it. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…s - the NO_PROGRESS arm, twice in one night Two ProgressProbe fleet-stall kills of ChaosChurnStormIT four hours apart on unrelated docs-only branches (#310 and #308), seeds 3086917415748208232 and 8603691233664838594 captured before log expiry, each with its passing revoke-under-work control arm. Records the truncated-console-log trap that misattributed the first of them to the passing cooperative test (the circulated seed 4087023100803854645 is the control arm - do not replay it expecting a failure) and the run-logs-archive retrieval route that recovers what --job log cuts off. Also logs the untracked ReactorBatchTest.simpleBatchTest awaitility flake seen on #308's CI at d930ca9. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fq6AcSoq6nMqbRHQxw25wx
…ions Master landed #310's ranked revival of the 2022 micro-actor family the same day this branch wrote up the interrupt-overload finding, and the two were not pointed at each other. Forward: this branch's design read as greenfield - "add a nudge variant" - when a framework already exists, 537 lines in 4 files coupled to PC by one 16-line marker interface, with six ranked directions for reviving it. Both the solution write-up and the contract-debts note now say to read next-actor-revival.md first, and name survivor 5 (skeleton-first strangler) as the shape a payload-free nudge should land in rather than a rewrite. Back: survivor 6 is a concurrency mass budget - an ArchUnit ratchet on primitive counts, conversions graded on locks removed - and this branch has already taken a reading it can start from. Four meanings on one bit, four hand-clears, one of which does not clear and only warns that it cannot tell which meaning it got. That is a mass measurement with a documented failure behind it, which is more useful to a ratchet than a count taken cold. Also merges master: #310 and, in the previous merge, #304, #305, #307, #286 and #312. Core unit suite: Tests run 372, Failures 0, Errors 0, BUILD SUCCESS. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ahSzHD72EvTGTYkmpTsx6
…carry meaning Four debts #209 surfaced and did not fix, each a contract currently enforced by a reader's attention, all in one class - ranked by how likely the next person is to trip over them. The first is the one that bit this branch. The control thread is signalled by interrupting it, and that one JVM bit carries four unrelated meanings: wake up, stop blocking on the mailbox, shut down, and "your next commit-lock acquisition will throw". A receiver cannot tell which it got, so the class has accumulated four hand-clears instead of a fix - one of which does not clear at all and only warns that it cannot tell. It recurred here in the most ordinary way available: adding a state transition inherited a shutdown hazard from a wakeup. No test could catch it, and the assertion written for it passed under mutation and had to be deleted. Review then found the follow-on, which is better evidence than the defect: the clear CANNOT be made to hold, because any worker finishing work re-arms the flag through notifySomethingToDo, and the guard that would suppress that is not set until later in the close. A defensive clear is a local fix to a shared channel. Written up as a solution rather than a code comment because the transferable part is a counting rule: when the same clear, reset or re-check appears three or more times for one piece of state, the state is overloaded and the next feature adds a fourth. The clears are not the bug being fixed; they are the bug being paid for, repeatedly. The fix is designed and deliberately not built - an interrupt carries no meaning at all, messages carry it, coalescing answers the flooding, and the ordering trap is clearing before draining rather than after. It is thread-model work and belongs with the God-class decomposition, so it is earmarked as a concrete first slice of the existing Actor / IPC message bus entry rather than started here. Both directions are linked: #310's revival note gains the measurement its concurrency-mass-budget survivor proposes taking, and this gains the 537-line framework that already exists so nobody rebuilds it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ahSzHD72EvTGTYkmpTsx6
…carry meaning Four debts #209 surfaced and did not fix, each a contract currently enforced by a reader's attention, all in one class - ranked by how likely the next person is to trip over them. The first is the one that bit this branch. The control thread is signalled by interrupting it, and that one JVM bit carries four unrelated meanings: wake up, stop blocking on the mailbox, shut down, and "your next commit-lock acquisition will throw". A receiver cannot tell which it got, so the class has accumulated four hand-clears instead of a fix - one of which does not clear at all and only warns that it cannot tell. It recurred here in the most ordinary way available: adding a state transition inherited a shutdown hazard from a wakeup. No test could catch it, and the assertion written for it passed under mutation and had to be deleted. Review then found the follow-on, which is better evidence than the defect: the clear CANNOT be made to hold, because any worker finishing work re-arms the flag through notifySomethingToDo, and the guard that would suppress that is not set until later in the close. A defensive clear is a local fix to a shared channel. Written up as a solution rather than a code comment because the transferable part is a counting rule: when the same clear, reset or re-check appears three or more times for one piece of state, the state is overloaded and the next feature adds a fourth. The clears are not the bug being fixed; they are the bug being paid for, repeatedly. The fix is designed and deliberately not built - an interrupt carries no meaning at all, messages carry it, coalescing answers the flooding, and the ordering trap is clearing before draining rather than after. It is thread-model work and belongs with the God-class decomposition, so it is earmarked as a concrete first slice of the existing Actor / IPC message bus entry rather than started here. Both directions are linked: #310's revival note gains the measurement its concurrency-mass-budget survivor proposes taking, and this gains the 537-line framework that already exists so nobody rebuilds it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ahSzHD72EvTGTYkmpTsx6
…carry meaning Four debts #209 surfaced and did not fix, each a contract currently enforced by a reader's attention, all in one class - ranked by how likely the next person is to trip over them. The first is the one that bit this branch. The control thread is signalled by interrupting it, and that one JVM bit carries four unrelated meanings: wake up, stop blocking on the mailbox, shut down, and "your next commit-lock acquisition will throw". A receiver cannot tell which it got, so the class has accumulated four hand-clears instead of a fix - one of which does not clear at all and only warns that it cannot tell. It recurred here in the most ordinary way available: adding a state transition inherited a shutdown hazard from a wakeup. No test could catch it, and the assertion written for it passed under mutation and had to be deleted. Review then found the follow-on, which is better evidence than the defect: the clear CANNOT be made to hold, because another thread can re-arm the flag through notifySomethingToDo in the gap, and the guard that would suppress that is not set until later in the close. Not a worker thread - addToMailbox only enqueues; the re-armers are the rebalance listener, a close(DRAIN), and the public requestCommitAsap and resumeIfPaused, and since notifySomethingToDo is itself public that list is open-ended. A defensive clear is a local fix to a shared channel. Written up as a solution rather than a code comment because the transferable part is a counting rule: when the same clear, reset or re-check appears three or more times for one piece of state, the state is overloaded and the next feature adds a fourth. The clears are not the bug being fixed; they are the bug being paid for, repeatedly. The fix is designed and deliberately not built - an interrupt carries no meaning at all, messages carry it, coalescing answers the flooding, and the ordering trap is clearing before draining rather than after. It is thread-model work and belongs with the God-class decomposition, so it is earmarked as a concrete first slice of the existing Actor / IPC message bus entry rather than started here. Both directions are linked: #310's revival note gains the measurement its concurrency-mass-budget survivor proposes taking, and this gains the 537-line framework that already exists so nobody rebuilds it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ahSzHD72EvTGTYkmpTsx6
…carry meaning Four debts #209 surfaced and did not fix, each a contract currently enforced by a reader's attention, all in one class - ranked by how likely the next person is to trip over them. The first is the one that bit this branch. The control thread is signalled by interrupting it, and that one JVM bit carries four unrelated meanings: wake up, stop blocking on the mailbox, shut down, and "your next commit-lock acquisition will throw". A receiver cannot tell which it got, so the class has accumulated four hand-clears instead of a fix - one of which does not clear at all and only warns that it cannot tell. It recurred here in the most ordinary way available: adding a state transition inherited a shutdown hazard from a wakeup. No test could catch it, and the assertion written for it passed under mutation and had to be deleted. Review then found the follow-on, which is better evidence than the defect: the clear CANNOT be made to hold, because another thread can re-arm the flag through notifySomethingToDo in the gap, and the guard that would suppress that is not set until later in the close. Not a worker thread - addToMailbox only enqueues; nearly everything else is: every state transition calls notifySomethingToDo, both forms of close() reach it, the rebalance listener reaches it from the broker poll thread, and it is public. The write-up enumerated that set three times and was wrong three times - naming worker threads, then omitting close(DRAIN), then omitting plain close() - so it now states the rule and keeps no list. That is the thesis as a fact about the documentation: a channel with no owner has no enumerable set of senders. A defensive clear is a local fix to a shared channel. Written up as a solution rather than a code comment because the transferable part is a counting rule: when the same clear, reset or re-check appears three or more times for one piece of state, the state is overloaded and the next feature adds a fourth. The clears are not the bug being fixed; they are the bug being paid for, repeatedly. The fix is designed and deliberately not built - an interrupt carries no meaning at all, messages carry it, coalescing answers the flooding, and the ordering trap is clearing before draining rather than after. It is thread-model work and belongs with the God-class decomposition, so it is earmarked as a concrete first slice of the existing Actor / IPC message bus entry rather than started here. Both directions are linked: #310's revival note gains the measurement its concurrency-mass-budget survivor proposes taking, and this gains the 537-line framework that already exists so nobody rebuilds it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ahSzHD72EvTGTYkmpTsx6
…carry meaning Four debts #209 surfaced and did not fix, each a contract currently enforced by a reader's attention, all in one class - ranked by how likely the next person is to trip over them. The first is the one that bit this branch. The control thread is signalled by interrupting it, and that one JVM bit carries four unrelated meanings: wake up, stop blocking on the mailbox, shut down, and "your next commit-lock acquisition will throw". A receiver cannot tell which it got, so the class has accumulated four hand-clears instead of a fix - one of which does not clear at all and only warns that it cannot tell. It recurred here in the most ordinary way available: adding a state transition inherited a shutdown hazard from a wakeup. No test could catch it, and the assertion written for it passed under mutation and had to be deleted. Review then found the follow-on, which is better evidence than the defect: the clear CANNOT be made to hold, because another thread can re-arm the flag through notifySomethingToDo in the gap, and the guard that would suppress that is not set until later in the close. Not a worker thread - addToMailbox only enqueues; nearly everything else is: every state transition calls notifySomethingToDo, both forms of close() reach it, the rebalance listener reaches it from the broker poll thread, and it is public. The write-up enumerated that set three times and was wrong three times - naming worker threads, then omitting close(DRAIN), then omitting plain close() - so it now states the rule and keeps no list. That is the thesis as a fact about the documentation: a channel with no owner has no enumerable set of senders. A defensive clear is a local fix to a shared channel. Written up as a solution rather than a code comment because the transferable part is a counting rule: when the same clear, reset or re-check appears three or more times for one piece of state, the state is overloaded and the next feature adds a fourth. The clears are not the bug being fixed; they are the bug being paid for, repeatedly. The fix is designed and deliberately not built - an interrupt carries no meaning at all, messages carry it, coalescing answers the flooding, and the ordering trap is clearing before draining rather than after. It is thread-model work and belongs with the God-class decomposition, so it is earmarked as a concrete first slice of the existing Actor / IPC message bus entry rather than started here. Both directions are linked: #310's revival note gains the measurement its concurrency-mass-budget survivor proposes taking, and this gains the 537-line framework that already exists so nobody rebuilds it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ahSzHD72EvTGTYkmpTsx6
Description
Adds the ideation deliverable for reviving the 2022 micro-actor branch family (manifest entry
sweep-2023-actor-ipc, registered by #305), plus thedocs/inflight/next-actor-revival.mdpointer that makes it discoverable from the inflight directory.The doc (
docs/ideation/2026-08-17-actor-collection-revival-ideation.html, self-contained HTML) holds six survivors from ~55 generated candidates, each with a verified basis - direct quotes spot-checked against the repo and the 2022 branch trees by an independent verification pass - confidence/complexity, downsides, and a rejection table recording what was cut and why (including one candidate killed because its cited evidence was factually backwards, and one whose headline number was a 4x diffstat misread).Ranked survivors:
The inflight note states the open decision: top pick is 1; the real fork in the road is 3 vs 5.
Related: #305 (tracking registration this doc references - no merge dependency, no file overlap).
Checklist
docs/features/- N/A - internal planning/ideation doc, not a product feature🤖 Generated with Claude Code
https://claude.ai/code/session_01QqHpNSXC39ANv9kG1ZvUzn