-
Notifications
You must be signed in to change notification settings - Fork 1
Closed
Labels
new featureIssues or PRs for a new feature that doesn't currently existIssues or PRs for a new feature that doesn't currently existphase-2Phase 2 spec generationPhase 2 spec generationtraceabilityConvention-based traceabilityConvention-based traceability
Milestone
Description
Summary
Match test files and functions to existing spec files and scenarios by naming convention. Annotates draft specs with inferred traceability links and enriches specleft status output with convention-matched entries.
New file
src/specleft/discovery/traceability.py
from specleft.discovery.models import DiscoveredItem
from specleft.schema import SpecsConfig
@dataclass(frozen=True)
class TraceabilityLink:
test_file: Path
test_function: str
spec_file: Path
scenario_id: str
match_kind: str # "filename" | "function" | "both"
confidence: float
def infer_traceability(
discovered: list[DiscoveredItem],
specs: SpecsConfig,
) -> list[TraceabilityLink]:
"""
Pure function: accepts pre-loaded specs rather than resolving internally.
Caller is responsible for loading SpecsConfig from the correct directory.
This keeps the discovery package decoupled from spec resolution.
Does not scan .specleft/specs/_discovered/ — caller should load specs
from resolve_specs_dir() which excludes underscore-prefixed directories.
"""Matching algorithm
Step 1 — Filename match
Normalise both sides (replace -, _ with space, strip test_ prefix from test filename stem):
.specleft/specs/user-authentication.md → "user authentication"
tests/test_user_authentication.py → "user authentication"
Exact normalised match = filename link.
Step 2 — Function match within a filename-matched pair
Normalise scenario slug and function name (strip test_, replace _ with space):
Scenario: valid-credentials → "valid credentials"
def test_valid_credentials() → "valid credentials"
- Exact match →
confidence=0.9,match_kind="both" - Common prefix >=60% of shorter string →
confidence=0.6,match_kind="function"
Step 3 — Annotate draft specs
For matched scenarios, add a frontmatter block to the generated markdown:
---
linked_tests:
- file: tests/test_user_authentication.py
function: test_valid_credentials
confidence: 0.9
---Integration with specleft status
Update src/specleft/commands/status.py:
- After the existing
_index_specleft_tests()check, if a scenario has no decorator-based match, attempt convention-based lookup viainfer_traceability() - Pass pre-loaded
SpecsConfig— do not re-resolve specs internally - If a convention match is found, set
match_kind: "convention"in the status entry - Table output: show
✓ (convention)instead of✓for convention-matched scenarios
Acceptance criteria
-
tests/test_user_authentication.py::test_valid_credentialslinks to.specleft/specs/user-authentication.mdscenariovalid-credentials -
tests/test_payment.pydoes not link to.specleft/specs/user-authentication.md(no false positives) -
infer_traceability()acceptsSpecsConfigdirectly (dependency injection, not path resolution) -
infer_traceability()returns[](not an error) whenSpecsConfighas no features -
.specleft/specs/_discovered/files are excluded (caller loads specs fromresolve_specs_dir()which skips_-prefixed dirs) -
specleft statustable shows(convention)tag for convention-matched scenarios - Tests in
tests/discovery/test_traceability.pyusing fixture spec files and test files - Update scenarios and tests in
features/feature-spec-discovery.mdto cover the functionality introduced by this issue
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
new featureIssues or PRs for a new feature that doesn't currently existIssues or PRs for a new feature that doesn't currently existphase-2Phase 2 spec generationPhase 2 spec generationtraceabilityConvention-based traceabilityConvention-based traceability