docs(design): conduit generate — AI-assisted pipeline generation#2647
Merged
Conversation
Design doc for `conduit generate` (v0.19 roadmap item), incorporating an independent review pass that hardens the prompt-injection trust boundary: corrects the confirm-precedent claim and names deploy.confirm()'s unconditional stdin read as the anti-pattern generate must not copy, anchors the human deploy decision on the diff + semantic-check results rather than unverified model rationale, reframes the "no code execution surface" argument to account for pipeline-as-exfiltration-channel risk, specifies --out basename sanitization, adds an MCP cost-amplification failure mode, relaxes the ambiguous_prompt pre-call refusal to be conservative, and tightens the fuzzymatch/semantic-score/timeout specs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ust-fixes Reframe the v0.19 scope to design doc + eval harness only; the command build is deferred to v0.20+ (Python connector SDK took the v0.19 build slot). Fold in the DX/security review findings: - Record the validate.Run/RunWithOptions disk seam: both take a file path and read from disk, so "nothing touches disk before preview" contradicts "candidate passes validate". Resolve with a RunBytes/RunReader in-memory seam (preferred) or a crash-cleaned temp-file lifecycle (fallback). - State the injection threat precisely: deploy.confirm() declines on EOF, so the hole is a piped `y\n`, not non-TTY in general; the isatty gate on both stdin and stdout is the mitigation. - Require the retry loop to bound the validate.Report feedback fed back into the model prompt (typed fields, capped count, truncated values), with a testable assertion. - Record Claude Sonnet 5 as the anthropic adapter default (approved). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015GQFzakPShAYj8CcwajYDD
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.
Summary
Design doc for
conduit generate(v0.19 roadmap item, Agent-native section) — a natural-language-to-pipeline-config command, gated by the existingvalidateengine plus a new deterministic semantic-intent checker, with deployment only ever reachable through a TTY-confirmed hand-off to the existingdeploy/applymachinery.Status: APPROVE-WITH-CHANGES. This revision applies an independent review pass focused on hardening the prompt-injection trust boundary before any code is written. No feature code in this PR — doc only, per CLAUDE.md's design-doc-before-code rule.
Findings applied
pipelines deploy --apply'sconfirm()(cmd/conduit/root/pipelines/deploy.go:198-212) already reads a line fromcmd.InOrStdin()unconditionally, with no isatty gate, so a pipedyis read as affirmative even non-interactively. The doc now statesgenerateMUST isatty-gate both stdin and stdout before reading any confirmation, and MUST NOT reuse that unconditional-read shape — named explicitly in Context, Decision §4, the Upgrade/rollback ADR note, and the Testing section's load-bearing security-test bullet.[y/N]decision is now explicitly anchored on the YAML diff + deterministic semantic-check results (trusted);rationale/assumptions[]are called out as unverified model output, visually marked, never the primary basis for a yes/no. Also corrected §4's "no code-execution surface, therefore harmless" framing — a deployed pipeline is a data-movement primitive (source → external sink = exfiltration channel); the bound is now stated as "the deployed effect is limited to whatdeploy/applywould let any config do," not "schema-shaped therefore safe." Failure-mode npm: bump sinon from 9.2.4 to 12.0.1 in /ui #4 (prompt injection) updated to match.--outpath traversal. Specified that the model-controlled inferred filename is sanitized to a bare basename within cwd (path separators and..stripped/rejected);--outnever escapes the working directory without an explicit user-supplied path. Independent of the TTY/confirm boundary since it needs no confirmation at all. Added a corresponding Testing bullet.generatetool lets any connected agent trigger outbound LLM calls on the operator's key/cost with agent-controlled prompts;--max-retriesbounds one call, not calls-per-session. Named mitigation lever: a per-session call budget, or documented reliance on provider-side rate/spend caps until one exists.ambiguous_promptpre-call refusal too aggressive. Made the pre-call refusal conservative — refuses only clearly-empty/self-contradictory prompts; borderline prompts now pass through to the provider and are judged post-hoc by the semantic checker.ambiguous_promptis now documented as a post-hoc code as much as a pre-filter.provider_errorinstead of wedging, plus a one-line note that grounding-prompt size × retries is the token-cost lever.len(want)), case-insensitivity, and that plain Levenshtein (not Damerau) is adequate for v1.--yesreasoning and the--outsanitization reasoning, so both survive without archaeology.Test plan
npx markdownlint-cli2 --fix— clean, 0 errors🤖 Generated with Claude Code