Repository navigation
aggregator: complexity-weighted project render — blocked weight + depth graph (#2400, part 2 of #1122) - #2831
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 11 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 09ec60d616
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // acyclic; a cycle degrades to a path, never a hang). | ||
| const memo = new Map<RefKey, RefKey[]>(); | ||
| const chainFrom = (ref: RefKey, visiting: Set<RefKey>): RefKey[] => { | ||
| if (memo.has(ref) && visiting.size === 0) return memo.get(ref)!; |
There was a problem hiding this comment.
Memoize shared blocker tails during recursive traversal
When open items share blocker chains, the visiting.size === 0 restriction prevents recursive calls from using the memo, while results are only cached after each top-level traversal. This enumerates exponentially many paths even for an acyclic graph: a local Bun reproduction with 32 open items, each blocked by the next two items, took approximately seven seconds. Because src/server.ts:705 invokes this renderer synchronously for each project request, such a dependency graph blocks the server's event loop. Cache reusable acyclic suffixes while retaining cycle protection instead of recomputing them for every path.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Fixed in 788e41e8 — thank you. chainFrom now caches a node's chain as soon as its subtree completes, and recursive calls reuse memo entries for any node not on the current path, so shared blocker tails are computed once. Cycle safety is preserved with a guard-hit counter: a frame caches only when no cycle-guard hit occurred anywhere in its subtree, so path-truncated (path-dependent) results — and all their ancestors — are never cached, and a cached chain can never contain a node on the caller's path (that would close a cycle through the cached node and would have hit the guard during its computation). Regression test added (shared blocker tails are memoized, not re-enumerated per path): the 32-item fan-out DAG from your repro now resolves with the full 32-longest chain; the whole graph test file runs in ~15ms and the full aggregator suite shows only the 7 pre-existing #2580 manifest failures.
…2400) Codex P1 on PR #2831: the visiting.size===0 restriction kept recursive calls from using the memo, enumerating exponentially many paths on shared blocker chains (~7s for a 32-item fan-out DAG) inside a synchronous per-request render. A frame now caches its chain whenever its subtree completed without hitting the cycle guard (tracked with a hit counter, so path-truncated results and their ancestors stay uncached), and recursive calls reuse memo entries for nodes not on the current path. Regression test: the 32-item fan-out DAG resolves instantly with the full 32-longest chain.
Implements #2400 — part 2 of 2 of the #1122 split, consuming the part-1 edge contract (#2399, PR #2744, merged). With this merged, parent #1122's acceptance is fully met.
Closes #2400
Closes #1122
What
The weighted rollup and hands queue already rendered on /program/ (src/weights.ts, #1108). This PR adds the remaining two elements plus the honest-absence states, in a new pure module
src/graph.ts:parentRefchains: depth = sub-issue nesting, squares are epics, amber = open / grey = closed, border encodes mode (thick solid = physical, dashed = hybrid, thin = online/none). DFS order, capped at 120 nodes with an explicit truncation note; parent cycles degrade to roots instead of looping.Tests
test/graph.test.ts(13 tests): blocked weight/unsized/chain, closed-blocker resolution, out-of-pool blocker, blocked-by cycle, closed items never blocked; depth layout (parent chain, epic/mode carriage, out-of-pool parent, cap); and render tests for all three shapes (sized+graphed / unsized+edgeless / sized+edgeless).Queue task 3573 · repo-worker-code Lane A.
Need help on this PR? Tag
@codesmith-botwith what you need.