Repository navigation
CI (lane GO): split the full checks into full-checks and full-checks-2 (DEC-2334) - #2195
Merged
Merged
Conversation
…st tests first A full selection's third shard ran 293 s of tests after about five minutes of setup and build, with xtask's 104 s leak test alone at the tail, and hit the ten-minute cap (DEC-464). Four counted partitions take a quarter each, and a nextest priority override starts the leak test and the live-build check first, so they overlap the rest; no test is dropped or moved out of a shard. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU
DEC-871's Status line points at it; its text is unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU
A top-level `.config/` is a path the outside-path scan reads in every `.config` field access, so `every_outside_path_a_crate_names_is_one_the_scan_covers` failed on mandate-risk and mandate-version-backtest; xtask now hands every nextest run `xtask/nextest.toml` instead. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU
… by key #2129 turned `kubeApi.enabled` on in vault-staging.yaml, and the chart's lookup has no cluster in `cargo xtask ci cell`'s chart checks, so `helm template` of the staging values failed and the `cell` job went red. The checks now give the vault chart the same k3s address as journal-db, set per key so the values file's `enabled` survives, as test_gitops does since #2129. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU
…ps-fast-test-shards
…ess, key by key" This reverts commit 07a751f.
A full selection ran `cargo xtask ci full` past the ten-minute cap in one job (DEC-464). The parts that need Postgres, OpenBao or the S3 store stay in `full-checks`; `tofu`, `stub-release` and `exchange-release` move to `full-checks-2`, started by the same selection and needed by `full`. `the_full_jobs_run_exactly_the_full_group` pins that the two jobs run exactly `ci full`'s parts, each once. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU
12 of 13 tasks
kunwarshivam
changed the base branch from
claude/go-gitops-fast-test-shards
to
main
October 22, 2026 06:18
kunwarshivam
marked this pull request as ready for review
October 22, 2026 06:18
…s-full-checks-split
…full-checks-2 On #2195's full selection `full-checks` ran 9 min 57 s, three seconds under the cap, and `full-checks-2` 1 min 12 s. The three parts that need neither a service nor the Postgres build move to `full-checks-2`, with cargo-deny and gitleaks; DEC-2334 records the timings. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU
Owner
Author
|
This PR changes only Generated by Claude Code |
This was referenced Oct 23, 2026
kunwarshivam
added a commit
that referenced
this pull request
Oct 23, 2026
…s for RUSTSEC-2026-0385 (DEC-2334, DEC-2338) (#2322) * CI (lane GO): run api-release in a full-checks-3 job of its own (DEC-2334, DEC-2338) #2289 added `api-release` to `cargo xtask ci full` (DEC-2338 item 5) after #2195 had split `full`'s parts into `full-checks` and `full-checks-2` (DEC-2334). No CI job ran `api-release`, and `the_full_jobs_run_exactly_the_full_group` failed on main. Its release build of `mandate-api-server` takes about five minutes on its own. Neither existing job has room for that under ten minutes (DEC-464): `full-checks-2`'s `reference` alone is about 4.5 minutes, before its two release builds. So it runs in `full-checks-3`, on the same selection, and `full` needs all three. The verdict table now shows a failed, cancelled or skipped `full-checks-3` failing `full`. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU * Supply chain: bump ctutils 0.4.2 -> 0.4.5 for RUSTSEC-2026-0385 `cargo deny --locked check` fails on main. In ctutils 0.4.2, the constant-time `Choice` mask lacked an optimization barrier (RUSTSEC-2026-0385, RustCrypto/utils#1569); 0.4.4 and later fix it. ctutils is a transitive RustCrypto crate, reached through aes-gcm, crypto-bigint, digest, sec1 and universal-hash (webpush, p256, sqlx-postgres). `cargo update -p ctutils` makes a patch-level bump. Nothing else in Cargo.lock moves, and no manifest or dependency row changes. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU --------- Co-authored-by: Claude <[email protected]>
kunwarshivam
added a commit
that referenced
this pull request
Oct 23, 2026
… from /v2/account alone and kept in the account entry's one byte form (DEC-2339) (#2228) * E21-32 PRV-1a: Kubernetes auth's templated policies, the provisioner's policy and its role requests, tests pending (DEC-2060) Reserves DEC-2060. Each per-connection process logs in with Kubernetes auth as the ServiceAccount named by its connection id's hex; one templated policy per kind reads the path from the login's own ServiceAccount name, so the dedicated provisioner only ever creates a role bound to exactly that ServiceAccount, every other parameter pinned. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-1b: Kubernetes auth's templated policies, the provisioner's policy and its role requests (DEC-2060) Implements the stubs and deletes the pending markers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-1a: both kinds in the workspace's namespace, the exchange's ServiceAccount named x and the hex (DEC-2060) A separate exchange namespace would leave its pods outside the workspace's default deny, egress policies and admission pin. A second spike on OpenBao 2.7.1 showed a literal x before the template within one path segment works: the executor, SA <hex>, reads connections/x<hex>/token, which the exchange, SA x<hex>, writes; each role binds its one SA, and an even-length hex name is never an odd-length x name. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-1b: one namespace, the exchange's ServiceAccount x and the hex (DEC-2060) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-1a: the Kubernetes auth mounts live in Mounts, and the namespace is the workspace's (DEC-2060) So OpenBaoConfig names every mount the login and the provisioner use, from one place, and no second layout can disagree with it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2a: login_kubernetes and the projected ServiceAccount token's reader, tests pending (DEC-2060) The contract agreed with lane LV: OpenBaoSource::login_kubernetes(config, identity, jwt, now) for a connection's executor or token exchange, and mounted::read_service_account_token(dir) with SERVICE_ACCOUNT_TOKEN_DIR. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2a: the Kubernetes login's path and its verdict as pure functions, tests pending (DEC-2060) So the role and ServiceAccount checks are tested and mutated without a cluster. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2b: login_kubernetes and the projected ServiceAccount token's reader (DEC-2060) Implements the stubs and deletes the pending markers. read_mounted and the token reader share one bounded, link-safe read, differing only in the mode bits they refuse and their bound. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-1a: one storage segment for a connection, x and its hex, and the cross-contract tests, pending (DEC-2060) kv_path and openbao_policy become fallible so kv_path can place a connection's entries through connection_segment, a stub here. The pending tests pin the segment, roles named by their ServiceAccount (OpenBao folds role and policy names to lowercase), every role parameter required, a malformed accessor refused, and a cross-contract test: each kind's policy with its bound ServiceAccount put in is exactly the policy written from kv_path, over ids that collide under a raw or case-folding layout. The process-name test reads processes.json. DEC-2060 is written in full. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2a: a Kubernetes login reaches the role named by its ServiceAccount, tests pending (DEC-2060) OpenBao folds role names to lowercase, so PRV-1 names each role by its ServiceAccount; the login's path and its verdict follow, with an Ab case. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * DEC-2060: the AppRole executor and exchange are retired, and the deployment manager makes the ServiceAccounts Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-1a: provisioning sets the Kubernetes auth mounts up, and a missing role is its own refusal, tests pending (DEC-2060) SourceError::RoleMissing (role_missing, not an outage) lets the token exchange's login wait for a role the provisioner has not made yet, as agreed with lane D1; kubernetes_login_refusal is that mapping, a stub. provision takes an optional KubernetesAuth and, given one, sets up both Kubernetes mounts and their templated policies through stubs kubernetes_mount_requests, mount_accessor and provision_kubernetes. A server test pins the result on the dev server, a missing role included. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-1b: provisioning sets the Kubernetes auth mounts up, and a missing role is its own refusal (DEC-2060) provision, given a KubernetesAuth, enables each Kubernetes mount the vault's sys/auth does not list, points it at the API server, and writes each kind's templated policy keyed by its mount's accessor. A Kubernetes login reads a refusal's body only to tell RoleMissing from the rest, and wipes it like every other body. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * Reserve DEC-2061: the token exchange may overwrite its own connection's code Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-2a: the exchange takes its own code, and a Kubernetes login is held to the workspace's namespace, tests pending (DEC-2061) Access::Take is a new access that only a connection's token exchange holds, on its own connection's code, granted only by its Kubernetes-auth templated policy as update without create; the AppRole policies never grant it. login_kubernetes gains namespace, checked by kubernetes_namespace_verdict (a stub), and read_service_account_namespace (a stub) reads the downward API's namespace beside the projected token. DEC-2061 is written in full and infrastructure §5.2's token-exchange row names the take. Three tests that widen implemented tables are behaviour-only rows until PRV-2c-2b. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-2a: the executor reads its namespace beside its token for its Kubernetes login login_kubernetes now takes the workspace's namespace; #2009's executor reads it from the projected volume with read_service_account_namespace, so no pod names its own namespace in its arguments. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-2a: name the behaviour-only rows by their in-file path, and read the executor's namespace before it dials The pending gate names a test by its path inside its file, so each row's test is the bare function name. The executor reads its namespace before vault_login, as LV asked, so an unreadable one is vault_credentials_unreadable and nothing dials without it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-2a: an AppRole policy never grants a take on a secret, not never update at all The connection manager's AppRole grant paths rightly carry update, so the check is over the KV data paths only. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-2b: the exchange takes its own code, and a Kubernetes login is held to the workspace's namespace (DEC-2061) allows grants Access::Take to a connection's token exchange on its own code, and the exchange's templated policy gives that code read and update, never create. read_service_account_namespace reads the projected namespace by the token's rules and holds it to a label; kubernetes_namespace_verdict accepts only the workspace's namespace. The three behaviour-only rows go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: a connection's exchange takes its code once, on both backends, tests pending (DEC-2061) SecretSource::take_code takes a code once: of overlapping takers exactly one gets it, and a source that holds no codes refuses by default. The local and OpenBao takes are stubs. The conformance suite pins, on both backends, that only the code's own exchange takes it, once, and that of two racing takers exactly one wins; on OpenBao that a tombstone is never a code and that no version is left after a take. The OpenBao harness's taker holds the Kubernetes-auth exchange's own policy through an operator token, the only way to hold it without a cluster. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: each taker's policy is named by its ServiceAccount, so a second taker does not rewrite the first's Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3b: a connection's exchange takes its code once, on both backends (DEC-2061) The local take is the local vault's own rename take (DEC-2628 item 2), after the policy check. The OpenBao take reads the code with its version, overwrites that version alone with a tombstone by check-and-set, then deletes every version; a lost overwrite, a tombstone or no code is None. A read of a tombstone is no code. Http::post_judged lets the login and the take each judge a refusal's body. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3b: a take refused after the code is gone is a lost race, not a denial The exchange may update its code but never create it, so once another taker has deleted the code OpenBao refuses the overwrite as 403 before it checks the version. The take then reads again, and reports None only when the code is gone or a tombstone; any other refusal stays Denied. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: pin a lost overwrite's refusal, an exchange without the take, and provisioning over a planted policy cas_refusal (a stub) is pinned by a pure test, so a lost overwrite is caught without a race. The AppRole exchange, whose policy lacks the take, is refused and leaves the code. Provisioning replaces a policy planted under its name, as the reviewer of #2079 asked. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: the exchange's update never creates a code, as the reviewer of #2087 asked Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3b: run the update-never-creates test Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: pin the take's read and its read again as pure verdicts, the code a secret from its decoding taken_read and lost_or_denied_verdict are stubs pinned by unit tests, so the tombstone, the lost race and the denial are caught without a server, and the read's answer never shows the code, as the reviewer of #2117 asked. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: pin DEC-2321's take, which destroys the version it took and keeps the version count The exchange's policy swaps its metadata delete for a delete on its code's data and an update on its code's destroy path; a taker stalled across a take cannot overwrite the code a re-connect stores. DEC-2321 records it and DEC-2061's Status line points at it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3b: a take destroys the version it took and deletes its tombstone, keeping the version count (DEC-2321) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: a taken code's versions hold no data, though the kept metadata still answers Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3a: the take deletes its tombstone's version alone, and a code decodes at its exact size A plain DELETE of the data path deletes whatever version is latest, which hides a code a re-connect stored between the tombstone and the delete; deleting version v+1 through delete/ never does. The exchange's grant becomes update on delete/ in place of delete on data. The decoding test covers every padding length and malformed lengths, for an exact-size decode. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3b: delete the tombstone's version alone, and decode a code at its exact size Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32 PRV-2c-3b: drop exact_decode's two guards the decode already makes Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: a connection's broker account id is kept in the personal-data vault, created once by its own executor, tests pending (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: a connection's broker account id is kept in the personal-data vault, created once by its own executor (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: a source that holds no personal data refuses a create (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E10-13: the broker account id is a shared secret type, read from /v2/account alone and kept in the account entry's one byte form, tests pending (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E10-13: the broker account id is a shared secret type, read from /v2/account alone and kept in the account entry's one byte form (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E10-13: the account id form test names a stub's report when it fails Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E10-13: two ids are equal only by their text, and an entry is written only under a pii_ reference Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E10-13: the id equality and pii_ reference tests run Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: a refused account entry create fails closed, as an unreadable account (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E10-13: the entry decode test's name is spelled as typos reads it Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: DEC-2339's fingerprint is the vault's keyed hash, per connections spec §3.1 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: no identity reads the personal-data vault; the manager gets the vault's keyed hash alone, per connections spec §3.1, tests pending (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: one account entry per request, below its connection and account stream, tests pending (DEC-2339) A request again on the same connection to another account stream (DEC-699) has an entry of its own, so nothing is overwritten and a refused request's entry is kept until its erasure. The executor creates below its own connection's templated segment with one '+', the account stream, create only: the one wildcard of any templated policy, pinned by a test. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: one account entry per request, below its connection and account stream (DEC-2339) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-32: the take test keeps its own connection alone Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * CI (lane GO): run api-release in a full-checks-3 job of its own (DEC-2334, DEC-2338) #2289 added `api-release` to `cargo xtask ci full` (DEC-2338 item 5) after #2195 had split `full`'s parts into `full-checks` and `full-checks-2` (DEC-2334). No CI job ran `api-release`, and `the_full_jobs_run_exactly_the_full_group` failed on main. Its release build of `mandate-api-server` takes about five minutes on its own. Neither existing job has room for that under ten minutes (DEC-464): `full-checks-2`'s `reference` alone is about 4.5 minutes, before its two release builds. So it runs in `full-checks-3`, on the same selection, and `full` needs all three. The verdict table now shows a failed, cancelled or skipped `full-checks-3` failing `full`. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU * Supply chain: bump ctutils 0.4.2 -> 0.4.5 for RUSTSEC-2026-0385 `cargo deny --locked check` fails on main. In ctutils 0.4.2, the constant-time `Choice` mask lacked an optimization barrier (RUSTSEC-2026-0385, RustCrypto/utils#1569); 0.4.4 and later fix it. ctutils is a transitive RustCrypto crate, reached through aes-gcm, crypto-bigint, digest, sec1 and universal-hash (webpush, p256, sqlx-postgres). `cargo update -p ctutils` makes a patch-level bump. Nothing else in Cargo.lock moves, and no manifest or dependency row changes. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU --------- Co-authored-by: Claude <[email protected]>
kunwarshivam
added a commit
that referenced
this pull request
Oct 23, 2026
…EC-2350 S4c follow-up) (#2311) * Test the env-name pin, the vault CA mount and the exchange's launch on the deploy-manager's pods Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Pin each managed container's environment, mount the vault's CA, and launch the exchange with its vault flags Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Cite DEC-2332 for the env pin, the vault CA and the exchange's launch Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Bind the API to the vault with its AppRole and the vault's CA, copied owner-only, where its binding is on (DEC-2338) api.vaultBinding projects the vault-approle-api Secret's two keys and the vault-ca CA into one read-only source directory, which an init container copies into a memory-backed directory at 0600 as api.role-id, api.secret-id and ca.crt, since mandate_vault's reader refuses any group or other bit; the API mounts it read-only and names it in MANDATE_API_VAULT_DIR, beside MANDATE_API_VAULT_ADDRESS, and its egress names the vault on 8200. Off by default; staging's values turn it on, production, which runs no vault, may not. Infrastructure design 3.1's API row says so. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Check that the API's AppRole is named by the api alone, its egress exactly, and its vault address exactly (DEC-2338) Every workload's volumes, environment, arguments and init containers are scanned for the AppRole's Secret, which only the api's projection may name. The api's whole egress is its unbound rules with the one vault rule added, and the vault rule is exactly its workspace's vault pod on 8200. Seeded: the AppRole mounted into each other process, an ipBlock or namespaceSelector on the vault rule, a wide peer on 443, a portless rule, and a foreign vault address. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Check that only the copy and the api mount the api pod's vault volumes (DEC-2338) With the binding on, vault-sources is mounted by the vault-credentials init container alone, read-only, and vault by it read-write and by the api read-only; with it off, neither anywhere. Seeded with a copy of the api container, hardened as it is, mounting either volume as a container or an init container. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Add the role provisioner's connection-role records and start an exchange only once its roles exist (journal v0.77, DEC-2350) Journal spec §9.33 adds ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream at schema version 1, with rule 261 (a system actor and a cause) and stream rules 262 and 263 (each record tied to its OAuth request; a removal after the roles were made, each role once, on its occasion, and the executor's role on a revocation only once no generation of its executor is left running). §9.21 starts a token exchange only once its request's ConnectionRolesMade is read. Connections spec §5.2 step 4 orders the roles first. The reference module connection_roles builds the vectors: 36 invalid and 4 valid drafts, 19 rule-262 and rule-263 streams, 4 validator, 8 stream and 7 vector mutants caught. Reserves and fills DEC-2350; adds the provisioner's backlog row. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Name only the added delete as DEC-2350's: the provisioner's + on its role paths is DEC-2630 item 7's Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Never remove the executor's role: the provisioner removes the token exchange's alone (DEC-2350 item 3) Rule 263 narrows to one removal per made roles, of the token exchange's role, on a closed request or a revocation. A kill switch's start after a revocation can always log in; the cost, one executor role per closed or revoked connection granting a read of its own destroyed token, is recorded in DEC-2350 with the sweep left in the backlog. The executor's role is an invalid draft; its stream cases and the process fold go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Tie each role removal to its own request's close, refresh the fixture, and grant delete on the exchange's mount alone (DEC-2350, review) Rule 263 now holds a removal's causation_id to a closer of its connection journaled after the latest ConnectionRolesMade, so it never cites an earlier request's refusal under a new request of the same id (DEC-699). The fold and the oracle each read it their own way; four new streams and a vector mutant pin it. DEC-2350 item 5 adds delete on the token exchange's mount's block only, so the policy itself keeps the executor's role. fixtures/refcases/journal.json is regenerated. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Drop read from both provisioner role blocks, and send pinned list parameters as strings (DEC-2350 item 5, V2's live check) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * E21-33: the role provisioner's identity and AppRole, delete on the exchange's roles alone, tests pending (DEC-2350) S2 of DEC-2350, the vault side, option (B): the executor's role is never removed. - Identity::Provisioner, provisioned with an AppRole and a secret id only when provisioning is given the workspace's namespace (KubernetesAuth::namespace, from --secrets-namespace); its policy is provisioner_policy for that namespace and nothing else. - provisioner_policy grants delete on the token exchange's mount's block alone (stubbed seam: provisioner_capabilities). - role_request sends the pinned list parameters, the namespace and the policy, as plain strings: OpenBao's allowed_parameters pin refuses a JSON array however it is filled, so every role request was refused (verified on OpenBao 2.7.1; stubbed seam: pinned). - A pin test that the provisioner's + sits on exactly the two Kubernetes mounts' role paths, and a live test that the provisioner's own token makes both roles, is refused a widened role, an executor role's removal, a policy and a secret, and removes the exchange's. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's identity and AppRole, delete on the exchange's roles alone (DEC-2350) S2's implementation: provisioner_capabilities grants delete on the token exchange's roles alone, and pinned sends a pinned list parameter as a plain string. Deletes the pending markers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the provisioner's role blocks grant no read (DEC-2350 item 5) DEC-2350 item 5 now drops read from both blocks, since OpenBao refuses a role read under required_parameters however it is granted: the executor's block is create and update, the token exchange's create, update and delete. The pin test asserts that, and the live test that the provisioner reads neither role it makes. Merges #2278's head. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's journal records and rules 261 to 263, tests pending (DEC-2350) S3 of DEC-2350: journal spec v0.77 §9.33's ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream, against the vectors' connection_roles section. Pending: the catalogue entry, each base and valid draft parsing, every invalid draft refused at its path, append judging rule 261 alone, and the verifier's fold verify_connection_roles answering every stream case of rules 262 and 263. The fold is stubbed; the parse tests fail on the unknown event type, with behaviour-only rows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's journal records and rules 261 to 263 (DEC-2350) S3's implementation: the journal registers ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream at schema version 1, catalogued with no configuration, and append checks rule 261 on each (a system actor, then a cause). The verifier's fold verify_connection_roles judges rules 262 and 263 as the reference does: an answer names its own version-2 OAuth request, once; a removal follows its connection's latest roles made, once, and names a closer of those roles of its own occasion, a connect refusal or a revocation journaled after them. Deletes the pending markers and the four behaviour-only rows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the policy provisioning writes for the provisioner's role is pinned without a server, test pending (DEC-2350) Review item on S2: only a live server told provisioner_policy from openbao_policy for the provisioner's role, so the gate missed a mutant there. provisioned_policy, stubbed here, is the one choice provision makes, and a unit test pins it: provisioner_policy for the provisioner given the namespace, openbao_policy for every other identity and for the provisioner without one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the policy provisioning writes for the provisioner's role is pinned without a server (DEC-2350) provision writes each role's policy through provisioned_policy. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner makes a connection's roles and removes the exchange's, tests pending (DEC-2350) S4a of DEC-2350: RoleProvisioner, the role provisioner's session with the vault, as OpenBaoSource is when it logs in as the provisioner: make_roles makes the executor's and then the token exchange's role as role_request forms them, and remove_exchange_role removes the exchange's. No operation removes an executor's role (DEC-2350 item 3). RoleRefusal names a failure in ConnectionRolesRefused's two reasons. Both operations and the error mapping are stubbed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner makes a connection's roles and removes the exchange's (DEC-2350) S4a's implementation: make_roles POSTs the executor's and then the token exchange's role_request, and remove_exchange_role DELETEs the exchange's, a 404 being a role already gone. A refusal maps to vault_unavailable for an outage or a sealed vault and to role_refused for every other. Removes the temporary Unimplemented variant and the pending markers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: a removal names a connect refusal of its own occasion, test pending (DEC-2350) Mutants found two readings of rule 263 the vectors leave open: a ConnectionRefused of another occasion taken for a request's close, and a removal whose occasion does not name its closer's kind. A pending test edits the removed_on_close case into each and expects rule 263 at the removal. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: a removal names a connect refusal of its own occasion (DEC-2350) The fold compares a removal's named occasion against its closer's kind in one step, an occasion that names neither standing for no closer, and deletes the pending marker. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's plan and pass, tests pending (DEC-2350) S4b of DEC-2350: mandate-provisioner, the role provisioner's library. plan folds the control stream into the steps owed: roles to make for each unanswered version-2 OAuth request, and the exchange's role to remove once a request whose roles were made closes, or its connection is revoked. Provisioner::tick performs each on the vault within the 30 s deadline and journals it, with the opaque alert connection_roles_refused (RB-12) on a refusal. The records' drafts are real, with event ids derived from the step; the plan and the pass are stubbed. Pending: a request's roles once, a refusal and a slow vault, a close and a revocation removing only the exchange's role, a step the journal missed done again and recorded once, two racing writers, an unopened stream, and the plan against every valid vector stream. The crate is at layer 9, above mandate-vault, with its layers row and CODEOWNERS line. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's plan and pass (DEC-2350) S4b's implementation. plan folds the control stream as the journal's verify_connection_roles reads rules 262 and 263: a version-2 OAuth request with no answer is owed its roles, unless it closed first, and a connection whose roles were made is owed the exchange's removal once its request closes or it is revoked, with that first closer as cause. tick performs the first step owed on the vault within the deadline, journals it, and reads the stream again, so each record is drafted against the stream as it is; another writer's record under it is read again at most APPEND_TRIES times. A refusal raises connection_roles_refused (RB-12) with no ids; a removal the vault does not do is retried by the next pass. No step removes an executor's role. Deletes the temporary Unimplemented variants and the pending markers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the live suite's vault set-up names the provisioning error it fails on Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the plan's own connection, version and occasion readings, tests pending; the feature map's entry (DEC-2350) Mutants found readings of the plan the vectors leave open: an API-key or version-1 request, a close of one connection's request before its answer, two connections' made roles, and a refusal of another occasion. Three pending tests pin each over synthetic streams. The role provisioner's feature-map entry names its code, tests and runs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: a provisioner's pass ends after the steps it owed (DEC-2350) A pass takes at most the steps it first owed and APPEND_TRIES more, so a stream that never shows a record committed ends the pass as a journal halt rather than looping; the plan tests' pending markers go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: only the provisioner's session makes or removes roles, test pending A session that never logged in, built for unit tests, lets the identity check be tested with no vault running. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: only the provisioner's session makes or removes roles A role operation from any other session is refused role_refused before the vault is reached. The DELETE's doc now says why a missing auth mount counts as removed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's process, mandate-provisionerd (DEC-2350) The provisioner over the Postgres control stream, written as mandate-deployd writes it, and the vault, logged in by AppRole as the provisioner and again every hour. A session near its token's end that no login replaced stops the process, failed, so it never calls the vault with a lapsed token. --fixture runs it over memory and a vault that keeps nothing, and a release build refuses it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the fixture run is a debug build's block, not a release stub Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the workspace services' pinned list names the role provisioner Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the workspace services' pinned list names the provisioner's process Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the API's owner-only vault copy becomes the chart's shared helper, by role mandate.vaultCopy and mandate.vaultVolumes take the process's vault role; the API's render is byte-for-byte the same. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the workspace chart's role provisioner, its AppRole alone and no Kubernetes credential (DEC-2350) The role-provisioner process: one Deployment per workspace once its image is named, reading ctl:<api.workspace> as mandate_role_provisioner, binding roles in its own namespace, with its AppRole and the vault's CA copied owner-only by the shared vault helper, no service-account token, and egress to the journal and its vault on 8200 alone. Infrastructure design §3.1 gains its row; roles.sql, the Compose file and initdb.sh are regenerated. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's image, and its process marked built (DEC-2350) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's pod holds exactly its own volumes, and no token or ConfigMap besides (DEC-2350, review G1) Its volume set is pinned by name and kind, and its projected volume to its Secret and the vault's CA, with seeds for a projected service-account token, a token in its vault sources, an extra ConfigMap, a host path, a downward API volume, and a second kind on one volume. Infrastructure design §3.1 says its writing only the three role records is its convention, not a database grant. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * CI (lane GO): run api-release in a full-checks-3 job of its own (DEC-2334, DEC-2338) #2289 added `api-release` to `cargo xtask ci full` (DEC-2338 item 5) after #2195 had split `full`'s parts into `full-checks` and `full-checks-2` (DEC-2334). No CI job ran `api-release`, and `the_full_jobs_run_exactly_the_full_group` failed on main. Its release build of `mandate-api-server` takes about five minutes on its own. Neither existing job has room for that under ten minutes (DEC-464): `full-checks-2`'s `reference` alone is about 4.5 minutes, before its two release builds. So it runs in `full-checks-3`, on the same selection, and `full` needs all three. The verdict table now shows a failed, cancelled or skipped `full-checks-3` failing `full`. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU * Supply chain: bump ctutils 0.4.2 -> 0.4.5 for RUSTSEC-2026-0385 `cargo deny --locked check` fails on main. In ctutils 0.4.2, the constant-time `Choice` mask lacked an optimization barrier (RUSTSEC-2026-0385, RustCrypto/utils#1569); 0.4.4 and later fix it. ctutils is a transitive RustCrypto crate, reached through aes-gcm, crypto-bigint, digest, sec1 and universal-hash (webpush, p256, sqlx-postgres). `cargo update -p ctutils` makes a patch-level bump. Nothing else in Cargo.lock moves, and no manifest or dependency row changes. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU --------- Co-authored-by: Claude <[email protected]>
kunwarshivam
added a commit
that referenced
this pull request
Oct 23, 2026
#2313) * Test the env-name pin, the vault CA mount and the exchange's launch on the deploy-manager's pods Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Pin each managed container's environment, mount the vault's CA, and launch the exchange with its vault flags Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Cite DEC-2332 for the env pin, the vault CA and the exchange's launch Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Start an OAuth connect's executor on its exchange's success (journal v0.74, DEC-2335) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Name J2 PR #2200 as an ES-22 atomic exception (DEC-2335 item 6) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Test the connect's executor: started on its exchange's success, stopped when its connection closes (E21-33 K2a, DEC-2336) The tests half of DEC-77's pair. Phase::Succeeded joins the orchestrator port and the fake can succeed an instance; the manager's fold and decision have no stub form, so the tests that need a success read are pending as behaviour-only rows until K2a's implementation lands. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Start the connect's executor on its exchange's success and stop it when its connection closes (E21-33 K2a, DEC-2336) The implementation half of DEC-77's pair: the manager reads the request's account, journals the executor's exchanged start while the request is open and the account's executor never ran, wants it until a refusal or revocation, and names each executor stop by the last reason taken away. The pending tests' ignore lines and behaviour-only rows go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Name K2b's executor self-check dependency and the Deployment executor's account in DEC-2336's risks Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Test that each executor runs as its connection's own account (E21-33 K2b, DEC-2336 items 6 to 10) The tests half of DEC-77's pair. The orchestrator port's start takes a Launch of the exchange's lifetime and the executor's connection, and its stop the connection; the driver passes none yet and the adapter ignores it, so the tests that need it are pending as behaviour-only rows. DEC-2336 gains K2b's items and the coordinator's F2 wording. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Run each manager-started executor as its connection's own account, and pin it at admission (E21-33 K2b, DEC-2336 items 6 to 10) The implementation half of DEC-77's pair. The manager names an executor's connection on its start and stop and asks once per account per pass; the adapter makes and deletes the executor's hex account, names it and the namespace in its environment, and reads a succeeded pod as Succeeded. The chart pins a manager-started executor to an even-length hex account its environment names, admits that account with the executor's label, and mounts the vault token only on pods the manager starts. The pending tests' ignore lines and behaviour-only rows go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Test that an executor's start and stop name the same connection, the deployment's or the connect's (E21-33 K2b, review F1) Four pending tests: a revoked connection the deployment does not name is never chosen; a restart after the connect ended names the deployment's connection, across the manager's restart; a stop names its generation's connection once nothing else does; and no executor takes another account's connection. DEC-2336 item 6 says which connection a start names. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Name each executor generation's connection when its start is folded, from its deployment or its connect (E21-33 K2b, review F1) An executor's start names the connection a running agent's deployment of its account names, else its open connect's; the manager records it per generation as it folds the start, so the stop names the same account and a restarted manager names the same one. A revoked connection no deployment names is no longer chosen. The pending tests' ignore lines and rows go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Test that a kill switch reaches an executor no agent wants, once per switch (DEC-2344 items 1 and 3) Pending E21-33. A covering kill switch gives an account's executor that every agent's retirement left down exactly one start, cause kill_switch, journaled first and caused by the switch; each later covering switch one more; a generation that ends on its own is never restarted; nothing else starts it; and a switch the executor has not answered keeps the account's last retirement from stopping it. A property over random deploys, retirements, kill switches of every scope, ends, clock steps and manager restarts checks both against an oracle computed from the operations alone. Each pending test has its behaviour-only row: the manager answers, no stub. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Test that a kill-switch start crash-looping before it ends raises kill_switch_unapplied (DEC-2344 item 1) Pending E21-33. A crash of the start is restarted, so one crash loses no switch; at the crash-loop bound the manager journals ProcessCrashLooped and raises the opaque operator alert kill_switch_unapplied, once, in place of crash_loop. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Extend the kill-switch property to crashes and the unapplied-switch alert (DEC-2344 item 1) The executor no agent wants may now crash before it ends. The oracle allows a crash's restart only before its loop and with no switch pending, requires the switch's one start when one is, never lets the manager stop a generation a switch keeps, admits a crash loop only after a kill switch's crashing start, and requires each such loop to raise kill_switch_unapplied once and every other alert never. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Read a successful end as answering only the switches committed before its start (DEC-2344, journal v0.76 §9.21) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Add the role provisioner's connection-role records and start an exchange only once its roles exist (journal v0.77, DEC-2350) Journal spec §9.33 adds ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream at schema version 1, with rule 261 (a system actor and a cause) and stream rules 262 and 263 (each record tied to its OAuth request; a removal after the roles were made, each role once, on its occasion, and the executor's role on a revocation only once no generation of its executor is left running). §9.21 starts a token exchange only once its request's ConnectionRolesMade is read. Connections spec §5.2 step 4 orders the roles first. The reference module connection_roles builds the vectors: 36 invalid and 4 valid drafts, 19 rule-262 and rule-263 streams, 4 validator, 8 stream and 7 vector mutants caught. Reserves and fills DEC-2350; adds the provisioner's backlog row. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Name only the added delete as DEC-2350's: the provisioner's + on its role paths is DEC-2630 item 7's Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Never remove the executor's role: the provisioner removes the token exchange's alone (DEC-2350 item 3) Rule 263 narrows to one removal per made roles, of the token exchange's role, on a closed request or a revocation. A kill switch's start after a revocation can always log in; the cost, one executor role per closed or revoked connection granting a read of its own destroyed token, is recorded in DEC-2350 with the sweep left in the backlog. The executor's role is an invalid draft; its stream cases and the process fold go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Tie each role removal to its own request's close, refresh the fixture, and grant delete on the exchange's mount alone (DEC-2350, review) Rule 263 now holds a removal's causation_id to a closer of its connection journaled after the latest ConnectionRolesMade, so it never cites an earlier request's refusal under a new request of the same id (DEC-699). The fold and the oracle each read it their own way; four new streams and a vector mutant pin it. DEC-2350 item 5 adds delete on the token exchange's mount's block only, so the policy itself keeps the executor's role. fixtures/refcases/journal.json is regenerated. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Start an executor no agent wants once per covering kill switch, and hold it until its switches are answered (DEC-2344 items 1 and 3) The manager starts such an executor, cause kill_switch, journaled first, once for the covering switches it has not answered, as the account of the connection its last generation ran as. It never stops a generation a switch started or one a switch read while it ran is waiting on; a success ends it, a crash restarts with back-off, and a crash loop raises kill_switch_unapplied in place of crash_loop, again once from a restarted manager. The six pending retired.rs tests run, their behaviour-only rows go, and new tests cover a revoked connection, the restarted alert, a wanted executor's successful exit, and the oracle's seeded bugs. Two older tests follow DEC-2344's change. The alert has its RB-14 section and its infrastructure design §8.2 row. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Drop read from both provisioner role blocks, and send pinned list parameters as strings (DEC-2350 item 5, V2's live check) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Move the implementation's new tests here as pending: a revoked connection's start, the restarted alert, the oracle's seeded bugs (DEC-2344 item 1, review) The four tests the implementation PR wrote fail on today's manager and are pending E21-33 with behaviour-only rows: the N3 revoked-connection start, the restarted manager's one re-raise, the seeded-bug harness, and manager.rs's stopped-agent test with DEC-2344's extra start. The property expects the re-raise, and properties.rs exempts an executor's unwanted start, which retired.rs's property checks more strictly. A wanted executor's restart after a success already passes, so it is a plain test. Record::CrashLooped carries the alert it raises, crash_loop for every loop today, so the harness can seed a loop. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Reflow RB-14's kill_switch_unapplied escalation step Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Test that a later switch after an unapplied loop starts a new run, that a held crash waits its back-off, and that a redeploy ends a kill-switch run (DEC-2344 item 1, review) Three more tests, pending E21-33 with behaviour-only rows, each failing on today's manager: a covering switch after an unapplied crash loop starts a new run that is restarted and can loop and alert again; a crashed kill-switch generation waits backoff(0) before exactly one restart; and a deployment during a kill-switch run makes its later loop an ordinary crash_loop, after a manager restart too. The property's oracle lets such a start begin a new run. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Begin a new run at a kill switch's start after an unapplied loop, and merge #2257's new tests (DEC-2344 item 1, review) A kill_switch start of an executor no agent wants clears the last run's restarts, crash loop and alert, so a later covering switch after an unapplied loop is restarted after a crash, loops again, and is reported again: a second ProcessCrashLooped and a second kill_switch_unapplied. The merge takes #2257's three new tests and deletes their ignore lines and rows; a held crash's back-off and a redeploy's ordinary loop already held and are now pinned. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Test that a deploy and retire during a kill switch's generation does not stop it (DEC-2344 item 3, review) Pending E21-33 with its behaviour-only row: the generation a covering switch started stays running through an agent's deployment and retirement on the account, and its own end is not restarted. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Let the property's oracle keep a kill-switch run held through a deployment (DEC-2344 item 3, review) A deployment on the account no longer ends a held run in the oracle's view: only its own successful end does, so a crash of it is still restarted after the agent retires. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Keep a kill switch's run held through a deployment and retirement, and classify its loop at the loop (DEC-2344 item 3, review) resume no longer clears held, and a kill_switch start made while the executor is wanted no longer clears it either, so an agent deployed and retired while a switch's generation runs never gets that generation stopped before it ends itself (rule 13). A stop the manager journals is only ever of a generation it does not hold, so folding it clears held, and a replay agrees. A crash loop leaves a switch unapplied only when no agent wants the executor at the loop. #2257's new test runs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * E21-33: the role provisioner's journal records and rules 261 to 263, tests pending (DEC-2350) S3 of DEC-2350: journal spec v0.77 §9.33's ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream, against the vectors' connection_roles section. Pending: the catalogue entry, each base and valid draft parsing, every invalid draft refused at its path, append judging rule 261 alone, and the verifier's fold verify_connection_roles answering every stream case of rules 262 and 263. The fold is stubbed; the parse tests fail on the unknown event type, with behaviour-only rows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's journal records and rules 261 to 263 (DEC-2350) S3's implementation: the journal registers ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream at schema version 1, catalogued with no configuration, and append checks rule 261 on each (a system actor, then a cause). The verifier's fold verify_connection_roles judges rules 262 and 263 as the reference does: an answer names its own version-2 OAuth request, once; a removal follows its connection's latest roles made, once, and names a closer of those roles of its own occasion, a connect refusal or a revocation journaled after them. Deletes the pending markers and the four behaviour-only rows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * Test a kill switch's start during an open connect, a connect during a held run, a connect's ordinary loop, and a stop a restart must not undo (DEC-2351 item 2, review) Three pending E21-33 with rows, each failing on today's manager, and one plain test that passes today: an executor only a connect wants loops as crash_loop. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Hold a kill switch's run by the agents alone, and say so in the loop's alert, and merge #2257's tests (DEC-2351 item 2, review) A kill_switch start of an executor holds its run when no agent of its account is deployed and not stopped, whatever connect request wants it, and the crash loop's alert says kill_switch_unapplied when the run is held and no agent wants the executor at the loop, as journal spec rule 264 reads it; a runtime's start never holds. A deployment on a connection revoked since counts until its AgentStopped, as the rule reads it. The merge takes #2257's four new tests. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * E21-33: a removal names a connect refusal of its own occasion, test pending (DEC-2350) Mutants found two readings of rule 263 the vectors leave open: a ConnectionRefused of another occasion taken for a request's close, and a removal whose occasion does not name its closer's kind. A pending test edits the removed_on_close case into each and expects rule 263 at the removal. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: a removal names a connect refusal of its own occasion (DEC-2350) The fold compares a removal's named occasion against its closer's kind in one step, an occasion that names neither standing for no closer, and deletes the pending marker. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the token exchange waits for its request's roles, tests pending (DEC-2350 S6) A connect's token exchange starts only once its request's ConnectionRolesMade is read (journal spec §9.21, §9.33). The new roles suite and the exchange property's oracle say so; the existing connect tests gain the Made row their scenarios now need. The pending tests fail on the manager's behaviour, which has no stub to stop at, and are named in xtask/behaviour-only until the implementation lands. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the seeded double launch waits for a first launch to copy (DEC-2350 S6) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the token exchange waits for its request's roles (DEC-2350 S6) The manager reads the role provisioner's ConnectionRolesMade and keeps each request's event id; a connect's token exchange is wanted only once the Made that answers its own request is read, so a refusal, a record for another request, or none starts nothing, and the connect ends by its deadline (journal spec §9.21). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * CI (lane GO): run api-release in a full-checks-3 job of its own (DEC-2334, DEC-2338) #2289 added `api-release` to `cargo xtask ci full` (DEC-2338 item 5) after #2195 had split `full`'s parts into `full-checks` and `full-checks-2` (DEC-2334). No CI job ran `api-release`, and `the_full_jobs_run_exactly_the_full_group` failed on main. Its release build of `mandate-api-server` takes about five minutes on its own. Neither existing job has room for that under ten minutes (DEC-464): `full-checks-2`'s `reference` alone is about 4.5 minutes, before its two release builds. So it runs in `full-checks-3`, on the same selection, and `full` needs all three. The verdict table now shows a failed, cancelled or skipped `full-checks-3` failing `full`. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU * Supply chain: bump ctutils 0.4.2 -> 0.4.5 for RUSTSEC-2026-0385 `cargo deny --locked check` fails on main. In ctutils 0.4.2, the constant-time `Choice` mask lacked an optimization barrier (RUSTSEC-2026-0385, RustCrypto/utils#1569); 0.4.4 and later fix it. ctutils is a transitive RustCrypto crate, reached through aes-gcm, crypto-bigint, digest, sec1 and universal-hash (webpush, p256, sqlx-postgres). `cargo update -p ctutils` makes a patch-level bump. Nothing else in Cargo.lock moves, and no manifest or dependency row changes. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU --------- Co-authored-by: Claude <[email protected]>
kunwarshivam
added a commit
that referenced
this pull request
Oct 23, 2026
…EC-2350 S4b-2 follow-up) (#2308) * Add the role provisioner's connection-role records and start an exchange only once its roles exist (journal v0.77, DEC-2350) Journal spec §9.33 adds ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream at schema version 1, with rule 261 (a system actor and a cause) and stream rules 262 and 263 (each record tied to its OAuth request; a removal after the roles were made, each role once, on its occasion, and the executor's role on a revocation only once no generation of its executor is left running). §9.21 starts a token exchange only once its request's ConnectionRolesMade is read. Connections spec §5.2 step 4 orders the roles first. The reference module connection_roles builds the vectors: 36 invalid and 4 valid drafts, 19 rule-262 and rule-263 streams, 4 validator, 8 stream and 7 vector mutants caught. Reserves and fills DEC-2350; adds the provisioner's backlog row. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Name only the added delete as DEC-2350's: the provisioner's + on its role paths is DEC-2630 item 7's Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Never remove the executor's role: the provisioner removes the token exchange's alone (DEC-2350 item 3) Rule 263 narrows to one removal per made roles, of the token exchange's role, on a closed request or a revocation. A kill switch's start after a revocation can always log in; the cost, one executor role per closed or revoked connection granting a read of its own destroyed token, is recorded in DEC-2350 with the sweep left in the backlog. The executor's role is an invalid draft; its stream cases and the process fold go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Tie each role removal to its own request's close, refresh the fixture, and grant delete on the exchange's mount alone (DEC-2350, review) Rule 263 now holds a removal's causation_id to a closer of its connection journaled after the latest ConnectionRolesMade, so it never cites an earlier request's refusal under a new request of the same id (DEC-699). The fold and the oracle each read it their own way; four new streams and a vector mutant pin it. DEC-2350 item 5 adds delete on the token exchange's mount's block only, so the policy itself keeps the executor's role. fixtures/refcases/journal.json is regenerated. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * Drop read from both provisioner role blocks, and send pinned list parameters as strings (DEC-2350 item 5, V2's live check) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01LmJtE8JXVQjyqTteJ5b9Cm * E21-33: the role provisioner's identity and AppRole, delete on the exchange's roles alone, tests pending (DEC-2350) S2 of DEC-2350, the vault side, option (B): the executor's role is never removed. - Identity::Provisioner, provisioned with an AppRole and a secret id only when provisioning is given the workspace's namespace (KubernetesAuth::namespace, from --secrets-namespace); its policy is provisioner_policy for that namespace and nothing else. - provisioner_policy grants delete on the token exchange's mount's block alone (stubbed seam: provisioner_capabilities). - role_request sends the pinned list parameters, the namespace and the policy, as plain strings: OpenBao's allowed_parameters pin refuses a JSON array however it is filled, so every role request was refused (verified on OpenBao 2.7.1; stubbed seam: pinned). - A pin test that the provisioner's + sits on exactly the two Kubernetes mounts' role paths, and a live test that the provisioner's own token makes both roles, is refused a widened role, an executor role's removal, a policy and a secret, and removes the exchange's. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's identity and AppRole, delete on the exchange's roles alone (DEC-2350) S2's implementation: provisioner_capabilities grants delete on the token exchange's roles alone, and pinned sends a pinned list parameter as a plain string. Deletes the pending markers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the provisioner's role blocks grant no read (DEC-2350 item 5) DEC-2350 item 5 now drops read from both blocks, since OpenBao refuses a role read under required_parameters however it is granted: the executor's block is create and update, the token exchange's create, update and delete. The pin test asserts that, and the live test that the provisioner reads neither role it makes. Merges #2278's head. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's journal records and rules 261 to 263, tests pending (DEC-2350) S3 of DEC-2350: journal spec v0.77 §9.33's ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream, against the vectors' connection_roles section. Pending: the catalogue entry, each base and valid draft parsing, every invalid draft refused at its path, append judging rule 261 alone, and the verifier's fold verify_connection_roles answering every stream case of rules 262 and 263. The fold is stubbed; the parse tests fail on the unknown event type, with behaviour-only rows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's journal records and rules 261 to 263 (DEC-2350) S3's implementation: the journal registers ConnectionRolesMade, ConnectionRolesRefused and ConnectionRolesRemoved on the control stream at schema version 1, catalogued with no configuration, and append checks rule 261 on each (a system actor, then a cause). The verifier's fold verify_connection_roles judges rules 262 and 263 as the reference does: an answer names its own version-2 OAuth request, once; a removal follows its connection's latest roles made, once, and names a closer of those roles of its own occasion, a connect refusal or a revocation journaled after them. Deletes the pending markers and the four behaviour-only rows. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the policy provisioning writes for the provisioner's role is pinned without a server, test pending (DEC-2350) Review item on S2: only a live server told provisioner_policy from openbao_policy for the provisioner's role, so the gate missed a mutant there. provisioned_policy, stubbed here, is the one choice provision makes, and a unit test pins it: provisioner_policy for the provisioner given the namespace, openbao_policy for every other identity and for the provisioner without one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the policy provisioning writes for the provisioner's role is pinned without a server (DEC-2350) provision writes each role's policy through provisioned_policy. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner makes a connection's roles and removes the exchange's, tests pending (DEC-2350) S4a of DEC-2350: RoleProvisioner, the role provisioner's session with the vault, as OpenBaoSource is when it logs in as the provisioner: make_roles makes the executor's and then the token exchange's role as role_request forms them, and remove_exchange_role removes the exchange's. No operation removes an executor's role (DEC-2350 item 3). RoleRefusal names a failure in ConnectionRolesRefused's two reasons. Both operations and the error mapping are stubbed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner makes a connection's roles and removes the exchange's (DEC-2350) S4a's implementation: make_roles POSTs the executor's and then the token exchange's role_request, and remove_exchange_role DELETEs the exchange's, a 404 being a role already gone. A refusal maps to vault_unavailable for an outage or a sealed vault and to role_refused for every other. Removes the temporary Unimplemented variant and the pending markers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: a removal names a connect refusal of its own occasion, test pending (DEC-2350) Mutants found two readings of rule 263 the vectors leave open: a ConnectionRefused of another occasion taken for a request's close, and a removal whose occasion does not name its closer's kind. A pending test edits the removed_on_close case into each and expects rule 263 at the removal. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: a removal names a connect refusal of its own occasion (DEC-2350) The fold compares a removal's named occasion against its closer's kind in one step, an occasion that names neither standing for no closer, and deletes the pending marker. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's plan and pass, tests pending (DEC-2350) S4b of DEC-2350: mandate-provisioner, the role provisioner's library. plan folds the control stream into the steps owed: roles to make for each unanswered version-2 OAuth request, and the exchange's role to remove once a request whose roles were made closes, or its connection is revoked. Provisioner::tick performs each on the vault within the 30 s deadline and journals it, with the opaque alert connection_roles_refused (RB-12) on a refusal. The records' drafts are real, with event ids derived from the step; the plan and the pass are stubbed. Pending: a request's roles once, a refusal and a slow vault, a close and a revocation removing only the exchange's role, a step the journal missed done again and recorded once, two racing writers, an unopened stream, and the plan against every valid vector stream. The crate is at layer 9, above mandate-vault, with its layers row and CODEOWNERS line. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's plan and pass (DEC-2350) S4b's implementation. plan folds the control stream as the journal's verify_connection_roles reads rules 262 and 263: a version-2 OAuth request with no answer is owed its roles, unless it closed first, and a connection whose roles were made is owed the exchange's removal once its request closes or it is revoked, with that first closer as cause. tick performs the first step owed on the vault within the deadline, journals it, and reads the stream again, so each record is drafted against the stream as it is; another writer's record under it is read again at most APPEND_TRIES times. A refusal raises connection_roles_refused (RB-12) with no ids; a removal the vault does not do is retried by the next pass. No step removes an executor's role. Deletes the temporary Unimplemented variants and the pending markers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the live suite's vault set-up names the provisioning error it fails on Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the plan's own connection, version and occasion readings, tests pending; the feature map's entry (DEC-2350) Mutants found readings of the plan the vectors leave open: an API-key or version-1 request, a close of one connection's request before its answer, two connections' made roles, and a refusal of another occasion. Three pending tests pin each over synthetic streams. The role provisioner's feature-map entry names its code, tests and runs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: a provisioner's pass ends after the steps it owed (DEC-2350) A pass takes at most the steps it first owed and APPEND_TRIES more, so a stream that never shows a record committed ends the pass as a journal halt rather than looping; the plan tests' pending markers go. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: only the provisioner's session makes or removes roles, test pending A session that never logged in, built for unit tests, lets the identity check be tested with no vault running. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: only the provisioner's session makes or removes roles A role operation from any other session is refused role_refused before the vault is reached. The DELETE's doc now says why a missing auth mount counts as removed. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the role provisioner's process, mandate-provisionerd (DEC-2350) The provisioner over the Postgres control stream, written as mandate-deployd writes it, and the vault, logged in by AppRole as the provisioner and again every hour. A session near its token's end that no login replaced stops the process, failed, so it never calls the vault with a lapsed token. --fixture runs it over memory and a vault that keeps nothing, and a release build refuses it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the fixture run is a debug build's block, not a release stub Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the workspace services' pinned list names the role provisioner Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: the workspace services' pinned list names the provisioner's process Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * E21-33: CI builds the role provisioner in release and checks it refuses its fixture cargo xtask ci provisionerd-release, in full and in check, like stub-release: it builds mandate-provisionerd with --release when the diff selects it, runs it with --fixture, and requires exit 2 with fixture_not_built alone on stderr. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF * CI (lane GO): run api-release in a full-checks-3 job of its own (DEC-2334, DEC-2338) #2289 added `api-release` to `cargo xtask ci full` (DEC-2338 item 5) after #2195 had split `full`'s parts into `full-checks` and `full-checks-2` (DEC-2334). No CI job ran `api-release`, and `the_full_jobs_run_exactly_the_full_group` failed on main. Its release build of `mandate-api-server` takes about five minutes on its own. Neither existing job has room for that under ten minutes (DEC-464): `full-checks-2`'s `reference` alone is about 4.5 minutes, before its two release builds. So it runs in `full-checks-3`, on the same selection, and `full` needs all three. The verdict table now shows a failed, cancelled or skipped `full-checks-3` failing `full`. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU * Supply chain: bump ctutils 0.4.2 -> 0.4.5 for RUSTSEC-2026-0385 `cargo deny --locked check` fails on main. In ctutils 0.4.2, the constant-time `Choice` mask lacked an optimization barrier (RUSTSEC-2026-0385, RustCrypto/utils#1569); 0.4.4 and later fix it. ctutils is a transitive RustCrypto crate, reached through aes-gcm, crypto-bigint, digest, sec1 and universal-hash (webpush, p256, sqlx-postgres). `cargo update -p ctutils` makes a patch-level bump. Nothing else in Cargo.lock moves, and no manifest or dependency row changes. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU * Run the role provisioner's release check in full-checks-3 Main's full-job split has no room for it in full-checks-2, so it runs beside the API's release build, about two minutes more, under ten (DEC-464). Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01B5V2t72QcDywyLPViJtmFF --------- Co-authored-by: Claude <[email protected]>
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.
Story
CI capacity under DEC-464, at the coordinator's request. Decisions: DEC-2334, assigned by the coordinator, and DEC-2325 (via #2142).
This PR contains #2142. #2142 at its approved head adc790f was green except
full-checks, which hit the cap again (05:54:12 to 06:04:23), sofullfailed and #2142 can't land green alone. This PR merges that head and current main and adds the split, so landing it lands both. Its base ismain, and its diff over main is #2142's 6 files plus DEC-2334.On #2142 at 72a6297, a full selection's single
full-checkswas cancelled at the ten-minute cap atci exchange-release. Every part before it had passed.full-checkskeeps the parts that need its services (PostgreSQL, OpenBao, S3), plusrefcases, whose build the Postgres tests reuse:refcases,postgres,openbao,objectstore, each as its own step.full-checks-2, new, runs on its own runner with no service:reference,schemas,supply-chain,tofu,stub-release,exchange-release. cargo-deny, gitleaks, OpenTofu, tflint andMANDATE_TOFU_REQUIREDmove with the parts that use them. It needsselectand starts onneeds.select.outputs.full_checks, exactly asfull-checksdoes.fullneeds both. Each must have succeeded where selected and been skipped where not.cargo xtask ci fullandcheckstill run every part.fast-testshards, andxtask/nextest.tomlstarting the two longest xtask tests first.Timings on full selections
full-checksfull-checks-2full-checks)fast-testshards on 6f3fb9f: 1/4 8.7 min, 2/4 6.3, 3/4 7.8, 4/4 7.0.fastandfullare green.Spec clause → test
ci full's parts, each once and in order, and no other job runs one. Each is capped at 10 min, needsselect, starts onfull_checks, and is needed byfull. Seeded: droppingfull-checks-2fromfull's needs, or a duplicated part, both fail itthe_full_jobs_run_exactly_the_full_group(new)full's script: either job off its selection fails the verdictfull_accepts_a_skipped_matrix_only_beside_a_plan_of_zero(eight new cases)every_mutation_shard_has_the_database_…,…_the_store_…(gates nowci postgresandci objectstore)the_scoped_jobs_follow_the_selection(SELECT_GATES16),ci_leaves_the_base_to_the_event(22 checkouts), the guard tablethe_fast_jobs_run_exactly_the_fast_group,the_nextest_partition_is_checkedDependencies
None.
Journal events added
None.
Not done
Nothing.
Decisions needed
None.
Safety checklist (safety-critical changes)
Not a safety-critical path. Only the CI job layout and test order change; no check is removed.
Checks
cargo nextest run -p xtask: 542 passed at 6f3fb9f.-p xtask -D warnings, fmt, actionlint, typos, markers and decision numbers are clean.full-checksandfull-checks-2on a full selection (table above).cell-kill-switch's first attempt failed in k3d setup (an image-import race; see the comment), and its one re-run passed (07:59:25 to 08:06:35).🤖 Generated with Claude Code
https://claude.ai/code/session_01UoxcMViCbnGUTPSaduuGYU