open-codev-workflow 0.1.0__py3-none-any.whl
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.
- codev_workflow/__init__.py +5 -0
- codev_workflow/__main__.py +4 -0
- codev_workflow/bundle/.agents/skills/build-change/SKILL.md +96 -0
- codev_workflow/bundle/.agents/skills/build-change/agents/openai.yaml +4 -0
- codev_workflow/bundle/.agents/skills/build-change/assets/implementation-plan.template.md +51 -0
- codev_workflow/bundle/.agents/skills/define-product/SKILL.md +79 -0
- codev_workflow/bundle/.agents/skills/define-product/agents/openai.yaml +4 -0
- codev_workflow/bundle/.agents/skills/define-product/assets/brief.template.md +50 -0
- codev_workflow/bundle/.agents/skills/design-solution/SKILL.md +75 -0
- codev_workflow/bundle/.agents/skills/design-solution/agents/openai.yaml +4 -0
- codev_workflow/bundle/.agents/skills/design-solution/assets/decision.template.md +26 -0
- codev_workflow/bundle/.agents/skills/design-solution/assets/design.template.md +76 -0
- codev_workflow/bundle/.agents/skills/launch-product/SKILL.md +66 -0
- codev_workflow/bundle/.agents/skills/launch-product/agents/openai.yaml +4 -0
- codev_workflow/bundle/.agents/skills/launch-product/assets/launch-plan.template.md +48 -0
- codev_workflow/bundle/.agents/skills/plan-delivery/SKILL.md +140 -0
- codev_workflow/bundle/.agents/skills/plan-delivery/agents/openai.yaml +4 -0
- codev_workflow/bundle/.agents/skills/plan-delivery/assets/delivery-plan.template.md +41 -0
- codev_workflow/bundle/.agents/skills/review-change/SKILL.md +48 -0
- codev_workflow/bundle/.agents/skills/review-change/agents/openai.yaml +4 -0
- codev_workflow/bundle/.agents/skills/specify-project/SKILL.md +205 -0
- codev_workflow/bundle/.agents/skills/specify-project/agents/openai.yaml +4 -0
- codev_workflow/bundle/.agents/skills/specify-project/assets/specification.template.md +151 -0
- codev_workflow/bundle/.agents/skills/specify-project/references/interview-coverage.md +303 -0
- codev_workflow/bundle/.agents/skills/specify-project/scripts/validate_specification.py +143 -0
- codev_workflow/bundle/.opencode/agents/builder.md +54 -0
- codev_workflow/bundle/.opencode/agents/orchestrator.md +72 -0
- codev_workflow/bundle/.opencode/agents/reviewer.md +35 -0
- codev_workflow/bundle/AGENTS.md +23 -0
- codev_workflow/bundle/docs/AI-WORKFLOW-PROMPTS.md +318 -0
- codev_workflow/bundle/docs/WORKFLOW-COOKBOOK.md +419 -0
- codev_workflow/bundle/docs/WORKFLOW-HUMAN.md +212 -0
- codev_workflow/bundle/docs/for-ai/WORKFLOW-AGENTS.md +171 -0
- codev_workflow/bundle/docs/handbooks/IDEA-TO-PRODUCTION-HANDBOOK.md +1190 -0
- codev_workflow/bundle/docs/handbooks/LANGUAGE-AGNOSTIC-PROJECT-HANDBOOK.md +745 -0
- codev_workflow/bundle/docs/handbooks/PYTHON-PROJECT-HANDBOOK.md +960 -0
- codev_workflow/bundle/evals/development-workflow/scenarios.json +132 -0
- codev_workflow/bundle/scripts/evaluate-development-workflow.py +352 -0
- codev_workflow/bundle/scripts/validate-development-workflow.py +213 -0
- codev_workflow/cli.py +140 -0
- codev_workflow/installer.py +891 -0
- open_codev_workflow-0.1.0.dist-info/METADATA +150 -0
- open_codev_workflow-0.1.0.dist-info/RECORD +47 -0
- open_codev_workflow-0.1.0.dist-info/WHEEL +5 -0
- open_codev_workflow-0.1.0.dist-info/entry_points.txt +2 -0
- open_codev_workflow-0.1.0.dist-info/licenses/LICENSE +28 -0
- open_codev_workflow-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,960 @@
|
|
|
1
|
+
# Google-Inspired Python Project Handbook
|
|
2
|
+
|
|
3
|
+
**Audience:** first-time contributors, experienced Python developers, technical
|
|
4
|
+
leads, and engineering managers
|
|
5
|
+
|
|
6
|
+
**Purpose:** create a maintainable, testable, secure Python repository from an
|
|
7
|
+
empty directory and operate it with disciplined human and AI collaboration
|
|
8
|
+
|
|
9
|
+
**Interpretation of “Google style”:** this handbook applies Google's publicly
|
|
10
|
+
documented engineering principles and Python style rules. The concrete open
|
|
11
|
+
source stack—`pyproject.toml`, `src/`, uv, Ruff, mypy, pytest, and GitHub
|
|
12
|
+
Actions—is a pragmatic industry implementation. It is not a claim that all
|
|
13
|
+
Google teams use these exact tools or repository layouts.
|
|
14
|
+
|
|
15
|
+
## 1. The standard in one page
|
|
16
|
+
|
|
17
|
+
Use the repository's four human-facing steps—Understand, Build, Review, and
|
|
18
|
+
Ship—from the [Product Development Workflow](../WORKFLOW-HUMAN.md). Developers
|
|
19
|
+
describe their work normally; the AI routes to detailed skills internally.
|
|
20
|
+
|
|
21
|
+
A production Python project should have:
|
|
22
|
+
|
|
23
|
+
- one canonical Git repository and a protected `main` branch;
|
|
24
|
+
- a written user or business outcome before significant implementation;
|
|
25
|
+
- a reviewed technical design for material architecture, API, data, security,
|
|
26
|
+
privacy, or migration decisions;
|
|
27
|
+
- a `src/` package layout and a standards-based `pyproject.toml`;
|
|
28
|
+
- one dependency declaration, one committed lockfile for applications, and a
|
|
29
|
+
reproducible environment;
|
|
30
|
+
- automated formatting, linting, type checking, tests, packaging, and security
|
|
31
|
+
checks available through documented commands;
|
|
32
|
+
- tests in the same change as behavior;
|
|
33
|
+
- small, focused pull requests reviewed by someone other than the author;
|
|
34
|
+
- code ownership, explicit risk escalation, and no secrets in Git;
|
|
35
|
+
- automated release artifacts built from reviewed commits;
|
|
36
|
+
- observability, progressive rollout, and rollback for production services; and
|
|
37
|
+
- repository-local instructions that tell AI tools what they may read, change,
|
|
38
|
+
validate, and escalate.
|
|
39
|
+
|
|
40
|
+
Google's public engineering guidance emphasizes canonical documentation under
|
|
41
|
+
source control, design review for major projects, trunk-oriented development,
|
|
42
|
+
small reviewed changes, tests with changes, actionable CI, and progressive
|
|
43
|
+
delivery. See the [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html),
|
|
44
|
+
[Software Engineering at Google](https://abseil.io/resources/swe-book), and
|
|
45
|
+
[Google Engineering Practices](https://google.github.io/eng-practices/review/).
|
|
46
|
+
|
|
47
|
+
## 2. Decide what you are creating
|
|
48
|
+
|
|
49
|
+
Do not initialize tooling until you can answer these questions.
|
|
50
|
+
|
|
51
|
+
For a greenfield product where those answers and the architecture are still
|
|
52
|
+
unclear, invoke `specify-project` before scaffolding. It conducts a one-question-
|
|
53
|
+
at-a-time interview, accepts the product frame before the technical design, and
|
|
54
|
+
creates one canonical `SPECIFICATION.md`. Use the normal `define-product` and
|
|
55
|
+
`design-solution` path for a bounded feature or when separate product and design
|
|
56
|
+
ownership is more useful. Never create all three artifacts with duplicated facts.
|
|
57
|
+
|
|
58
|
+
### 2.1 Project type
|
|
59
|
+
|
|
60
|
+
Choose one primary type:
|
|
61
|
+
|
|
62
|
+
| Type | Deliverable | Typical entry point | Dependency policy |
|
|
63
|
+
|---|---|---|---|
|
|
64
|
+
| Library | Wheel/sdist consumed by other projects | Imported public API | Broad compatible runtime ranges; test lowest and highest supported versions |
|
|
65
|
+
| CLI application | Installed executable | `[project.scripts]` | Lock exact deployment dependencies |
|
|
66
|
+
| Service | Container or deployment artifact | Server process | Lock exact dependencies and configuration schema |
|
|
67
|
+
| Batch/worker | Scheduled or queued process | Job command | Lock exact dependencies; make retries/idempotency explicit |
|
|
68
|
+
| Research prototype | Evidence, not production | Notebook/script | Time-box it; promote successful logic into a package before production |
|
|
69
|
+
|
|
70
|
+
Avoid combining unrelated deployables in one package. A monorepo can contain
|
|
71
|
+
multiple packages, but each deployable still needs an owner, dependency boundary,
|
|
72
|
+
build target, tests, and release unit.
|
|
73
|
+
|
|
74
|
+
### 2.2 Naming
|
|
75
|
+
|
|
76
|
+
Define three related names deliberately:
|
|
77
|
+
|
|
78
|
+
- **Repository:** `example-service`
|
|
79
|
+
- **Distribution package:** `example-service`
|
|
80
|
+
- **Python import package:** `example_service`
|
|
81
|
+
|
|
82
|
+
Use lowercase import modules with underscores and no dashes. Google’s Python
|
|
83
|
+
guide requires `.py` filenames without dashes and recommends `CapWords` for
|
|
84
|
+
classes and `lower_with_under` for modules and functions.
|
|
85
|
+
|
|
86
|
+
### 2.3 Runtime and support window
|
|
87
|
+
|
|
88
|
+
Write down:
|
|
89
|
+
|
|
90
|
+
- minimum and maximum supported Python versions;
|
|
91
|
+
- operating systems and CPU architectures;
|
|
92
|
+
- whether alternative interpreters are supported;
|
|
93
|
+
- expected project lifetime;
|
|
94
|
+
- availability, latency, throughput, and recovery objectives if it is a service;
|
|
95
|
+
- data classification and regulatory scope; and
|
|
96
|
+
- package or deployment destination.
|
|
97
|
+
|
|
98
|
+
For a new internal application, a reasonable default is the current stable
|
|
99
|
+
Python series used by your organization, with one previous series supported only
|
|
100
|
+
when consumers require it. This handbook uses Python 3.12 as an example baseline;
|
|
101
|
+
replace it with your documented support decision.
|
|
102
|
+
|
|
103
|
+
### 2.4 Ownership and risk
|
|
104
|
+
|
|
105
|
+
Before the first feature, name:
|
|
106
|
+
|
|
107
|
+
- accountable product owner;
|
|
108
|
+
- technical owner;
|
|
109
|
+
- code reviewers;
|
|
110
|
+
- production/on-call owner when applicable;
|
|
111
|
+
- security/privacy/compliance contacts; and
|
|
112
|
+
- release authority.
|
|
113
|
+
|
|
114
|
+
For a solo project, one person may hold several roles, but an independent human
|
|
115
|
+
review is still required before consequential releases whenever feasible.
|
|
116
|
+
|
|
117
|
+
## 3. Install the bootstrap tools
|
|
118
|
+
|
|
119
|
+
The recommended baseline is Git plus uv. uv manages Python versions,
|
|
120
|
+
environments, dependencies, lockfiles, commands, and builds. A standards-only
|
|
121
|
+
fallback using `python -m venv` and `pip` is acceptable if your organization
|
|
122
|
+
does not approve uv; keep the same repository structure and quality gates.
|
|
123
|
+
|
|
124
|
+
### 3.1 Install Git
|
|
125
|
+
|
|
126
|
+
Install Git through your operating system or company-managed developer image.
|
|
127
|
+
Configure your real identity:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
git config --global user.name "Your Name"
|
|
131
|
+
git config --global user.email "you@example.com"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Use signed commits or organization-managed signing when policy requires it.
|
|
135
|
+
|
|
136
|
+
### 3.2 Install uv
|
|
137
|
+
|
|
138
|
+
Use an organization-approved package manager or a pinned installer version.
|
|
139
|
+
Examples:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# macOS with Homebrew
|
|
143
|
+
brew install uv
|
|
144
|
+
|
|
145
|
+
# Windows with WinGet
|
|
146
|
+
winget install --id=astral-sh.uv -e
|
|
147
|
+
|
|
148
|
+
# Isolated Python installation
|
|
149
|
+
pipx install uv
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Do not execute an unreviewed network installer in a high-assurance environment.
|
|
153
|
+
The [official uv installation guide](https://docs.astral.sh/uv/getting-started/installation/)
|
|
154
|
+
documents installers, checksums, package managers, and version pinning.
|
|
155
|
+
|
|
156
|
+
Confirm:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
git --version
|
|
160
|
+
uv --version
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## 4. Create the repository step by step
|
|
164
|
+
|
|
165
|
+
The following example creates a package named `example_service`.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
uv init --lib example-service
|
|
169
|
+
cd example-service
|
|
170
|
+
git init -b main
|
|
171
|
+
uv python pin 3.12
|
|
172
|
+
uv add --dev pytest pytest-cov ruff mypy build
|
|
173
|
+
uv lock
|
|
174
|
+
uv sync
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Then create the policy and documentation directories:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
.agents/skills/
|
|
181
|
+
.github/workflows/
|
|
182
|
+
docs/design/decisions/
|
|
183
|
+
docs/features/
|
|
184
|
+
docs/operations/runbooks/
|
|
185
|
+
docs/product/
|
|
186
|
+
src/example_service/
|
|
187
|
+
tests/unit/
|
|
188
|
+
tests/integration/
|
|
189
|
+
tools/
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Use repository-native file operations rather than copying shell commands blindly.
|
|
193
|
+
Do not create empty directories merely to resemble the example; add a directory
|
|
194
|
+
when it has an owner and purpose.
|
|
195
|
+
|
|
196
|
+
Copy or adapt the human–AI workflow from this repository:
|
|
197
|
+
|
|
198
|
+
- [`AGENTS.md`](../../AGENTS.md)
|
|
199
|
+
- [`docs/WORKFLOW-HUMAN.md`](../WORKFLOW-HUMAN.md)
|
|
200
|
+
- [`docs/for-ai/WORKFLOW-AGENTS.md`](../for-ai/WORKFLOW-AGENTS.md)
|
|
201
|
+
- [the lifecycle skills and guided project facade](../../.agents/skills/)
|
|
202
|
+
|
|
203
|
+
Run the workflow validator after copying:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
python scripts/validate-development-workflow.py
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## 5. Canonical repository layout
|
|
210
|
+
|
|
211
|
+
Use this as a mature target, not a requirement to create every path on day one.
|
|
212
|
+
|
|
213
|
+
```text
|
|
214
|
+
example-service/
|
|
215
|
+
├── SPECIFICATION.md # Optional canonical greenfield blueprint
|
|
216
|
+
├── .agents/
|
|
217
|
+
│ └── skills/ # Repository-local AI lifecycle skills
|
|
218
|
+
├── .github/
|
|
219
|
+
│ ├── CODEOWNERS # Review ownership
|
|
220
|
+
│ ├── PULL_REQUEST_TEMPLATE.md # Change intent and evidence
|
|
221
|
+
│ └── workflows/
|
|
222
|
+
│ ├── ci.yml # Presubmit quality gates
|
|
223
|
+
│ └── release.yml # Artifact creation/publishing
|
|
224
|
+
├── docs/
|
|
225
|
+
│ ├── WORKFLOW-HUMAN.md
|
|
226
|
+
│ ├── for-ai/WORKFLOW-AGENTS.md
|
|
227
|
+
│ ├── product/ # Accepted product/feature briefs
|
|
228
|
+
│ ├── features/<feature>/ # Feature-local brief/design if useful
|
|
229
|
+
│ ├── design/
|
|
230
|
+
│ │ ├── system-design.md
|
|
231
|
+
│ │ └── decisions/ # Durable ADR-style decisions
|
|
232
|
+
│ └── operations/
|
|
233
|
+
│ ├── runbooks/
|
|
234
|
+
│ └── service-level-objectives.md
|
|
235
|
+
├── src/
|
|
236
|
+
│ └── example_service/
|
|
237
|
+
│ ├── __init__.py
|
|
238
|
+
│ ├── __main__.py # Optional `python -m` entry point
|
|
239
|
+
│ ├── cli.py # Thin CLI adapter
|
|
240
|
+
│ ├── config.py # Typed configuration loading
|
|
241
|
+
│ ├── domain/ # Business rules; no infrastructure imports
|
|
242
|
+
│ ├── application/ # Use cases and orchestration
|
|
243
|
+
│ ├── adapters/ # Database, HTTP, queues, filesystem
|
|
244
|
+
│ └── observability.py # Logging/metrics/tracing setup
|
|
245
|
+
├── tests/
|
|
246
|
+
│ ├── unit/ # Fast, hermetic behavior tests
|
|
247
|
+
│ ├── integration/ # Real component boundaries
|
|
248
|
+
│ ├── contract/ # Producer/consumer compatibility
|
|
249
|
+
│ └── end_to_end/ # Few critical user journeys
|
|
250
|
+
├── tools/ # Reviewed developer/build utilities
|
|
251
|
+
├── scripts/
|
|
252
|
+
│ └── validate-development-workflow.py
|
|
253
|
+
├── .editorconfig
|
|
254
|
+
├── .gitignore
|
|
255
|
+
├── AGENTS.md # Repository AI policy
|
|
256
|
+
├── CHANGELOG.md # If externally versioned
|
|
257
|
+
├── CONTRIBUTING.md
|
|
258
|
+
├── LICENSE
|
|
259
|
+
├── README.md
|
|
260
|
+
├── SECURITY.md
|
|
261
|
+
├── pyproject.toml
|
|
262
|
+
├── uv.lock # Commit for applications and reproducible CI
|
|
263
|
+
└── .python-version
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Populate the repository contract
|
|
267
|
+
|
|
268
|
+
Add a conservative `.gitignore`; extend it for your editor and deployment tools
|
|
269
|
+
without ignoring source or lockfiles:
|
|
270
|
+
|
|
271
|
+
```gitignore
|
|
272
|
+
.venv/
|
|
273
|
+
__pycache__/
|
|
274
|
+
*.py[cod]
|
|
275
|
+
.pytest_cache/
|
|
276
|
+
.mypy_cache/
|
|
277
|
+
.ruff_cache/
|
|
278
|
+
.coverage
|
|
279
|
+
htmlcov/
|
|
280
|
+
build/
|
|
281
|
+
dist/
|
|
282
|
+
*.egg-info/
|
|
283
|
+
.env
|
|
284
|
+
.env.*
|
|
285
|
+
!.env.example
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Normalize text before the first collaborative change:
|
|
289
|
+
|
|
290
|
+
```ini
|
|
291
|
+
# .editorconfig
|
|
292
|
+
root = true
|
|
293
|
+
|
|
294
|
+
[*]
|
|
295
|
+
charset = utf-8
|
|
296
|
+
end_of_line = lf
|
|
297
|
+
insert_final_newline = true
|
|
298
|
+
trim_trailing_whitespace = true
|
|
299
|
+
|
|
300
|
+
[*.py]
|
|
301
|
+
indent_style = space
|
|
302
|
+
indent_size = 4
|
|
303
|
+
|
|
304
|
+
[*.md]
|
|
305
|
+
trim_trailing_whitespace = false
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Create `.github/CODEOWNERS` with real teams or maintainers. Protect workflow,
|
|
309
|
+
security, deployment, dependency, schema, and migration paths explicitly:
|
|
310
|
+
|
|
311
|
+
```text
|
|
312
|
+
* @example/python-maintainers
|
|
313
|
+
/.github/workflows/ @example/platform-security
|
|
314
|
+
/deploy/ @example/platform-security
|
|
315
|
+
/src/example_service/security/ @example/security-reviewers
|
|
316
|
+
/src/example_service/schema/ @example/data-owners
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Create a pull-request template that asks for evidence rather than ceremony:
|
|
320
|
+
|
|
321
|
+
```markdown
|
|
322
|
+
## Outcome
|
|
323
|
+
|
|
324
|
+
<!-- What accepted behavior does this change deliver? -->
|
|
325
|
+
|
|
326
|
+
## Scope and non-goals
|
|
327
|
+
|
|
328
|
+
## Design and work-item links
|
|
329
|
+
|
|
330
|
+
## Validation
|
|
331
|
+
|
|
332
|
+
<!-- Exact commands, results, screenshots, traces, or benchmarks. -->
|
|
333
|
+
|
|
334
|
+
## Risk and compatibility
|
|
335
|
+
|
|
336
|
+
<!-- Security, privacy, data, API, migration, operations. Write "None" with reason. -->
|
|
337
|
+
|
|
338
|
+
## Rollout and rollback
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
The first `README.md` should contain status, purpose, supported Python versions,
|
|
342
|
+
five-minute quick start, canonical `format`/`lint`/`typecheck`/`test`/`build`/`run`
|
|
343
|
+
commands, configuration link, architecture link, contribution link, security
|
|
344
|
+
reporting link, ownership, and support route. `CONTRIBUTING.md` expands tool
|
|
345
|
+
installation, branch/review policy, quality gates, dependency rules, and release
|
|
346
|
+
process. `SECURITY.md` states supported versions and an approved private reporting
|
|
347
|
+
channel; never ask reporters to disclose an unpatched vulnerability publicly.
|
|
348
|
+
|
|
349
|
+
### Why use `src/`
|
|
350
|
+
|
|
351
|
+
The Python Packaging User Guide explains that `src/` prevents the repository
|
|
352
|
+
root from accidentally becoming the import source and helps tests exercise the
|
|
353
|
+
installed package rather than a convenient but incomplete checkout. It also
|
|
354
|
+
prevents packaging mistakes where undeclared files import locally but disappear
|
|
355
|
+
from the wheel. See [src layout vs flat layout](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/).
|
|
356
|
+
|
|
357
|
+
## 6. Configure `pyproject.toml`
|
|
358
|
+
|
|
359
|
+
Use `pyproject.toml` as the canonical declaration for build metadata and Python
|
|
360
|
+
tools. Do not maintain competing settings in `setup.py`, `setup.cfg`, `tox.ini`,
|
|
361
|
+
and several requirements files unless a tool truly requires them.
|
|
362
|
+
|
|
363
|
+
The following is a strong starting point. Replace names, descriptions, licence,
|
|
364
|
+
Python support, entry points, and coverage threshold intentionally.
|
|
365
|
+
|
|
366
|
+
```toml
|
|
367
|
+
[build-system]
|
|
368
|
+
requires = ["hatchling"]
|
|
369
|
+
build-backend = "hatchling.build"
|
|
370
|
+
|
|
371
|
+
[project]
|
|
372
|
+
name = "example-service"
|
|
373
|
+
version = "0.1.0"
|
|
374
|
+
description = "A concise description of the delivered capability."
|
|
375
|
+
readme = "README.md"
|
|
376
|
+
requires-python = ">=3.12"
|
|
377
|
+
license = "Apache-2.0"
|
|
378
|
+
authors = [
|
|
379
|
+
{ name = "Example Team", email = "team@example.com" },
|
|
380
|
+
]
|
|
381
|
+
dependencies = []
|
|
382
|
+
|
|
383
|
+
[project.scripts]
|
|
384
|
+
example-service = "example_service.cli:main"
|
|
385
|
+
|
|
386
|
+
[dependency-groups]
|
|
387
|
+
dev = [
|
|
388
|
+
"build",
|
|
389
|
+
"mypy",
|
|
390
|
+
"pytest",
|
|
391
|
+
"pytest-cov",
|
|
392
|
+
"ruff",
|
|
393
|
+
]
|
|
394
|
+
|
|
395
|
+
[tool.hatch.build.targets.wheel]
|
|
396
|
+
packages = ["src/example_service"]
|
|
397
|
+
|
|
398
|
+
[tool.ruff]
|
|
399
|
+
target-version = "py312"
|
|
400
|
+
line-length = 80
|
|
401
|
+
src = ["src", "tests"]
|
|
402
|
+
|
|
403
|
+
[tool.ruff.lint]
|
|
404
|
+
select = [
|
|
405
|
+
"B", # likely bugs
|
|
406
|
+
"C4", # comprehensions
|
|
407
|
+
"E", # pycodestyle errors
|
|
408
|
+
"F", # Pyflakes
|
|
409
|
+
"I", # import ordering
|
|
410
|
+
"PIE", # miscellaneous improvements
|
|
411
|
+
"RUF", # Ruff-specific correctness
|
|
412
|
+
"SIM", # simplification
|
|
413
|
+
"UP", # modern Python syntax
|
|
414
|
+
]
|
|
415
|
+
|
|
416
|
+
[tool.ruff.lint.per-file-ignores]
|
|
417
|
+
"tests/**/*.py" = ["S101"]
|
|
418
|
+
|
|
419
|
+
[tool.mypy]
|
|
420
|
+
python_version = "3.12"
|
|
421
|
+
strict = true
|
|
422
|
+
warn_unreachable = true
|
|
423
|
+
pretty = true
|
|
424
|
+
files = ["src", "tests"]
|
|
425
|
+
|
|
426
|
+
[tool.pytest.ini_options]
|
|
427
|
+
addopts = [
|
|
428
|
+
"-ra",
|
|
429
|
+
"--strict-config",
|
|
430
|
+
"--strict-markers",
|
|
431
|
+
"--import-mode=importlib",
|
|
432
|
+
]
|
|
433
|
+
testpaths = ["tests"]
|
|
434
|
+
xfail_strict = true
|
|
435
|
+
|
|
436
|
+
[tool.coverage.run]
|
|
437
|
+
branch = true
|
|
438
|
+
source = ["example_service"]
|
|
439
|
+
|
|
440
|
+
[tool.coverage.report]
|
|
441
|
+
show_missing = true
|
|
442
|
+
skip_covered = true
|
|
443
|
+
fail_under = 85
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
Notes:
|
|
447
|
+
|
|
448
|
+
- `uv add` should normally edit dependency declarations; do not hand-edit the
|
|
449
|
+
lockfile.
|
|
450
|
+
- A library should declare the broadest honest compatible runtime ranges and
|
|
451
|
+
test every supported Python version. An application should deploy from a
|
|
452
|
+
committed exact lock.
|
|
453
|
+
- An 85% coverage threshold is an example starting guardrail, not a Google
|
|
454
|
+
requirement and not evidence that tests are good. Raise or lower it based on
|
|
455
|
+
risk, and require stronger branch coverage for critical logic.
|
|
456
|
+
- If strict typing cannot be enabled immediately, configure narrow per-module
|
|
457
|
+
exceptions with owner and removal issue. Do not disable checking globally.
|
|
458
|
+
- Do not use `lint.select = ["ALL"]` without reviewing upgrades; new Ruff rules
|
|
459
|
+
would silently become policy.
|
|
460
|
+
|
|
461
|
+
The Python Packaging User Guide defines `pyproject.toml` and the standard
|
|
462
|
+
`[project]` metadata. See [Writing your pyproject.toml](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/).
|
|
463
|
+
|
|
464
|
+
## 7. Dependency policy
|
|
465
|
+
|
|
466
|
+
### 7.1 Add dependencies intentionally
|
|
467
|
+
|
|
468
|
+
```bash
|
|
469
|
+
uv add httpx
|
|
470
|
+
uv add --dev hypothesis
|
|
471
|
+
uv remove httpx
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
Before adding a package, check:
|
|
475
|
+
|
|
476
|
+
- whether the standard library or existing dependency already solves the need;
|
|
477
|
+
- maintenance activity and responsible disclosure process;
|
|
478
|
+
- licence compatibility;
|
|
479
|
+
- known vulnerabilities and malicious-package risk;
|
|
480
|
+
- transitive dependency size;
|
|
481
|
+
- platform and Python support;
|
|
482
|
+
- type information;
|
|
483
|
+
- expected runtime, memory, and import cost; and
|
|
484
|
+
- whether the package becomes part of a public API.
|
|
485
|
+
|
|
486
|
+
Record the reason for large, security-sensitive, or hard-to-replace dependencies
|
|
487
|
+
in the design document or a durable decision.
|
|
488
|
+
|
|
489
|
+
### 7.2 Lock and reproduce
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
uv lock
|
|
493
|
+
uv sync
|
|
494
|
+
uv run --locked pytest
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
Commit `uv.lock` for applications. For published libraries, commit it for
|
|
498
|
+
development/CI reproducibility but test declared dependency ranges rather than
|
|
499
|
+
claiming consumers receive your lockfile. CI should fail when the lock is stale;
|
|
500
|
+
it should not silently update dependencies.
|
|
501
|
+
|
|
502
|
+
Upgrade one dependency at a time where practical:
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
uv lock --upgrade-package httpx
|
|
506
|
+
uv run --locked pytest
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
Review lockfile changes, release notes, compatibility, licences, and security
|
|
510
|
+
advisories. Automate update proposals, not unconditional merging.
|
|
511
|
+
|
|
512
|
+
### 7.3 Environments and secrets
|
|
513
|
+
|
|
514
|
+
`.venv/` is disposable and must not be committed. Python's official `venv`
|
|
515
|
+
documentation likewise treats environments as isolated, disposable, and
|
|
516
|
+
recreated rather than moved. Store secrets in a developer secret manager,
|
|
517
|
+
deployment environment, or short-lived identity mechanism—not `.env` committed
|
|
518
|
+
to Git. A local `.env` may be ignored for convenience, but provide a redacted
|
|
519
|
+
`.env.example` containing names and documentation only.
|
|
520
|
+
|
|
521
|
+
## 8. Python architecture rules
|
|
522
|
+
|
|
523
|
+
### 8.1 Keep entry points thin
|
|
524
|
+
|
|
525
|
+
`cli.py`, HTTP handlers, queue consumers, and scheduled jobs should:
|
|
526
|
+
|
|
527
|
+
1. parse and validate external input;
|
|
528
|
+
2. establish request/job context;
|
|
529
|
+
3. call an application use case;
|
|
530
|
+
4. translate domain results to the external protocol; and
|
|
531
|
+
5. emit structured operational evidence.
|
|
532
|
+
|
|
533
|
+
Business rules belong in importable functions or classes that can be tested
|
|
534
|
+
without a network, database, process environment, or wall clock.
|
|
535
|
+
|
|
536
|
+
### 8.2 Point dependencies inward
|
|
537
|
+
|
|
538
|
+
A practical dependency direction is:
|
|
539
|
+
|
|
540
|
+
```text
|
|
541
|
+
entry points -> application use cases -> domain
|
|
542
|
+
|
|
|
543
|
+
v
|
|
544
|
+
declared interfaces
|
|
545
|
+
^
|
|
546
|
+
|
|
|
547
|
+
adapters
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
The domain must not import an HTTP framework, database driver, cloud SDK, or CLI
|
|
551
|
+
parser. Application code defines the interfaces it needs; adapters implement
|
|
552
|
+
them. Do not create an interface for every class—create one where ownership,
|
|
553
|
+
testing, replacement, or external behavior justifies it.
|
|
554
|
+
|
|
555
|
+
### 8.3 Model data explicitly
|
|
556
|
+
|
|
557
|
+
- Use immutable values where mutation is unnecessary.
|
|
558
|
+
- Separate untrusted input models from internal domain types.
|
|
559
|
+
- Validate at system boundaries, then rely on internal invariants.
|
|
560
|
+
- Use UTC instants for storage and transport; apply user time zones at display
|
|
561
|
+
boundaries.
|
|
562
|
+
- Distinguish text (`str`) from bytes (`bytes`).
|
|
563
|
+
- Make identifiers distinct when mixing them would be dangerous.
|
|
564
|
+
- Treat database schemas, serialized messages, and public function signatures as
|
|
565
|
+
compatibility contracts.
|
|
566
|
+
|
|
567
|
+
### 8.4 Configuration
|
|
568
|
+
|
|
569
|
+
Create one typed configuration object at startup. Define source precedence, for
|
|
570
|
+
example:
|
|
571
|
+
|
|
572
|
+
1. safe built-in defaults;
|
|
573
|
+
2. version-controlled static configuration;
|
|
574
|
+
3. deployment environment values;
|
|
575
|
+
4. secret-manager values; and
|
|
576
|
+
5. explicitly approved command-line overrides.
|
|
577
|
+
|
|
578
|
+
Validate configuration before serving traffic. Never read arbitrary environment
|
|
579
|
+
variables throughout domain code. Include static configuration in release
|
|
580
|
+
testing; Google’s CI guidance notes that configuration is a frequent source of
|
|
581
|
+
production failures and should be versioned and reviewed with code.
|
|
582
|
+
|
|
583
|
+
### 8.5 Errors
|
|
584
|
+
|
|
585
|
+
- Raise exceptions for exceptional conditions, not normal branching.
|
|
586
|
+
- Catch only errors you can handle, translate, retry, or enrich.
|
|
587
|
+
- Preserve causal chains with `raise ... from error`.
|
|
588
|
+
- Define stable domain exceptions where callers need semantic handling.
|
|
589
|
+
- Do not expose stack traces, credentials, queries, tokens, or personal data to
|
|
590
|
+
users.
|
|
591
|
+
- Do not use `assert` for input validation or essential runtime behavior; Python
|
|
592
|
+
may remove assertions. Assertions are appropriate in tests.
|
|
593
|
+
- Document retryability and idempotency at network and job boundaries.
|
|
594
|
+
|
|
595
|
+
### 8.6 Resources and concurrency
|
|
596
|
+
|
|
597
|
+
- Use context managers for files, locks, database transactions, and clients.
|
|
598
|
+
- Pass explicit timeouts to every network operation.
|
|
599
|
+
- Bound concurrency, queues, memory, and retries.
|
|
600
|
+
- Use exponential backoff with jitter only for retryable operations.
|
|
601
|
+
- Make retried writes idempotent or protect them with idempotency keys.
|
|
602
|
+
- Avoid mutable global state.
|
|
603
|
+
- Do not assume built-in operations are atomic across Python implementations.
|
|
604
|
+
|
|
605
|
+
## 9. Apply the Google Python Style Guide
|
|
606
|
+
|
|
607
|
+
Read the complete [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)
|
|
608
|
+
and make deviations explicit in `CONTRIBUTING.md`. Essential rules include:
|
|
609
|
+
|
|
610
|
+
- run a linter and do not suppress warnings casually;
|
|
611
|
+
- import packages and modules rather than individual classes/functions, with
|
|
612
|
+
documented exceptions for typing;
|
|
613
|
+
- use full package paths and avoid relative imports;
|
|
614
|
+
- keep imports at the top, grouped by future, standard library, third-party, and
|
|
615
|
+
repository packages;
|
|
616
|
+
- avoid mutable default arguments;
|
|
617
|
+
- avoid mutable global state;
|
|
618
|
+
- use context managers for stateful resources;
|
|
619
|
+
- use four spaces, never tabs;
|
|
620
|
+
- target 80-character lines, allowing documented formatter/import/URL
|
|
621
|
+
exceptions;
|
|
622
|
+
- use triple-double-quoted docstrings and document public behavior;
|
|
623
|
+
- prefer clear, unabbreviated names;
|
|
624
|
+
- use `lower_with_under`, `CapWords`, and `UPPER_WITH_UNDER` consistently;
|
|
625
|
+
- keep functions focused and reconsider functions above roughly 40 lines;
|
|
626
|
+
- put executable work in `main()` rather than import-time side effects; and
|
|
627
|
+
- type-check new and changed public APIs.
|
|
628
|
+
|
|
629
|
+
Automation removes style debate, but it does not replace judgment about API
|
|
630
|
+
clarity, ownership, complexity, and correctness.
|
|
631
|
+
|
|
632
|
+
## 10. Testing strategy
|
|
633
|
+
|
|
634
|
+
### 10.1 Test levels
|
|
635
|
+
|
|
636
|
+
| Level | Purpose | Properties | Typical frequency |
|
|
637
|
+
|---|---|---|---|
|
|
638
|
+
| Unit | Domain and small application behavior | Fast, hermetic, deterministic | Every local change and CI |
|
|
639
|
+
| Contract | Producer/consumer agreement | Versioned examples or schemas | Every affected change |
|
|
640
|
+
| Integration | Real database, queue, HTTP client, filesystem, or framework boundary | Isolated environment; controlled dependencies | CI and pre-release |
|
|
641
|
+
| End-to-end | Critical user journey | Few, high-value, production-like | CI subset and staged release |
|
|
642
|
+
| Performance | Latency, throughput, memory, scaling | Stable environment and budgets | Scheduled and release gate |
|
|
643
|
+
| Resilience | Timeouts, retries, partial failure, recovery | Fault injection or controlled simulation | High-risk changes and scheduled |
|
|
644
|
+
|
|
645
|
+
### 10.2 Test design rules
|
|
646
|
+
|
|
647
|
+
- Test externally meaningful behavior, not private implementation steps.
|
|
648
|
+
- A bug fix begins with a test that fails for the bug when practical.
|
|
649
|
+
- Keep behavior and its tests in the same pull request.
|
|
650
|
+
- Use explicit Arrange–Act–Assert structure when it improves readability.
|
|
651
|
+
- Give tests names such as `test_method_state_expected_result`.
|
|
652
|
+
- Make time, randomness, IDs, and external I/O controllable.
|
|
653
|
+
- Prefer small fakes at your own interfaces over deep mocks of implementation.
|
|
654
|
+
- Assert important outputs and side effects, not every intermediate call.
|
|
655
|
+
- Do not allow tests to access production services or real customer data.
|
|
656
|
+
- Quarantine is temporary: every skipped, flaky, or expected-failure test needs a
|
|
657
|
+
reason, owner, and removal condition.
|
|
658
|
+
- Review test code as carefully as production code. Google’s review guidance
|
|
659
|
+
explicitly notes that tests do not test themselves.
|
|
660
|
+
|
|
661
|
+
### 10.3 Commands
|
|
662
|
+
|
|
663
|
+
```bash
|
|
664
|
+
# Fast local feedback
|
|
665
|
+
uv run ruff check .
|
|
666
|
+
uv run ruff format --check .
|
|
667
|
+
uv run mypy src tests
|
|
668
|
+
uv run pytest tests/unit
|
|
669
|
+
|
|
670
|
+
# Full presubmit
|
|
671
|
+
uv run pytest --cov=example_service --cov-report=term-missing
|
|
672
|
+
uv build
|
|
673
|
+
|
|
674
|
+
# Verify the built wheel in a clean environment
|
|
675
|
+
uv run --isolated --with dist/example_service-*.whl python -c "import example_service"
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
Adapt the final wheel command to the exact artifact name or use a reviewed
|
|
679
|
+
verification script; shell glob behavior differs by platform.
|
|
680
|
+
|
|
681
|
+
pytest recommends `src/` layout and `--import-mode=importlib` for new projects.
|
|
682
|
+
See [pytest good integration practices](https://docs.pytest.org/en/stable/explanation/goodpractices.html).
|
|
683
|
+
|
|
684
|
+
## 11. One-command developer experience
|
|
685
|
+
|
|
686
|
+
Document canonical commands in `CONTRIBUTING.md`. Every developer and AI agent
|
|
687
|
+
must be able to discover how to:
|
|
688
|
+
|
|
689
|
+
```bash
|
|
690
|
+
uv sync # bootstrap/update environment
|
|
691
|
+
uv run ruff format . # format
|
|
692
|
+
uv run ruff check --fix . # safe lint fixes; inspect diff
|
|
693
|
+
uv run mypy src tests # types
|
|
694
|
+
uv run pytest tests/unit # fast tests
|
|
695
|
+
uv run pytest # complete tests
|
|
696
|
+
uv build # package
|
|
697
|
+
python scripts/validate-development-workflow.py
|
|
698
|
+
```
|
|
699
|
+
|
|
700
|
+
If commands become complex, add a small cross-platform task runner or Python
|
|
701
|
+
tool under `tools/`. The wrapper must call the same underlying tools used in CI;
|
|
702
|
+
do not create a second hidden implementation of the build.
|
|
703
|
+
|
|
704
|
+
## 12. Git, branches, and pull requests
|
|
705
|
+
|
|
706
|
+
### 12.1 Repository configuration
|
|
707
|
+
|
|
708
|
+
- Default branch: `main`.
|
|
709
|
+
- Protect `main`; disallow direct pushes except controlled automation.
|
|
710
|
+
- Require passing CI and current review.
|
|
711
|
+
- Require code-owner or domain approval for protected areas.
|
|
712
|
+
- Dismiss or refresh approval when material code changes.
|
|
713
|
+
- Require conversation resolution.
|
|
714
|
+
- Prevent force-push and deletion.
|
|
715
|
+
- Define an emergency path that is fast but still reviewed and audited.
|
|
716
|
+
|
|
717
|
+
### 12.2 Branch model
|
|
718
|
+
|
|
719
|
+
Use short-lived branches:
|
|
720
|
+
|
|
721
|
+
```bash
|
|
722
|
+
git switch main
|
|
723
|
+
git pull --ff-only
|
|
724
|
+
git switch -c feature/short-purpose
|
|
725
|
+
```
|
|
726
|
+
|
|
727
|
+
Integrate at least daily when the project allows it. Hide incomplete behavior
|
|
728
|
+
behind safe feature flags rather than maintaining long-lived feature branches.
|
|
729
|
+
Google’s version-control guidance describes trunk-based development as a
|
|
730
|
+
scalable policy; DORA similarly associates small batches and frequent mainline
|
|
731
|
+
integration with better delivery performance.
|
|
732
|
+
|
|
733
|
+
### 12.3 Change size
|
|
734
|
+
|
|
735
|
+
One pull request should have one review purpose and contain its tests and
|
|
736
|
+
documentation. Google’s published guidance says roughly 100 lines is often a
|
|
737
|
+
reasonable change and 1,000 is usually too large, while emphasizing that
|
|
738
|
+
conceptual focus matters more than a hard number. This repository’s `build-change`
|
|
739
|
+
skill uses a softer warning around 400 non-generated changed lines or eight files.
|
|
740
|
+
|
|
741
|
+
Split:
|
|
742
|
+
|
|
743
|
+
- behavior-preserving refactor from behavior change;
|
|
744
|
+
- API/schema contract from consumers when each intermediate state works;
|
|
745
|
+
- generated changes from generator logic;
|
|
746
|
+
- configuration/flag activation from dormant implementation; and
|
|
747
|
+
- independent vertical user outcomes.
|
|
748
|
+
|
|
749
|
+
Never split so finely that the repository is broken or an unused, misleading API
|
|
750
|
+
is merged.
|
|
751
|
+
|
|
752
|
+
### 12.4 Pull-request description
|
|
753
|
+
|
|
754
|
+
Every nontrivial change states:
|
|
755
|
+
|
|
756
|
+
- problem and intended outcome;
|
|
757
|
+
- scope and non-goals;
|
|
758
|
+
- brief/design/work-item links;
|
|
759
|
+
- important decisions and alternatives;
|
|
760
|
+
- behavior and files changed;
|
|
761
|
+
- validation commands and results;
|
|
762
|
+
- security/privacy/data/compatibility impact;
|
|
763
|
+
- rollout and rollback; and
|
|
764
|
+
- screenshots, traces, or benchmark evidence where relevant.
|
|
765
|
+
|
|
766
|
+
## 13. CI from the first change
|
|
767
|
+
|
|
768
|
+
Create `.github/workflows/ci.yml`. The example uses current major action tags for
|
|
769
|
+
readability. High-assurance repositories should pin third-party actions to
|
|
770
|
+
reviewed commit SHAs and let an update bot propose changes.
|
|
771
|
+
|
|
772
|
+
```yaml
|
|
773
|
+
name: ci
|
|
774
|
+
|
|
775
|
+
on:
|
|
776
|
+
pull_request:
|
|
777
|
+
push:
|
|
778
|
+
branches: [main]
|
|
779
|
+
|
|
780
|
+
permissions:
|
|
781
|
+
contents: read
|
|
782
|
+
|
|
783
|
+
concurrency:
|
|
784
|
+
group: ci-${{ github.ref }}
|
|
785
|
+
cancel-in-progress: true
|
|
786
|
+
|
|
787
|
+
jobs:
|
|
788
|
+
quality:
|
|
789
|
+
runs-on: ubuntu-latest
|
|
790
|
+
timeout-minutes: 15
|
|
791
|
+
steps:
|
|
792
|
+
- uses: actions/checkout@v6
|
|
793
|
+
- uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
|
794
|
+
with:
|
|
795
|
+
enable-cache: true
|
|
796
|
+
python-version: "3.12"
|
|
797
|
+
- run: uv sync --locked --all-groups
|
|
798
|
+
- run: uv run --locked ruff format --check .
|
|
799
|
+
- run: uv run --locked ruff check .
|
|
800
|
+
- run: uv run --locked mypy src tests
|
|
801
|
+
- run: uv run --locked pytest --cov=example_service --cov-report=term-missing
|
|
802
|
+
- run: uv build
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
Production CI should additionally:
|
|
806
|
+
|
|
807
|
+
- run supported Python/OS matrices for libraries;
|
|
808
|
+
- test migrations against representative snapshots;
|
|
809
|
+
- scan dependencies, source, secrets, licences, and containers;
|
|
810
|
+
- produce machine-readable test and coverage evidence;
|
|
811
|
+
- separate trusted release jobs from untrusted pull-request jobs;
|
|
812
|
+
- use minimum `GITHUB_TOKEN` permissions;
|
|
813
|
+
- never expose secrets to forked or untrusted code;
|
|
814
|
+
- make failure output actionable; and
|
|
815
|
+
- run relevant post-merge integration and end-to-end tests.
|
|
816
|
+
|
|
817
|
+
## 14. Security and supply chain
|
|
818
|
+
|
|
819
|
+
At minimum:
|
|
820
|
+
|
|
821
|
+
- provide `SECURITY.md` with a private reporting route;
|
|
822
|
+
- enable secret scanning and dependency alerts;
|
|
823
|
+
- protect workflow files with `CODEOWNERS`;
|
|
824
|
+
- pin CI actions and deployment tools by immutable digest/SHA where risk warrants;
|
|
825
|
+
- generate an SBOM for release artifacts;
|
|
826
|
+
- build releases on a controlled hosted runner from a reviewed commit;
|
|
827
|
+
- sign artifacts and publish provenance;
|
|
828
|
+
- use short-lived federated credentials such as OIDC rather than stored cloud
|
|
829
|
+
keys; and
|
|
830
|
+
- verify provenance before promotion in high-assurance environments.
|
|
831
|
+
|
|
832
|
+
SLSA defines progressive source/build supply-chain guarantees and provenance
|
|
833
|
+
formats. Use [SLSA v1.2](https://slsa.dev/spec/v1.2/) as a maturity model rather
|
|
834
|
+
than claiming compliance without verifying every requirement.
|
|
835
|
+
|
|
836
|
+
## 15. Releases and operations
|
|
837
|
+
|
|
838
|
+
### 15.1 Build once
|
|
839
|
+
|
|
840
|
+
Create the wheel, container, or executable once from a reviewed commit. Record:
|
|
841
|
+
|
|
842
|
+
- Git commit and source repository;
|
|
843
|
+
- build workflow identity;
|
|
844
|
+
- dependency lock digest;
|
|
845
|
+
- artifact digest;
|
|
846
|
+
- configuration/migration version;
|
|
847
|
+
- test and scan evidence; and
|
|
848
|
+
- provenance/signature.
|
|
849
|
+
|
|
850
|
+
Promote that artifact through environments; do not rebuild different bits for
|
|
851
|
+
staging and production.
|
|
852
|
+
|
|
853
|
+
### 15.2 Versioning
|
|
854
|
+
|
|
855
|
+
For published APIs/packages, use semantic versioning when it accurately
|
|
856
|
+
communicates compatibility. Define deprecation duration and removal policy.
|
|
857
|
+
Applications may use immutable build identifiers while still maintaining a
|
|
858
|
+
human-readable release version.
|
|
859
|
+
|
|
860
|
+
### 15.3 Production services
|
|
861
|
+
|
|
862
|
+
Before launch, define:
|
|
863
|
+
|
|
864
|
+
- structured logs with correlation identifiers and redaction;
|
|
865
|
+
- request, error, latency, saturation, queue, and business metrics;
|
|
866
|
+
- distributed tracing where it adds diagnostic value;
|
|
867
|
+
- dashboards and actionable alerts;
|
|
868
|
+
- SLOs and an error budget;
|
|
869
|
+
- health/readiness behavior;
|
|
870
|
+
- capacity expectations;
|
|
871
|
+
- backup/restore and disaster recovery;
|
|
872
|
+
- on-call ownership and runbooks; and
|
|
873
|
+
- feature-flag and rollback procedure.
|
|
874
|
+
|
|
875
|
+
Use canary or staged exposure when the blast radius justifies it. Google SRE
|
|
876
|
+
defines canarying as a partial, time-limited deployment evaluated before
|
|
877
|
+
continuing. See [Canarying Releases](https://sre.google/workbook/canarying-releases/).
|
|
878
|
+
|
|
879
|
+
## 16. Integrate the human–AI workflow
|
|
880
|
+
|
|
881
|
+
Use the lifecycle skills and optional guided facade according to work size:
|
|
882
|
+
|
|
883
|
+
| Situation | Skills |
|
|
884
|
+
|---|---|
|
|
885
|
+
| Local low-risk fix | `build-change` -> human review; add `review-change` when useful |
|
|
886
|
+
| Normal feature | `define-product` -> optional `design-solution` -> `build-change` -> `review-change` -> proportionate rollout |
|
|
887
|
+
| New greenfield product, guided | `specify-project` -> `plan-delivery` -> build/review loops -> `launch-product` |
|
|
888
|
+
| New product, modular | `define-product` -> `design-solution` -> all later lifecycle skills through `launch-product` |
|
|
889
|
+
| Multi-developer milestone | add `plan-delivery`; agree contracts before parallel work |
|
|
890
|
+
|
|
891
|
+
`specify-project` is a facade over product definition and solution design, not an
|
|
892
|
+
additional delivery stage. Use its root `SPECIFICATION.md` for a single-product
|
|
893
|
+
repository or `docs/product/<slug>/SPECIFICATION.md` in a multi-product
|
|
894
|
+
repository. The specification remains Draft until its product frame and
|
|
895
|
+
technical design are separately accepted by accountable humans.
|
|
896
|
+
|
|
897
|
+
The AI must inspect this exact repository before suggesting files or APIs. It may
|
|
898
|
+
implement and validate one bounded change, but it must stop for product,
|
|
899
|
+
architecture, API, data, security, dependency, or destructive decisions. A new
|
|
900
|
+
request does not silently supersede an accepted design. The implementing AI
|
|
901
|
+
does not approve its own change, and humans retain merge and release authority.
|
|
902
|
+
|
|
903
|
+
See [Idea to Production in the Modern AI Age](IDEA-TO-PRODUCTION-HANDBOOK.md)
|
|
904
|
+
for the complete operating model.
|
|
905
|
+
|
|
906
|
+
## 17. Definition of done
|
|
907
|
+
|
|
908
|
+
A Python change is done only when:
|
|
909
|
+
|
|
910
|
+
- acceptance behavior is implemented;
|
|
911
|
+
- non-goals remain out of scope;
|
|
912
|
+
- public APIs and data contracts are reviewed and documented;
|
|
913
|
+
- tests would fail if the new behavior broke;
|
|
914
|
+
- formatting, linting, typing, tests, and packaging pass;
|
|
915
|
+
- security, privacy, licence, compatibility, and migration effects are addressed;
|
|
916
|
+
- documentation and examples are current;
|
|
917
|
+
- operational signals and rollback are ready when applicable;
|
|
918
|
+
- the complete diff has independent human review;
|
|
919
|
+
- the exact reviewed commit is identified; and
|
|
920
|
+
- rollout evidence—not merely merge status—supports calling the feature shipped.
|
|
921
|
+
|
|
922
|
+
## 18. Common failure modes
|
|
923
|
+
|
|
924
|
+
| Failure | Prevention |
|
|
925
|
+
|---|---|
|
|
926
|
+
| Imports work locally but not from the wheel | `src/` layout; test installed artifact |
|
|
927
|
+
| “Works on my machine” dependencies | committed lock; `--locked` CI; disposable environments |
|
|
928
|
+
| Huge AI-generated pull request | one-purpose work item; small-batch warning; human plan checkpoint |
|
|
929
|
+
| Tests mirror implementation and miss bugs | behavior assertions; mutation/property testing for critical logic; independent review |
|
|
930
|
+
| Secrets in Git or CI logs | secret manager, least privilege, redaction, scanning |
|
|
931
|
+
| Flaky CI normalized as noise | owner, diagnostic evidence, fix/quarantine deadline |
|
|
932
|
+
| Silent breaking API/schema change | accepted contract, compatibility tests, version/migration plan |
|
|
933
|
+
| Import-time network/config failure | thin entry point; explicit startup; dependency injection |
|
|
934
|
+
| Manual release cannot be reproduced | hosted build, artifact digest, provenance, automated promotion |
|
|
935
|
+
| Documentation drifts | canonical docs beside code, ownership, reviewed updates |
|
|
936
|
+
|
|
937
|
+
## 19. Authoritative references
|
|
938
|
+
|
|
939
|
+
- [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)
|
|
940
|
+
- [Software Engineering at Google](https://abseil.io/resources/swe-book)
|
|
941
|
+
- [Google Engineering Practices: Code Review](https://google.github.io/eng-practices/review/)
|
|
942
|
+
- [Google Engineering Practices: Small CLs](https://google.github.io/eng-practices/review/developer/small-cls.html)
|
|
943
|
+
- [Python Packaging User Guide](https://packaging.python.org/)
|
|
944
|
+
- [Writing `pyproject.toml`](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/)
|
|
945
|
+
- [`src` layout vs flat layout](https://packaging.python.org/en/latest/discussions/src-layout-vs-flat-layout/)
|
|
946
|
+
- [Python virtual environments](https://docs.python.org/3/library/venv.html)
|
|
947
|
+
- [uv project documentation](https://docs.astral.sh/uv/guides/projects/)
|
|
948
|
+
- [Ruff documentation](https://docs.astral.sh/ruff/)
|
|
949
|
+
- [pytest good integration practices](https://docs.pytest.org/en/stable/explanation/goodpractices.html)
|
|
950
|
+
- [mypy documentation](https://mypy.readthedocs.io/en/stable/)
|
|
951
|
+
- [SLSA specification](https://slsa.dev/spec/v1.2/)
|
|
952
|
+
- [Google SRE: Canarying Releases](https://sre.google/workbook/canarying-releases/)
|
|
953
|
+
|
|
954
|
+
## 20. Companion guides
|
|
955
|
+
|
|
956
|
+
- [Google-Inspired Language-Agnostic Project Handbook](LANGUAGE-AGNOSTIC-PROJECT-HANDBOOK.md)
|
|
957
|
+
- [Idea-to-Production Handbook](IDEA-TO-PRODUCTION-HANDBOOK.md)
|
|
958
|
+
- [Product Development Workflow](../WORKFLOW-HUMAN.md)
|
|
959
|
+
- [Four Common Workflow Recipes](../WORKFLOW-COOKBOOK.md)
|
|
960
|
+
- [AI Agent Workflow](../for-ai/WORKFLOW-AGENTS.md)
|