Repository navigation
internal-api, trigger-queue, store: bind the substrate value instead of writing it in SQL - #383
Merged
Merged
Conversation
ac-pplx
force-pushed
the
ac/substrate-kind-sql-internal-api
branch
from
October 13, 2026 17:34
1347b08 to
ff497ef
Compare
This was referenced Oct 13, 2026
api, cluster-controller: sort the tests that use the Direct substrate as a fixture (tests only)
#402
Merged
ac-pplx
force-pushed
the
ac/substrate-kind-sql-internal-api
branch
from
October 14, 2026 17:40
ff497ef to
422d26a
Compare
ac-pplx
force-pushed
the
ac/substrate-kind-sql-internal-api
branch
from
October 14, 2026 18:29
422d26a to
5e846a2
Compare
Base automatically changed from
ac/substrate-kind-sql-cluster-controller
to
main
October 14, 2026 19:13
ac-pplx
force-pushed
the
ac/substrate-kind-sql-internal-api
branch
from
October 14, 2026 19:22
5e846a2 to
180d2a1
Compare
…of writing it in SQL
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold
the substrate that owns a row, 'k8s' or 'space'. The internal API, the
trigger queue and the sandbox store scoped on that value with raw string
literals in 11 production SQL statements and one Rust comparison. Their
production code now binds `SubstrateKind` as a parameter and matches the
parsed variant, as the cluster controller does, so each statement stays
syntactically whole.
internal-api:
- `managed_by = 'k8s'` / `'space'` becomes `managed_by = $n`, bound to
`SubstrateKind::Kubernetes` or `::Space` and numbered after the
statement's existing parameters: the Direct and Kubernetes node
listings, the Kubernetes node-name lookup, the absent stopped Direct
sandbox delete, the local suspend handoff observation, the failed-report
projection (its `FOR NO KEY UPDATE OF s` claim is unchanged) and the
census prune.
- Kubernetes node bootstrap binds one `$4` for both the inserted
`managed_by` and the ON CONFLICT guard on the existing row.
- The two `managed_by IN ('space', 'k8s')` filters bind both variants.
They are kept, though the column's CHECK constraint already allows only
those values.
trigger queue: `fetch_trigger_targets` binds `SubstrateKind::Space` for its
`n.managed_by != $4` scope.
sandbox store: `AutoLifecycleExecution::proves_no_execution` parses
`managed_by` and matches `SubstrateKind::Kubernetes`. The field stays the
column's text, because the struct is a public `FromRow` row type the api
crate reads; it and `SandboxRecord.managed_by` remain listed as debt.
common-svc: `routable_execution_or_non_k8s` keeps its `'k8s'` literal and
says why. It is spliced into statements with their own parameter
numbering, one of them in the api crate, so binding it changes every
caller.
docs/rust/space-conventions.md now names internal-api and the trigger
queue, with the cluster controller, as following the convention apart from
that fragment, and lists the store's two text `managed_by` fields as debt.
Tests: each converted statement has a Postgres-backed test with a 'k8s'
row and an otherwise identical 'space' row on the expected sides of the
predicate. New: node lookups and bootstrap (`tests/substrate_scope.rs`),
the local suspend handoff, and a store unit test that includes an
unparseable value. The census-prune and absent-delete tests gain an
otherwise identical 'k8s' row (including the absent-delete test's pool-slot
receipt, which stays bound). Dropping any one converted predicate fails a test, except the two IN
filters, which the CHECK constraint makes always true; dropping a value
from either fails one.
No schema, wire format, metric or configuration changes. Statement text
changes, so the converted statements' `/*module_path:line*/` locators,
sqlx statement-cache keys and DBM query signatures change.
ac-pplx
force-pushed
the
ac/substrate-kind-sql-internal-api
branch
from
October 14, 2026 19:43
180d2a1 to
0135f69
Compare
ac-pplx
marked this pull request as ready for review
October 14, 2026 19:59
nickdujay-pplx
approved these changes
Oct 15, 2026
nickdujay-pplx
left a comment
Collaborator
There was a problem hiding this comment.
Reviewed commit 0135f69. No blocking findings: the 11 SQL conversions preserve parameter ordering and substrate scope, and the Rust comparison preserves behavior. The added tests cover wrong-substrate exclusion, bootstrap conflicts, and cleanup preserving Kubernetes rows. Locally, 621 tests passed with PostgreSQL dependencies required; CI is green on this commit. The documented generic-plan trade-off for inventory cleanup is nonblocking; the synthetic benchmark does not establish unchanged production performance.
ac-pplx
added a commit
that referenced
this pull request
Oct 16, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` matches SQL comparisons of `managed_by` with a 'k8s'/'space' literal (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN; any case and alias) and Rust comparisons or match arms on "k8s"/"space". It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches exactly the four converted lines; on this commit it matches nothing, so it has no baseline table and every behaviour is required. - Tests: Postgres-backed twins for each converted statement. A new Kubernetes builder-lookup test, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; Rust parses it and matches the variant (or calls the `SubstrateKind` method that names the question) and never compares the label string; and the archcheck rule enforces it. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
ac-pplx
added a commit
that referenced
this pull request
Oct 17, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus three statements that landed on main since: internal-api's publisher-node lookup and Direct's create-target claim and release. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - internal-api: `publisher_node_for_identity` binds `n.managed_by = $3` (`Kubernetes`). - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` matches SQL comparisons of `managed_by` with a 'k8s'/'space' literal (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN; any case and alias) and Rust comparisons or match arms on "k8s"/"space". It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches exactly the seven converted lines; on this commit it matches nothing, so it has no baseline table and every behaviour is required. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, a relabelled-builder case in the tenant publication table, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; Rust parses it and matches the variant (or calls the `SubstrateKind` method that names the question) and never compares the label string; and the archcheck rule enforces it. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
ac-pplx
added a commit
that referenced
this pull request
Oct 17, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus Direct's create-target claim and release, which landed on main since. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` matches SQL comparisons of `managed_by` with a 'k8s'/'space' literal (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN; any case and alias) and Rust comparisons or match arms on "k8s"/"space". It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches exactly the six converted lines; on this commit it matches nothing, so it has no baseline table and every behaviour is required. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; Rust parses it and matches the variant (or calls the `SubstrateKind` method that names the question) and never compares the label string; and the archcheck rule enforces it. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
ac-pplx
added a commit
that referenced
this pull request
Oct 17, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus Direct's create-target claim and release, which landed on main since. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` matches SQL comparisons of `managed_by` with a 'k8s'/'space' literal (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN; any case and alias) and Rust comparisons or match arms on "k8s"/"space". It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches exactly the six converted lines; on this commit it matches nothing, so it has no baseline table and every behaviour is required. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; Rust parses it and matches the variant (or calls the `SubstrateKind` method that names the question) and never compares the label string; and the archcheck rule enforces it. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
ac-pplx
added a commit
that referenced
this pull request
Oct 17, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus Direct's create-target claim and release, which landed on main since. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` matches SQL comparisons of `managed_by` with a 'k8s'/'space' literal (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN; any case and alias) and Rust comparisons or match arms on "k8s"/"space". It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches exactly the six converted lines; on this commit it matches nothing, so it has no baseline table and every behaviour is required. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; Rust parses it and matches the variant (or calls the `SubstrateKind` method that names the question) and never compares the label string; and the archcheck rule enforces it. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
ac-pplx
added a commit
that referenced
this pull request
Oct 17, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus Direct's create-target claim and release, which landed on main since. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` catches the common literal forms in production code: SQL comparisons of `managed_by` with 'k8s'/'space' (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN, = ANY, same-line CASE ... WHEN; any case, alias, prefix, cast or wrapping call), and Rust comparisons, label-string matches and match arms on "k8s"/"space" beside a substrate name. Its comment lists what it misses and its false positives. It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches the seven lines this commit converts; on this commit it matches nothing, so it has no baseline table. no_crossing, listed_no_growth and stale_entries are required; no_new_entries and no_raised_caps are advisory, so a deliberate exception is a reviewed baseline entry. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; in Rust a decision about a row's substrate calls a `SubstrateKind` method named for the question, a fact about the running substrate reads `capabilities()`, and code never compares the label string; and the archcheck rule catches the common literal forms. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
ac-pplx
added a commit
that referenced
this pull request
Oct 17, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus Direct's create-target claim and release, which landed on main since. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` catches the common literal forms in production code: SQL comparisons of `managed_by` with 'k8s'/'space' (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN, = ANY, same-line CASE ... WHEN; any case, alias, prefix, quoting, cast or wrapping call), and Rust comparisons with the label (raw strings included), a `NODE_MANAGED_BY_*` const or a variant's `.as_str()`/`.to_string()`, matches on the label string, and match arms on "k8s"/"space" beside a substrate name. Its comment lists what it misses and its false positives. It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches the seven lines this commit converts; on this commit it matches nothing, so it has no baseline table. no_crossing, listed_no_growth and stale_entries are required; no_new_entries and no_raised_caps are advisory, so a deliberate exception is a reviewed baseline entry. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; in Rust a decision about a row's substrate calls a `SubstrateKind` method named for the question, a fact about the running substrate reads `capabilities()`, and code never compares the label string; and the archcheck rule catches the common literal forms. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
ac-pplx
added a commit
that referenced
this pull request
Oct 17, 2026
Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After #373, #383 and #506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus Direct's create-target claim and release, which landed on main since. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` catches the common literal forms in production code: SQL comparisons of `managed_by` with 'k8s'/'space' (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN, = ANY, same-line CASE ... WHEN; any case, alias, prefix, quoting, cast or wrapping call), and Rust comparisons with the label (raw strings included), a `NODE_MANAGED_BY_*` const or a variant's `.as_str()`/`.to_string()`, matches on the label string, and match arms on "k8s"/"space" beside a substrate name. Its comment lists what it misses and its false positives. It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches the seven lines this commit converts; on this commit it matches nothing, so it has no baseline table. no_crossing, listed_no_growth and stale_entries are required; no_new_entries and no_raised_caps are advisory, so a deliberate exception is a reviewed baseline entry. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; in Rust a decision about a row's substrate calls a `SubstrateKind` method named for the question, a fact about the running substrate reads `capabilities()`, and code never compares the label string; and the archcheck rule catches the common literal forms. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
meefs
pushed a commit
to meefs/SPACE
that referenced
this pull request
Oct 18, 2026
…erplexityai#611) Control-plane Postgres `sandboxes.managed_by` and `nodes.managed_by` hold the substrate that owns a row, 'k8s' or 'space'. After perplexityai#373, perplexityai#383 and perplexityai#506 the remaining production literals were the shared routability fragment, the Kubernetes adapter's builder lookup and the Direct route-identity match, plus Direct's create-target claim and release, which landed on main since. They now bind `SubstrateKind` or match its parsed variant, and a new archcheck instance keeps new literals out of production code. No schema, wire format, metric or configuration changes, and no behavior change. - common-svc: `routable_execution_or_non_k8s(alias, kubernetes_placeholder)` writes `{alias}.managed_by <> {placeholder}` instead of `<> 'k8s'`. Each caller binds `SubstrateKind::Kubernetes` at the placeholder it numbers after its own parameters: the transient sweeper's aged-transient list and restoring converge (`$5`), internal-api's restored-state convergence (`$4`) and the api's wake-completion CAS (`$2`). - api Kubernetes adapter: `builder_client_for_node` binds `n.managed_by = $2`. - api Direct: `claim_create_target` and `release_create_target` bind `managed_by = $3` (`Space`). - api Direct: the route identity's `substrate_kind` text is parsed as `SubstrateKind` in `route_identity_substrate_kind`, which maps exactly 'space' and 'k8s' as before and rejects any other text with the same error. - ARCHITECTURE.toml: `pattern_ratchet.substrate_literals` catches the common literal forms in production code: SQL comparisons of `managed_by` with 'k8s'/'space' (=, <>, !=, IS [NOT] DISTINCT FROM, [NOT] IN, = ANY, same-line CASE ... WHEN; any case, alias, prefix, quoting, cast or wrapping call), and Rust comparisons with the label (raw strings included), a `NODE_MANAGED_BY_*` const or a variant's `.as_str()`/`.to_string()`, matches on the label string, and match arms on "k8s"/"space" beside a substrate name. Its comment lists what it misses and its false positives. It allows test-support modules and fixtures that archcheck's filename-based test rule counts as production. On the parent commit it matches the seven lines this commit converts; on this commit it matches nothing, so it has no baseline table. no_crossing, listed_no_growth and stale_entries are required; no_new_entries and no_raised_caps are advisory, so a deliberate exception is a reviewed baseline entry. - Tests: Postgres-backed twins for each converted statement. New Kubernetes builder-lookup and Direct create-target tests, a unit table for the route-identity labels, and an otherwise identical 'space' row added to the sweeper's converge, internal-api's restored convergence and the wake-completion redrive tests. Test callers of the sweeper's shared builders bind the extra parameter. - Docs: `docs/rust/space-conventions.md`, the substrate AGENTS.md and the space-rust-development skill say every crate's production SQL binds the value; in Rust a decision about a row's substrate calls a `SubstrateKind` method named for the question, a fact about the running substrate reads `capabilities()`, and code never compares the label string; and the archcheck rule catches the common literal forms. Plugin version 0.2.33 -> 0.2.34. Converted statements' text changes, so their sqlx statement-cache keys and query signatures change; statements below an added `.bind` move to new `sql!` locators.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Based on
main, now that #373 has merged (fc47b31). This PR is one commit.What merging does
Control-plane Postgres
sandboxes.managed_byandnodes.managed_byhold the substrate that owns a row,'k8s'or'space'. #373 binds that value in the cluster controller. This PR does the same in the internal API, the trigger queue and the sandbox store. They scoped on the value with raw string literals in 11 production SQL statements and one Rust comparison. Their production code now bindsSubstrateKindas a parameter (managed_by = $nwith.bind(SubstrateKind::Kubernetes)/::Space) and matches the parsed variant. Each statement stays syntactically whole. This is phase 2, PR 2 of containing the Direct/Kubernetes substrate split.There are no schema, wire format, metric or configuration changes, and no behavior changes.
SubstrateKindencodes as the column's text, so a boundSubstrateKind::Kubernetesmatches exactly the rows'k8s'did.This revision replaces the previous one, which spliced the now-removed
sql_substrate_*!macros intosql!(concat!(…)).Rebase history. The commit was written on #373's
14e5b7b. It was rebased cleanly onto #373'sbbe7ae1, which changed only tests, docs and comments. After #373 merged, it was rebased ontomain(fc47b31), dropping #373's commit. That rebase had one conflict, incrates/libs/internal/api/server/src/tests.rs:main(#435) addedmod reconcile_claim_origins;on the line where this PR addsmod substrate_scope;. Both declarations are kept, and nothing else in the file changed.git range-diffshows the commit is otherwise identical. I re-checked every converted statement on the new base.main's changes in these crates (adapter.rs,metadata.rs, a new test module) add no substrate literal. The only'k8s'/'space'left in production code in scope is theroutable_execution_or_non_k8sfragment (see below).internal-api (
crates/libs/internal/api/server/src/)Each new placeholder is numbered after the statement's existing parameters, and its
.bindcomes last.lib.rsfetch_nodes(Direct node listing)n.managed_by = 'space'→$3=Spacelib.rsresolve_origin_node_id(Kubernetes node-name lookup)n.managed_by = 'k8s'→$3=Kuberneteslib.rsbootstrap_k8s_origin_nodeINSERT … ON CONFLICTVALUES (…, 'k8s', …)andWHERE nodes.managed_by = 'k8s'→ one$4=Kubernetesfor bothlib.rsregistered_origin_noden.managed_by IN ('space', 'k8s')→IN ($3, $4)=Space,Kubernetesnode_inventory.rslist_kubernetesn.managed_by = 'k8s'→$5=Kubernetespublished_state.rspublish_sandbox_states: delete reported-absent stopped Direct sandboxess.managed_by = 'space'→$3=Spacepublished_state.rspublish_sandbox_states: local suspend handoff observations.managed_by = 'k8s'→$5=Kubernetespublished_state.rsproject_node_published_failed_sandboxes(#337)s.managed_by = 'k8s'→$3=Kubernetes. The rest of #337's statement, includingFOR NO KEY UPDATE OF s, is unchanged.status.rsprune_absent_node_sandboxes:marked_deletedCTEs.managed_by = 'space'→$4=Spacetemplate_releases_store.rsnode_scope_for_addressmanaged_by IN ('space', 'k8s')→IN ($2, $3)=Space,KubernetesTrigger queue (
crates/libs/cluster/trigger-queue/src/lib.rs)fetch_trigger_targetsn.managed_by != 'space'→$4=SpaceSandbox store (
crates/libs/sandbox/store/src/lib.rs)AutoLifecycleExecution::proves_no_executionchanges fromself.managed_by == "k8s"tomatches!(self.managed_by.parse::<SubstrateKind>(), Ok(SubstrateKind::Kubernetes))(Share the 4 MiB message cap and state native write limits in the API docs #12 below).managed_bystays aStringfield.AutoLifecycleExecutionis a publicFromRowrow type that the api crate reads, so typing the field changes that crate's interface, which is outside this PR. (sandboxes_managed_by_checkalready limits the column to'space'/'k8s', so the database can't return an unrecognized value.)AutoLifecycleExecution.managed_byandSandboxRecord.managed_by(both single-row reads) remain text, and the conventions doc lists them as debt.common-svc (
crates/libs/common/svc/src/sql/sandbox_routability.rs): not converted, documented as debtroutable_execution_or_non_k8s(alias)returns a fragment that callers splice into their own statements, each with its own parameter numbering. Binding its'k8s'means each caller passes a placeholder, as cluster-controller: bind the substrate value instead of writing it in SQL #373 did forrow_state_guards.wake_completion.rs, which this PR may not edit. The others are the cluster controller's transient sweeper and internal-api's restored-state convergence.docs/rust/space-conventions.md(from cluster-controller: bind the substrate value instead of writing it in SQL #373) already names this fragment as remaining debt, and this PR updates that paragraph: internal-api and the trigger queue now follow the convention apart from the fragment, alongside the cluster controller. The paragraph also lists the sandbox store's two textmanaged_byfields as debt. Thespace-rust-developmentskill's sentence ("Remaining raw-literal sites, including the sharedroutable_execution_or_non_k8sfragment, are existing debt") is still accurate, so the skill and the plugin version don't change.No change needed or left alone
crates/libs/cluster/pool/: itsmanaged_byis the warm-pool config owner ('manual'/'autoscaler'), not a substrate.crates/libs/sandbox/portability/: its Kubernetes finalization helpers take no substrate value.data_plane_sessions.rsandroute_identity.rsreadmanaged_byas data and hold no literal.target.managed_by == NodeManagedBy::Kubernetesalready compares variants.#[cfg(test)]support modules: fixtures keep writing literalmanaged_byvalues into the rows they set up. This includes internal-api: characterize node publication's lifecycle writers (tests only) #324'spublished_state_tests/lifecycle_writers.rsand internal-api: recheck the failed projection's guards under the row lock #337'spublished_state_lifecycle_race_tests.rs, both unchanged.//////comments.Evidence
A Postgres-backed test per converted statement
Each test seeds a row the statement would act on, then shows the
'k8s'row and an otherwise identical'space'row on the expected sides of the predicate. For the Direct-scoped statements (#1, #6, #9, #11) the'space'row is the included one.New tests:
tests::substrate_scope::node_lookups_select_only_their_substrate(src/tests/substrate_scope.rs). It gives each node both anode_directand anode_k8srow. The existing listing test seeds only the substrate's own registration, so its joins did the excluding andmanaged_bynever decided anything.tests::substrate_scope::bootstrap_k8s_origin_node_writes_and_updates_only_kubernetes_rows. A fresh bootstrap writes'k8s'. An existing'k8s'row at the derived id is refreshed. A'space'row there is refused withFailedPreconditionand left unchanged. No test reached the ON CONFLICT branch before.publishing_local_suspend_handoff_records_only_kubernetes_rows(tests/published_state.rs). No internal-api test covered this statement; the api crate's Kubernetes tests seed only'k8s'.sandbox-store tests::proves_no_execution_only_for_kubernetes_rows, a unit table:"k8s"→ true;"space","kubernetes"and""→ false.Extended tests, with an otherwise identical
'k8s'row added beside the existing'space'one:status::status_tests::complete_inventory_marks_missing_space_sandbox_deleted. The'k8s'row staysstarted/on_node.publishing_absent_stopped_space_sandbox_deletes_central_row. Both rows get the sameboundpool-slot receipt. The'k8s'row staysstoppedand its receipt staysbound. The'space'row and its receipt are gone.Predicate-removal check. For each statement I replaced the converted predicate with
(… OR TRUE), ran the owning package's whole suite (--all-targets --all-features --run-ignored all --retries 0 --no-fail-fast), and reverted.14e5b7b) with this PR's production code. The check ran on that base, before the rebases. The rebases changed none of the statements or tests involved. "After" is this head.OR TRUEcannot fail any test:nodes_managed_by_checkalready limits the column to'space'and'k8s'. Those rows also drop one bound value instead, to show that each bind is load-bearing.true || matches!(…).fetch_nodessubstrate_scope::node_lookups_select_only_their_substrateresolve_origin_node_idsubstrate_scope::bootstrap_k8s_origin_node_writes_and_updates_only_kubernetes_rows(the'space'row is adopted as'k8s')registered_origin_nodeINOR TRUE: passed → passed.IN ($3, $3)(Space only): 65 → 66 tests fail.IN ($4, $4)(Kubernetes only): 2 → 3 fail (existingbase_snapshot_policy_state_prefers_requesting_node_inventory,template_desired_state_projects_snapshot_pool_shape, plusnode_lookups_select_only_their_substrate)list_kubernetessubstrate_scope::node_lookups_select_only_their_substratepublishing_absent_stopped_space_sandbox_deletes_central_rowpublishing_local_suspend_handoff_records_only_kubernetes_rowsproject_node_published_failed_sandboxeslifecycle_writers::failed_report_moves_every_live_k8s_lifecycle_to_failed(#324) andpublishing_direct_failed_sandbox_does_not_mark_central_lifecycle_failedprune_absent_node_sandboxesmarked_deletedstatus_tests::complete_inventory_marks_missing_space_sandbox_deletednode_scope_for_addressINOR TRUE: passed → passed.IN ($2, $2)(Space only): 11 → 12 fail.IN ($3, $3)(Kubernetes only): passed → fails (node_lookups_select_only_their_substrate; every earlier scope test used'k8s'nodes only)fetch_trigger_targetstests::fetch_targets_requires_live_direct_row_for_space_nodesproves_no_executionsandbox-store tests::proves_no_execution_only_for_kubernetes_rows; also the api crate's existingroutes::e2b::tests::timeout_route_distinguishes_dormant_intent_from_unreachable_executionBefore this PR's tests, 3 of the 10 discriminable statements (#8, #11, #12 via the api crate) failed a test when their predicate was dropped. After it, all 10 do. #4 and #10 can't be told apart by
OR TRUE, but dropping either bound value fails a test.Generic plans:
prune_absent_node_sandboxesWhy this statement. It runs in every node publication that carries a complete sandbox census (
publish.rs), for every node. Itsmarked_deletedCTE scans the publishing node's whole resident set, not rows keyed by reported ids. It is also the only convertedsandboxesscan whose literal is the rare value ('space') on a column with an index (idx_sandboxes_managed_by). So it's the statement where losing the literal's statistics could matter most. The other convertedsandboxesstatements look rows up by reported id or primary key.Setup. A scratch database migrated from the test template on the repository's test image (PostgreSQL 16.15), with synthetic, deliberately skewed data: 400 nodes (10%
'space'), 200,000 sandboxes (5%'space', mixed lifecycles), an active execution per started'k8s'sandbox, thenANALYZE. I ranEXPLAIN (GENERIC_PLAN)on the statement text from #373's head (literal) and from this commit (bound). The statement is the same onmain. Only themarked_deletedCTE differs; the other CTEs' plans are identical.The generic plan does differ. Without the value, Postgres estimates
managed_by = $4at 1/ndistinct (50%) instead of the literal's 5%. It drops theBitmapAndwithidx_sandboxes_managed_byand filters the node's rows instead. Both plans start from the node'sidx_sandboxes_active_nodeentries; neither scans the table. Custom plans are identical to the literal plan by construction. The question is whatplan_cache_mode = auto(the default) does with the statement over repeated executions on one connection.That first database had no
sandbox_observed_statesor facet rows. So the other four CTEs (theremoveddelete of the node's observed states and the facet deletes) cost almost nothing, and themarked_deleteddifference dominated. On that databaseautokept building custom plans for the bound statement (generic estimate 1781 vs about 233 for the custom plans). It used the cached generic plan for the literal one.Plan caching with realistic rows (review round 1). I rebuilt the scratch database. It has 400 nodes (10%
'space') and 200,000 sandboxes (5%'space'). 125,000 of them are placed; most nodes hold about 90–150, a few about 1,000, and three about 5,100. Every placed sandbox has asandbox_observed_statesrow and anetwork-policyfacet status row. A third have a facet condition and half a snapshot inventory row. A further 60'k8s'nodes hold 0–9 sandboxes each.Each sequence ran on one connection:
PREPAREonce, then 30 ×EXPLAIN (ANALYZE, TIMING OFF) EXECUTE. Each execution passes a complete census:$2lists the node's present sandboxes, so the data stays stable.generic_plans/custom_plansare read frompg_prepared_statementsat the end. "Before" is the statement text onmain(literal); "after" is this commit (bound).'k8s'and 6 Direct nodes, 91–1,034 sandboxes, shuffled'k8s'nodes with about 5,100 and Direct nodes with 853 and 126, then 25'k8s'nodes with 99–146'k8s'nodes with 0–9 sandboxesEstimated costs explain the table. The whole statement's generic plan costs 3311.2 with the literal and 3358.2 bound, a premium of 47 units (1.4%). Custom plans cost 2574 for a
'k8s'node with 107 sandboxes, 5046 for a Direct node with 853, and 8143 for a'k8s'node with 5,155. With realistic rows, the CTEs this PR doesn't touch dominate both numbers.autodecides from each connection's first five custom plans. Both "large first" sequences latched after their large-node executions. The bound statement's latched plan reads the node's resident rows inmarked_deletedwhere the literal's used theBitmapAnd. I compared them withforce_generic_planandEXPLAIN (ANALYZE, BUFFERS):marked_deletedbuffers, literal → bound'k8s', 107 sandboxes'k8s', 5,155 sandboxesOn the largest node the latched bound plan reads 281 more buffers (+24% for the statement). Execution grows 1.8%, because the generic plan's other CTEs cost about 40 ms for that node either way. That cost predates this PR. The extra read is bounded by the node's resident set through
idx_sandboxes_active_node.Trade-off. On these measurements the planning cost and plan choice are unchanged, and a latched generic plan costs at most a bounded per-node read (+281 buffers at 5,155 sandboxes). I don't consider that material, so I kept the binding. If the owner prefers, this one statement could keep its fixed
'space'as a documented literal exception. The conventions doc would then name it, and the predicate-removal test (#9) would apply unchanged.These are synthetic numbers on one PostgreSQL 16.15 instance. A production database's statistics and node sizes decide the actual margins.
For comparison, the local suspend handoff observation (#7, also run on every publication) has an identical generic plan. The only difference is its filter line,
(managed_by = 'k8s'::text)vs(managed_by = $5), under the same id-driven join.There are no partial indexes on
managed_by, so no generic plan can lose one.Characterization tests pass unchanged
#324's 9
published_state_tests::lifecycle_writerstests and #337'spublished_state_lifecycle_race_tests::failed_projection_decides_on_the_row_committed_while_it_waitspass in every run below. Their files are unchanged.Decisions made unattended
routable_execution_or_non_k8s's literalwake_completion.rs, which is outside this PR's scope. The task allows leaving it as documented debt. The doc comment and the conventions paragraph say so.substrate.managed_by()$4for the bootstrap INSERT's value and its ON CONFLICT guardIN (…)filters, boundproves_no_executionparses aStringinstead of typing the fieldAutoLifecycleExecutionis a publicFromRowrow type the api crate reads; typing its field changes that crate's interface, outside this PR's scope. The CHECK constraint means the database can't return an unrecognized value, so this isn't about robustness. The field andSandboxRecord.managed_byare listed as debt.prune_absent_node_sandboxessrc/tests/substrate_scope.rssrc/tests.rsis already large. A sibling module besideprefetch_catalogandpublicationreuses itscluster_fixture.docs/rust/space-conventions.md, not the skillReview round 1 → changes
prune_absent_node_sandboxesomits per-execution replanning (a) and per-connection latching (b)generic_plans/custom_plans, planning vs execution time, costs and buffers. The "Generic plans" section now states (a) and (b) with those numbers and the trade-off. The binding is kept, and the literal exception is offered as an option.Stringcited unrecognized valuesFromRowtype the api crate reads). The conventions paragraph listsSandboxRecord.managed_byandAutoLifecycleExecution.managed_byas remaining debt instead of saying the store follows the convention.'k8s'row gets the sameboundreceipt, and the test asserts it staysbound. The predicate-removal mutation (#6) still fails the test.Locator note
Converted statements' text changes (a placeholder replaces the literal). Their
/*module_path:line*/locators, sqlx statement-cache keys and DBM query signatures change accordingly. Statements below an added.bindline move to new locators. Module paths don't change.Overlaps with open PRs
#283 adds two raw literals in internal-api:
n.managed_by IN ('space', 'k8s')in a new origin-node lookup, andowner.managed_by <> 'k8s'in a backup-admission statement. Whichever of #283 and this PR lands second should bind them. #165 no longer adds a substrate literal.Validation
Heads:
422d26a(this commit on #373's14e5b7b) →5e846a2(on #373'sbbe7ae1) →180d2a1(onmainfc47b31) →0135f69(review round 1: a doc comment, docs, one test and evidence; this head). The code checks were rerun on each head. Kind ran on422d26aand wasn't rerun for round 1, which changed a doc comment, docs, one test and evidence. After that, this commit's production code is unchanged, butmainhas since merged other production changes (#450, #237, #435), so the Kind results describe this commit on #373's base, not on today'smain.cargo fmt --all -- --check(andci/scripts/run-rust-checks.sh fmt: env contract, Rust error policy)422d26a,5e846a2,180d2a1,0135f69)cargo clippy --workspace --all-targets --all-features --locked -- -D warnings422d26a,5e846a2,180d2a1,0135f69)pre-commit run gitleaks --from-ref origin/main --to-ref HEADon180d2a1and0135f69space-public-reviewon the staged change and this textcargo nextest run --locked -p pplx-space-internal-api-server -p pplx-space-cluster-trigger-queue -p pplx-space-sandbox-store -p pplx-space-common-svc --all-targets --all-features --run-ignored all --retries 0,SPACE_CI_REQUIRE_TEST_DEPS=10135f69: 628/628 passed, 0 skipped (once, per the round-1 instructions).180d2a1: 628/628 in each of 3 runs. That'smain's newreconcile_claim_originstest plus the 627 below.422d26a: 627/627 in each of 3 runs.5e846a2: 627/627 once. Every run includes the characterization tests above and the 4 new tests.cargo test --locked --docon the four packages;RUSTDOCFLAGS=-D warnings cargo doc -p pplx-space-sandbox-storeon0135f69(the new intra-doc link)scripts/source_guards/*.pythin_service_mains.py, which flags onlycrates/apps/*/main.rsfiles this PR doesn't touch: PRE-EXISTINGscripts/check_no_inline_rust_test_modules.pycrates/libs/observability/src/{otlp_endpoint,selection}.rs, untouched: PRE-EXISTINGcargo arch180d2a1. 69 advisory and 0 required findings, the same set asmain. Growth:internal/api/server/src/lib.rsgoes from 1298 to 1303 code lines andpublished_state.rsfrom 3762 to 3765 (the added.bindlines). Both are advisorylisted_no_growthcaps (1222, 3750) the files already exceeded.SPACE_KIND_RUST_ARTIFACTS=docker(chosen to keep the build off the home volume), several runtime images each ran a BuildKit cook at once. The Docker data device filled (49 GB of 49 GB) and the build failed. I tore the cluster down, then ran cleanup step 1:docker builder prune -affreed 36.43 GB anddocker image prune -ffreed 0 B. I reran with the default incremental mode, which serializes one cargo build.smoke-kind-e2e.sh(BOOTSTRAP_TIMEOUT=1800,DATA_PLANE_URL, as CI sets) createdspace-localand started Tilt from this checkout. The api, internal-api and cluster-controller services logversion: 422d26a51afc. Their deployed binaries are byte-identical (sha256) to the artifact image's, before and after the suites. The internal-api binary contains the boundn.managed_by IN ($3, $4),VALUES ($1, $2::INET, $3, $4, 'registered', NOW())and #337'sFOR NO KEY UPDATE OF s, and noAND s.managed_by = 'k8s',AND s.managed_by = 'space'orIN ('space', 'k8s'). The cluster controller contains the trigger queue'sn.managed_by != $4and not!= 'space'.smoke-kind-e2e.sh(start)smoke-kind-typed.sh all(unsharded, CI's env: admin token file, cold-receipts dir, host dm targets loaded)smoke-kind-e2e.sh(end)teardown.shon the task-owned cluster; scratch checkouts and the scratch Postgres container removedTyped-suite non-pass, rerun once:
local.rate_limiters_enforce_and_fail_open: FLAKY. On the first run, the preflight ECW create timed out after 90 s without a response, right after the scenario rolled the public API to enable its limiters. The scenario's own rerun command passed every phase: cluster admission, per-client create and connect concurrency, fail-open with Redis unreachable, and the env restore. This PR doesn't touch the API's limiters. The same scenario's preflight timed out in cluster-controller: bind the substrate value instead of writing it in SQL #373's validation too.🤖 Generated with Claude Code