Skip to content
Back to skills

Bugs

ASecurity

> **Status:** Fixed > **Verification depth:** functional (resolved from an EMPTY fixture root, so only the loaded skill dir can satisfy it; absent-path control and the derivation both pinned) > **Severity:** High > **Points:** 3 > **Affects:** .claude/skills/sdlc-studio/scripts/lib/sdlc_md.py, .claude/skills/sdlc-studio/scripts/readiness.py, .claude/skills/sdlc-studio/scripts/tests/test_detector_owed.py, .claude/skills/sdlc-studio/scripts/tests/test_sdlc_md.py, .claude/skills/sdlc-studio/scri...

  • 23 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 23, 2026
developmentpython

Security analysis

A100/100

Pro scans all 21 files and shows the line behind each finding

Scanned September 23, 2026

npx -y skills add DarrenBenson/sdlc-studio --skill bugs --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Bugs?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Bugs
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/darrenbenson-bugs/badge)](https://www.skillsdirectory.com/skills/darrenbenson-bugs)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
# BG0436: resolve_affects never resolves against the installed skill dir, so detector-owed --file tracebacks on every default install

> **Status:** Fixed
> **Verification depth:** functional (resolved from an EMPTY fixture root, so only the loaded skill dir can satisfy it; absent-path control and the derivation both pinned)
> **Severity:** High
> **Points:** 3
> **Affects:** .claude/skills/sdlc-studio/scripts/lib/sdlc_md.py, .claude/skills/sdlc-studio/scripts/readiness.py, .claude/skills/sdlc-studio/scripts/tests/test_detector_owed.py, .claude/skills/sdlc-studio/scripts/tests/test_sdlc_md.py, .claude/skills/sdlc-studio/scripts/tests/test_readiness.py
> **Evidence:** Executed by an independent reviewer on two identical roots differing only in whether the skill is vendored; the mechanism is confirmed statically here (resolve_affects has two candidate bases, neither of them SKILL_DIR).
> **Created:** 2026-07-30
> **Created-by:** sdlc-studio file
> **Raised-by:** Claude Opus 5 (independent adversarial review of the EP0169/EP0172/EP0175 batch); agent; skill v5.0.0
> **Raised-in-batch:** 2026-07-29T15:35:33Z

## Summary

`resolve_affects` resolves a declared path against `root` and `root/.claude/skills/sdlc-studio` only - never the skill dir the run is actually loaded from - although its own docstring says 'or the installed skill dir'. `detector-owed --file` declares the owed unit's Affects as `.claude/skills/sdlc-studio/templates/audit-profiles/<profile>.md`, which therefore resolves only in a project that VENDORS the skill in-tree. `install.sh` defaults to `--global`, so in every other project the path resolves to nothing and the pre-mint Affects check raises an uncaught ValueError: the operator gets a Python stack trace, not a message. The story's own fixture manufactures that path inside the audited root, which is exactly the shape that conceals it. Sub-case: for an owed lens with no pack the declared Affects is a DIRECTORY, which passes only because `resolve_affects` accepts one - the fictional-footprint class the code comment says it was fixing.

## Steps to Reproduce

1. Build a consuming project with no vendored skill and two findings sharing a lens across two registered runs.
2. `readiness.py --root <project> detector-owed --file`.
3. Uncaught ValueError from `file_owed_detectors`; no CR minted, no message.

## Proposed Fix

Resolve an Affects path against the loaded `SKILL_DIR` as the docstring already promises, and make the shipped-payload path declaration relative to that. Handle the no-pack case with a real file footprint or no Affects rather than a directory.

## Acceptance Criteria

### AC1: a shipped-payload path resolves without vendoring

- **Given** a project that does NOT vendor the skill into its tree
- **When** an Affects naming shipped payload is resolved
- **Then** it resolves against the LOADED skill dir, as the docstring already promised - because everywhere but this repo it silently resolved to nothing, and an Affects that resolves to nothing reads as an ungroomed unit
- **Verify:** pytest .claude/skills/sdlc-studio/scripts/tests/test_sdlc_md.py::ResolveAffectsSkillDirTests::test_a_shipped_payload_path_resolves_without_vendoring
- **Verified:** yes (2026-08-02)

### AC2: a genuinely absent path still resolves to nothing

- **Given** a path that exists nowhere
- **When** it is resolved
- **Then** it is None, so greenfield paths keep reading as absent and the grooming gate still catches a declared file nobody has written
- **Verify:** pytest .claude/skills/sdlc-studio/scripts/tests/test_sdlc_md.py::ResolveAffectsSkillDirTests::test_a_genuinely_absent_path_still_resolves_to_nothing
- **Verified:** yes (2026-08-02)

### AC3: the loaded skill dir is derived, not assumed

- **Given** the module's own location
- **When** the skill dir is taken
- **Then** it is derived from there, because the skill runs from an INSTALLED copy in every consuming project and a hardcoded repo path would resolve only here
- **Verify:** pytest .claude/skills/sdlc-studio/scripts/tests/test_sdlc_md.py::ResolveAffectsSkillDirTests::test_the_loaded_skill_dir_is_derived_not_assumed
- **Verified:** yes (2026-08-02)

## Revision History

| Date | Author | Change |
| --- | --- | --- |
| 2026-07-30 | Claude Opus 5 (independent adversarial review of the EP0169/EP0172/EP0175 batch) | Filed |

Files in this skill

  • BG0001-workflow-cr-status-vocabulary-diverges-across-refe.md2.8 KB
  • BG0002-reconcile-py-and-status-py-both-omit-bug-and-workf.md2.4 KB
  • BG0003-verify-ac-py-only-parses-ac-headings-silently-igno.md2.3 KB
  • BG0004-review-prep-persona-check-reads-personas-md-while.md2.2 KB
  • BG0005-prd-performance-nfr-falsely-claims-all-scripts-are.md1.6 KB
  • BG0006-prd-names-its-own-artifact-metadata-format-two-inc.md1.6 KB
  • BG0007-prd-quality-assessment-conceals-four-open-bugs-inc.md2.1 KB
  • BG0008-trd-script-contract-rule-5-is-incomplete-verify-ac.md2.2 KB
  • BG0009-trd-181-script-layer-tests-all-must-pass-before-re.md2 KB
  • BG0010-tsd-instruction-hygiene-release-gate-validate-py-i.md1.6 KB
  • BG0011-tsd-availability-gate-is-inverted-the-cited-test-p.md1.8 KB
  • BG0012-tsd-lint-links-gate-is-skill-scoped-so-the-sdlc-st.md1.9 KB
  • BG0013-persona-section-headings-carry-a-high-suffix-that.md2.1 KB
  • BG0014-story-verify-lines-do-not-test-what-their-acs-asse.md3.2 KB
  • BG0015-epic-ownership-double-mapping-github-sync-review-p.md2.6 KB
  • BG0016-ep0004-s-prd-reference-points-to-section-10-with-a.md1.6 KB
  • BG0017-rfc0003-buries-a-fixable-false-guarantee-reconcile.md2 KB
  • BG0018-reconcile-index-status-parser-matches-title.md3.1 KB
  • BG0019-determinism-checks-mishandle-bug-artifact-class.md2.7 KB
  • BG0020-parser-rejects-consuming-repo-house-templates.md3.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.