feat(provisioner): allow system-prompt.md through the asset channel (de-bake concierge) #3246
Reference in New Issue
Block a user
Delete Branch "feat/asset-channel-system-prompt-allowlist"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Allows
system-prompt.mdthrough the asset-channel allowlist (IsCPTemplateAssetPath), which previously permitted onlyconfig.yaml+prompts/*.system-prompt.mdis the SSOT concierge/agent prompt filename (runtime default + what the platform-agent template ships + the key core substitutes{{CONCIERGE_NAME}}into). Without this it can't be delivered live, forcing the concierge onto the bakedmolecule-platform-agentimage. This is the key unblock for the de-bake migration — concierge gets its identity via the asset channel on the standard runtime image (MCP already via plugin).Guardrail:
TestIsCPTemplateAssetPath_AllowsSystemPromptMd— narrowing the allowlist back boots the concierge identity-less and fails CI (review guardrail G6/G0).The asset-channel allowlist (IsCPTemplateAssetPath) permitted only config.yaml + prompts/*, so the concierge's identity prompt — system-prompt.md, the SSOT filename the runtime loads, the platform-agent template ships, and core substitutes {{CONCIERGE_NAME}} into — could NOT be delivered live. That forced the concierge onto the baked molecule-platform-agent image to get its identity. Allow system-prompt.md so a kind=platform concierge gets its identity LIVE on the standard runtime image — the key unblock for removing the special baked image (everything dynamic: identity via asset channel, MCP via plugin). Guardrail: TestIsCPTemplateAssetPath_AllowsSystemPromptMd — narrowing the allowlist back would boot the concierge identity-less and fail CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>APPROVE — exact-match name=="system-prompt.md" added AFTER filepath.Clean. Adversarial traversal probe (../system-prompt.md, x/system-prompt.md, /system-prompt.md, foo/../../system-prompt.md, system-prompt.md.bak, evil-system-prompt.md) ALL rejected; only system-prompt.md + ./system-prompt.md admitted. Narrower than the existing prompts/ prefix rule. Prove-fail test confirmed.
APPROVE (security). Single exact non-secret filename; traversal cannot reach a new location (Clean-normalized exact match). Upstream traversal guard at cp_provisioner.go addAsset + gitea_template_assets.go fetcher unchanged; fail-closed posture intact. Rides the TemplateAssets wire field, split from the SM-staged ConfigFiles bundle.
qa 5-axis review on current head
76db4b2826: APPROVE.Correctness: IsCPTemplateAssetPath now admits exactly the SSOT prompt filename system-prompt.md in addition to config.yaml and prompts/*, unblocking live concierge identity delivery through the asset channel. The match is an exact filename match after the existing filepath.Clean/ToSlash normalization; traversal remains governed by the existing caller-side traversal invariant documented in template_assets.go. Robustness: the change is narrowly scoped to one allowlist entry and has a prove-fail guardrail test for system-prompt.md delivery. Security: no glob/prefix broadening, no secrets or agent-owned files are admitted, and existing traversal/path namespace tests remain in place. Performance: constant-time allowlist check. Readability: rationale comment is clear and tied to the de-bake migration.
APPROVED: independent 5-axis review on head
76db4b2826.Correctness: the allowlist adds only the exact cleaned path system-prompt.md alongside existing config.yaml/prompts/ handling; no glob or prefix expansion was introduced. Robustness: existing caller-side path normalization/traversal invariant is unchanged, and the test proves the new exact asset path is accepted without widening other paths. Security: no new traversal surface beyond the pre-existing Clean/ToSlash behavior; the added rule is a single filename equality check. Performance/readability: constant-time check, simple and consistent with the existing allowlist shape.