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.
Files changed (47) hide show
  1. codev_workflow/__init__.py +5 -0
  2. codev_workflow/__main__.py +4 -0
  3. codev_workflow/bundle/.agents/skills/build-change/SKILL.md +96 -0
  4. codev_workflow/bundle/.agents/skills/build-change/agents/openai.yaml +4 -0
  5. codev_workflow/bundle/.agents/skills/build-change/assets/implementation-plan.template.md +51 -0
  6. codev_workflow/bundle/.agents/skills/define-product/SKILL.md +79 -0
  7. codev_workflow/bundle/.agents/skills/define-product/agents/openai.yaml +4 -0
  8. codev_workflow/bundle/.agents/skills/define-product/assets/brief.template.md +50 -0
  9. codev_workflow/bundle/.agents/skills/design-solution/SKILL.md +75 -0
  10. codev_workflow/bundle/.agents/skills/design-solution/agents/openai.yaml +4 -0
  11. codev_workflow/bundle/.agents/skills/design-solution/assets/decision.template.md +26 -0
  12. codev_workflow/bundle/.agents/skills/design-solution/assets/design.template.md +76 -0
  13. codev_workflow/bundle/.agents/skills/launch-product/SKILL.md +66 -0
  14. codev_workflow/bundle/.agents/skills/launch-product/agents/openai.yaml +4 -0
  15. codev_workflow/bundle/.agents/skills/launch-product/assets/launch-plan.template.md +48 -0
  16. codev_workflow/bundle/.agents/skills/plan-delivery/SKILL.md +140 -0
  17. codev_workflow/bundle/.agents/skills/plan-delivery/agents/openai.yaml +4 -0
  18. codev_workflow/bundle/.agents/skills/plan-delivery/assets/delivery-plan.template.md +41 -0
  19. codev_workflow/bundle/.agents/skills/review-change/SKILL.md +48 -0
  20. codev_workflow/bundle/.agents/skills/review-change/agents/openai.yaml +4 -0
  21. codev_workflow/bundle/.agents/skills/specify-project/SKILL.md +205 -0
  22. codev_workflow/bundle/.agents/skills/specify-project/agents/openai.yaml +4 -0
  23. codev_workflow/bundle/.agents/skills/specify-project/assets/specification.template.md +151 -0
  24. codev_workflow/bundle/.agents/skills/specify-project/references/interview-coverage.md +303 -0
  25. codev_workflow/bundle/.agents/skills/specify-project/scripts/validate_specification.py +143 -0
  26. codev_workflow/bundle/.opencode/agents/builder.md +54 -0
  27. codev_workflow/bundle/.opencode/agents/orchestrator.md +72 -0
  28. codev_workflow/bundle/.opencode/agents/reviewer.md +35 -0
  29. codev_workflow/bundle/AGENTS.md +23 -0
  30. codev_workflow/bundle/docs/AI-WORKFLOW-PROMPTS.md +318 -0
  31. codev_workflow/bundle/docs/WORKFLOW-COOKBOOK.md +419 -0
  32. codev_workflow/bundle/docs/WORKFLOW-HUMAN.md +212 -0
  33. codev_workflow/bundle/docs/for-ai/WORKFLOW-AGENTS.md +171 -0
  34. codev_workflow/bundle/docs/handbooks/IDEA-TO-PRODUCTION-HANDBOOK.md +1190 -0
  35. codev_workflow/bundle/docs/handbooks/LANGUAGE-AGNOSTIC-PROJECT-HANDBOOK.md +745 -0
  36. codev_workflow/bundle/docs/handbooks/PYTHON-PROJECT-HANDBOOK.md +960 -0
  37. codev_workflow/bundle/evals/development-workflow/scenarios.json +132 -0
  38. codev_workflow/bundle/scripts/evaluate-development-workflow.py +352 -0
  39. codev_workflow/bundle/scripts/validate-development-workflow.py +213 -0
  40. codev_workflow/cli.py +140 -0
  41. codev_workflow/installer.py +891 -0
  42. open_codev_workflow-0.1.0.dist-info/METADATA +150 -0
  43. open_codev_workflow-0.1.0.dist-info/RECORD +47 -0
  44. open_codev_workflow-0.1.0.dist-info/WHEEL +5 -0
  45. open_codev_workflow-0.1.0.dist-info/entry_points.txt +2 -0
  46. open_codev_workflow-0.1.0.dist-info/licenses/LICENSE +28 -0
  47. 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)