docs(ceiling): the plan cannot loop, the process can — scope the refusal - #378
Conversation
Documentation build overview
4 files changed± ARCHITECTURE/index.html± ROADMAP/index.html± changelog/index.html± design/ceiling/index.html |
|
Warning Review limit reached
Next review available in: 4 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
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 |
ceiling.md put "lazy cut generation, a solve loop" outside the closure because there is no "before" for them to happen in, while ROADMAP Track 2c says value-only re-solve is in scope and names Benders as what it is for. Both cannot stand. The refusal is about the symbolic plan, not the engine: a plan cannot contain a loop, but a process may loop over plans, each with its shape fixed before its own data. Rolling horizon is already that shape. Appending also costs less than the label contract suggests. var_label is a ROW_NUMBER() over the rows surviving the where mask, so adding rows moves no column and renumbers no existing row — primal and dual keep working across cuts. Removal and reindexing are what the contract refuses, and decomposition needs neither. addRows is already the call the direct sink makes to feed the initial build, so appending a cut is that code path, not a new one. New Track 2d states the positive claim, since the opposite is the natural assumption: an architecture whose model *is* sparse triplets plus label tables suits decomposition better than an array-based layer, because each step is a query rather than a scatter — the master/sub split is a GROUP BY over A (#39), cut coefficients are a join against duals that already read back, and var_label is the solver column index with no remapping. What is missing is #204, an addRows on it, and #39. Both places now leave the same open question, which is scope rather than ceiling: rule 6 refuses a Python modeling API, so either a decomposition driver ships reading the frames, or the seam composition already forces gets blessed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
63d7649 to
9c91e93
Compare
docs/design/ceiling.mdanddocs/ROADMAP.mdcontradicted each other, and the contradiction was hiding a claim worth making.The contradiction
ceiling.md put "lazy cut generation, a solve loop" outside the closure, "because there is no 'before' for it to happen in." ROADMAP Track 2c says value-only re-solve is in scope — "which is what rolling horizon, sweeps and Benders need."
Both cannot stand.
The resolution
The refusal is about the symbolic plan, not the engine. A plan cannot contain a loop; a process may loop over plans, each with its shape fixed before its own data. Rolling horizon is already that shape and already in scope. ceiling.md now says so and stops, instead of reading as a claim about what the engine can do.
Appending also costs less than the label contract suggests.
var_labelis aROW_NUMBER()over the rows surviving thewheremask, so adding rows moves no column and renumbers no existing row —primalanddualkeep working across cuts. Removal and reindexing are what the contract refuses, and decomposition needs neither.addRowsis already the callsinks/highs.py:135makes to feed the initial build, so appending a cut is that code path rather than a new one.New Track 2d
States the positive claim, because the opposite is the natural assumption: an architecture whose model is sparse triplets plus label tables suits decomposition better than an array-based layer, since each step is a query rather than a scatter.
GROUP BYover theAframe — Structural analysis: infer the coupling graph from the IR (separable dims, linking constraints) #39 is exactly that analysisduals ⋈ subproblem rows, and dual read-back has shippedvar_labelis the solver column index with no remapping, so a cut lands with zero translationforeachdims supply block boundaries for free — the concept Solve dimension: may a dimension declare that no variable spans it? #123 names for scenarios and pathwaysWhat is missing is small and already tracked: #204 for the session, an
addRowson it, and #39.Also notes that
sinks/highs.py:119already callschangeColsIntegrality, so therelaxitem added in #377 is a flag on the session rather than a new path.The open question, now stated in both places
Not feasibility — who writes the cut. Rule 6 refuses a Python modeling API, so either a decomposition driver ships reading the model frames, or the narrow seam that composition already forces gets blessed. Same question arriving from a second direction; filed separately.
mkdocs build --strictpasses,tests/test_docs_site.pygreen, the new cross-anchor into ceiling.md resolves in the built site.🤖 Generated with Claude Code