Plan: Document the command placeholder contract in the README (4.4.1) - #699
Draft
leynos wants to merge 3 commits into
Draft
Plan: Document the command placeholder contract in the README (4.4.1)#699leynos wants to merge 3 commits into
leynos wants to merge 3 commits into
Conversation
Add the ExecPlan for roadmap item 4.4.1, which adds a "Security and command interpolation" section to the README and settles the three contract questions that docs/formal-verification-methods-in-netsuke.md leaves open. Ground truth was established by reading src/ir/cmd_interpolate/ rather than by trusting existing prose, and three findings shaped the plan: - `$in` and `$out` ARE substituted in `script:` recipes though not in `command:` recipes, contradicting docs/developers-guide.md and docs/formal-verification-methods-in-netsuke.md; - the backtick guard is a whole-string odd-parity count, not a quoting-aware model, and does not defend against author-written command substitution; - `shlex::split` gates POSIX and Bash `command:` recipes only, never `script:` recipes and never PowerShell. The plan therefore spans five milestones: a new ADR recording the three decisions, the README section with two executable examples, correction of the two inaccurate internal documents, the six translated READMEs, and the roadmap closure. Because tests/documentation_examples/ requires a `tested-example` marker on every README fence and compares identifiers for exact set equality, adding the section is a test change as well as a prose change. That gives the item a genuine red-green cycle, which the verification plan uses to make each documented claim falsifiable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fold a six-lens design review into revision 2 of the ExecPlan. The
review found four factual errors in revision 1 and two obligations
that should have existed and did not.
Blocking corrections:
- EP-M2 (document corrections) now precedes the README milestone and
covers docs/users-guide.md:1697,1713, which also contradict the
script-recipe placeholder behaviour. Revision 1 would have shipped a
README that contradicted the very page it links to.
- The negative controls now run after the README is committed and
restore by file copy. Revision 1 ran them first and restored with
`git checkout -- README.md`, which would have deleted the section it
had just written.
- OBL-PLACEHOLDERS' negative control was non-discriminating:
UndefinedBehavior::Strict makes an undefined `{{ inputs }}` fail
during rendering, before marker recognition is reached.
- Two obligations added. OBL-RECIPE-KIND covers the plan's own headline
finding, and OBL-QUOTING covers the section's only positive security
promise. Neither had any test in revision 1.
Factual corrections: assert_shell_command is in src/ninja_gen/mod.rs,
not src/ninja_gen_recipe_shell.rs; `shlex = "2.0.1"` is a caret
requirement, not a pin; the registry test is
every_documented_fence_has_a_known_unique_identifier; and
docs/netsuke-design.md already states the contract correctly and must
not be touched.
Rewording: D2 now promises the marker invariant and the backtick parity
check at different strengths, so a future quoting-aware fix is not a
breaking change. D3 names both shlex drift directions and states that
passing the gate does not make a command safe. D1 frames the
script-only $in/$out forms as retained legacy with a shadowing warning
and raises D1-LEGACY for the owner.
The README section order was inverted to put the live hazards before
the placeholder table, and the templated-value injection vector was
promoted out of a bullet list into its own labelled part. Scope
tolerance was raised to 18 files / 1200 lines, because the review
showed the original would fire on the plan's own expected path.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueComment |
Contributor
Reviewer's GuideThis planning-only PR introduces a revision-2 ExecPlan for roadmap item 4.4.1, specifying how the command interpolation contract will be documented, tested through executable README examples and negative controls, propagated across documentation and translations, and recorded in ADR-021; no implementation changes are included. Flow diagram for planned command placeholder handlingflowchart TD
Recipe{Recipe kind}
Recipe -->|command| Command[Rewrite ins and outs]
Recipe -->|script| Script[Rewrite ins outs and legacy dollar aliases]
Command --> Guard[POSIX or Bash validation gates]
Script --> ScriptResult[Generate script text]
Guard -->|accepted| CommandResult[Generate command text]
Guard -->|rejected| Invalid[Invalid command interpolation]
CommandResult --> Quoted[Own path substitutions are shell-quoted]
ScriptResult --> Quoted
Flow diagram for planned documentation and verification milestonesflowchart LR
Decisions[ADR-021 decisions D1 D2 D3] --> Corrections[Correct internal documentation]
Corrections --> README[README contract and examples]
README --> Tests[Executable examples and negative controls]
README --> Translations[Six translated READMEs]
Tests --> Gates[Validation gates]
Translations --> Parity[README structural parity]
Gates --> Closure[Close roadmap item 4.4.1]
Parity --> Closure
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
The `spelling` gate rejects "hand-written". The plan already used "handwritten" in the other of its two occurrences, so this also makes the document internally consistent. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Plans roadmap item 4.4.1, which adds a "Security and command interpolation" section to the README and settles the three contract questions that
docs/formal-verification-methods-in-netsuke.md§Command placeholder contract leaves open.No implementation yet — this PR is the plan, and it needs approval before anything is built.
ExecPlan:
docs/execplans/4-4-1-document-command-placeholder-contract-in-readme.mdWhat the ground truth turned out to be
The contract was established by reading
src/ir/cmd_interpolate/rather than bytrusting the existing prose, and three findings shaped the plan:
$inand$outare rewritten inscript:recipes, though not incommand:recipes (find_script_substitution,src/ir/cmd_interpolate/mod.rs:269-297). Three documents state the oppositewithout qualification.
(
has_unmatched_backticks,src/ir/cmd_interpolate/mod.rs:172-174), not aquoting-aware model. It does not defend against author-written command
substitution: a balanced pair reaches the shell and executes.
shlex::splitgates POSIX and Bashcommand:recipes only — neverscript:recipes, never PowerShell — and is never used to build an argv.The three decisions
{{ ins }}/{{ outs }}in both recipe kinds;$in/$outinscript:only, documented as retained legacy with a shadowing warningrather than as a blessed feature.
documented as a conservative check that a future release may widen without
that being a breaking change; author-written backticks carry no guarantee at
all.
shlexrejection is contractual; the precise accepted set isnot, because
Cargo.toml:138is a caret requirement rather than a pin. Bothdrift directions are named, and the README states that passing the gate does
not make a command safe.
Why this is not a documentation-only change
tests/documentation_examples/requires a<!-- tested-example: ... -->markeron every README fence and compares identifiers for exact set equality. Adding
the section is therefore a test change too, which gives the item a genuine
red-green cycle. Five verification obligations make each documented claim
falsifiable, with three negative controls including a seeded mutation from
docs/verification/mutations/.Scope
Five milestones: ADR-021 recording the decisions; correction of the three
inaccurate documents (deliberately before the README, so the repository is
never in a state where two normative documents disagree); the README section
with three executable examples; the six translated READMEs, preserving their
current section-for-section parity; and the roadmap closure.
Review
A six-lens community-of-experts design review ran against revision 1 and found
four factual errors in the plan plus two obligations that should have existed
and did not — notably that the plan's own headline finding had no test behind
it, and that the section's only positive security promise was unasserted.
Revision 2 folds all of it in; the
Revision noteandSurprises & discoveriessections record what changed and why.
One decision,
D1-LEGACY, is flagged as awaiting the owner's confirmation: theevidence is genuinely ambiguous about whether the
script:-only$in/$outforms are intended or vestigial. The plan is written so that either answer
leaves the documentation honest.
References
🤖 Generated with Claude Code
Summary by Sourcery
Approve and execute the plan for documenting Netsuke’s command placeholder and shell-interpolation contract across the project.
Enhancements:
shlex::splitrejection guard.Documentation:
Tests:
shlexcoverage.Chores: