feature: Refinements become versioned specs refining another spec #13
No reviewers
Labels
No labels
breaking
bug
ci
dependencies
documentation
feature
security
skip-changelog
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
thierryade/backend!13
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/refinement-specs"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #12
Backend half of the refinement-as-spec refactor. Do not merge before the matching frontend PR —
/api/refinements/disappears and the spec/version payloads change.Model
Refinementremoved. A refinement is aSpecat a direct child place withrefines→ the refined spec (required by the API outside the root place; the refined spec's current version must be a draft, as before).SpecVersion.refines_versions(M2M): versions ofspec.refinesthis version covers. Monotonic (cover()/check_coverage()): never older than what the previous version covers; equal is allowed.SpecVersion.is_absence: documented absence,content= justification (required to validate). Vacuously implemented, needs no refinements below.SpecVersion.refinement_versions()/missing_refinement_places(): for each spec refining this one, its latest version covering it; completeness = ≥ 1 per direct child place (1..n allowed).SpecCodeAlias: former-R-codes, resolved by the coverage upload after spec codes.Project.next_refinement_sequenceremoved.Reopen cascade
Spec.reopen()cascades to refinement specs whose current version covers the reopened version → new drafts withpending_decision, covering nothing yet. A refinement already in draft just covers the new version.POST /api/spec-versions/{id}/decide/{decision: keep|new_version|absence, reason}— top down (parent decided first).keep/absencerevert the still-pending drafts below.API
SpecSerializer:refines,code_aliases, write-onlyis_absence+contenton creation;place/refinesfixed after creation.?refines=filter.SpecVersionSerializer:is_absence(writable on drafts),refines_versions,pending_decision,refinement_versions,missing_refinement_places.exists_in_refinementsremoved from stored files.Data migration (0007 → 0008 → 0009)
refinesthe parent spec, target version covers the parent version,R-*→ alias, attachments moved to the target version (same file deduplicated, name clash suffixed with the R code), automatic tests moved to the target spec (deduplicated, most recent run kept).apps/specs/test_migrations.py.Tests
pytest: 117 passed. pylint 10.00, autopep8 clean.🤖 Generated with Claude Code
https://claude.ai/code/session_014BSmBtGWeFBD9z4mYm9SjA
Replace the Refinement link model: a refinement is now a regular Spec at a direct child place, with `Spec.refines` pointing at the refined spec. - SpecVersion.refines_versions (M2M, monotonic): one refinement version can cover several versions of the refined spec. - SpecVersion.is_absence: a documented absence is a refinement version, its content being the justification. - Reopen cascades down the refinement tree as drafts with a pending decision (keep / new version / absence), settled top down through POST /spec-versions/{id}/decide/; a project version cannot be validated while a decision is pending. - Former "-R-" codes survive as SpecCodeAlias, still resolved by the coverage upload; no new refinement code is issued. - Data migration 0008 moves every Refinement row (targets, grouped absences, attachments, automatic tests) and stops on a target refined by two parent specs. - /api/refinements/ and attachment/test refinement targets are removed. Refs #12 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014BSmBtGWeFBD9z4mYm9SjA📊 Rapports Argus pour cette PR
Migration 0008 no longer stops on a spec refined from two parent specs (prod pre-check found one: FLO-3 <- FLO-2, FLO-18). The target keeps the parent of its oldest refinement; each other parent gets a copy (new code, title suffixed with the parent code, versions + manual tests + attachments copied, automatic tests left on the original). The copy has no refinements below it yet, so it will show missing child places until handled.
🤖 Generated with Claude Code
https://claude.ai/code/session_014BSmBtGWeFBD9z4mYm9SjA
WIP: Refinements become versioned specs refining another specto feature: Refinements become versioned specs refining another spec