Skip to content

[bug-fix] Fix preset-wrap-drops-argument-hint: inherit argument-hint from core template - #3996

Merged
mnriem merged 2 commits into
mainfrom
fix/3991-preset-wrap-drops-argument-hint-6fc1afa14c852556
Aug 10, 2026
Merged

[bug-fix] Fix preset-wrap-drops-argument-hint: inherit argument-hint from core template#3996
mnriem merged 2 commits into
mainfrom
fix/3991-preset-wrap-drops-argument-hint-6fc1afa14c852556

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Bug fix — preset-wrap-drops-argument-hint

Proposed fix for issue #3991, applying the remediation from the bug assessment.

Verdict: Valid · Severity: medium

Summary

Extended the inheritance allowlist in _register_skills and _compose_layers to include argument-hint, so wrap-strategy presets that omit this key now inherit it from the core template instead of silently dropping it (and risking its value being leaked/concatenated into description).

Changes

File Change Notes
src/specify_cli/presets/__init__.py modified Added "argument-hint" to two inheritance allowlists (lines ~2746 and ~5728)
tests/test_presets.py added test test_wrap_preset_inherits_argument_hint_from_core — pins the regression

Tests Added or Updated

  • tests/test_presets.py::TestSkillsPreset::test_wrap_preset_inherits_argument_hint_from_core — installs a wrap preset with no argument-hint in its frontmatter against a core template that declares it, then asserts (a) argument-hint is present in the generated SKILL.md with the correct value, and (b) description is exactly the preset's declared string (not a concatenation including the hint value).

Local Verification

  • No project test command could be exercised in this environment (no virtualenv with dependencies available). Fix verified by code inspection: the two changed loop bodies now include "argument-hint" in the key set, which feeds the existing apply_argument_hint dict-based path at line 2781 — the same path PR fix(presets): preserve argument-hint in preset SKILL.md generation #2978 proved correct for the explicit-declaration case.

Deviations from Assessment

None. The fix matches the preferred remediation exactly: one-line addition of "argument-hint" to the allowlist tuple in each of the two locations named by the assessment.

Risks & Review Notes

  • Adding argument-hint to the inheritance allowlist could silently inherit a core value that a preset author intended to omit. Risk is low: argument-hint is a UX hint for Claude's slash-command input only, not a functional directive.
  • The _compose_layers change affects the composed-file path used by non-skills agents; the existing integration tests for those agents should be run during CI.
  • No API breakage: adding argument-hint to a SKILL.md is additive.

Refs #3991 · cc @takaya0

Generated by 🛠️ Fix Bug from Labeled Issue for issue #3991 · 991.9 AIC · ⌖ 16.7 AIC · ⊞ 38K ·

Apply the remediation from the bug assessment on issue #3991.
Extend the inheritance allowlist in _register_skills and _compose_layers
to include 'argument-hint', so wrap-strategy presets that omit this key
will inherit it from the core template rather than silently dropping it
and risking its value being leaked into description.

Refs #3991

Assisted-by: GitHub Copilot (model: claude-sonnet-4.6, autonomous)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added automated bug-fix Trigger the bug-fix agentic workflow labels Aug 5, 2026
@mnriem
mnriem marked this pull request as ready for review August 5, 2026 15:43
@mnriem
mnriem self-requested a review as a code owner August 5, 2026 15:43
Copilot AI balanced review requested due to automatic review settings August 5, 2026 15:43

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes wrap-strategy presets so argument-hint is inherited from core command metadata.

Changes:

  • Adds argument-hint to both composition allowlists.
  • Adds a regression test, though coverage gaps remain.
Show a summary per file
File Description
src/specify_cli/presets/__init__.py Inherits argument-hint during command and skill composition.
tests/test_presets.py Tests core argument-hint inheritance.

Review details

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 3
  • Review effort level: Balanced

Comment thread tests/test_presets.py
Comment thread tests/test_presets.py
Comment thread src/specify_cli/presets/__init__.py
The existing regression test for #3991 wraps `speckit.specify`, whose stem
is in Claude's ARGUMENT_HINTS map. The string-injection fallback in
post_process_skill_content re-adds argument-hint even when wrap composition
drops it, so that test passes with or without the inheritance fix and does
not actually guard the regression.

Add a parallel test that wraps an extension-like command
(`speckit.myfeature`) absent from ARGUMENT_HINTS, so the wrap-composition
inheritance is the only path that can carry argument-hint into the SKILL.md.
This test fails without the fix and passes with it.

Refs #3991

Assisted-by: GitHub Copilot (model: claude-opus-4.8, autonomous)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 970babe2-48cd-4c41-adae-0282d879a9ce
@mnriem

mnriem commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Ran the bug-test stage locally (the CI bug-test run was inconclusive — the runner's firewall blocked PyPI, so pytest never ran).

Findings:

  • The fix in _register_skills/_compose_layers is correct; full tests/test_presets.py suite passes.
  • However, the shipped regression test test_wrap_preset_inherits_argument_hint_from_core passes with and without the source fix, so it does not actually guard the regression. It wraps speckit.specify, whose stem is in Claude's ARGUMENT_HINTS map, so post_process_skill_content's string-injection fallback re-adds argument-hint regardless of the inheritance fix (and the test's chosen hint value happens to equal ARGUMENT_HINTS['specify']).

Change pushed (581c3ac): added test_wrap_preset_inherits_argument_hint_for_unmapped_command, which wraps an extension-like command (speckit.myfeature) absent from ARGUMENT_HINTS. Verified it fails without the source fix and passes with it — a genuine regression guard. Full suite: 581 passed.

Posted on behalf of @mnriem by GitHub Copilot (model: claude-opus-4.8, autonomous).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review details

  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@mnriem
mnriem merged commit 1a60d1b into main Aug 10, 2026
16 checks passed
@mnriem
mnriem deleted the fix/3991-preset-wrap-drops-argument-hint-6fc1afa14c852556 branch August 10, 2026 15:19
mnriem pushed a commit that referenced this pull request Aug 11, 2026
…tions (#4045)

* fix(claude): make argument-hint injection fold-aware for long descriptions

ClaudeIntegration.inject_argument_hint spliced argument-hint: "..." as a
raw text line right after the first line starting with "description:".
When a description is long enough for the YAML dumper to fold it across
indented continuation lines, that splice landed inside the scalar,
producing invalid YAML (plain scalar) or silently absorbing the hint
into the description string (quoted scalar). This reproduces #3991 for
the case #3996 didn't cover: bundled core commands have no argument-hint
in their source frontmatter, so the structural apply_argument_hint path
is a no-op and this raw-text fallback is what actually runs.

Skip every continuation line of the description scalar (anything more
indented than the key itself) before inserting, so the new key always
lands after the whole scalar ends rather than in the middle of it.

Fixes #4044

* fix(claude): also skip unindented blank lines in description scalar

PyYAML serializes an embedded paragraph break ("\n\n") inside a quoted
description as unindented blank lines, not indented continuation
lines. inject_argument_hint only skipped indented lines, so it still
inserted argument-hint mid-scalar for multi-paragraph descriptions,
reproducing the #4044 failure modes. Skip blank lines too, and add a
regression test for the multi-paragraph case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated bug-fix Trigger the bug-fix agentic workflow

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: preset wrap composition drops core argument-hint and leaks its value into description

2 participants