Repository navigation
Conversation
…zed look-ahead TopicMemoryWindowSelector projected the whole 100-Source look-ahead and fell back to a single-Source Window whenever that projection failed. A Source that failed on its own, or a look-ahead past the 4 MiB Window character ceiling, therefore split every healthy Source before it into its own Window, each running the full model pipeline. Project Sources in Journal order and end the Window just before the first Source that fails projection, would exceed the character ceiling, or would exceed the Probe input budget. Only a failing Source at the frontier forms a single-Source Window, so the Worker still records the durable rejection there. Sources past the stopping point are no longer projected.
Size the character-ceiling backlog so two Sources fill a Window to exactly 4,194,304 canonical characters. Moving either the selector's or the Worker's ceiling comparison now fails the test. Also assert that the frontier rejection spends no provider requests.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota. Try requesting a review at a lower effort level.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
Both failing checks at 42bddbc come from CI timing, not from this change:
Both jobs need a re-run once the workflow finishes. |
hidb4ai
left a comment
There was a problem hiding this comment.
Reviewed 42bddbc. I found no correctness issue in the changed selector and no new database tables or public interfaces.
Approval is pending a green CI result: worker-observability and harness-validation / Recall effort (OceanBase) are still failing. The logs show a missing worker-error stats field and a 600-second migration-test timeout; I have not established either as a regression from this patch. Please rerun or fix these jobs before merging.
Which issue or RFC does this PR close?
Implements the Window selection rules of RFC 1417 ("Window selection and context budgets", "Cumulative work and evidence ceilings"). No issue tracks this defect; it came out of a review of the Topic Memory processing path.
Rationale for this change
TopicMemoryWindowSelector.select()reads up to 100 Sources after the Cursor and projects all of them before it chooses a Window. If that projection raisedTopicMemoryGenerationError, it returned a single-Source Window at the frontier. Two situations raise:source_complexity_limit: over 4 MiB characters, 65,536 nodes or depth 32; orunsupported_evidence). Every healthy Source before it is then processed alone. With 10 small healthy Sources followed by one Source over 4 MiB, the frontier walks[1], [2], …, [10], [11]. Without the bad Source, the same 10 share[1..10].[1]…[9]before the 4-Source Windows the token budget allows ([10..13],[14..17], …). A backlog that keeps about 52 or more Sources of that size pending produces only singleton Windows.Each Window runs the full pipeline: Probe, the global evolver or planner plus evolvers, the reconciler, embeddings and an atomic publish. Singleton Windows therefore multiply model calls and rewrite the same Topics once per Source. Every
select()call also read and projected the whole look-ahead again.What changes are included in this PR?
topic_memory_processing.py,TopicMemoryWindowSelector.select():source_complexity_limitis recorded as a durable rejection at the frontier, and the tail is never skipped.source_window_changedand the work-availability check are unchanged._project_windowis unchanged. Every Window the selector returns stays within the same character ceiling, so the Worker never rejects a selected multi-Source Window for exceeding it.tests/builtin/runtime/test_topic_memory_work_budget.py), throughselect()andTopicMemoryProcessor.process():test_failing_source_ends_the_window_after_the_healthy_prefix: three healthy Sources and a lineage-only Source share one Window. The oversized Source after them is then selected alone at the frontier and durably rejected without provider requests, and it blocks later selection.test_large_healthy_backlog_fills_each_window_to_its_budget: two backlogs larger than the Window character ceiling, each Window published by the processor.>=fails this case.upstream/master. In the first test,select()returns 1 instead of 4. The backlogs start with 8 and 2 singleton Windows.Are there any user-facing changes?
No API, configuration or persisted-format change. Topic processing of a backlog that contains a failing Source or exceeds 4 MiB now runs fewer, larger Windows, so the per-Window pipeline (model calls and Topic revisions) runs fewer times. Rejection of a failing Source at the frontier is unchanged.
How was this change tested?
Window sequences from a
select()walk that mirrors the Scope loop (default 125,000-token context window, character token estimator):upstream/master[1],[2], …,[10],[11][1..10],[11][1]…[9], then[10..13], …,[58..60](22 Windows)[1..4],[5..8], …,[57..60](15 Windows)uv run pyteston the Topic Memory selector, processor, scope, recovery, fragment-reduction, security and e2e processing tests.Additional local checks, not committed:
select()over ten 150k-character Sources reads only the three Sources up to the stopping point.make checkmake docs-testmake unit-test: 8,139 passed, 417 skipped, 6 failed, all unrelated to this change.tests/test_ci_installation_roles.py::test_batch_keeps_all_roles_isolated_and_reports_every_failure(4 cases) fails the same way on unmodifiedupstream/masterin this environment.test_processing_scheduler.py::test_overflow_flush_cannot_advance_retry_and_cached_failures_cannot_extend_gateandtest_handoff_report.py::test_handoff_report_statement_count_does_not_grow_with_scope_countfailed only under the parallel run and pass on rerun.Not validated: no run against a real model provider or a real Server workload, and no OceanBase or seekdb backend run. The change does not touch persistence. The model-call savings are inferred from the Window counts above, not measured.
Alternatives considered
select(), including Sources past the stopping point.AI usage statement
Claude Code, Claude Opus 5.5