refactor(arch): make runtime.NewExecutor a strong invariant boundary — no post-construction mutation#118
Conversation
…— no post-construction mutation Harden the runtimebundle executor construction so all Executor fields are computed before runtime.NewExecutor and passed through ExecutorConfig. NewExecutor is now a strong invariant boundary with no post-construction field mutation. - Delete runtimebundle.BuildExecutor (the last thin wrapper around Build); switch the one remaining stdhttp test caller to runtimebundle.Build. - build_executor.go: compute interleaved/accounting/security/observability/ routing runtimes (including model-catalog resolver attachment) before constructing the executor; NewExecutor receives them via ExecutorConfig. - interleaved.go: applyInterleavedToExecutor -> interleavedExecutorRuntime (returns runtime.InterleavedRuntime instead of mutating *Executor). - secure_session.go: applySecureSessionToExecutor -> securityRuntimeFromSecureSession (returns runtime.SecurityRuntime instead of mutating *Executor). - modelcatalog_attach.go: attachModelCatalog now takes/returns a runtime.RoutingRuntime (enriches routing before construction) instead of mutating *Executor. - build_test.go: rename TestBuildExecutor_* -> TestBuild_*. - built.go / doc.go: correct BuildOptions doc references to the grouped sub-struct paths (Infra.HTTPClient, Diagnostics.SecureSessionStore). - stdhttp/route.go: comment follow-on — DefaultWireModel now lives in standardplugins (relocated by the standardplugins split). - Add internal/archtest/executor_invariant_test.go: AST-based archtest that rejects any assignment to runtime.Executor fields after a NewExecutor call in internal/infra/runtimebundle, locking the invariant. - Update critical_files.go budget comment to reflect BuildExecutor removal. No behavior change; construction is now data-in/config-out. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Warning Review limit reached
Next review available in: 2 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: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (12)
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 |
…rdrails, EchoesVault
Documentation closure for the go-llm-interactive-proxy architecture
de-slopification effort. Updates the spec docs and project knowledge
base to reflect the end state of the refactor.
- specs/go_llm_proxy_arch_review/resolution-plan.md: mark all phases
complete; rewrite the plan as the final closure record.
- specs/go_llm_proxy_arch_review/{architecture-review,findings-register,
source-index}.md: update to reflect deleted BuildExecutor wrappers,
moved standard_table.go, and the feature merge surface.
- docs/adr/0001-registry-driven-composition.md: registry is now the
registry type only; standard tables live in standardplugins; add a
dated update entry for the standardbundle/types.go/BuildExecutor
cleanup.
- docs/architecture-guardrails.md: document the bootstrap_plan.go
composition-root exemption, the role metadata in the hexagonal
baseline, and the standardplugins.DefaultWireModel rename.
- docs/architecture.md: note the MergeBundles/Append merge-surface
simplification.
- internal/plugins/features/README.md: wiring location corrected from
internal/pluginreg to internal/standardplugins.
- EchoesVault/pages/{plugin-system,testing-strategy}.md and
EchoesVault/daily/2026-07-08.md: compiled knowledge base updated.
Docs only; no code or test changes.
Note: this PR describes the end state of the cleanup, which is delivered
across #118 (runtimebundle invariant boundary), #119 (baseline role),
and #120 (merge surface). It should merge after those three to keep
docs and code consistent.
Co-authored-by: Cursor <cursoragent@cursor.com>
Hardens the runtimebundle executor construction so
runtime.NewExecutorbecomes a strong invariant boundary: allExecutorfields are computed before construction and passed throughExecutorConfig, with no post-construction field mutation.What changed
runtimebundle.BuildExecutor(last thin wrapper aroundBuild); switch the one remainingstdhttptest caller toruntimebundle.Build.build_executor.go: compute interleaved / accounting / security / observability / routing runtimes (including model-catalog resolver attachment) before constructing the executor;NewExecutorreceives them all viaExecutorConfig.interleaved.go:applyInterleavedToExecutor→interleavedExecutorRuntime(returnsruntime.InterleavedRuntimeinstead of mutating*Executor).secure_session.go:applySecureSessionToExecutor→securityRuntimeFromSecureSession(returnsruntime.SecurityRuntimeinstead of mutating*Executor).modelcatalog_attach.go:attachModelCatalognow takes/returns aruntime.RoutingRuntime(enriches routing before construction) instead of mutating*Executor.build_test.go: renameTestBuildExecutor_*→TestBuild_*.built.go/doc.go: correctBuildOptionsdoc references to the grouped sub-struct paths (Infra.HTTPClient,Diagnostics.SecureSessionStore).stdhttp/route.go: comment follow-on —DefaultWireModelnow lives instandardplugins(relocated by the standardplugins split in refactor(arch): finish standardplugins split — remove pluginreg/standardbundle shim and types.go alias #117).internal/archtest/executor_invariant_test.go: AST-based archtest that rejects any assignment toruntime.Executorfields after aNewExecutorcall ininternal/infra/runtimebundle, locking the invariant against regressions.critical_files.go: update budget comment to reflectBuildExecutorremoval.Verification (PR scoped, in isolation)
go build ./...— passes.go test ./internal/archtest/... ./internal/infra/runtimebundle/... ./internal/stdhttp/...— passes.go vet ./internal/archtest/... ./internal/infra/runtimebundle/... ./internal/stdhttp/...— clean.TestExecutorConstructionNoPostConstructionMutation— passes.No behavior change; construction is now data-in / config-out.
Second of the PRs splitting the post-review cleanup changes on the local working tree.