fix(claude-k8s): carry the source volume's items selector through propagation (BLO-18927) - #1368
Merged
allyblockcast[bot] merged 2 commits intoAug 15, 2026
Conversation
…pagation (BLO-18927) getSelfPodInfo() captured only secretName/mountPath/defaultMode from each inherited secret volume, and buildJobManifest() rebuilt the volume without a key selector. A source mount projecting ONE key out of a multi-key Secret was therefore re-expanded into EVERY key of that Secret on the agent Job pod. Measured live: paperclip-api projects gbrain-plugin-service-key alone out of authbot-mcp-consumer-service-keys, while agent pods received all 7 keys — the agent held more key material than the container the mount was copied from. optional: true stays hardcoded at the mount site by design, so a Secret absent in the agent namespace still cannot hard-fail the Job. Refs BLO-18927 AC-3. Does NOT close BLO-22514, which needs the env allowlist. Co-Authored-By: Claude <noreply@anthropic.com>
Author
1 similar comment
Author
Co-Authored-By: Claude <noreply@anthropic.com>
This was referenced Aug 15, 2026
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.
Carries the source volume's
items:key selector through secret-volume propagation in the vendoredclaude_k8sadapter.Thinking Path
Linked Issues or Issue Description
Refs BLO-18927 (AC-3, "
items:selectors are preserved"). Related: BLO-22514.No GitHub issue exists — Paperclip issues are not mirrored as numbered GH issues. Stating the problem in full:
vendor/paperclip-adapter-claude-k8s/src/server/k8s-client.tsdiscovers the server pod's secret volumes and records four fields per volume.V1SecretVolumeSource.itemsis not among them.job-manifest.tsthen reconstructs each volume for the agent Job from those four fields, so the selector cannot be re-emitted even in principle.Measured against the live cluster:
paperclip-apimountsauthbot-mcp-consumer-service-keyswithitems: [gbrain-plugin-service-key]— exactly one key. Agent pods receive all 7 keys of that Secret (figma, gbrain, gbrain-plugin, google-docs, grafana, linear, webflow). The agent pod ends up holding more key material than the container the mount was copied from, which inverts the intent of the mount.items secret volume selector(0 results) against a positive control ofvendor claude-k8s(44 results), so the zero is a real absence rather than a broken query.What Changed
src/server/k8s-client.ts— addeditems?: k8s.V1KeyToPath[]toSelfPodSecretVolumeand populated it ingetSelfPodInfo(), copying the array ([...items]) rather than aliasing the cached pod spec.src/server/job-manifest.ts— spreaditemsback onto the reconstructed volume when the source had one.PROVENANCE.md— updated the CI-enforced integrity hash and added the Local-modifications row.Two deliberate choices worth reviewing rather than waving through:
optional: truestays hardcoded at the mount site. The source'soptionalis not propagated. Carrying it through could turn a propagated Secret that is absent in the agent namespace into a hard Job failure — a behaviour change with availability blast radius, and not what this PR is for. The comment at the mount site records this as intentional.itemsis optional (items?:) rather than required-with-undefined. This mirrorsV1SecretVolumeSource.itemsupstream and keeps the diff to the behaviour change; the required-with-undefinedshape used by the neighbouringdefaultModewould have forceditems: undefinednoise into four unrelated existing tests.Verification
Run in
vendor/paperclip-adapter-claude-k8s:The integrity-hash procedure was validated before being trusted: on the pristine tree it reproduces the previously recorded
75eba541…exactly, which is what makes the newfcce97c7…meaningful rather than just different.Five tests added — three on the capture half (newly possible;
k8s-client.test.tsdid not exist when this fix was first written), two on the mount half. All three guards are mutation-checked, so none of them passes for an unrelated reason:itemsspread at the mount sitepreserves the source volume's items selector…itemsat the capture sitecarries the source volume's items selector through capturevol.secret.itemsinstead of copying itcopies the items array rather than aliasing the pod specAll three mutations were reverted; the full suite is green on the committed tree.
Risks
Low, and strictly narrowing — but the scope limit is the important part.
PAPERCLIP_AGENT_JWT_SECRET,DATABASE_URL,GITHUB_APP_PRIVATE_KEY) from the inherited env and volume set. This PR only stops a scoped projection from being widened; a volume that already propagates wholesale still propagates wholesale. PR feat(vendor): bring claude_k8s adapter in-tree and retire CLAUDE_K8S_REF (BLO-17980) #1092 deferred the allowlist deliberately because dropping the wrong key breaks every agent, and that reasoning is unchanged.itemsstaysundefinedandoptionalstaystrue.PROVENANCE.mdis excluded from the integrity hash by design, so updating the table alongside the hash cannot itself perturb the value CI checks.Model Used
claude-opus-5[1m] via Claude Code, extended thinking with tool use — running as the Paperclip CTO agent.
Checklist
Fixes: #/Closes #/Refs #OR (b) described the issue in-PR following the relevant issue templatePROVENANCE.mdhash + local-modifications row🤖 Generated with Claude Code