aws-test-plugin 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. aws_test_plugin-0.1.0/.claude-plugin/plugin.json +25 -0
  2. aws_test_plugin-0.1.0/.gitattributes +9 -0
  3. aws_test_plugin-0.1.0/.github/CODEOWNERS +11 -0
  4. aws_test_plugin-0.1.0/.github/pull_request_template.md +37 -0
  5. aws_test_plugin-0.1.0/.github/workflows/ci.yml +113 -0
  6. aws_test_plugin-0.1.0/.github/workflows/codeql.yml +43 -0
  7. aws_test_plugin-0.1.0/.github/workflows/publish.yml +53 -0
  8. aws_test_plugin-0.1.0/.gitignore +47 -0
  9. aws_test_plugin-0.1.0/.python-version +1 -0
  10. aws_test_plugin-0.1.0/CONTRIBUTING.md +294 -0
  11. aws_test_plugin-0.1.0/LICENSE +190 -0
  12. aws_test_plugin-0.1.0/PKG-INFO +342 -0
  13. aws_test_plugin-0.1.0/PLAN.md +78 -0
  14. aws_test_plugin-0.1.0/README.md +280 -0
  15. aws_test_plugin-0.1.0/agents/aws-test-engineer.md +95 -0
  16. aws_test_plugin-0.1.0/pyproject.toml +134 -0
  17. aws_test_plugin-0.1.0/skills/aws-contract-testing/SKILL.md +170 -0
  18. aws_test_plugin-0.1.0/skills/aws-contract-testing/references/openapi-patterns.md +249 -0
  19. aws_test_plugin-0.1.0/skills/aws-e2e-testing/SKILL.md +206 -0
  20. aws_test_plugin-0.1.0/skills/aws-e2e-testing/references/api-gateway-patterns.md +294 -0
  21. aws_test_plugin-0.1.0/skills/aws-e2e-testing/references/batch-patterns.md +184 -0
  22. aws_test_plugin-0.1.0/skills/aws-e2e-testing/references/step-function-patterns.md +210 -0
  23. aws_test_plugin-0.1.0/skills/aws-integration-testing/SKILL.md +206 -0
  24. aws_test_plugin-0.1.0/skills/aws-integration-testing/references/lambda-dynamodb-patterns.md +240 -0
  25. aws_test_plugin-0.1.0/skills/aws-integration-testing/references/lambda-eventbridge-patterns.md +337 -0
  26. aws_test_plugin-0.1.0/skills/aws-integration-testing/references/lambda-kinesis-patterns.md +431 -0
  27. aws_test_plugin-0.1.0/skills/aws-integration-testing/references/lambda-rds-patterns.md +227 -0
  28. aws_test_plugin-0.1.0/skills/aws-integration-testing/references/lambda-s3-patterns.md +174 -0
  29. aws_test_plugin-0.1.0/skills/aws-integration-testing/references/lambda-sns-patterns.md +350 -0
  30. aws_test_plugin-0.1.0/skills/aws-integration-testing/references/lambda-sqs-patterns.md +406 -0
  31. aws_test_plugin-0.1.0/skills/aws-perf-load-testing/SKILL.md +203 -0
  32. aws_test_plugin-0.1.0/skills/aws-perf-load-testing/references/benchmark-patterns.md +325 -0
  33. aws_test_plugin-0.1.0/skills/aws-perf-load-testing/references/locust-patterns.md +370 -0
  34. aws_test_plugin-0.1.0/skills/aws-test-orchestrator/SKILL.md +320 -0
  35. aws_test_plugin-0.1.0/skills/aws-test-orchestrator/references/secrets-and-config.md +644 -0
  36. aws_test_plugin-0.1.0/skills/aws-unit-testing/SKILL.md +520 -0
  37. aws_test_plugin-0.1.0/skills/aws-unit-testing/references/boundary-branch-patterns.md +308 -0
  38. aws_test_plugin-0.1.0/skills/aws-unit-testing/references/edge-case-patterns.md +543 -0
  39. aws_test_plugin-0.1.0/src/aws_test_plugin/AGENTS.md +66 -0
  40. aws_test_plugin-0.1.0/src/aws_test_plugin/__init__.py +3 -0
  41. aws_test_plugin-0.1.0/src/aws_test_plugin/cli.py +199 -0
  42. aws_test_plugin-0.1.0/src/aws_test_plugin/scripts/analyze_results.py +208 -0
  43. aws_test_plugin-0.1.0/src/aws_test_plugin/scripts/run_tests.py +187 -0
  44. aws_test_plugin-0.1.0/src/aws_test_plugin/scripts/scaffold.py +316 -0
  45. aws_test_plugin-0.1.0/tests/test_cli.py +253 -0
  46. aws_test_plugin-0.1.0/uv.lock +3102 -0
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "aws-test-plugin",
3
+ "description": "AI-powered test generation skills for AWS Python projects — Lambda, API Gateway, Step Functions, and Batch. Generates E2E, integration, contract, performance, and load tests by reading actual handler code.",
4
+ "version": "0.1.0",
5
+ "author": {
6
+ "name": "whitewhiteqq"
7
+ },
8
+ "homepage": "https://github.com/whitewhiteqq/aws-test-plugin",
9
+ "repository": "https://github.com/whitewhiteqq/aws-test-plugin",
10
+ "license": "Apache-2.0",
11
+ "keywords": [
12
+ "aws",
13
+ "testing",
14
+ "lambda",
15
+ "api-gateway",
16
+ "step-functions",
17
+ "batch",
18
+ "pytest",
19
+ "moto",
20
+ "locust",
21
+ "e2e",
22
+ "integration",
23
+ "contract"
24
+ ]
25
+ }
@@ -0,0 +1,9 @@
1
+ * text=auto
2
+
3
+ *.md text eol=lf
4
+ *.py text eol=lf
5
+ *.toml text eol=lf
6
+ *.json text eol=lf
7
+ *.yml text eol=lf
8
+ *.yaml text eol=lf
9
+ uv.lock text eol=lf
@@ -0,0 +1,11 @@
1
+ # Default owners for the repository
2
+ * @whitewhiteqq
3
+
4
+ # CI and repository governance
5
+ /.github/ @whitewhiteqq
6
+
7
+ # Package source and test assets
8
+ /src/ @whitewhiteqq
9
+ /tests/ @whitewhiteqq
10
+ /skills/ @whitewhiteqq
11
+ /agents/ @whitewhiteqq
@@ -0,0 +1,37 @@
1
+ ## Summary
2
+
3
+ - Describe the change clearly.
4
+ - Link any issue, task, or discussion if relevant.
5
+ - Use a PR title in conventional format when possible, for example `feat(cli): add agent filter`.
6
+ - State the problem, the approach, and any important tradeoffs.
7
+
8
+ ## PR Target
9
+
10
+ - [ ] This PR targets `develop`
11
+
12
+ ## History Hygiene
13
+
14
+ - [ ] My branch is rebased on the latest target branch
15
+ - [ ] This PR is intended for `Rebase and merge` or `Squash and merge`
16
+ - [ ] I did not add merge commits to this branch unless a maintainer explicitly requested it
17
+
18
+ ## Validation
19
+
20
+ - [ ] `uv run pytest tests/ -v`
21
+ - [ ] `uv run ruff check src tests`
22
+ - [ ] `uv run ruff format --check src tests`
23
+ - [ ] `uv run mypy src`
24
+ - [ ] `uv run bandit -q -c pyproject.toml -r src`
25
+ - [ ] `uv run pip-audit`
26
+
27
+ ## Risk Review
28
+
29
+ - [ ] No secrets, credentials, or private data were added
30
+ - [ ] Documentation was updated if behavior or workflow changed
31
+ - [ ] CI should pass for this branch before merge
32
+
33
+ ## Notes For Reviewers
34
+
35
+ - Call out any areas that need special attention.
36
+ - Note any follow-up work that is intentionally out of scope.
37
+ - Mention whether the final merge should be `Rebase and merge` or `Squash and merge` if maintainers need guidance.
@@ -0,0 +1,113 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ - develop
8
+ push:
9
+ branches:
10
+ - main
11
+ - develop
12
+
13
+ permissions:
14
+ contents: read
15
+
16
+ jobs:
17
+ test:
18
+ name: Test (Python ${{ matrix.python-version }})
19
+ runs-on: ubuntu-latest
20
+ strategy:
21
+ fail-fast: false
22
+ matrix:
23
+ python-version: ["3.10", "3.11", "3.12", "3.13"]
24
+
25
+ steps:
26
+ - name: Checkout
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Set up Python
30
+ uses: actions/setup-python@v5
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+
34
+ - name: Set up uv
35
+ uses: astral-sh/setup-uv@v5
36
+
37
+ - name: Sync dependencies
38
+ run: uv sync
39
+
40
+ - name: Run tests
41
+ run: uv run pytest tests/ -v
42
+
43
+ lint:
44
+ name: Lint
45
+ runs-on: ubuntu-latest
46
+
47
+ steps:
48
+ - name: Checkout
49
+ uses: actions/checkout@v4
50
+
51
+ - name: Set up Python
52
+ uses: actions/setup-python@v5
53
+ with:
54
+ python-version: "3.12"
55
+
56
+ - name: Set up uv
57
+ uses: astral-sh/setup-uv@v5
58
+
59
+ - name: Sync dependencies
60
+ run: uv sync
61
+
62
+ - name: Ruff check
63
+ run: uv run ruff check src tests
64
+
65
+ - name: Ruff format check
66
+ run: uv run ruff format --check src tests
67
+
68
+ typecheck:
69
+ name: Type Check
70
+ runs-on: ubuntu-latest
71
+
72
+ steps:
73
+ - name: Checkout
74
+ uses: actions/checkout@v4
75
+
76
+ - name: Set up Python
77
+ uses: actions/setup-python@v5
78
+ with:
79
+ python-version: "3.12"
80
+
81
+ - name: Set up uv
82
+ uses: astral-sh/setup-uv@v5
83
+
84
+ - name: Sync dependencies
85
+ run: uv sync
86
+
87
+ - name: Run mypy
88
+ run: uv run mypy src
89
+
90
+ security:
91
+ name: Security
92
+ runs-on: ubuntu-latest
93
+
94
+ steps:
95
+ - name: Checkout
96
+ uses: actions/checkout@v4
97
+
98
+ - name: Set up Python
99
+ uses: actions/setup-python@v5
100
+ with:
101
+ python-version: "3.12"
102
+
103
+ - name: Set up uv
104
+ uses: astral-sh/setup-uv@v5
105
+
106
+ - name: Sync dependencies
107
+ run: uv sync
108
+
109
+ - name: Run Bandit
110
+ run: uv run bandit -q -c pyproject.toml -r src
111
+
112
+ - name: Run pip-audit
113
+ run: uv run pip-audit
@@ -0,0 +1,43 @@
1
+ name: Code Scanning
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - main
7
+ - develop
8
+ push:
9
+ branches:
10
+ - main
11
+ - develop
12
+ schedule:
13
+ - cron: "23 3 * * 1"
14
+
15
+ permissions:
16
+ actions: read
17
+ contents: read
18
+ security-events: write
19
+
20
+ jobs:
21
+ analyze:
22
+ name: CodeQL
23
+ runs-on: ubuntu-latest
24
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
25
+ strategy:
26
+ fail-fast: false
27
+ matrix:
28
+ language: [python]
29
+
30
+ steps:
31
+ - name: Checkout
32
+ uses: actions/checkout@v4
33
+
34
+ - name: Initialize CodeQL
35
+ uses: github/codeql-action/init@v4
36
+ with:
37
+ languages: ${{ matrix.language }}
38
+ build-mode: none
39
+
40
+ - name: Analyze
41
+ uses: github/codeql-action/analyze@v4
42
+ with:
43
+ category: "/language:${{ matrix.language }}"
@@ -0,0 +1,53 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+ id-token: write # Required for trusted publishing
10
+
11
+ jobs:
12
+ build:
13
+ name: Build distribution
14
+ runs-on: ubuntu-latest
15
+
16
+ steps:
17
+ - name: Checkout
18
+ uses: actions/checkout@v4
19
+
20
+ - name: Set up Python
21
+ uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.12"
24
+
25
+ - name: Install build tools
26
+ run: pip install build
27
+
28
+ - name: Build package
29
+ run: python -m build
30
+
31
+ - name: Upload artifacts
32
+ uses: actions/upload-artifact@v4
33
+ with:
34
+ name: dist
35
+ path: dist/
36
+
37
+ publish:
38
+ name: Publish to PyPI
39
+ needs: build
40
+ runs-on: ubuntu-latest
41
+ environment:
42
+ name: pypi
43
+ url: https://pypi.org/p/aws-test-plugin
44
+
45
+ steps:
46
+ - name: Download artifacts
47
+ uses: actions/download-artifact@v4
48
+ with:
49
+ name: dist
50
+ path: dist/
51
+
52
+ - name: Publish to PyPI
53
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,47 @@
1
+ # Byte-compiled
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+
8
+ # Distribution
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+ *.egg
13
+
14
+ # Virtual environments
15
+ .venv/
16
+ venv/
17
+ env/
18
+
19
+ # IDE
20
+ .idea/
21
+ .vscode/
22
+ *.swp
23
+ *.swo
24
+ .history/
25
+
26
+ # OS
27
+ .DS_Store
28
+ Thumbs.db
29
+
30
+ # Claude local settings
31
+ .claude/settings.json
32
+ .claude/settings.local.json
33
+
34
+ # Local environment files
35
+ .env
36
+ .env.*
37
+ !.env.example
38
+
39
+ # Test artifacts
40
+ tests/reports/
41
+ .pytest_cache/
42
+ htmlcov/
43
+ .coverage
44
+ .coverage.*
45
+ *.xml
46
+
47
+ # uv.lock is committed for reproducibility
@@ -0,0 +1 @@
1
+ 3.12
@@ -0,0 +1,294 @@
1
+ # Contributing to aws-test-plugin
2
+
3
+ ## Development Setup
4
+
5
+ ```bash
6
+ # Clone
7
+ git clone https://github.com/whitewhiteqq/aws-test-plugin.git
8
+ cd aws-test-plugin
9
+
10
+ # Install uv (if not already installed)
11
+ # Windows: powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
12
+ # macOS/Linux: curl -LsSf https://astral.sh/uv/install.sh | sh
13
+
14
+ # Install with dev dependencies
15
+ uv sync
16
+
17
+ # Run tests
18
+ uv run pytest tests/ -v
19
+
20
+ # Lint
21
+ uv run ruff check src tests
22
+ uv run ruff format --check src tests
23
+
24
+ # Type checking
25
+ uv run mypy src
26
+
27
+ # Security scans
28
+ uv run bandit -q -c pyproject.toml -r src
29
+ uv run pip-audit
30
+ ```
31
+
32
+ ## Project Structure
33
+
34
+ ```
35
+ aws-test-plugin/
36
+ ├── skills/ # Skill definitions (auto-discovered by npx skills add)
37
+ │ ├── aws-test-orchestrator/SKILL.md
38
+ │ ├── aws-e2e-testing/ # SKILL.md + references/
39
+ │ ├── aws-integration-testing/
40
+ │ ├── aws-contract-testing/
41
+ │ └── aws-perf-load-testing/
42
+ ├── agents/
43
+ │ └── aws-test-engineer.md # Agent definition
44
+ ├── src/aws_test_plugin/
45
+ │ ├── __init__.py # Package version
46
+ │ ├── cli.py # CLI entry point (aws-test-plugin command)
47
+ │ ├── AGENTS.md # Codex-compatible instructions
48
+ │ └── scripts/ # Scaffold, run, analyze scripts
49
+ └── tests/
50
+ ```
51
+
52
+ ## Adding a New Skill
53
+
54
+ 1. Create `skills/<skill-name>/SKILL.md`
55
+ 2. Add YAML frontmatter with `name`, `description`, `license`, and `metadata`
56
+ 3. Add reference patterns in `references/` subdirectory
57
+ 4. Update the orchestrator skill's delegation table if needed
58
+ 5. Add the skill name to the agent's `skills:` list in `agents/aws-test-engineer.md`
59
+
60
+ ## Adding Reference Patterns
61
+
62
+ Reference files go in `skills/<skill-name>/references/<pattern-name>.md`.
63
+ Each file should contain:
64
+ - A clear heading describing the pattern category
65
+ - Multiple `## Pattern N: <Name>` sections
66
+ - Complete, runnable Python code blocks
67
+ - Inline comments explaining key decisions
68
+
69
+ ## Skill YAML Frontmatter
70
+
71
+ ```yaml
72
+ ---
73
+ name: skill-name # Must match directory name
74
+ license: Apache-2.0
75
+ metadata:
76
+ author: whitewhiteqq
77
+ version: "0.1.0"
78
+ description: > # Max 1024 chars — this triggers the skill
79
+ What it does, when to use it,
80
+ trigger phrases that should activate it.
81
+ ---
82
+ ```
83
+
84
+ ## Code Style
85
+
86
+ - Python 3.10+ (use `|` union types, not `Optional`)
87
+ - Ruff for linting and formatting
88
+ - Keep runtime dependencies minimal and justified
89
+ - Test patterns should be self-contained and runnable
90
+
91
+ ## Git as Engineering Memory
92
+
93
+ This project treats git history as a **persistent knowledge base** for both
94
+ human contributors and AI agents — not just a code transport mechanism.
95
+ Every commit message, PR description, and release tag is a record that
96
+ future readers will use to reconstruct *why* the codebase looks the way it
97
+ does, without opening a browser or searching Slack.
98
+
99
+ Design every commit message as if it will be read with zero prior context.
100
+ The goal: anyone should be able to run `git log --oneline`, pick a commit,
101
+ read its body, and fully understand the decision.
102
+
103
+ Principles:
104
+
105
+ - **Preserve the reasoning chain.** Record what changed, why, what
106
+ alternatives were considered, and what evidence supported the choice.
107
+ An AI agent that sees "we rejected approach X because of constraint Y"
108
+ will not waste a session re-proposing X.
109
+ - **Prefer granular commits over squashed blobs.** A well-structured
110
+ sequence of 4 commits teaches more than 1 squashed commit with a bullet
111
+ list. Default to `Rebase and merge`; reserve `Squash and merge` for
112
+ branches whose intermediate commits are unsalvageable noise.
113
+ - **Keep context in git, not only on GitHub.** PR discussions, review
114
+ feedback, and design context must be distilled into the merge commit
115
+ message or individual commit bodies, because `git log` works offline
116
+ and survives forks — GitHub PR threads do not.
117
+ - **Make history searchable.** Use consistent Conventional Commit types,
118
+ scopes, and keywords so `git log --grep` and AI semantic search return
119
+ focused results.
120
+ - **Tag decision boundaries.** Annotated release tags mark the point where
121
+ a set of changes was considered stable. Tag messages summarize what
122
+ shipped and why, giving AI agents a coarse-grained timeline.
123
+
124
+ ## Branch Strategy
125
+
126
+ - `main` is the release branch and should always be releasable.
127
+ - `develop` is the integration branch for reviewed work that is not yet released.
128
+ - Contributors should open short-lived feature or fix branches from `develop`.
129
+ - Do not push directly to `main` or `develop` except for urgent maintainer-only repository administration.
130
+ - Default to `Rebase and merge` for pull requests into `develop` so that every individual commit — and its reasoning — is preserved in the public history. Use `Squash and merge` only when the branch contains exploratory or fixup commits that add no lasting value; when squashing, the single merge commit must capture all essential context from the branch (see Commit Message Style).
131
+ - Avoid GitHub merge commits for routine pull requests because they create noisy branch divergence and a less readable graph.
132
+ - Promote releases from `develop` to `main` with a maintainer-run fast-forward update so both branches share identical history.
133
+ - Tag every release on `main` with an annotated tag (`git tag -a v0.1.0 -m "..."`). The tag message should summarize what shipped, key decisions made since the prior release, and any known limitations. Annotated tags are git objects — they survive cloning and forking, unlike GitHub-only release notes.
134
+
135
+ ## Commit Message Style
136
+
137
+ Use Conventional Commits for public history. The preferred format is:
138
+
139
+ ```text
140
+ type(scope): short imperative summary
141
+ ```
142
+
143
+ For non-trivial changes, include the full body template so git history
144
+ serves as **engineering memory** — future contributors (and LLMs) can
145
+ reconstruct the reasoning behind every decision:
146
+
147
+ ```text
148
+ type(scope): short imperative summary
149
+
150
+ INTENTION:
151
+ Why this change exists and what engineering principle it serves.
152
+ Connect to the broader goal so future readers understand the
153
+ "why behind the why."
154
+
155
+ WHAT CHANGED:
156
+ - Concise bullet list of specific changes
157
+ - Group by file or area when helpful
158
+
159
+ WHY:
160
+ Context that connects this change to the codebase's evolution.
161
+ What was wrong or missing before, and how this moves the project
162
+ forward.
163
+
164
+ ALTERNATIVES CONSIDERED:
165
+ - Option A: description — rejected because <reason>
166
+ - Option B: description — rejected because <reason>
167
+ (Omit when no meaningful alternatives exist. Include whenever a
168
+ design choice was made — this prevents future contributors and
169
+ AI agents from re-proposing already-rejected approaches.)
170
+
171
+ REFS:
172
+ - Closes #<issue>
173
+ - Related: <short-sha> (<one-line summary>)
174
+ - Follows up on: <short-sha>
175
+ (Omit when no related items apply. These cross-references let
176
+ AI agents trace reasoning chains across multiple commits.)
177
+
178
+ VERIFIED:
179
+ - What was tested or checked before committing
180
+ - Which checks were intentionally skipped and why
181
+ ```
182
+
183
+ Examples:
184
+
185
+ ```text
186
+ feat(cli): add agent filter for init command
187
+ fix(scaffold): handle missing tests directory on Windows
188
+ docs(readme): clarify GitHub merge strategy
189
+ test(cli): cover invalid agent option
190
+ ci(codeql): upgrade action to v4
191
+ refactor(scripts): simplify test result parsing
192
+ ```
193
+
194
+ Full body example:
195
+
196
+ ```text
197
+ refactor(scripts): align scaffold and runner to component-prefixed naming
198
+
199
+ INTENTION:
200
+ The plugin provides generic building blocks that the LLM customises to
201
+ the user's actual codebase. If the building blocks themselves use
202
+ inconsistent naming, the LLM inherits those inconsistencies. This commit
203
+ enforces the component-prefixed env var convention across all scripts.
204
+
205
+ WHAT CHANGED:
206
+ - scaffold.py: ENV_EXAMPLE_TEMPLATE uses ORDERS_API_BASE_URL, not
207
+ API_BASE_URL; removed fake AWS creds (conftest handles those)
208
+ - run_tests.py: removed non-prefixed API_BASE_URL gate check; E2E
209
+ tests now self-skip via pytest.skip()
210
+
211
+ WHY:
212
+ Previous iterations added component-prefixed naming to all skill docs
213
+ but scaffold.py and run_tests.py still assumed a single global
214
+ API_BASE_URL. This mismatch would confuse an LLM generating tests
215
+ for a real monorepo project.
216
+
217
+ ALTERNATIVES CONSIDERED:
218
+ - Keep a single global API_BASE_URL and add per-component overrides —
219
+ rejected because it creates ambiguity about which variable the LLM
220
+ should reference in generated tests.
221
+
222
+ REFS:
223
+ - Follows up on: a1b2c3d (docs: add component-prefixed env vars to skills)
224
+
225
+ VERIFIED:
226
+ - All 19 existing tests pass (pytest tests/ -v)
227
+ - No remaining non-prefixed API_BASE_URL in os.getenv() calls
228
+ ```
229
+
230
+ Guidelines:
231
+
232
+ - Use one of: `feat`, `fix`, `docs`, `refactor`, `test`, `ci`, `chore`, `build`, `perf`.
233
+ - Use a scope when it helps reviewers understand the affected area, for example `cli`, `readme`, `skills`, `tests`, `scaffold`, or `ci`.
234
+ - Write the summary in imperative mood: `add`, `fix`, `update`, not `added` or `fixed`.
235
+ - Keep the subject line short and specific. A good target is under 72 characters.
236
+ - Do not end the subject line with a period.
237
+ - If the change is breaking, use `!` after the type or scope and explain it in the body.
238
+ - For trivial changes (typo fixes, formatting), the subject line alone is sufficient — skip the body.
239
+ - For anything that changes behaviour, adds a feature, or fixes a bug, include at least INTENTION and WHAT CHANGED.
240
+ - Include ALTERNATIVES CONSIDERED whenever a design choice was made between two or more viable options. This is the single most valuable section for AI memory — it prevents circular re-discovery of rejected approaches.
241
+ - Include REFS when the commit relates to an issue, continues work from a prior commit, or responds to review feedback. Short SHAs and issue numbers create a navigable graph that AI agents can traverse with `git log --grep`.
242
+ - When a commit is generated or substantially assisted by an AI agent, add a `Co-authored-by: <agent-name>` trailer or note `AI-assisted: <tool>` in the body so future readers can calibrate trust and understand the commit's provenance.
243
+
244
+ ## Pull Request Style
245
+
246
+ Treat the pull request as the public review record — but remember that
247
+ PR threads live on GitHub, not in git. Any context that matters long-term
248
+ must also land in the commit messages that enter `develop`.
249
+
250
+ - Keep each pull request focused on one concern.
251
+ - Use a PR title that follows the same Conventional Commit style as the final merge commit.
252
+ - In the description, explain the problem, the approach, the risk level, and alternatives that were considered.
253
+ - List the validation you ran and any checks you intentionally did not run.
254
+ - Call out follow-up work instead of mixing it into the same PR.
255
+ - Avoid noisy history such as merge commits, fixup chains, or exploratory commit messages in public branches.
256
+ - Treat contributor pull requests as changes into `develop`; release promotion to `main` is a maintainer operation, not the standard contributor PR flow.
257
+ - **Before merging**, verify that the commit message(s) entering `develop` contain all essential reasoning from the PR discussion. If review feedback changed the approach, update the relevant commit body to reflect the final rationale — do not leave the reasoning only in GitHub comments. `git log` is the AI agent's primary context source; PR comments are supplementary.
258
+ - When using `Squash and merge`, the single resulting commit message must consolidate context from all individual commits and the PR discussion into the full INTENTION / WHAT CHANGED / WHY / ALTERNATIVES CONSIDERED / REFS / VERIFIED template.
259
+
260
+ ## Submitting Changes
261
+
262
+ 1. Fork the repo
263
+ 2. Create a feature branch from `develop`: `git checkout -b feat/new-pattern origin/develop`
264
+ 3. Make your changes
265
+ 4. Rebase your branch on the latest `origin/develop` before opening or updating the pull request
266
+ 5. Run local quality checks: `uv run pytest tests/ -v`, `uv run ruff check src tests`, `uv run ruff format --check src tests`, `uv run mypy src`, `uv run bandit -q -c pyproject.toml -r src`, and `uv run pip-audit`
267
+ 6. Submit a pull request to `develop` using `.github/pull_request_template.md`
268
+ 7. Merge pull requests with `Rebase and merge` (preferred — preserves individual commit reasoning) or `Squash and merge` (only when intermediate commits are noise); do not use merge commits
269
+ 8. Release `develop` to `main` with a maintainer-run fast-forward update after CI passes on `develop`; use `git merge --ff-only develop` from a local checkout of `main` so `main` advances without rewriting or duplicating commit history
270
+ 9. Review responsibility is assigned through `.github/CODEOWNERS`
271
+
272
+ ## Maintainer Notes
273
+
274
+ - Protect `main` and `develop` against direct pushes.
275
+ - Enable `Rebase and merge` (preferred) and `Squash and merge` (fallback) for contributor pull requests into `develop`. Disable `Create a merge commit` to enforce linear history.
276
+ - Do not rely on GitHub merge buttons for release promotion to `main`; use a local `git merge --ff-only develop` followed by `git push origin main`.
277
+ - Configure `develop` branch protection or rulesets to require linear history and the CI checks `Test (Python 3.10)`, `Test (Python 3.11)`, `Test (Python 3.12)`, `Test (Python 3.13)`, `Lint`, `Type Check`, and `Security`.
278
+ - Configure `main` so only maintainers can update it, with no force pushes or deletions.
279
+ - Keep release updates focused. Avoid mixing repository governance, experiments, and product changes in the same release.
280
+ - Do not rewrite shared branch history unless there is a clear operational reason and the change is communicated.
281
+ - After each fast-forward update to `main`, create an annotated tag and push it:
282
+ ```bash
283
+ git tag -a v<VERSION> -m "v<VERSION>: <one-line theme>
284
+
285
+ WHAT SHIPPED:
286
+ - Key changes since the prior release
287
+
288
+ KEY DECISIONS:
289
+ - Significant design choices made in this release cycle
290
+
291
+ KNOWN LIMITATIONS:
292
+ - Open issues or deferred work"
293
+ git push origin v<VERSION>
294
+ ```