Commit 0e37824
fix(client): split the conflated hash in registerEnv, so an inline secret can register (#157)
* fix(client): split the conflated hash in registerEnv, so an inline secret can register
Closes serve-stack KNOWN-ISSUES 20. `env.register()` carrying
`secrets: { KEY: { inline: … } }` threw IntegrityMismatchError against any real
StorageProvider — unconditionally, on both shipped secret stores.
ROOT CAUSE. One value was asked to be two incompatible things. The hash was
computed from the def while its secretRefs still held PLACEHOLDER names, then
staging replaced each placeholder with a store-returned ref that is fresh on
every call (`local-secret://<uuid>`, or a random-suffixed ARN), and the mutated
def was written at a URI carrying the pre-staging hash. `putBlob` re-hashes what
it stores and correctly rejected the mismatch.
Idempotency key needs to be STABLE across stagings -> must EXCLUDE the fresh ref
Content address needs to EQUAL the bytes stored -> must INCLUDE the fresh ref
FIX. Separate the roles. `idempotencyKey` stays the placeholder-derived hash;
`contentHash` becomes the hash of the bytes actually written, so a `sha256:` URI
describes its own contents again and putBlob's check passes because it is TRUE,
not because it was relaxed. This also aligns the client with the worker, which
already hashes the fetched BYTES (bundle-fetcher.ts:113) — the placeholder hash
was wrong at both ends.
The idempotency key is persisted in the blob, because after the split
`resolveLatest` reports the content address and there is nowhere else to read it
from. A bundle registered before this change carries no key, reads as undefined,
and is treated as not-idempotent: it re-registers once and is stable thereafter.
The UUID stays, deliberately: it keeps the ref opaque in a blob that
content-addressed storage hands to any reader, avoids clobbering a value an
in-flight dispatch is mid-resolve() on, and gives each staging its own TTL.
AND FIXED THE INSTRUMENT. The unit stub read the content hash out of the URI and
never recomputed it, so it accepted a pinned URI whose hash did not match its
bytes — which is exactly how an unconditionally-broken path shipped under a green
suite. The stub now enforces what a real provider enforces. Mutation-verified:
re-introducing the defect turns the PRE-EXISTING env-register tests red, where
before they stayed green.
New tests run against the REAL LocalStorageProvider, in `pnpm -r test` rather
than the Docker-gated lane CI never runs — this defect's survival is attributable
to that lane, so a fix verified only there would be unverified in practice.
NOT VERIFIED: that AwsSecretStore fails and is fixed identically. Its ref is a
random-suffixed ARN so the mechanism is the same by construction, but there are
no AWS credentials in this environment and the claim rests on reading, not
running.
Repo-wide: build, lint, typecheck clean; every package's suite green.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: record issue 20 as fixed, and that the AwsSecretStore half stays unverified
Follows the code fix in this branch.
- KNOWN-ISSUES 20 -> FIXED, naming both halves: the split itself, and the
correction to the unit stub that hid it. The stub fix is called out as the
more durable half — it is the instrument, and every test built on it was blind
to this class of defect.
- The at-a-glance table's "issue 20 is the only outright breakage left" line is
replaced rather than deleted: nothing is currently known-broken, what remains
is one open feature request (17's base-tree/patch half) and one unverified
claim.
- The design spec is marked IMPLEMENTED, keeping its original status visible.
The unverified AwsSecretStore half is stated in all three places rather than
quietly dropped. Its spec §5 AC6 says silence is not acceptable there, and a
fix that reads as covering both stores when only one was exercised is exactly
the overclaim this project's threat model warns against.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 64a2ffe commit 0e37824
5 files changed
Lines changed: 288 additions & 46 deletions
File tree
- deploy/serve-stack
- docs/superpowers/specs
- packages/pangolin-client
- src
- test
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
| 39 | + | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
42 | 44 | | |
43 | 45 | | |
44 | 46 | | |
| |||
2527 | 2529 | | |
2528 | 2530 | | |
2529 | 2531 | | |
2530 | | - | |
2531 | | - | |
2532 | | - | |
2533 | | - | |
2534 | | - | |
2535 | | - | |
2536 | | - | |
2537 | | - | |
2538 | | - | |
| 2532 | + | |
| 2533 | + | |
| 2534 | + | |
| 2535 | + | |
| 2536 | + | |
| 2537 | + | |
| 2538 | + | |
| 2539 | + | |
| 2540 | + | |
| 2541 | + | |
| 2542 | + | |
| 2543 | + | |
| 2544 | + | |
| 2545 | + | |
| 2546 | + | |
| 2547 | + | |
| 2548 | + | |
| 2549 | + | |
| 2550 | + | |
| 2551 | + | |
| 2552 | + | |
| 2553 | + | |
| 2554 | + | |
| 2555 | + | |
| 2556 | + | |
| 2557 | + | |
| 2558 | + | |
| 2559 | + | |
2539 | 2560 | | |
2540 | 2561 | | |
2541 | 2562 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
| 103 | + | |
107 | 104 | | |
108 | 105 | | |
109 | 106 | | |
| |||
142 | 139 | | |
143 | 140 | | |
144 | 141 | | |
145 | | - | |
146 | | - | |
147 | | - | |
| 142 | + | |
148 | 143 | | |
149 | 144 | | |
150 | 145 | | |
| |||
162 | 157 | | |
163 | 158 | | |
164 | 159 | | |
165 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
166 | 173 | | |
167 | 174 | | |
168 | 175 | | |
| |||
176 | 183 | | |
177 | 184 | | |
178 | 185 | | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
179 | 192 | | |
180 | | - | |
| 193 | + | |
181 | 194 | | |
182 | 195 | | |
183 | 196 | | |
184 | | - | |
| 197 | + | |
| 198 | + | |
185 | 199 | | |
186 | 200 | | |
187 | 201 | | |
| |||
206 | 220 | | |
207 | 221 | | |
208 | 222 | | |
209 | | - | |
210 | | - | |
211 | | - | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
212 | 242 | | |
213 | 243 | | |
214 | 244 | | |
215 | 245 | | |
216 | 246 | | |
217 | 247 | | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
223 | | - | |
224 | | - | |
225 | | - | |
226 | | - | |
227 | | - | |
228 | | - | |
229 | | - | |
| 248 | + | |
230 | 249 | | |
231 | 250 | | |
232 | 251 | | |
233 | 252 | | |
234 | 253 | | |
235 | 254 | | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
Lines changed: 163 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
0 commit comments