Skip to content

placement: delete the unused crates and move the stored lifecycle to sandbox-store - #1645

Merged
ac-pplx merged 1 commit into
mainfrom
ac/delete-placement-claim-store
Nov 6, 2026
Merged

ac-pplx merged 1 commit into
mainfrom
ac/delete-placement-claim-store

Conversation

@ac-pplx

@ac-pplx ac-pplx commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Summary

pplx-space-placement and pplx-space-placement-executor were written ahead of their callers, and no service calls them: the executor's place returns a typed refusal, and PostgresPlacementStore is reached only from its own tests and the executor. They still count as sandbox-row writers and readers of the evacuation restore marker, so every lifecycle or drain change has had to account for them.

Merging this:

  • deletes pplx-space-placement-executor and pplx-space-placement;
  • moves the one part in use, StoredSandboxLifecycle (the stored vocabulary of sandboxes.lifecycle) and its writer-test matrix, unchanged into pplx-space-sandbox-store, which owns that table. The four files move as pure renames. The matrix sits behind a new test-support feature;
  • switches the callers' imports and dev-dependencies to sandbox-store (internal-api in production; api, cluster-controller, internal-api and sandbox-store in tests). Every one of them already depended on sandbox-store;
  • removes the placement crate's sandboxes co-writer grant, its dependents entry and its baseline line from the architecture rules, and its rows from scripts/move_crates.toml;
  • updates the comments and docs that named the deleted code as current.

The design stays in history if a caller needs it later.

Validation

Rebased onto main after the removal of pplx-space-common-svc. The conflicts were mechanical: import paths, Cargo dependency lists, the architecture store_users entry, and keeping the deletion of a placement file main had edited. The four moved files are still pure renames.

At the rebased head, on a Linux build host:

  • cargo check --workspace --all-targets, and cargo check -p pplx-space-api --features kubernetes --all-targets: pass.
  • fmt and workspace clippy through ci/scripts/run-rust-checks.sh: pass. cargo arch: no required findings; its three new advisories are the removed dependents entry, store user and co-writer grant.
  • The six touched crates' tests at CI's test profile, with Postgres and Redis running: 4771 run, 4771 passed.
  • The full test inventory, both groups: every touched crate passed. Tests in 8 untouched crates that need process, namespace or cgroup operations the host's container blocks failed there, and fail the same way on the base commit.
  • cargo tree -e features for the internal-api, api and cluster-controller service binaries: a release build doesn't enable sandbox-store's test-support.
  • Mutation check on the new wiring: dropping the re-export, dropping the dev-dependency feature, or gating the matrix on cfg(test) alone breaks the build; changing a stored spelling, dropping case normalization, skipping a value in the sweep, or ignoring the lifecycle in a published-status check fails 10 to 54 tests.

Kind smoke was not run: the change deletes uncalled code and moves a type unchanged.

Severity and risk

Severity: does not apply.

Risk: a build that names either deleted crate stops compiling until it drops the name; the moved type keeps its name and behaviour. Open PR #1553 edits three of the moved files, three files this deletes (the placement crate's README.md, src/postgres.rs and src/postgres/tests/completion.rs), and the SandboxLifecycle::all doc comment in common-core that this rewrites. Git follows the renames, so its edits to the moved files carry over. Whichever lands second keeps the deletions and names pplx-space-sandbox-store in that doc comment. Open PR #1575 changes one comment in the placement crate's src/model.rs, which this deletes. Roll back by reverting this commit.

AI assistance: Claude Code made the change, ran the validation and drafted this description. A human reviews before merge.

@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

Explain Change →

Automatic approval withheld

Automatic approval is disabled by the configured approval policy for this pull request. Review comments and requests for changes continue normally.

Commit: 7e9b6431b456.

No actionable comments were generated in the recent review.

Walkthrough

The placement storage crate and executor are removed from the workspace. The sandbox store now exports StoredSandboxLifecycle and test support. API, controller, server, and test imports are updated to use the sandbox store. Architecture rules, documentation, and crate records are also revised.

Merge Risk: Moderate · up to 7e9b6

Placement claim and completion tests are removed along with the unused implementation. Confirm that loss of coverage is acceptable before merging.

Security architecture risk: Minimal · up to 7e9b6

The lifecycle implementation and test helpers move unchanged to the package that owns sandbox storage. The removed executor was not wired into production, and the inspected production consumers change only their imports. No introduced or worsened security risk was identified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • observed — The security-relevant change concerns interpretation of sandboxes.lifecycle and repository authorization for sandbox-row writers. The removed placement grant was a repository architecture-policy exception, not a database-role revocation.

Trust Boundaries and Controls

  • observed — The policy comparison removes only the deleted placement writer's co-writer grant and baseline entry. The sandbox-write matcher, sandbox-store allowance, and remaining API writer caps remain in place; the PR does not broaden those repository write exceptions.
Pre-merge checks: Passed 5

Check name Status Explanation
Title check Passed The title meets the format requirements and describes the removal of the placement crates and the lifecycle move.
Description Follows The Pr Template Passed The description includes all four required items: Summary, Validation, Severity and risk, and an AI assistance line.
Bug Fixes Name A Regression Test Passed This PR is not an application bug fix. It removes unused placement crates and moves the lifecycle type unchanged. The production call sites only change their imports.
Weakened Safeguards Are Justified Passed The description explains that the deleted tests covered placement code with no service callers. The lifecycle tests and matrix move unchanged. The removed architecture entries apply to the deleted cra…
Public-Safe Content Passed The diff, title, and description contain no identified sensitive content covered by the check. The addresses in deleted test fixtures are illustrative, and the database URLs use localhost.
Full details: Weakened Safeguards Are Justified

Explanation

The description explains that the deleted tests covered placement code with no service callers. The lifecycle tests and matrix move unchanged. The removed architecture entries apply to the deleted crate.

Recent review info

Automatic approval policy

Commit: 7e9b6431b456.

Setting Effective value Source
Automatic approvals Disabled Override 4
Merge risk Low Override 2
Security risk Not set Global configuration

Matching overrides (numbered as in the resolved configuration):

  • Override 2 — any author; paths: **, !ui/**; merge risk: Low.
  • Override 4 — any author; paths: .coderabbit.yaml, .coderabbit.yml, coderabbit.yaml, coderabbit.yml, .coderabbit.config.ts, **/AGENTS.md, **/CLAUDE.md, .agents/**, .claude/**, .claude-plugin/**, CONTRIBUTING.md, docs/versioning.md, docs/rust/space-conventions.md, docs/rust/space-review-lessons.md, .github/**, ci/**, !ci/scripts/setup-nextest-*.sh, scripts/source_guards/**, scripts/check*, clippy.toml, deny.toml, .gitleaks.toml, .pre-commit-config.yaml, lefthook.yaml, rust-toolchain.toml, .cargo/**, supply-chain/**, pyproject.toml, uv.lock, **/package.json, **/package-lock.json, **/go.mod, **/go.sum, **/requirements*.txt, **/requirements*.in, proto/**, db/**, crates/l40_api/api/src/auth.rs, crates/l40_api/api/src/auth/**, crates/l40_api/api/src/middleware/auth*, crates/l40_api/api/src/middleware/auth/**, crates/l40_api/api/src/routes/authz.rs, crates/l10_foundation/bearer/**, crates/l10_foundation/rustls/**, crates/l10_foundation/guest/**, crates/l10_foundation/pii/**, shim/**, docker/**, !docker/Dockerfile.rust-build-kind, templates/**, infra/space/aws/**, infra/space/cluster/**, infra/space/identity/**, infra/space/observability/**, infra/space/packer/**, infra/space/kind/charts/**, LICENSE, SECURITY.md; automatic approvals: disabled.

Any matching disabled override withholds approval, regardless of risk. Otherwise, the strictest explicitly set limit wins for each score. Limits omitted by all matching overrides inherit the global configuration.

Not set means no limit was configured after inheritance. Use @coderabbitai configuration to inspect the resolved settings and their sources.

Run configuration

  • Source mode: Auto
  • Repository: perplexityai/SPACE
  • Branch: main
  • File: .coderabbit.yaml
  • Commit: 23b1199
  • Layers: Repository YAML; Enforced overrides: Organization
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 80528208-78e2-4bb1-aca8-ce51e67c0e62
Commits

Reviewing files that changed from the base of the PR and between 1f3c9da and 7e9b643.

Files ignored due to path filters: 1

  • Cargo.lock is excluded by !**/*.lock, !**/Cargo.lock
Files selected for processing: 74

  • ARCHITECTURE.toml
  • Cargo.toml
  • architecture-baseline.toml
  • crates/l30_storage/db/migrate/src/bootstrap_roles/tests/execution_record_view_tests.rs
  • crates/l30_storage/placement/Cargo.toml
  • crates/l30_storage/placement/README.md
  • crates/l30_storage/placement/examples/user_wake.rs
  • crates/l30_storage/placement/src/lib.rs
  • crates/l30_storage/placement/src/model.rs
  • crates/l30_storage/placement/src/model/tests.rs
  • crates/l30_storage/placement/src/outcome.rs
  • crates/l30_storage/placement/src/outcome/tests.rs
  • crates/l30_storage/placement/src/postgres.rs
  • crates/l30_storage/placement/src/postgres/sql/claim_miss_snapshot.sql
  • crates/l30_storage/placement/src/postgres/sql/evacuation_restore_claim.sql
  • crates/l30_storage/placement/src/postgres/sql/user_restore_claim.sql
  • crates/l30_storage/placement/src/postgres/tests.rs
  • crates/l30_storage/placement/src/postgres/tests/claim.rs
  • crates/l30_storage/placement/src/postgres/tests/completion.rs
  • crates/l30_storage/placement/src/postgres/tests/support.rs
  • crates/l30_storage/placement/src/request.rs
  • crates/l30_storage/placement/src/store.rs
  • crates/l30_storage/sandbox/store/Cargo.toml
  • crates/l30_storage/sandbox/store/src/lib.rs
  • crates/l30_storage/sandbox/store/src/lifecycle.rs
  • crates/l30_storage/sandbox/store/src/lifecycle/tests.rs
  • crates/l30_storage/sandbox/store/src/test_support.rs
  • crates/l30_storage/sandbox/store/src/test_support/tests.rs
  • crates/l30_storage/sandbox/store/src/tests/insert_unplaced_tests.rs
  • crates/l40_api/api/Cargo.toml
  • crates/l40_api/api/src/controllers/sandbox/lifecycle/characterization_tests.rs
  • crates/l40_api/api/src/controllers/sandbox/lifecycle/drain_guard_tests.rs
  • crates/l40_api/api/src/controllers/sandbox/lifecycle/wake_completion_postgres_tests.rs
  • crates/l40_api/api/src/controllers/sandbox/list_page/admin.rs
  • crates/l40_api/api/src/controllers/sandbox/list_page/admin/tests.rs
  • crates/l40_api/api/src/controllers/sandbox/queries/create_postgres_tests.rs
  • crates/l40_api/api/src/controllers/substrate/AGENTS.md
  • crates/l40_api/api/src/controllers/substrate/direct/tests.rs
  • crates/l40_api/api/src/controllers/substrate/direct/tests/restore_lease_completion.rs
  • crates/l40_api/api/src/controllers/substrate/kubernetes/mod.rs
  • crates/l40_api/api/src/controllers/substrate/kubernetes/store/k8s_store_postgres_tests/cleanup_recovery_lifecycle_matrix_tests.rs
  • crates/l40_api/api/src/controllers/substrate/kubernetes/store/k8s_store_postgres_tests/lifecycle_writer_tests.rs
  • crates/l40_api/api/src/controllers/substrate/kubernetes/store/k8s_store_postgres_tests/suspend_lifecycle_matrix_tests.rs
  • crates/l40_api/api/src/controllers/substrate/node_api_client.rs
  • crates/l40_api/api/src/routes/e2b/state_render_tests.rs
  • crates/l40_api/api/src/routes/e2b/tests.rs
  • crates/l40_api/cluster/controller/server/Cargo.toml
  • crates/l40_api/cluster/controller/server/src/drained_node_terminator/store/stored_lifecycle_matrix_tests.rs
  • crates/l40_api/cluster/controller/server/src/failed_restorable_repair/tests.rs
  • crates/l40_api/cluster/controller/server/src/node_drain/store/lifecycle_writer_tests.rs
  • crates/l40_api/cluster/controller/server/src/node_drain/store/termination_gate_tests.rs
  • crates/l40_api/cluster/controller/server/src/orphaned_sandboxes/lifecycle_writer_tests.rs
  • crates/l40_api/cluster/controller/server/src/orphaned_sandboxes/quarantine_recovery/tests.rs
  • crates/l40_api/cluster/controller/server/src/tombstone_retention/tests.rs
  • crates/l40_api/cluster/controller/server/src/transient_lifecycle_sweeper/lifecycle_writer_tests.rs
  • crates/l40_api/internal/api/server/Cargo.toml
  • crates/l40_api/internal/api/server/src/auto_lifecycle_delete_completions.rs
  • crates/l40_api/internal/api/server/src/auto_lifecycle_delete_completions/tests.rs
  • crates/l40_api/internal/api/server/src/publish.rs
  • crates/l40_api/internal/api/server/src/published_state/input.rs
  • crates/l40_api/internal/api/server/src/published_state/published_status.rs
  • crates/l40_api/internal/api/server/src/published_state/published_status_tests.rs
  • crates/l40_api/internal/api/server/src/published_state_tests.rs
  • crates/l40_api/internal/api/server/src/published_state_tests/lifecycle_writers.rs
  • crates/l40_api/internal/api/server/src/status_tests.rs
  • crates/l40_api/placement/executor/Cargo.toml
  • crates/l40_api/placement/executor/src/driver.rs
  • crates/l40_api/placement/executor/src/executor.rs
  • crates/l40_api/placement/executor/src/lib.rs
  • crates/l40_api/placement/executor/src/outcome.rs
  • crates/l40_api/placement/executor/src/request.rs
  • crates/libs/common/core/src/types/sandbox.rs
  • crates/tools/archcheck/README.md
  • scripts/move_crates.toml
Files with no reviewable changes: 30

  • crates/l30_storage/sandbox/store/src/test_support/tests.rs
  • crates/l30_storage/placement/src/model/tests.rs
  • crates/l30_storage/placement/src/outcome/tests.rs
  • crates/l30_storage/sandbox/store/src/lifecycle.rs
  • crates/l30_storage/sandbox/store/src/lifecycle/tests.rs
  • crates/l30_storage/placement/src/request.rs
  • crates/l30_storage/placement/src/lib.rs
  • crates/l40_api/placement/executor/Cargo.toml
  • crates/l30_storage/placement/Cargo.toml
  • crates/l30_storage/placement/README.md
  • crates/l30_storage/placement/examples/user_wake.rs
  • architecture-baseline.toml
  • crates/l30_storage/placement/src/postgres/tests/claim.rs
  • crates/l30_storage/placement/src/postgres/sql/claim_miss_snapshot.sql
  • Cargo.toml
  • crates/l40_api/placement/executor/src/executor.rs
  • crates/l30_storage/placement/src/postgres/sql/evacuation_restore_claim.sql
  • crates/l30_storage/placement/src/postgres/tests.rs
  • crates/l40_api/placement/executor/src/outcome.rs
  • crates/l30_storage/placement/src/store.rs
  • crates/l30_storage/sandbox/store/src/test_support.rs
  • crates/l30_storage/placement/src/postgres/sql/user_restore_claim.sql
  • crates/l40_api/placement/executor/src/driver.rs
  • crates/l40_api/placement/executor/src/request.rs
  • crates/l30_storage/placement/src/model.rs
  • crates/l30_storage/placement/src/postgres.rs
  • crates/l30_storage/placement/src/postgres/tests/completion.rs
  • crates/l40_api/placement/executor/src/lib.rs
  • crates/l30_storage/placement/src/postgres/tests/support.rs
  • crates/l30_storage/placement/src/outcome.rs
Files skipped from review as they are similar to previous changes: 6

  • crates/l40_api/api/src/controllers/substrate/kubernetes/mod.rs
  • crates/l40_api/api/src/controllers/sandbox/list_page/admin.rs
  • crates/l40_api/api/src/controllers/substrate/AGENTS.md
  • crates/libs/common/core/src/types/sandbox.rs
  • crates/l40_api/api/src/controllers/substrate/node_api_client.rs
  • crates/l30_storage/db/migrate/src/bootstrap_roles/tests/execution_record_view_tests.rs

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 2 remain after this review.

@github-actions github-actions Bot added the triage:pending Waiting for a maintainer to triage label Nov 6, 2026
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown

Thanks for opening this pull request! A SPACE maintainer will take a look.

CONTRIBUTING.md explains how we review outside contributions.

@ac-pplx
ac-pplx marked this pull request as ready for review November 6, 2026 17:15
@ac-pplx
ac-pplx force-pushed the ac/delete-placement-claim-store branch from 2501616 to 1f3c9da Compare November 6, 2026 17:47
@the-gigi-pplx

Copy link
Copy Markdown
Collaborator

Review

No findings.

Verified against 1f3c9da3a9d833947e7fd80811c9af3ee753c279. Everything below is from reading this head, except the CI results.

Nothing left references the deleted crates. git grep for pplx[-_]space[-_]placement, placement[-_]executor, l30_storage/placement and l40_api/placement finds nothing anywhere in the tree: code, manifests, docs, skills, CI scripts or scripts/move_crates.toml.

The move is exact. git diff -M --summary shows lifecycle.rs, lifecycle/tests.rs, test_support.rs and test_support/tests.rs as 100% renames into pplx-space-sandbox-store. StoredSandboxLifecycle is re-exported from the crate root under the same name.

The test-only matrix stays out of release builds. test_support is gated #[cfg(any(test, feature = "test-support"))], and the new test-support feature is empty and off by default. internal-api, api and cluster-controller enable it only in [dev-dependencies]; their normal dependency on sandbox-store has no features.

The architecture rules lose exactly what was the placement crate's:

  • its store-users row (pplx-space-internal-api-server, pplx-space-placement-executor);
  • its temporary sandboxes co-writer grant;
  • its baseline line;
  • the include_str! example, which now reads generically.

internal-api's production use now goes through sandbox-store, which it already depended on.

CI on this head passes: Rust tests, clippy, format, isolated crates, dependency checks, and both Kind artifact builds.

Not done: I didn't run the suites or the mutation checks myself. I relied on CI and the description's validation for those.

@the-gigi-pplx the-gigi-pplx left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved. No findings; details in the review comment above.

…sandbox-store

The placement crate's claim and completion store, and the placement
executor built on it, were written ahead of their callers, and no
service calls them: the executor's `place` returns a typed refusal, and
`PostgresPlacementStore` is reached only from its own tests and the
executor. They still count as sandbox-row writers and readers of the
evacuation restore marker, so every lifecycle or drain change has to
account for them.

Delete `pplx-space-placement-executor` and `pplx-space-placement`. The
one part in use, `StoredSandboxLifecycle` (the stored vocabulary of
`sandboxes.lifecycle`) and its writer-test matrix, moves unchanged to
`pplx-space-sandbox-store`, which owns that table. The matrix sits
behind a new `test-support` feature there. Every caller already depends
on sandbox-store. The placement crate's `sandboxes` co-writer grant
goes too.

The design stays in history if a caller needs it later.
@ac-pplx
ac-pplx force-pushed the ac/delete-placement-claim-store branch from 1f3c9da to 7e9b643 Compare November 6, 2026 19:13
@ac-pplx
ac-pplx added this pull request to the merge queue Nov 6, 2026
Merged via the queue into main with commit e8f67b6 Nov 6, 2026
46 checks passed
@ac-pplx
ac-pplx deleted the ac/delete-placement-claim-store branch November 6, 2026 19:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

triage:pending Waiting for a maintainer to triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants