Skip to content

T-OTX2-setup-seeds-pytest-permission

Status: closed/obsoleted · Impact: low · Complexity: small

Auto-generated from a /sdlc:task-work post-mortem. Review and promote to open/ready before picking up.

A project that adopts the plugin/lib/ + pytest.ini convention runs its quality checks through pytest, but Bash(pytest:*) is not granted by default — the first /sdlc:task-work run stalls on a permission prompt and needs a manual /config grant plus a uv run --with pytest fallback. This task has /sdlc:setup seed the Bash(pytest:*) permission when it detects a pytest-based project, so adoption doesn’t hit that wall on the first run. Surfaced by T-75LX-establish-plugin-lib-convention.

LocationRole today
plugin/skills/setup/SKILL.mdInitializes the docs/planning/<type>/ layout and seeds project config; does not seed a Bash(pytest:*) permission even when the project uses pytest
plugin/skills/find-quality-checks/Detects quality runners (via detect_quality_runners.py) and writes the quality_checks: list to sdlc.yaml; can identify pytest but does not wire up the corresponding Bash permission
.claude/settings.json (consumer project)Holds the project’s Bash permission allowlist; Bash(pytest:*) is absent until a human adds it via /config
plugin/skills/task-work/ (preflight_permissions probe)Correctly flags the missing pytest permission at task-pickup time — but only after the project has already adopted the convention

The originating post-mortem records the friction verbatim:

pytest was not on PATH / not permitted initially; needed a /config grant of Bash(pytest:*) plus a uv run --with pytest fallback. The preflight_permissions probe flagged it correctly; projects adopting this pytest-based lib convention should seed Bash(pytest:*) at setup.

The probe catching it is the correct safety net, but the ergonomic fix is to seed the permission proactively when setup already knows the project is pytest-based, so the first run doesn’t stall.

When /sdlc:setup (or /sdlc:find-quality-checks, whichever owns permission seeding) detects that the project uses pytest — a pytest.ini at the root, a pytest entry in the detected quality runners, or a plugin/lib/-shaped layout — it adds Bash(pytest:*) to the project’s .claude/settings.json permission allowlist. Idempotent: re-running setup on a project that already has the grant is a no-op.

  1. Decide the owner: /sdlc:setup vs /sdlc:find-quality-checks. The latter already probes for runners (detect_quality_runners.py) and knows when pytest is in play, so it’s the natural seeding point — but setup is what runs first on adoption. Resolve where the permission write lands (likely find-quality-checks writes the permission alongside the quality_checks: entry it already manages).
  2. Detect the pytest signal (root pytest.ini, a pytest quality verb, or the plugin/lib/ layout) and, when present, ensure Bash(pytest:*) is in .claude/settings.json’s permission allowlist.
  3. Make the write idempotent — skip if the permission is already present.
  4. Verify on a fresh pytest-based fixture project that setup leaves Bash(pytest:*) granted and that a second run is a no-op.
LocationKindChange
plugin/skills/find-quality-checks/SKILL.mdmodifyWhen pytest is among the selected runners, also seed Bash(pytest:*) into the project’s .claude/settings.json allowlist
plugin/skills/find-quality-checks/detect_quality_runners.pymodifySurface a pytest-detected signal the skill can act on for permission seeding (if not already exposed)
plugin/skills/setup/SKILL.mdmodifyCross-reference / trigger the permission seed when the adopted layout is pytest-based

(Ownership split between setup and find-quality-checks is the open decision in Approach step 1; the touched files narrow once that’s settled.)

  • AC-1: Running setup (or find-quality-checks) on a project with a root pytest.ini results in Bash(pytest:*) present in the project’s .claude/settings.json permission allowlist.
  • AC-2: A second run on the same project does not duplicate the permission entry (idempotent).
  • AC-3: On a project with no pytest signal, no Bash(pytest:*) permission is added.
  • AC-4: After seeding, a /sdlc:task-work run that invokes pytest does not stall on a Bash(pytest:*) permission prompt.
  • Seeding permissions for other runners (ruff, mypy, etc.). This task is scoped to the pytest gap the lib convention introduced; a general “seed all detected-runner permissions” pass is a separate decision.
  • Adding the uv run --with pytest fallback to any skill — that fallback already works ad hoc; this task removes the need for it by granting the permission up front.
  • Changing the preflight_permissions probe. It already flags the gap correctly; this task makes the gap not occur in the first place.
  • none

Spawned by /sdlc:task-work post-mortem of T-75LX-establish-plugin-lib-convention on 2026-05-23.

Bullet: pytest was not on PATH / not permitted initially; needed a /config grant of Bash(pytest:) plus a uv run —with pytest fallback. The preflight_permissions probe flagged it correctly; projects adopting this pytest-based lib convention should seed Bash(pytest:) at setup. Keywords searched: preflight_permissions, pytest-based, convention, permitted, initially, correctly, fallback, projects Excluded: 2026-05-23-establish-plugin-lib-convention Top candidates (score / status / headline):

  • 26 / closed/done / 2026-05-21-task-work-step-6-inline-impl-fallback — /sdlc:task-work Step 6 declares Agent-tool dependency or describes inline fallback
  • 19 / closed/done / 2026-05-20-investigate-sandbox-multiline-commit-denial — Document Claude Code sandbox fallback for the heredoc commit-message pattern
  • 19 / open/draft / 2026-05-23-add-lease-protocol-library-and-schemas — Add lease-protocol library and payload schemas
  • 17 / closed/done / 2026-05-21-project-local-skill-extension-mechanism — Project-local skill extension / shadowing mechanism
  • 13 / closed/done / 2026-05-20-task-branches-use-task-prefix — Use task/ prefix for task-work branches (was feat/) Decision: SPAWNED

← Back to Tasks