Filed by the domain:spec seat 1 (session_01UtnxvdiN376GF3sgXwAw4d, seat post #6017) as an execution parameter of the maintainer's ruling A on #21263 (5945612493, batch #267 item 1, 「其他同意」). The ruling reads: "D1: the claiming seat files one card for ADR-0128 D1, scoped as ADR-0128 §2 and §4 state it (priority from triage). It is not this PR." ⛔ Not a claim. ⛔ Not graded here: priority and lane are triage's.
⚠️ Security family: this card names classes and positions only.
Why now
ADR-0128 (Accepted 2026-09-07) recorded D1–D3 as a direction and deferred the work (§4), naming four triggers that fund it. One of them is met: "ICryptoProvider is opened for another breaking change". PR #21292 (#21263) adds the required keyedDigest member. The ruling lands that break alone, because the organisation's repositories hold zero out-of-repo implementers (census 5945420994), so bundling would save a second break for no measured population. The deferral is therefore over, and this card schedules the work. A separate Tier H card carries ADR-0128's dated note.
Scope (ADR-0128 §2 and §4, as written)
- D1:
CryptoContext (packages/spec/src/contracts/crypto-provider.ts) carries a required scope discriminant from a closed set, with one member per producer: settings, object secret field and datasource credential. Every provider that binds AAD folds it in.
- D2: the AAD encoding is delimiter-safe: length-prefixed, escaped or canonical structured. ⛔ No unescaped join.
- D3: the fix is at the producer of the AAD (
ICryptoProvider and LocalCryptoProvider in packages/services/service-settings). ⛔ No consumer-side fallback that tries another vocabulary's AAD.
- §4.2, the expensive half: an at-rest rewrap of every existing ciphertext. It reads under the old AAD and writes under the new one, so the handle needs a version that says which derivation sealed it. The rewrap must be resumable, safe against a live deployment, and fail closed on any row it cannot read.
rotateKey is the seam §4 names.
- The producers to thread the discriminant through (ADR-0128's Consumers line): the settings service, the engine's secret-field path (
@objectstack/objectql) and the datasource secret binder (@objectstack/service-datasource). Out-of-repo, every cloud host constructs LocalCryptoProvider through a link: dependency (census 5945420994), so a framework change reaches them with the implementation.
What triage decides
- Priority, and whether this splits into stages, for example contract + provider + versioned handle first and the rewrap second. ADR-0128 §4's ordering note says both derivations must coexist during the migration.
- Lanes: the work spans
domain:spec (the contract) and domain:services (the provider and the producers).
- ⛔ This card does not reopen the direction (ADR-0128 D1–D4 stand). It only schedules them.
Dedupe
The 100 most recently updated open issues and PRs were listed over REST (repo-scoped) and grepped for ADR-0128, producer-discriminated and rewrap. The hits are seat post #6017 and PR #21292, the ruling's PR, and neither schedules D1. #12599 is the closed source card. #21263 is the ruling's anchor.
Dedupe words: ADR-0128 D1 producer-discriminated AAD · CryptoContext scope discriminant · sys_secret rewrap versioned handle
Filed by the
domain:specseat 1 (session_01UtnxvdiN376GF3sgXwAw4d, seat post #6017) as an execution parameter of the maintainer's ruling A on #21263 (5945612493, batch #267 item 1, 「其他同意」). The ruling reads: "D1: the claiming seat files one card for ADR-0128 D1, scoped as ADR-0128 §2 and §4 state it (priorityfrom triage). It is not this PR." ⛔ Not a claim. ⛔ Not graded here: priority and lane are triage's.Why now
ADR-0128 (Accepted 2026-09-07) recorded D1–D3 as a direction and deferred the work (§4), naming four triggers that fund it. One of them is met: "
ICryptoProvideris opened for another breaking change". PR #21292 (#21263) adds the requiredkeyedDigestmember. The ruling lands that break alone, because the organisation's repositories hold zero out-of-repo implementers (census5945420994), so bundling would save a second break for no measured population. The deferral is therefore over, and this card schedules the work. A separate Tier H card carries ADR-0128's dated note.Scope (ADR-0128 §2 and §4, as written)
CryptoContext(packages/spec/src/contracts/crypto-provider.ts) carries a required scope discriminant from a closed set, with one member per producer: settings, object secret field and datasource credential. Every provider that binds AAD folds it in.ICryptoProviderandLocalCryptoProviderinpackages/services/service-settings). ⛔ No consumer-side fallback that tries another vocabulary's AAD.rotateKeyis the seam §4 names.@objectstack/objectql) and the datasource secret binder (@objectstack/service-datasource). Out-of-repo, every cloud host constructsLocalCryptoProviderthrough alink:dependency (census5945420994), so a framework change reaches them with the implementation.What triage decides
domain:spec(the contract) anddomain:services(the provider and the producers).Dedupe
The 100 most recently updated open issues and PRs were listed over REST (repo-scoped) and grepped for
ADR-0128,producer-discriminatedandrewrap. The hits are seat post #6017 and PR #21292, the ruling's PR, and neither schedules D1. #12599 is the closed source card. #21263 is the ruling's anchor.Dedupe words: ADR-0128 D1 producer-discriminated AAD · CryptoContext scope discriminant · sys_secret rewrap versioned handle