Skip to content

refactor(daemon): give generic leaves their own execution vocabulary - #3315

Merged
thymikee merged 3 commits into
mainfrom
refactor/daemon-generic-leaf-vocabulary
Oct 8, 2026
Merged

thymikee merged 3 commits into
mainfrom
refactor/daemon-generic-leaf-vocabulary

Conversation

@thymikee

@thymikee thymikee commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Summary

Part of #3276 (collocation). The largest import cycle in the repo was 33 files across src/daemon/interaction/internal and the daemon runtime leaves. One misplaced type held it together.

ResolvedGenericExecution and its parts were declared in request-generic-dispatch.ts, but only the leaves use them: runtime-admission, focus-runtime, scroll-runtime, and nine others. The dispatcher itself never used ResolvedGenericExecution. Each leaf type-imported its caller. Through the dispatcher's lazy import() of generic-settle.ts, that closed a loop through the whole interaction runtime. That lazy seam exists to keep the interaction runtime out of this cycle.

The four types now live in src/daemon/generic-leaf-execution.ts, below both sides. This is a type-only move: no runtime or bundle change.

Cycles, all edge kinds main this PR
Largest 33 7
Count 23 22

R9 only counts value and type edges, where the largest cycle was 6 files before and after, so no gate saw this knot. I'll propose extending it separately.

Validation

At 0920aa908:

  • pnpm check:affected --run passes, including layering, fallow, and typecheck.
  • pnpm depgraph before and after gives the table above.

🤖 Generated with Claude Code

View guided diff Turn on auto-fix

thymikee and others added 2 commits October 8, 2026 10:08
The runtime-owned generic leaves type-imported ResolvedGenericExecution and
its parts from request-generic-dispatch, the dispatcher that calls them.
That back-edge closed a 33-file type/dynamic cycle across the interaction
runtime, defeating the lazy seam generic-settle.ts exists to keep. The
vocabulary now lives in generic-leaf-execution.ts, below both.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 24 files

View guided diff | Turn on auto-fix | Re-trigger cubic

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Size Report

Metric Base Current Diff
Installed (including dependencies) 5.13 MB 5.13 MB 0 B
Package (unpacked) 5.13 MB 5.13 MB 0 B
Package (download) 1.54 MB 1.54 MB +7 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 27.0 ms 28.1 ms +1.0 ms
CLI --help 83.8 ms 86.7 ms +2.9 ms

@thymikee

thymikee commented Oct 8, 2026

Copy link
Copy Markdown
Member Author

This PR is ready at 2cc75f3. I found no problems in the diff, and there are no conflicts. The only check still running is Smoke Tests. The imports are all import type, so they are erased at runtime and the emitted JS is unchanged, which means the change cannot affect a smoke path. The size report also shows 0 B installed-size change. I did not re-run pnpm depgraph or pnpm check:affected, so the cycle counts (33 -> 7, 23 -> 22) and the layering, fallow and typecheck results come from the PR body. I also did not check the remark that R9 only counts value and type edges against the gate. Nothing else stands in the way once Smoke Tests finishes. Not blocking, and you can take or leave these: the doc comment at src/daemon/keyboard-runtime.ts:37 still points at ResolvedGenericExecution in request-generic-dispatch.ts, but that type now lives in generic-leaf-execution.ts. The header comment at the top of src/daemon/generic-leaf-execution.ts tells the import-cycle story, and AGENTS.md asks to keep that kind of narration out of comments, so it could shrink to one line or go.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Oct 8, 2026
… trim its header

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@thymikee

thymikee commented Oct 8, 2026

Copy link
Copy Markdown
Member Author

Took both points in 0920aa9. The keyboard-runtime.ts doc comment now names generic-leaf-execution.ts, and that module's header is one line stating the constraint. pnpm check:affected --run passes.

Evidence for what you didn't reproduce, from pnpm depgraph plus getStronglyConnectedComponents on the same graph.json:

main 81f466640 this PR
Value + type edges: largest cycle / count 6 / 17 6 / 17
Value + type + dynamic edges: largest cycle / count 33 / 23 7 / 22

The first row is what R9 measures. On this branch the gate prints "the largest type-level cycle is 6 files (R9)", the same as main, so R9 never saw the 33-file knot. It only closes through the dispatcher's dynamic import() of generic-settle.ts.

@thymikee
thymikee merged commit d994d1f into main Oct 8, 2026
19 checks passed
@thymikee
thymikee deleted the refactor/daemon-generic-leaf-vocabulary branch October 8, 2026 10:54
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-10-08 10:55 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant