[WIP] CAS draft (adopting to CI/CD, not for review / merge) - #2073
Draft
filimonov wants to merge 4469 commits into
Draft
[WIP] CAS draft (adopting to CI/CD, not for review / merge)#2073filimonov wants to merge 4469 commits into
filimonov wants to merge 4469 commits into
Conversation
ilejn
reviewed
Jul 28, 2026
|
|
||
| ```sql | ||
| SYSTEM CONTENT ADDRESSED GC RUN [ON CLUSTER cluster_name] [disk_name] | ||
| ``` |
strtgbb
requested changes
Jul 31, 2026
Answers a review of rev.3, plus one owner correction that changes a decision. Owner correction: once the migration window closes, an unprefixed CAS setting name is REJECTED, not ignored. Silently discarding a value an operator wrote is worse than refusing to start, and it left `blob_hash` -- fixed at pool creation, unrecoverable afterwards -- protected by nothing but a log line. The design now has no state in which a CAS setting value is silently dropped. The price is a permanent reservation on twenty-five names inside a shared block, which the spec states outright rather than implying an open namespace: unlike the defect being fixed, that list is bounded, written down in three places, and a collision fails loudly with a one-line remedy. From the review: the aggregated warning is separated from the temporary application of legacy values and appears in the loader sketch; the landing order is fixed and made bisectable (Part 3 first, with a temporary `non_cas_keys` entry, because the still-scanning loader would otherwise reject the key it just moved -- and Part 2 hits the identical hazard, so it lands with Part 1); a key repeated in either spelling is rejected via an explicit repeat-index split, which Poco's `name[1]` rendering would otherwise let win silently; the state table's pre-change row is corrected; the rollout text is corrected; the gate is sized to the sweep, naming the stateless, integration, server-config and `WriteBufferFromS3` lanes plus a new CAS-over-Azure smoke; and startup-failure wording replaces "kills the server". The window-closing task is filed in the operability backlog with its trigger. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Answers a review of rev.3, plus one owner correction that changes a decision. Owner correction: once the migration window closes, an unprefixed CAS setting name is REJECTED, not ignored. Silently discarding a value an operator wrote is worse than refusing to start, and it left `blob_hash` -- fixed at pool creation, unrecoverable afterwards -- protected by nothing but a log line. The design now has no state in which a CAS setting value is silently dropped. The price is a permanent reservation on twenty-five names inside a shared block, which the spec states outright rather than implying an open namespace: unlike the defect being fixed, that list is bounded, written down in three places, and a collision fails loudly with a one-line remedy. From the review: the aggregated warning is separated from the temporary application of legacy values and appears in the loader sketch; the landing order is fixed and made bisectable (Part 3 first, with a temporary `non_cas_keys` entry, because the still-scanning loader would otherwise reject the key it just moved -- and Part 2 hits the identical hazard, so it lands with Part 1); a key repeated in either spelling is rejected via an explicit repeat-index split, which Poco's `name[1]` rendering would otherwise let win silently; the state table's pre-change row is corrected; the rollout text is corrected; the gate is sized to the sweep, naming the stateless, integration, server-config and `WriteBufferFromS3` lanes plus a new CAS-over-Azure smoke; and startup-failure wording replaces "kills the server". The window-closing task is filed in the operability backlog with its trigger. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ten tasks. Task 1 moves the GCS conditional-PUT cap into the S3 settings and must land first: it adds the key to `non_cas_keys` in the same commit, because the still-scanning CAS loader would otherwise reject the key it just moved. Task 2 is the namespace itself, the migration window and the `skip_access_check` demotion, in one commit for the same bisectability reason. Tasks 3-7 are the sweep, one commit per class, each with the lane that can actually see a miss -- the migration window is what makes them independently revertable. Task 8 adds a CAS-over-Azure smoke, the case that proves the claim rather than restating it. Task 9 is the full gate; Task 10 places the window-closing follow-up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two blockers, both confirmed against the code. The CAS-over-Azure smoke could never have passed. A non-Local object storage opens in Native mode, which requires enforced conditional operations; Azure implements neither `removeObjectIfTokenMatches` nor the single-attempt retry profile, and the base implementations refuse by design so the capability probe fails closed. "The CAS parser accepts Azure keys" and "Azure can host a CAS pool" are different claims and only the first is true. The spec now states that boundary, and the plan proves the reachable claim end to end instead, on the keys from the field report. Four commit steps staged whole directories despite the plan's own exact-paths rule; `utils/ca-soak` carries another session's edits and untracked run artifacts, so they would have committed foreign changes. Every sweep task now records its file list before editing and stages from that list, and the final cleanliness check diffs against a baseline recorded before the first edit. Also: the claim that the moved GCS cap had no unit seam was wrong -- the fake S3 client fixture already builds a real S3ObjectStorage, four sites in it pass the cap into the constructor Task 1 removes, and none of them asserts the cap is enforced, so the plan converts all four and adds the missing test; the migration warning is now asserted (one aggregated line, every legacy key, silence after a full migration) via the log-capture pattern already used in the CAS tests; the stateless selectors are derived from the recorded sweep list instead of a hand-picked subset; the final sweep check covers all five classes rather than XML alone; and the includes Task 2 needs are named. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts: # docs/superpowers/specs/2026-08-25-cas-disk-settings-namespace-design.md
`gcs_max_conditional_put_bytes` is a property of the GCS conditional-write dialect, not a CAS policy: it takes effect only on a generation-token store, and what CAS owns is the policy that such a write must not go multipart. That policy is already a per-write flag. Only the number was in the wrong place. The setting moves to `S3AuthSettings`, beside `gcs_issue_compose_request`, keeping its config spelling, and `S3ObjectStorage` applies it itself when the write carries the flag. `WriteSettings::s3_single_part_upload_max_bytes_override` had exactly one producer and disappears with it. The key is added to the CAS `non_cas_keys` skip-list in this commit so that the still-scanning CAS loader keeps accepting it; the whole list is removed next. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A CAS disk block is shared with the object storage, the generic disk layer and the proxy resolver, and the CAS settings were the only consumer in it that scanned every key and rejected whatever was not in a hand-written skip-list. Any legal key nobody had enumerated failed server startup: all `s3_*` request settings, most S3 client settings, repeated `<header>` elements, `<proxy>`, and every Azure key, so a CAS disk over Azure could not be configured at all. The CAS settings now live under a `cas_` config-key prefix and nothing else in the block is read, so the skip-list is gone with nothing in its place. A mis-spelled CAS setting is still rejected, because that check is now made over a namespace CAS actually owns. The unprefixed spelling is accepted for a bounded period, since configurations using it already exist in external CI/CD scripts; each disk reports its superseded keys once. A key written in both spellings, or twice in one spelling, is rejected rather than resolved silently. `skip_access_check` keeps its bare spelling and stops being a CAS setting: the generic disk layer reads the same key, and one key must not become two. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Classify duplicate and ambiguous `cas_` settings before parsing values, logging migration success, or changing the settings object. This keeps malformed values from masking the required fail-closed exceptions.
Validate every owned `cas_` and legacy setting in a temporary settings state before reporting migration success or changing the live configuration.
Run `loadFromConfig` post-processing and semantic validation on the temporary CAS settings state before reporting migration success or replacing the live state.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`http_keep_alive_timeout` in a CAS disk block used to fail server startup, which is what blocked the mitigation suggested in #2243. The CAS integration disk now carries that key and five more of the same class, so the lane fails if the disk block ever stops accepting them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Operator-facing XML snippets still advertised `server_root_id` and `blob_hash_allow_new` after CAS keys moved to the `cas_` namespace. Use `cas_server_root_id` and `cas_blob_hash_allow_new`, and pin the hash-admission exception in the pluggable-hash suite.
Report externally configured CAS settings with their `cas_*` names in validation, parser failures, staging capability checks, and mount-recovery guidance. Preserve the original prefixed spelling for unknown keys while keeping internal setting names and persisted fields unchanged. Refresh stale integration comments to describe namespace ownership instead of the deleted `non_cas_keys` list.
(cherry picked from commit 058b678)
(cherry picked from commit f76335f)
Signed-off-by: CarlosFelipeOR <carlosfelipeor@gmail.com> (cherry picked from commit cc73c9b)
Signed-off-by: CarlosFelipeOR <carlosfelipeor@gmail.com> (cherry picked from commit 3f288c1)
(cherry picked from commit eac9fc9)
(cherry picked from commit 5d14298)
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.
Changelog category (leave one):
Changelog entry (a user-readable short description of the changes that goes to CHANGELOG.md):
content addressable storage - draft PR
Documentation entry for user-facing changes
TBD.
Exclude tests:
Regression jobs to run: