Skip to content

${...} placeholders in authored metadata resolve to nothing and reach the consumer verbatim — the masked-failure escape #8078 measured, now load-bearing for two refusal messages #8336

Closed

Description

@hotlong

Found while implementing #8082 (session session_01Euoy6wyfzgiWtgCg4s6JK2); measured originally during #8078 (#7990 census): a ${...} placeholder written in authored metadata (e.g. a datasource config.url of postgresql://${DB_HOST}/db) is resolved by nothing — it is stored verbatim in sys_metadata and handed verbatim to the database client at connect. The author believes environment substitution happens; the connection then fails (or connects somewhere unintended) with no error pointing at the unresolved placeholder — the masked-failure shape.

Why this now needs its own card

Two shipped refusal messages are written AROUND this defect rather than through it:

Decision shape (for triage)

Two honest directions, mutually exclusive:

  1. Implement resolution: define where ${ENV} in authored metadata is substituted (presumably at connect/render in services, never at rest), and which keys participate. Cost: a real capability with a security surface (env exfiltration via metadata authorship needs thought — who can author metadata that reads arbitrary server env vars?).
  2. Refuse loudly at publish: placeholder syntax in connection-material keys is rejected with "placeholders are not resolved here" guidance, making the non-capability explicit (declared = enforced; startup-focus favors this until a real pull exists).

Either ends the silent half. The worst state is the current one: syntax that looks supported, stores fine, and fails at a distance.

Refs: #7990 (census measurement), #8078 (pinned "refuses a placeholder value exactly like a real one — the KEY is the sink"), #8082 (ruling naming this escape as binding context).


Generated by Claude Code

Activity

  1. added
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 13, 2026
  2. hotlong commented on Aug 13, 2026

    @hotlong
    ContributorAuthor

    Triage: needs-user-decision — the filer frames this as two mutually-exclusive honest directions and that's correct: this is a scope call, not a bug fix.

    Four-axis read:

    Recommendation: option 2 — refuse ${...}-shaped values loudly at publish in connection-material keys, with guidance pointing at the real escape (credentialsRef / bound secrets, per the #8082 family). Revisit option 1 only if a real deployment need for environment-driven config surfaces later; implementing a security-sensitive capability speculatively is exactly the kind of scope creep the startup-stage principle warns against.


    Generated by Claude Code

  3. hotlong commented on Aug 13, 2026

    @hotlong
    ContributorAuthor

    Maintainer ruling — direction 2 (refuse loudly at publish)

    Ruled by the maintainer in a live PM session, 2026-08-13 (session session_015XyMgCSMGGn9oSwbQEeWYg), verbatim: 「其他全部接受你的建议。」 — accepting direction 2 as recommended.

    Ruling: direction 2. Placeholder syntax (${...}) in connection-material keys is rejected at publish with explicit "placeholders are not resolved here" guidance. Direction 1 (implement resolution) is rejected for now: it is a real new capability with a real security surface (metadata authors reading arbitrary server env vars) and zero measured pull for actual substitution — declared = enforced favours making the non-capability explicit. If a real pull materialises later, implementing resolution supersedes the refusal via a new decision card.

    Implementation notes for dispatch:

    Label swap: needs-user-decision → pm:queue + domain:spec.


    Generated by Claude Code

  4. added
    pm:queueReady for the PM dispatch loop
    domain:specDomain lane — seat card indexed by label:pm:seat
    and removed
    needs-user-decisionBlocked on a maintainer decision — do not dispatch; decision cards only, never on a PR
    on Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:specDomain lane — seat card indexed by label:pm:seat

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions