From b5b15b9b8f953fe3adbc759615aecd645586f2af Mon Sep 17 00:00:00 2001 From: miroslavpojer Date: Tue, 14 Oct 2025 14:41:48 +0200 Subject: [PATCH 1/6] Backup of update spec-kit files. --- .specify/constitution.md | 86 +++++++++-- .specify/templates/plan-template.md | 74 +++------- .specify/templates/spec-template.md | 10 ++ .specify/templates/tasks-template.md | 208 +++++++-------------------- 4 files changed, 161 insertions(+), 217 deletions(-) diff --git a/.specify/constitution.md b/.specify/constitution.md index 2b03e219..4f4da94b 100644 --- a/.specify/constitution.md +++ b/.specify/constitution.md @@ -1,11 +1,12 @@ # Release Notes Scrapper Action Constitution @@ -65,11 +66,23 @@ manage version tagging; it consumes existing tags. 7. `ReleaseNotesBuilder` iterates chapters → collects matching records → applies row format templates / duplicity markers. 8. Final Markdown string emitted; composite action sets `release-notes` output. -### Boundary Rules +### Boundary Rules (Refined) - Action inputs boundary: all configurable behavior must pass via declared inputs (no hidden runtime switches). - GitHub API boundary: all repository data access encapsulated within miner and rate limiter logic. - Formatting boundary: only row format templates and chapters influence visible line structure; business logic must not directly embed presentation markup elsewhere. +- Error boundary: modules MUST NOT leak raw exceptions across boundaries; they must convert failures into logged events + and structured return values (see Principle 9). Internal exceptions MAY be raised and caught within the same module. +- Utility boundary: functions in `utils/` MUST be demonstrably used by at least one importing module or removed (see Principle 8 & 10). + +### Module Boundary Follow-Up +A scheduled audit SHALL verify: +- `utils/` contains only actively referenced functions (dead code removal list to be created). +- `generator.py` remains orchestration-only (no direct formatting or low-level API calls beyond miner invocation). +- `builder/` never performs mining; strictly transforms records to Markdown. +- `record/factory` isolates construction logic; future refactors MAY extract validation into a separate `validators/` module. +- Logging configuration centralization: confirm no duplicate ad-hoc log setup outside `main.py`. +Outcome: Produce a follow-up task list referencing each violation if found; merge only with accompanying unit tests. ## 3. Data & Integrations @@ -119,13 +132,37 @@ manage version tagging; it consumes existing tags. ## 5. Quality & Testing ### Test Types -- Unit tests (expected for pure utility and formatting functions). +- Unit tests for pure utility, transformation, formatting, and record construction functions. - Integration tests (e.g. `integration_test.py`) covering end-to-end generation using mocked or controlled data. -- No explicit contract tests yet; future addition may define record/chapter contract snapshots. +- Future: contract/snapshot tests MAY be introduced for chapter output stability (not mandatory yet). + +### Test Directory Structure (New) +``` +tests/ + unit/ # All Python unit tests (test_.py) - REQUIRED location + integration/ # Future integration tests (current single file may migrate here) + fixtures/ # Shared static test data & factories (optional) + helpers/ # Helper utilities used only by tests (must be imported by tests/*) + release_notes/ # Domain-specific sample data (review for possible move under fixtures/) + utils/ # Test-only utility functions (rename to helpers/ or remove if redundant) +``` +Rules: +- All unit tests MUST reside under `tests/unit/` (root-level `test_*.py` files SHALL be relocated). +- Naming: `test_.py`; multiple related small targets MAY share one file if cohesive. +- Test style: uses ONLY `pytest` (no unittest classes). Prefer functions + fixtures. +- Fixtures: define shared objects in `tests/conftest.py` or per-file fixtures; keep scope minimal. +- Parametrization: use `@pytest.mark.parametrize` for input matrix instead of loops. +- Coverage: new logic MUST raise overall coverage or keep it steady; dropping coverage requires explicit justification. + +### Organization & Integration +- Integration tests MUST import public interfaces only (`main`, `ReleaseNotesGenerator`) not internal private helpers. +- Unit tests MUST avoid real network calls; use mocking or local sample data. +- Cross-test independence: tests MUST NOT rely on execution order; no shared mutation outside fixture scope. +- Relocation of existing root-level unit tests into `tests/unit/` SHALL be part of first compliance PR post-amendment. ### Coverage -- `pytest-cov` integrated; HTML coverage artifacts seen in `htmlcov/`. Target: maintain or improve existing coverage - (implicit baseline > minimal demonstration). New core logic MUST include tests before implementation (Test‑First Principle). +- `pytest-cov` integrated; HTML coverage artifacts under `htmlcov/`. Baseline maintained or improved. New core logic MUST + include tests before implementation (Test‑First Principle). ### Static Analysis & Review - `pylint`, `mypy` required to pass (configuration present). @@ -135,6 +172,7 @@ manage version tagging; it consumes existing tags. ### Quality Gates (Minimum Acceptance) - Tests: ALL must pass. - Lint + type: zero blocking errors. +- No unused functions/methods (see Principle 10) — introduce usage or delete in same PR. - Backward compatibility: no silent change to input names or placeholder semantics without version bump & documentation update. ## 6. Constraints & Compatibility @@ -169,6 +207,7 @@ manage version tagging; it consumes existing tags. - Hierarchy expansion could incur additional API calls increasing latency. - Duplicate detection edge cases may confuse users if same issue intentionally spans categories. - CodeRabbit integration features may parse unintended summary content (format variance risk). +- Dead code accumulation in `utils/` may reduce clarity if Principle 10 not enforced promptly. ### Assumptions - Repository uses semantic version tags (prefixed optionally by `v`). @@ -236,7 +275,7 @@ Ensure Constitution Check section in `plan.md` passes before advancing to detail ## Change Log / Versioning - Project releases follow Git tags; this constitution uses semantic versioning independent of code releases. -- Current Constitution Version: 1.0.1 (initial ratification). +- Current Constitution Version: 1.1.0 (amended with new principles & test structure). - Future amendments tracked via Sync Impact Report at top of this file. ## Core Principles @@ -277,5 +316,28 @@ Mining MUST use rate limiter abstraction; avoid redundant API calls (e.g. re-fet MUST short-circuit when disabled. Performance considerations addressed before accepting features that multiply API calls. Rationale: Preserves quota & improves speed on large repositories. +### Principle 8: Lean Python Design +Prefer simple functions and modules over unnecessary classes. A class MUST only be introduced when stateful behavior or +polymorphism is required. Utility modules SHOULD expose pure functions. Avoid deep inheritance; favor composition. +Rationale: Reduces complexity and improves readability & testability. + +### Principle 9: Localized Error Handling & Non-Exceptional Flow +Modules MUST catch internal exceptions and convert them into structured return values plus logged messages. Cross-module +exception propagation (raising raw exceptions across boundaries) is prohibited except for truly unrecoverable setup +failures at the entry point (`main`). Return either a valid result or a clearly logged empty/partial result. +Rationale: Ensures predictable action behavior and prevents silent termination in CI pipelines. + +### Principle 10: Dead Code Prohibition +No unused methods/functions SHALL remain in the codebase (properties or inherited abstract/interface methods excepted). +Utility files MUST contain only actively invoked functions. Removal of unused code MUST occur in the same PR that +introduces its obsolescence. +Rationale: Prevents confusion, reduces maintenance overhead, and keeps coverage meaningful. + +### Principle 11: Focused & Informative Comments +Comments MUST explain non-obvious logic, constraints, or reasoning succinctly. Prohibited: narrative, outdated, or +speculative comments. Allowed: brief context before complex loops, rationale for workaround, links to issue references. +Comments SHOULD be maintained or updated alongside code changes; stale comments MUST be removed. +Rationale: Enhances clarity without adding noise. + ## Governance Metadata -**Version**: 1.0.1 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-12 +**Version**: 1.1.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 diff --git a/.specify/templates/plan-template.md b/.specify/templates/plan-template.md index 70fa8f97..1bf482e9 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -17,21 +17,25 @@ the iteration process. --> -**Language/Version**: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION] -**Primary Dependencies**: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION] -**Storage**: [if applicable, e.g., PostgreSQL, CoreData, files or N/A] -**Testing**: [e.g., pytest, XCTest, cargo test or NEEDS CLARIFICATION] -**Target Platform**: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] -**Project Type**: [single/web/mobile - determines source structure] -**Performance Goals**: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION] -**Constraints**: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION] -**Scale/Scope**: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION] +**Language/Version**: [e.g., Python 3.11 or NEEDS CLARIFICATION] +**Primary Dependencies**: [e.g., PyGithub, PyYAML, semver or NEEDS CLARIFICATION] +**Testing**: pytest ONLY (per Constitution) +**Target Platform**: GitHub Action runners (Ubuntu) or NEEDS CLARIFICATION +**Performance Goals**: [domain-specific, e.g., <5s generation time for 500 issues] +**Constraints**: [e.g., rate limit adherence, stable deterministic output] +**Scale/Scope**: [e.g., repos up to 10k issues in release window] ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* -[Gates determined based on constitution file] +Mandatory alignment items: +- Test‑First Reliability: Provide failing unit test list BEFORE implementation. +- Explicit Configuration Boundaries: All new behavior exposed via action inputs (list any new inputs needed). +- Deterministic Output Formatting: Confirm ordering & placeholders remain stable. +- Lean Python Design: Justify each new class; prefer functions for stateless logic. +- Localized Error Handling: Define how errors are logged instead of cross-module exceptions. +- Dead Code Prohibition: Identify any code to delete made obsolete by this feature. ## Project Structure @@ -48,51 +52,19 @@ specs/[###-feature]/ ``` ### Source Code (repository root) - ``` -# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT) -src/ -├── models/ -├── services/ -├── cli/ -└── lib/ +release_notes_generator/ + ...existing modules... tests/ -├── contract/ -├── integration/ -└── unit/ - -# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected) -backend/ -├── src/ -│ ├── models/ -│ ├── services/ -│ └── api/ -└── tests/ - -frontend/ -├── src/ -│ ├── components/ -│ ├── pages/ -│ └── services/ -└── tests/ - -# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected) -api/ -└── [same as backend above] - -ios/ or android/ -└── [platform-specific structure: feature modules, UI flows, platform tests] + unit/ # All unit tests (REQUIRED) + integration/ # End-to-end tests (if any new ones added by feature) + fixtures/ # Static data samples (optional) + helpers/ # Test helper utilities ``` -**Structure Decision**: [Document the selected structure and reference the real -directories captured above] +**Structure Decision**: [Document any new modules or directories added] ## Complexity Tracking @@ -100,5 +72,5 @@ directories captured above] | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| -| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | -| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | +| [e.g., new class] | [current need] | [function approach insufficient due to state] | +| [e.g., added input] | [feature toggle] | [implicit behavior would break determinism] | diff --git a/.specify/templates/spec-template.md b/.specify/templates/spec-template.md index c67d9149..96007cca 100644 --- a/.specify/templates/spec-template.md +++ b/.specify/templates/spec-template.md @@ -5,6 +5,16 @@ **Status**: Draft **Input**: User description: "$ARGUMENTS" +## Constitution Alignment (Mandatory) +List how this feature will comply with core principles: +- Test‑First (P1): Failing unit tests in `tests/unit/test_.py` BEFORE implementation. +- Explicit Configuration Boundaries (P2): New behavior exposed only via documented action inputs (list if any needed). +- Deterministic Output (P3): Define ordering / formatting impacts; MUST remain stable across runs. +- Lean Python Design (P8): Prefer functions; justify any new class (state or polymorphism requirement). +- Localized Error Handling (P9): Describe logging + return strategy; no cross-module exception raises. +- Dead Code Prohibition (P10): Identify any functions to remove or refactor; commit with tests. +- Focused Comments (P11): Plan for concise logic/rationale comments; avoid narrative. + ## User Scenarios & Testing *(mandatory)* @@ -45,9 +31,9 @@ description: "Task list template for feature implementation" **Purpose**: Project initialization and basic structure -- [ ] T001 Create project structure per implementation plan -- [ ] T002 Initialize [language] project with [framework] dependencies -- [ ] T003 [P] Configure linting and formatting tools +- [ ] T001 Create any new module directories in `release_notes_generator/` +- [ ] T002 [P] Add initial failing unit tests in `tests/unit/` for new logic (Test‑First gate) +- [ ] T003 [P] Configure/verify linting and formatting tools --- @@ -55,16 +41,12 @@ description: "Task list template for feature implementation" **Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented -**⚠️ CRITICAL**: No user story work can begin until this phase is complete +**⚠ CRITICAL**: No user story work can begin until this phase is complete -Examples of foundational tasks (adjust based on your project): - -- [ ] T004 Setup database schema and migrations framework -- [ ] T005 [P] Implement authentication/authorization framework -- [ ] T006 [P] Setup API routing and middleware structure -- [ ] T007 Create base models/entities that all stories depend on -- [ ] T008 Configure error handling and logging infrastructure -- [ ] T009 Setup environment configuration management +- [ ] T004 Implement feature configuration parsing (test: `tests/unit/test_action_inputs.py` extended) +- [ ] T005 [P] Add utilities (if needed) with tests (`tests/unit/test_utils_.py`) +- [ ] T006 Setup error handling pattern (log & return) — no cross-module exception leakage +- [ ] T007 Dead code removal (list obsolete functions) + tests ensuring replacement paths **Checkpoint**: Foundation ready - user story implementation can now begin in parallel @@ -72,179 +54,97 @@ Examples of foundational tasks (adjust based on your project): ## Phase 3: User Story 1 - [Title] (Priority: P1) 🎯 MVP -**Goal**: [Brief description of what this story delivers] - -**Independent Test**: [How to verify this story works on its own] +**Goal**: [Brief description] -### Tests for User Story 1 (OPTIONAL - only if tests requested) ⚠️ +**Independent Test**: [How to verify] -**NOTE: Write these tests FIRST, ensure they FAIL before implementation** +### Mandatory Tests for User Story 1 -- [ ] T010 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py -- [ ] T011 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py +- [ ] T010 [P] [US1] Unit tests for new pure functions in `tests/unit/test_.py` (start failing) +- [ ] T011 [US1] Update integration test (if scope touched) in `tests/integration/test_generation.py` (optional creation) ### Implementation for User Story 1 -- [ ] T012 [P] [US1] Create [Entity1] model in src/models/[entity1].py -- [ ] T013 [P] [US1] Create [Entity2] model in src/models/[entity2].py -- [ ] T014 [US1] Implement [Service] in src/services/[service].py (depends on T012, T013) -- [ ] T015 [US1] Implement [endpoint/feature] in src/[location]/[file].py -- [ ] T016 [US1] Add validation and error handling -- [ ] T017 [US1] Add logging for user story 1 operations +- [ ] T012 [P] [US1] Implement function(s) in `release_notes_generator/.py` +- [ ] T013 [US1] Logging additions (INFO lifecycle, DEBUG details) +- [ ] T014 [US1] Ensure deterministic ordering adjustments -**Checkpoint**: At this point, User Story 1 should be fully functional and testable independently +**Checkpoint**: User Story 1 fully functional & independently testable --- ## Phase 4: User Story 2 - [Title] (Priority: P2) -**Goal**: [Brief description of what this story delivers] +**Goal**: [Brief description] -**Independent Test**: [How to verify this story works on its own] +**Independent Test**: [How to verify] -### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️ +### Mandatory Tests for User Story 2 -- [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py -- [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py +- [ ] T015 [P] [US2] Unit tests for added logic ### Implementation for User Story 2 -- [ ] T020 [P] [US2] Create [Entity] model in src/models/[entity].py -- [ ] T021 [US2] Implement [Service] in src/services/[service].py -- [ ] T022 [US2] Implement [endpoint/feature] in src/[location]/[file].py -- [ ] T023 [US2] Integrate with User Story 1 components (if needed) +- [ ] T016 [US2] Implement logic in existing module +- [ ] T017 [US2] Update records builder ensuring no cross-module exceptions -**Checkpoint**: At this point, User Stories 1 AND 2 should both work independently +**Checkpoint**: User Stories 1 & 2 independently functional --- ## Phase 5: User Story 3 - [Title] (Priority: P3) -**Goal**: [Brief description of what this story delivers] +**Goal**: [Brief description] -**Independent Test**: [How to verify this story works on its own] +**Independent Test**: [How to verify] -### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️ +### Mandatory Tests for User Story 3 -- [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py -- [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py +- [ ] T018 [P] [US3] Unit tests for added logic ### Implementation for User Story 3 -- [ ] T026 [P] [US3] Create [Entity] model in src/models/[entity].py -- [ ] T027 [US3] Implement [Service] in src/services/[service].py -- [ ] T028 [US3] Implement [endpoint/feature] in src/[location]/[file].py +- [ ] T019 [US3] Implement functionality +- [ ] T020 [US3] Update documentation/comments (concise, logic-focused) -**Checkpoint**: All user stories should now be independently functional - ---- - -[Add more user story phases as needed, following the same pattern] +**Checkpoint**: All user stories functional; tests green --- ## Phase N: Polish & Cross-Cutting Concerns -**Purpose**: Improvements that affect multiple user stories - -- [ ] TXXX [P] Documentation updates in docs/ -- [ ] TXXX Code cleanup and refactoring -- [ ] TXXX Performance optimization across all stories -- [ ] TXXX [P] Additional unit tests (if requested) in tests/unit/ -- [ ] TXXX Security hardening -- [ ] TXXX Run quickstart.md validation +- [ ] TXXX [P] Documentation updates in `README.md`, `docs/` +- [ ] TXXX Code cleanup (remove any newly unused code) +- [ ] TXXX Performance optimization +- [ ] TXXX [P] Additional unit tests (edge cases) in `tests/unit/` +- [ ] TXXX Security/robustness improvements --- ## Dependencies & Execution Order -### Phase Dependencies - -- **Setup (Phase 1)**: No dependencies - can start immediately -- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories -- **User Stories (Phase 3+)**: All depend on Foundational phase completion - - User stories can then proceed in parallel (if staffed) - - Or sequentially in priority order (P1 → P2 → P3) -- **Polish (Final Phase)**: Depends on all desired user stories being complete +- Setup → Foundational → User Stories (can parallelize after Foundational) → Polish +- Failing unit tests precede implementation per story +- No story proceeds without its mandatory unit tests -### User Story Dependencies - -- **User Story 1 (P1)**: Can start after Foundational (Phase 2) - No dependencies on other stories -- **User Story 2 (P2)**: Can start after Foundational (Phase 2) - May integrate with US1 but should be independently testable -- **User Story 3 (P3)**: Can start after Foundational (Phase 2) - May integrate with US1/US2 but should be independently testable - -### Within Each User Story - -- Tests (if included) MUST be written and FAIL before implementation -- Models before services -- Services before endpoints -- Core implementation before integration -- Story complete before moving to next priority - -### Parallel Opportunities - -- All Setup tasks marked [P] can run in parallel -- All Foundational tasks marked [P] can run in parallel (within Phase 2) -- Once Foundational phase completes, all user stories can start in parallel (if team capacity allows) -- All tests for a user story marked [P] can run in parallel -- Models within a story marked [P] can run in parallel -- Different user stories can be worked on in parallel by different team members - ---- +## Parallel Opportunities -## Parallel Example: User Story 1 - -```bash -# Launch all tests for User Story 1 together (if tests requested): -Task: "Contract test for [endpoint] in tests/contract/test_[name].py" -Task: "Integration test for [user journey] in tests/integration/test_[name].py" - -# Launch all models for User Story 1 together: -Task: "Create [Entity1] model in src/models/[entity1].py" -Task: "Create [Entity2] model in src/models/[entity2].py" -``` - ---- +- All tasks marked [P] can run in parallel +- Different user stories can be developed concurrently once Foundational completes ## Implementation Strategy ### MVP First (User Story 1 Only) - -1. Complete Phase 1: Setup -2. Complete Phase 2: Foundational (CRITICAL - blocks all stories) -3. Complete Phase 3: User Story 1 -4. **STOP and VALIDATE**: Test User Story 1 independently -5. Deploy/demo if ready +1. Setup & Foundational +2. User Story 1 tests → implementation → validation +3. Demo/merge if stable ### Incremental Delivery - -1. Complete Setup + Foundational → Foundation ready -2. Add User Story 1 → Test independently → Deploy/Demo (MVP!) -3. Add User Story 2 → Test independently → Deploy/Demo -4. Add User Story 3 → Test independently → Deploy/Demo -5. Each story adds value without breaking previous stories - -### Parallel Team Strategy - -With multiple developers: - -1. Team completes Setup + Foundational together -2. Once Foundational is done: - - Developer A: User Story 1 - - Developer B: User Story 2 - - Developer C: User Story 3 -3. Stories complete and integrate independently - ---- +Add each story with its own failing tests → implementation → validation cycle. ## Notes -- [P] tasks = different files, no dependencies -- [Story] label maps task to specific user story for traceability -- Each user story should be independently completable and testable -- Verify tests fail before implementing -- Commit after each task or logical group -- Stop at any checkpoint to validate story independently -- Avoid: vague tasks, same file conflicts, cross-story dependencies that break independence - - +- Avoid unused functions (delete immediately if obsoleted) +- Prefer functions over classes unless state/polymorphism required +- Handle errors locally; log & return +- Comments concise & logic-focused From 8cdf1667c8032b7c18f525db7a37f90f25892460 Mon Sep 17 00:00:00 2001 From: miroslavpojer Date: Tue, 14 Oct 2025 15:11:57 +0200 Subject: [PATCH 2/6] Backup of update spec-kit files. Partial migration of unit tests. --- .specify/constitution.md | 26 ++- .specify/memory/constitution.md | 148 ++++++++++---- .specify/templates/plan-template.md | 1 + .specify/templates/spec-template.md | 1 + .specify/templates/tasks-template.md | 37 ++-- integration_test.py | 32 --- tests/integration/integration_test.py | 28 +++ .../test_action_inputs.py | 190 +++++++++++++----- .../test_generator.py} | 42 ++-- 9 files changed, 341 insertions(+), 164 deletions(-) delete mode 100644 integration_test.py create mode 100644 tests/integration/integration_test.py rename tests/{ => unit/release_notes_generator}/test_action_inputs.py (64%) rename tests/{test_release_notes_generator.py => unit/release_notes_generator/test_generator.py} (92%) diff --git a/.specify/constitution.md b/.specify/constitution.md index 4f4da94b..38bbdaf4 100644 --- a/.specify/constitution.md +++ b/.specify/constitution.md @@ -1,12 +1,12 @@ # Release Notes Scrapper Action Constitution @@ -153,6 +153,8 @@ Rules: - Fixtures: define shared objects in `tests/conftest.py` or per-file fixtures; keep scope minimal. - Parametrization: use `@pytest.mark.parametrize` for input matrix instead of loops. - Coverage: new logic MUST raise overall coverage or keep it steady; dropping coverage requires explicit justification. +- NEW: Unit test file path MUST mirror source relative package path (Principle 12). For source file `release_notes_generator/utils/constants.py`, the test lives at `tests/unit/release_notes_generator/utils/test_constants.py`. +- Transitional Exception: Existing categorized test directories (`tests/release_notes`, `tests/data`, `tests/model`, `tests/utils`) are grandfathered until migrated; new tests MUST follow mirroring immediately. ### Organization & Integration - Integration tests MUST import public interfaces only (`main`, `ReleaseNotesGenerator`) not internal private helpers. @@ -275,7 +277,7 @@ Ensure Constitution Check section in `plan.md` passes before advancing to detail ## Change Log / Versioning - Project releases follow Git tags; this constitution uses semantic versioning independent of code releases. -- Current Constitution Version: 1.1.0 (amended with new principles & test structure). +- Current Constitution Version: 1.2.0 (amended with new principles & test structure). - Future amendments tracked via Sync Impact Report at top of this file. ## Core Principles @@ -339,5 +341,13 @@ speculative comments. Allowed: brief context before complex loops, rationale for Comments SHOULD be maintained or updated alongside code changes; stale comments MUST be removed. Rationale: Enhances clarity without adding noise. +### Principle 12: Test Path Mirroring +Each unit test file MUST reside under `tests/unit/` mirroring the source package path and file name: `tests/unit//test_.py`. +Mandatory Rules: +- One test file per source file unless tightly coupled logic demands grouping (justify in PR). +- Legacy non-mirrored category folders are deprecated; migrate incrementally without reducing coverage. +- New or refactored modules require mirrored test path in same PR. +Rationale: Ensures predictable test discovery, simplifies navigation between code and tests, and supports scalable refactors. + ## Governance Metadata -**Version**: 1.1.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 +**Version**: 1.2.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index 1ed8d77a..51b484fc 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -1,50 +1,128 @@ -# [PROJECT_NAME] Constitution - + + +# Generate Release Notes Action Constitution ## Core Principles -### [PRINCIPLE_1_NAME] - -[PRINCIPLE_1_DESCRIPTION] - +### Principle 1: Test‑First Reliability +All core logic (mining, filtering, record building, formatting) MUST have failing unit tests written before implementation +and passing after. Refactors MUST preserve existing green tests. No feature merges without unit tests. +Rationale: Prevent regressions & maintain deterministic behavior for CI consumers. + +### Principle 2: Explicit Configuration Boundaries +Runtime behavior MUST be controlled only via declared GitHub Action inputs. Hidden flags or undeclared env vars prohibited. +Add inputs → MINOR version bump; rename/remove → MAJOR bump. +Rationale: Ensures predictability & backward compatibility for workflows pinning versions. + +### Principle 3: Deterministic Output Formatting +Given identical repository state & inputs, release notes MUST be identical. Ordering MUST be stable (sorted where needed). +Row template placeholders MUST remain consistent (additions allowed; removals require MAJOR bump). +Rationale: Stable diffs & reliable downstream automation (publishing, auditing). + +### Principle 4: Minimal Surface & Single Responsibility +Modules stay focused (inputs parsing, mining, building, logging). Cross-cutting concerns (tag creation, external alerts) +are excluded; implement in separate tools/actions. Avoid feature creep. +Rationale: Low maintenance cost & clear mental model. + +### Principle 5: Transparency & Observability +Structured logging MUST trace lifecycle: start → inputs validated → mining done → build done → finish. Errors logged with +context; verbose flag unlocks extra diagnostics without altering behavior. +Rationale: Fast debugging in ephemeral CI environments. + +### Principle 6: Safe Extensibility +New placeholders, chapters, or hierarchy features MUST default to non-breaking behavior. Provide opt-in flags if impact +uncertain. Document additions in README + release notes. +Rationale: Incremental evolution without destabilizing existing users. + +### Principle 7: Resource-Conscious GitHub API Usage +All mining MUST route through rate limiter abstractions. Disable hierarchy expansion when feature off. Avoid redundant +fetches (cache IDs once retrieved). Performance concerns addressed before merging API-heavy features. +Rationale: Preserves rate limits & improves speed. + +### Principle 8: Lean Python Design +Prefer pure functions; introduce classes ONLY when stateful behavior or polymorphism required. Avoid deep inheritance; +favor composition. Utility modules keep narrow surface. +Rationale: Improves readability, testability, and reduces accidental complexity. + +### Principle 9: Localized Error Handling & Non-Exceptional Flow +Do NOT raise raw exceptions across module boundaries. Catch internally → log → return structured result (empty/partial). +Only unrecoverable initialization failures (e.g., missing auth token) may exit early at entry point. +Rationale: Predictable action completion and clear diagnostics. -### [PRINCIPLE_2_NAME] - -[PRINCIPLE_2_DESCRIPTION] - +### Principle 10: Dead Code Prohibition +Unused functions/methods (except properties or required inherited methods) MUST be removed in same PR that obsoletes them. +Utility files contain ONLY invoked logic. CI or review MUST flag new unused code. +Rationale: Prevents confusion & keeps coverage meaningful. -### [PRINCIPLE_3_NAME] - -[PRINCIPLE_3_DESCRIPTION] - +### Principle 11: Focused & Informative Comments +Comments MUST succinctly explain non-obvious logic, constraints, or workaround rationale. Prohibited: stale, narrative, +Speculative, or redundant comments. Maintain or delete on change; never leave outdated intent. +Rationale: Enhances clarity without noise. -### [PRINCIPLE_4_NAME] - -[PRINCIPLE_4_DESCRIPTION] - +### Principle 12: Test Path Mirroring +Unit tests MUST mirror source file paths inside `tests/unit/`: +`release_notes_generator//file.py` → `tests/unit/release_notes_generator//test_file.py`. +Rules: +- New tests follow mirroring immediately. +- Grouping multiple source files in one test file requires justification (shared invariant or helper pattern). +- Legacy categorized folders (`tests/release_notes`, `tests/data`, `tests/model`, `tests/utils`) are transitional; migrate gradually without lowering coverage. +Rationale: Streamlines navigation, encourages focused tests, reduces ambiguity in ownership. -### [PRINCIPLE_5_NAME] - -[PRINCIPLE_5_DESCRIPTION] - +## Quality & Testing -## [SECTION_2_NAME] - +- Test Directory Structure: + - tests/unit/: All unit tests (test_.py) — required location. + - tests/integration/: End-to-end tests (integration_test.py to be migrated here when reorganized). + - tests/fixtures/: Optional static data samples. + - tests/helpers/ & tests/utils/: Test-only helpers (utils may merge into helpers). +- Framework: pytest ONLY (no unittest classes). +- Coverage: Enforce threshold ≥80% (existing command uses --cov-fail-under=80). New logic must keep or raise coverage. +- Independence: Tests MUST not depend on run order or mutate shared global state beyond fixture scope. +- Parametrization: Use @pytest.mark.parametrize instead of manual loops. +- Integration tests import public interfaces only (e.g., main entry, generator class). +- Failing tests are written first (Principle 1) for new core logic. +- NEW: Path mirroring (Principle 12) enforced for all new/changed modules. +- Transitional Migration Plan: Add tasks in upcoming PRs to relocate remaining categorized tests. -[SECTION_2_CONTENT] - +## Workflow & Quality Gates -## [SECTION_3_NAME] - +Pre-merge local mandatory checkers (from DEVELOPER.md): +1. Formatting: black --check (line length 120 per pyproject.toml). +2. Linting: pylint global score target ≥9.5 (no fatal errors). +3. Typing: mypy (0 blocking errors) — treat Any proliferation as smell (justify if unavoidable). +4. Tests: pytest all green. +5. Coverage: ≥80% overall; justify any temporary dip (must be recovered within next PR). +6. Dead Code: grep for unused utilities; remove or reference usage in same PR. +7. Determinism: (Manual) Validate repeated runs produce identical output for sample dataset. -[SECTION_3_CONTENT] - +Quality Gate Failure Handling: +- Minor failures (formatting, lint) → fix immediately; do not merge with waivers unless urgent hotfix. +- Coverage dip → requires explicit justification + recovery plan (link issue ID). +- Non-deterministic output → BLOCKING until resolved. ## Governance - -[GOVERNANCE_RULES] - +- Constitution supersedes ad-hoc practices; PRs MUST state compliance or list justified exceptions. +- Versioning (this constitution): Semantic (MAJOR.MINOR.PATCH). + - MAJOR: Remove/redefine a principle or backward incompatible process change. + - MINOR: Add new principle/section (current change qualifies here). + - PATCH: Clarifications/typos with no semantic effect. +- Amendment Flow: + 1. Propose change with rationale & impact assessment. + 2. Update Sync Impact Report header (include affected templates & TODOs). + 3. Bump version according to rule above. + 4. Obtain maintainer approval (≥1) — emergency fixes allow retroactive review. +- Compliance Review: PR template SHOULD reference Principles 1 (Test‑First), 2 (Configuration Boundaries), 10 (Dead Code), + and coverage threshold. Reviewers reject if principles violated without justification. +- Backward Compatibility: Input names & placeholder semantics require MAJOR bump if changed. +- Enforcement: CI pipeline SHOULD automate black, pylint, mypy, pytest, coverage threshold; manual deterministic checks remain. -**Version**: [CONSTITUTION_VERSION] | **Ratified**: [RATIFICATION_DATE] | **Last Amended**: [LAST_AMENDED_DATE] - \ No newline at end of file +**Version**: 1.2.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 diff --git a/.specify/templates/plan-template.md b/.specify/templates/plan-template.md index 1bf482e9..ef3090f8 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -36,6 +36,7 @@ Mandatory alignment items: - Lean Python Design: Justify each new class; prefer functions for stateless logic. - Localized Error Handling: Define how errors are logged instead of cross-module exceptions. - Dead Code Prohibition: Identify any code to delete made obsolete by this feature. +- Test Path Mirroring: Confirm new unit tests placed in `tests/unit//test_.py`. ## Project Structure diff --git a/.specify/templates/spec-template.md b/.specify/templates/spec-template.md index 96007cca..37c8d577 100644 --- a/.specify/templates/spec-template.md +++ b/.specify/templates/spec-template.md @@ -14,6 +14,7 @@ List how this feature will comply with core principles: - Localized Error Handling (P9): Describe logging + return strategy; no cross-module exception raises. - Dead Code Prohibition (P10): Identify any functions to remove or refactor; commit with tests. - Focused Comments (P11): Plan for concise logic/rationale comments; avoid narrative. +- Test Path Mirroring (P12): Place unit tests at `tests/unit//test_.py`. ## User Scenarios & Testing *(mandatory)* diff --git a/.specify/templates/tasks-template.md b/.specify/templates/tasks-template.md index 9b6f3aab..f66d1c40 100644 --- a/.specify/templates/tasks-template.md +++ b/.specify/templates/tasks-template.md @@ -19,6 +19,7 @@ description: "Task list template for feature implementation" ## Path Conventions - Single project: `release_notes_generator/` for source, `tests/` for tests - Tests MUST go under `tests/unit/` (unit) or `tests/integration/` (integration) +- Mirrored paths: For `release_notes_generator/x/y.py` create `tests/unit/release_notes_generator/x/test_y.py`. # Release Notes Scrapper Action Constitution @@ -154,7 +154,7 @@ Rules: - Parametrization: use `@pytest.mark.parametrize` for input matrix instead of loops. - Coverage: new logic MUST raise overall coverage or keep it steady; dropping coverage requires explicit justification. - NEW: Unit test file path MUST mirror source relative package path (Principle 12). For source file `release_notes_generator/utils/constants.py`, the test lives at `tests/unit/release_notes_generator/utils/test_constants.py`. -- Transitional Exception: Existing categorized test directories (`tests/release_notes`, `tests/data`, `tests/model`, `tests/utils`) are grandfathered until migrated; new tests MUST follow mirroring immediately. +- Branch Naming: Feature / fix / docs / chore PRs MUST originate from correctly prefixed branch (Principle 13); CI may validate. ### Organization & Integration - Integration tests MUST import public interfaces only (`main`, `ReleaseNotesGenerator`) not internal private helpers. @@ -176,6 +176,7 @@ Rules: - Lint + type: zero blocking errors. - No unused functions/methods (see Principle 10) — introduce usage or delete in same PR. - Backward compatibility: no silent change to input names or placeholder semantics without version bump & documentation update. +- Branch naming compliance (Principle 13) — allowed prefixes: feature/, fix/, docs/, chore/; rename if violated. ## 6. Constraints & Compatibility @@ -241,6 +242,7 @@ Rules: ### Compliance Review - PR template or automated check SHOULD reference Constitution principles (especially Test‑First & Stability) before merge. - Violations require explicit justification section in PR description. +- Review checklist MUST confirm Principle 13 prefix correctness and scope alignment. ### Release Management - Tagging strategy external; this action consumes tags. Recommend semantic versioning for repository releases. @@ -277,7 +279,7 @@ Ensure Constitution Check section in `plan.md` passes before advancing to detail ## Change Log / Versioning - Project releases follow Git tags; this constitution uses semantic versioning independent of code releases. -- Current Constitution Version: 1.2.0 (amended with new principles & test structure). +- Current Constitution Version: 1.4.0 (amended with new principles & test structure). - Future amendments tracked via Sync Impact Report at top of this file. ## Core Principles @@ -349,5 +351,22 @@ Mandatory Rules: - New or refactored modules require mirrored test path in same PR. Rationale: Ensures predictable test discovery, simplifies navigation between code and tests, and supports scalable refactors. +### Principle 13: Branch Naming Consistency +All new branches for work MUST start with one of the approved prefixes followed by a concise kebab-case descriptor (optional numeric ID). +Approved prefixes: +- `feature/` – new features & enhancements +- `fix/` – bug fixes / defect resolutions +- `docs/` – documentation-only updates +- `chore/` – maintenance, dependency bumps, CI, non-behavioral refactors +Examples: +`feature/add-hierarchy-support`, `fix/567-handle-empty-chapters`, `docs/improve-readme-start`, `chore/upgrade-semver-lib` +Rules: +- Prefix REQUIRED and MUST be in approved set; rename non-compliant branches prior to PR. +- Descriptor: lowercase kebab-case; hyphen separators; no spaces/underscores/trailing slash. +- Optional numeric ID may precede description (`fix/987-null-title`). +- Category alignment: branch prefix MUST match primary scope of PR contents. +- Avoid vague descriptors (`update`, `changes`). Prefer action or subject (`improve-logging`, `remove-dead-code`). +Rationale: Standardizes history, enables automated governance checks, clarifies intent for reviewers & tooling. + ## Governance Metadata -**Version**: 1.2.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 +**Version**: 1.4.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index 51b484fc..7bfd3ae4 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -1,11 +1,11 @@ # Generate Release Notes Action Constitution @@ -76,6 +76,27 @@ Rules: - Legacy categorized folders (`tests/release_notes`, `tests/data`, `tests/model`, `tests/utils`) are transitional; migrate gradually without lowering coverage. Rationale: Streamlines navigation, encourages focused tests, reduces ambiguity in ownership. +### Principle 13: Branch Naming Consistency +All new work branches MUST start with an approved prefix followed by a concise kebab-case descriptor (optional leading numeric ID). +Allowed prefixes (enforced): +- `feature/` → Feature & enhancement work introducing new capability or non-trivial behavior +- `fix/` → Bug fixes addressing defects (issues labeled bug/error) +- `docs/` → Documentation-only changes (README, docs/, CONTRIBUTING, DEVELOPER guides) +- `chore/` → Maintenance, dependency updates, CI adjustments, refactors without behavioral change +Examples: +- `feature/add-hierarchy-support`, `feature/123-hierarchy-support` +- `fix/456-null-pointer-on-empty-labels` +- `docs/improve-hierarchy-guide` +- `chore/update-pylint-config` +Rules: +- Prefix MUST be one of the allowed set; otherwise branch renamed before PR. +- Descriptor: lowercase kebab-case; hyphens only; no spaces/underscores/trailing slash. +- Optional numeric ID may precede description: `fix/987-label-trim`. +- Avoid vague terms (`update`, `changes`); state intent (`improve-logging`, `relabel-duplicate-detection`). +- Forbidden: mixing categories (e.g., `feature-fix/`), uppercase, camelCase. +- Scope alignment: PR description MUST align with chosen prefix category; reviewers reject mismatches (e.g., docs-only PR on feature/ branch). +Rationale: Enables automated classification, precise audit tooling, clearer commit/PR history semantics, and supports future CI policy enforcement. + ## Quality & Testing - Test Directory Structure: @@ -91,6 +112,7 @@ Rationale: Streamlines navigation, encourages focused tests, reduces ambiguity i - Failing tests are written first (Principle 1) for new core logic. - NEW: Path mirroring (Principle 12) enforced for all new/changed modules. - Transitional Migration Plan: Add tasks in upcoming PRs to relocate remaining categorized tests. +- Branch Naming Check: Implementation PRs MUST originate from an allowed prefixed branch (`feature/`, `fix/`, `docs/`, `chore/`). (Principle 13) ## Workflow & Quality Gates @@ -102,27 +124,28 @@ Pre-merge local mandatory checkers (from DEVELOPER.md): 5. Coverage: ≥80% overall; justify any temporary dip (must be recovered within next PR). 6. Dead Code: grep for unused utilities; remove or reference usage in same PR. 7. Determinism: (Manual) Validate repeated runs produce identical output for sample dataset. +8. Branch Naming: CI/Review MUST verify allowed prefix (feature|fix|docs|chore). Non-compliant branches BLOCK merge until renamed. Quality Gate Failure Handling: - Minor failures (formatting, lint) → fix immediately; do not merge with waivers unless urgent hotfix. - Coverage dip → requires explicit justification + recovery plan (link issue ID). - Non-deterministic output → BLOCKING until resolved. +- Branch naming violation → BLOCKING until branch renamed; no exception (prefix set: feature|fix|docs|chore). ## Governance - Constitution supersedes ad-hoc practices; PRs MUST state compliance or list justified exceptions. - Versioning (this constitution): Semantic (MAJOR.MINOR.PATCH). - MAJOR: Remove/redefine a principle or backward incompatible process change. - - MINOR: Add new principle/section (current change qualifies here). + - MINOR: Add new principle/section (current change qualifies here: Branch Naming Consistency). - PATCH: Clarifications/typos with no semantic effect. - Amendment Flow: 1. Propose change with rationale & impact assessment. 2. Update Sync Impact Report header (include affected templates & TODOs). 3. Bump version according to rule above. 4. Obtain maintainer approval (≥1) — emergency fixes allow retroactive review. -- Compliance Review: PR template SHOULD reference Principles 1 (Test‑First), 2 (Configuration Boundaries), 10 (Dead Code), - and coverage threshold. Reviewers reject if principles violated without justification. +- Compliance Review: PR template SHOULD reference Principles 1, 2, 10, 12, 13 (multi-prefix) + coverage threshold. Reviewers reject if principles violated without justification. - Backward Compatibility: Input names & placeholder semantics require MAJOR bump if changed. -- Enforcement: CI pipeline SHOULD automate black, pylint, mypy, pytest, coverage threshold; manual deterministic checks remain. +- Enforcement: CI pipeline SHOULD automate black, pylint, mypy, pytest, coverage threshold; manual deterministic checks remain. Branch naming can be auto-validated by simple prefix check script. -**Version**: 1.2.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 +**Version**: 1.4.0 | **Ratified**: 2025-10-12 | **Last Amended**: 2025-10-14 diff --git a/.specify/templates/plan-template.md b/.specify/templates/plan-template.md index ef3090f8..3cb340d9 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -1,6 +1,6 @@ # Implementation Plan: [FEATURE] -**Branch**: `[###-feature-name]` | **Date**: [DATE] | **Spec**: [link] +**Branch**: `/[###-descriptor]` (prefix ∈ {feature, fix, docs, chore}) | **Date**: [DATE] | **Spec**: [link] **Input**: Feature specification from `/specs/[###-feature-name]/spec.md` **Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow. @@ -37,6 +37,8 @@ Mandatory alignment items: - Localized Error Handling: Define how errors are logged instead of cross-module exceptions. - Dead Code Prohibition: Identify any code to delete made obsolete by this feature. - Test Path Mirroring: Confirm new unit tests placed in `tests/unit//test_.py`. +- Branch Naming Consistency: Confirm current branch uses allowed prefix (feature|fix|docs|chore): + `git rev-parse --abbrev-ref HEAD | grep -E '^(feature|fix|docs|chore)/'`. ## Project Structure diff --git a/.specify/templates/spec-template.md b/.specify/templates/spec-template.md index 37c8d577..218cfad9 100644 --- a/.specify/templates/spec-template.md +++ b/.specify/templates/spec-template.md @@ -1,6 +1,6 @@ # Feature Specification: [FEATURE NAME] -**Feature Branch**: `[###-feature-name]` +**Work Branch**: `/[###-descriptor]` where `` ∈ {feature, fix, docs, chore} **Created**: [DATE] **Status**: Draft **Input**: User description: "$ARGUMENTS" @@ -15,6 +15,7 @@ List how this feature will comply with core principles: - Dead Code Prohibition (P10): Identify any functions to remove or refactor; commit with tests. - Focused Comments (P11): Plan for concise logic/rationale comments; avoid narrative. - Test Path Mirroring (P12): Place unit tests at `tests/unit//test_.py`. +- Branch Naming Consistency (P13): Branch MUST start with one of: `feature/`, `fix/`, `docs/`, `chore/`. Use kebab-case descriptor (optional numeric ID). Rename before merge if violated. ## User Scenarios & Testing *(mandatory)* diff --git a/.specify/templates/tasks-template.md b/.specify/templates/tasks-template.md index f66d1c40..1740d823 100644 --- a/.specify/templates/tasks-template.md +++ b/.specify/templates/tasks-template.md @@ -20,6 +20,7 @@ description: "Task list template for feature implementation" - Single project: `release_notes_generator/` for source, `tests/` for tests - Tests MUST go under `tests/unit/` (unit) or `tests/integration/` (integration) - Mirrored paths: For `release_notes_generator/x/y.py` create `tests/unit/release_notes_generator/x/test_y.py`. +- Branch naming: Branch MUST start with allowed prefix (feature|fix|docs|chore) + kebab-case descriptor.