engineering-process 2.0.1__tar.gz → 2.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. {engineering_process-2.0.1 → engineering_process-2.1.0}/MANIFEST.in +1 -0
  2. {engineering_process-2.0.1/engineering_process.egg-info → engineering_process-2.1.0}/PKG-INFO +55 -1
  3. {engineering_process-2.0.1 → engineering_process-2.1.0}/README.md +54 -0
  4. engineering_process-2.1.0/RELEASE_NOTES.md +23 -0
  5. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/__init__.py +1 -1
  6. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/cli.py +1 -0
  7. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/lifecycle.py +16 -1
  8. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/repository.py +6 -0
  9. {engineering_process-2.0.1 → engineering_process-2.1.0/engineering_process.egg-info}/PKG-INFO +55 -1
  10. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process.egg-info/SOURCES.txt +2 -0
  11. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/change-complete/SKILL.md +11 -1
  12. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/change-implement/SKILL.md +7 -0
  13. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/change-plan/SKILL.md +8 -0
  14. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/change-review/SKILL.md +43 -2
  15. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/change-start/SKILL.md +11 -0
  16. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/deliver-change/SKILL.md +8 -7
  17. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/production-engineering/SKILL.md +29 -2
  18. {engineering_process-2.0.1 → engineering_process-2.1.0}/pyproject.toml +1 -1
  19. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/run.schema.json +1 -0
  20. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_automation.py +25 -0
  21. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_cli.py +5 -0
  22. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_lifecycle.py +87 -0
  23. engineering_process-2.1.0/tests/test_publication_workflow.py +92 -0
  24. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_release.py +88 -0
  25. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_repository.py +12 -1
  26. {engineering_process-2.0.1 → engineering_process-2.1.0}/LICENSE +0 -0
  27. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/__main__.py +0 -0
  28. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/_supervisor_contract.py +0 -0
  29. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/_supervisor_posix.py +0 -0
  30. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/_supervisor_windows.py +0 -0
  31. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/_windows_job.py +0 -0
  32. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/adoption.py +0 -0
  33. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/commands.py +0 -0
  34. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/contracts.py +0 -0
  35. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/distribution.py +0 -0
  36. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/helper_launch.py +0 -0
  37. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/production_engineering.py +0 -0
  38. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/project.py +0 -0
  39. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/publication_compat.py +0 -0
  40. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/release.py +0 -0
  41. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/requirements-dev.txt +0 -0
  42. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/requirements-runtime.txt +0 -0
  43. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/skills.py +0 -0
  44. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process/supervision.py +0 -0
  45. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process.egg-info/dependency_links.txt +0 -0
  46. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process.egg-info/entry_points.txt +0 -0
  47. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process.egg-info/requires.txt +0 -0
  48. {engineering_process-2.0.1 → engineering_process-2.1.0}/engineering_process.egg-info/top_level.txt +0 -0
  49. {engineering_process-2.0.1 → engineering_process-2.1.0}/process-graph.json +0 -0
  50. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/change-verify/SKILL.md +0 -0
  51. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/process-improve/SKILL.md +0 -0
  52. {engineering_process-2.0.1 → engineering_process-2.1.0}/process_assets/skills/production-engineering/invariants.json +0 -0
  53. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/change.schema.json +0 -0
  54. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/plan.schema.json +0 -0
  55. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/process-graph.schema.json +0 -0
  56. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/process-lock.schema.json +0 -0
  57. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/production-engineering.schema.json +0 -0
  58. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/project-legacy.schema.json +0 -0
  59. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/project.schema.json +0 -0
  60. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/receipt.schema.json +0 -0
  61. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/release-change.schema.json +0 -0
  62. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/release.schema.json +0 -0
  63. {engineering_process-2.0.1 → engineering_process-2.1.0}/schemas/review.schema.json +0 -0
  64. {engineering_process-2.0.1 → engineering_process-2.1.0}/setup.cfg +0 -0
  65. {engineering_process-2.0.1 → engineering_process-2.1.0}/templates/AGENTS.process.md +0 -0
  66. {engineering_process-2.0.1 → engineering_process-2.1.0}/templates/PULL_REQUEST_TEMPLATE.md +0 -0
  67. {engineering_process-2.0.1 → engineering_process-2.1.0}/templates/adopt-process-windows-job.py +0 -0
  68. {engineering_process-2.0.1 → engineering_process-2.1.0}/templates/adopt-process.py +0 -0
  69. {engineering_process-2.0.1 → engineering_process-2.1.0}/templates/renovate.json +0 -0
  70. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_adoption.py +0 -0
  71. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_architecture.py +0 -0
  72. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_commands.py +0 -0
  73. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_contracts.py +0 -0
  74. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_distribution.py +0 -0
  75. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_production_engineering.py +0 -0
  76. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_publication_compat.py +0 -0
  77. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_pypi_cache_horizon.py +0 -0
  78. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_skills.py +0 -0
  79. {engineering_process-2.0.1 → engineering_process-2.1.0}/tests/test_supervisor_posix.py +0 -0
@@ -1,4 +1,5 @@
1
1
  include process-graph.json
2
+ include RELEASE_NOTES.md
2
3
  recursive-include process_assets/skills SKILL.md *.json
3
4
  recursive-include schemas *.json
4
5
  recursive-include templates *.md *.py *.json
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: engineering-process
3
- Version: 2.0.1
3
+ Version: 2.1.0
4
4
  Summary: A small agent-neutral engineering lifecycle with managed adoption
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/phuongnse/engineering-process
@@ -69,6 +69,14 @@ may have implemented the current cycle. There is no attestation hierarchy,
69
69
  recommendation chain, authority-transition protocol, remote-evidence federation, or
70
70
  second handwritten validator.
71
71
 
72
+ The coordinator hands review to an actual reviewer. A new agent review starts in a
73
+ fresh context with the accepted source artifacts and no suggested verdict; the same
74
+ reviewer continues corrections. The reviewer inspects the change and authors its
75
+ own report. The runner's existing task/session interaction and returned result make
76
+ that work inspectable. Sharing a model, provider, or account is allowed; this is a
77
+ workflow for independent judgment, not authenticated identity or merge enforcement.
78
+ See [change-review](process_assets/skills/change-review/SKILL.md) for the handoff.
79
+
72
80
  Runtime architecture is enforced by semantic fitness functions, not module or source-
73
81
  line quotas. Every module has an explicit dependency layer, imports point toward lower
74
82
  layers, the internal graph remains acyclic, and lifecycle.py alone owns state
@@ -174,6 +182,25 @@ runtime/license delivery, Linux advisory resolution, real-host workspace securit
174
182
  updater, incident recovery, and independent security review remain planned.
175
183
  Consumers without readiness remain compatible during that evidence-backed rollout.
176
184
 
185
+ ### Design quality
186
+
187
+ Changes that materially alter logic, state, or collaboration boundaries carry
188
+ consumer design standards in their existing acceptance criteria. The shared
189
+ [design quality guidance](process_assets/skills/production-engineering/SKILL.md#design-quality)
190
+ requires understandable responsibilities, data and state, ownership, and contracts.
191
+ Agents actively introduce or refine cohesive abstractions when current requirements
192
+ justify them, weighing comprehension and change locality against indirection.
193
+ Consumer architecture and language choices remain authoritative.
194
+
195
+ Start defines scoped design outcomes; the plan explains material choices in its
196
+ existing approach and work items; implementation revisits the affected flow before
197
+ verification. Independent review traces behavior and a concrete maintenance scenario
198
+ against the actual code. Demonstrated violations of accepted criteria can block
199
+ completion despite passing tests. Routine edits stay proportional, and a clear
200
+ direct implementation remains valid. The existing lifecycle enforces criterion-bound
201
+ findings and evidence freshness; contextual design quality remains the reviewer's
202
+ judgment, without another gate, artifact, or canonical invariant.
203
+
177
204
  ### Production engineering invariants
178
205
 
179
206
  Every new plan and independent review applies one small, versioned invariant floor:
@@ -440,6 +467,19 @@ approved can finish only while the repository still matches the reviewed snapsho
440
467
  --actor coordinator \
441
468
  --context finish-123
442
469
 
470
+ New runs preserve the accepted `comparisonBase` ref and contract digest, and record
471
+ its resolved commit separately as `comparisonBaseCommit`. Start rejects missing or
472
+ non-commit refs before writing the run. Lifecycle output supplies the recorded commit
473
+ for review even after commits or branch movement. Older runs without this field stay
474
+ readable; their original review boundary must be established from available history,
475
+ not retrospectively claimed as pinned. If that boundary cannot be established, use
476
+ an owner-selected replacement contract.
477
+
478
+ Correction reports must retain every previously open blocker until its unchanged
479
+ identity receives an explicit `resolved` disposition. Omitting it or changing it to
480
+ `accepted-risk` or `tracked-follow-up` cannot retire the blocker. This applies to all
481
+ supported review schemas; ordinary legacy non-blocking observations remain readable.
482
+
443
483
  ### Public pull-request evidence
444
484
 
445
485
  The managed pull-request template keeps public assurance separate from local
@@ -465,12 +505,26 @@ and authors plus independent review keep it out of free-form values. The validat
465
505
  a positive grammar for public fields; it deliberately does not guess identities from
466
506
  an open-ended vocabulary of names or labels.
467
507
 
508
+ This producer's local `review` profile runs `verification/verify_publication.py`
509
+ against the actual Git branch. `main` is the consumer's integration branch, not a
510
+ proposal; detached local checkouts require explicit PR context instead of a guessed
511
+ branch name. In CI, the `Adopted public process` job supplies actual PR metadata and
512
+ the base/head commit range to the installed publication adapters. Metadata edits and
513
+ draft-state changes rerun CI. Maintainers must keep this existing job in `main`'s
514
+ required status checks alongside the other required checks. These publication choices
515
+ belong to this consumer; the shared lifecycle does not impose a naming policy.
516
+
468
517
  At any point:
469
518
 
470
519
  processctl change status --change-id change-123 --json
471
520
 
472
521
  ## Release to consumer PR
473
522
 
523
+ Each release includes [reviewed release contents](RELEASE_NOTES.md) generated from
524
+ the canonical manifest: shipped features/fixes, their source issues or changes, and
525
+ upgrade guidance. The release PR reviews this file; the GitHub Release publishes the
526
+ same contents. See [the release procedure](RELEASING.md) for authoring and checks.
527
+
474
528
  This producer's release identity inputs and text assets declared by
475
529
  `tool.setuptools.data-files` use UTF-8 without BOM and LF, matching `.gitattributes`.
476
530
  Writers select that representation explicitly; JSON writers use
@@ -45,6 +45,14 @@ may have implemented the current cycle. There is no attestation hierarchy,
45
45
  recommendation chain, authority-transition protocol, remote-evidence federation, or
46
46
  second handwritten validator.
47
47
 
48
+ The coordinator hands review to an actual reviewer. A new agent review starts in a
49
+ fresh context with the accepted source artifacts and no suggested verdict; the same
50
+ reviewer continues corrections. The reviewer inspects the change and authors its
51
+ own report. The runner's existing task/session interaction and returned result make
52
+ that work inspectable. Sharing a model, provider, or account is allowed; this is a
53
+ workflow for independent judgment, not authenticated identity or merge enforcement.
54
+ See [change-review](process_assets/skills/change-review/SKILL.md) for the handoff.
55
+
48
56
  Runtime architecture is enforced by semantic fitness functions, not module or source-
49
57
  line quotas. Every module has an explicit dependency layer, imports point toward lower
50
58
  layers, the internal graph remains acyclic, and lifecycle.py alone owns state
@@ -150,6 +158,25 @@ runtime/license delivery, Linux advisory resolution, real-host workspace securit
150
158
  updater, incident recovery, and independent security review remain planned.
151
159
  Consumers without readiness remain compatible during that evidence-backed rollout.
152
160
 
161
+ ### Design quality
162
+
163
+ Changes that materially alter logic, state, or collaboration boundaries carry
164
+ consumer design standards in their existing acceptance criteria. The shared
165
+ [design quality guidance](process_assets/skills/production-engineering/SKILL.md#design-quality)
166
+ requires understandable responsibilities, data and state, ownership, and contracts.
167
+ Agents actively introduce or refine cohesive abstractions when current requirements
168
+ justify them, weighing comprehension and change locality against indirection.
169
+ Consumer architecture and language choices remain authoritative.
170
+
171
+ Start defines scoped design outcomes; the plan explains material choices in its
172
+ existing approach and work items; implementation revisits the affected flow before
173
+ verification. Independent review traces behavior and a concrete maintenance scenario
174
+ against the actual code. Demonstrated violations of accepted criteria can block
175
+ completion despite passing tests. Routine edits stay proportional, and a clear
176
+ direct implementation remains valid. The existing lifecycle enforces criterion-bound
177
+ findings and evidence freshness; contextual design quality remains the reviewer's
178
+ judgment, without another gate, artifact, or canonical invariant.
179
+
153
180
  ### Production engineering invariants
154
181
 
155
182
  Every new plan and independent review applies one small, versioned invariant floor:
@@ -416,6 +443,19 @@ approved can finish only while the repository still matches the reviewed snapsho
416
443
  --actor coordinator \
417
444
  --context finish-123
418
445
 
446
+ New runs preserve the accepted `comparisonBase` ref and contract digest, and record
447
+ its resolved commit separately as `comparisonBaseCommit`. Start rejects missing or
448
+ non-commit refs before writing the run. Lifecycle output supplies the recorded commit
449
+ for review even after commits or branch movement. Older runs without this field stay
450
+ readable; their original review boundary must be established from available history,
451
+ not retrospectively claimed as pinned. If that boundary cannot be established, use
452
+ an owner-selected replacement contract.
453
+
454
+ Correction reports must retain every previously open blocker until its unchanged
455
+ identity receives an explicit `resolved` disposition. Omitting it or changing it to
456
+ `accepted-risk` or `tracked-follow-up` cannot retire the blocker. This applies to all
457
+ supported review schemas; ordinary legacy non-blocking observations remain readable.
458
+
419
459
  ### Public pull-request evidence
420
460
 
421
461
  The managed pull-request template keeps public assurance separate from local
@@ -441,12 +481,26 @@ and authors plus independent review keep it out of free-form values. The validat
441
481
  a positive grammar for public fields; it deliberately does not guess identities from
442
482
  an open-ended vocabulary of names or labels.
443
483
 
484
+ This producer's local `review` profile runs `verification/verify_publication.py`
485
+ against the actual Git branch. `main` is the consumer's integration branch, not a
486
+ proposal; detached local checkouts require explicit PR context instead of a guessed
487
+ branch name. In CI, the `Adopted public process` job supplies actual PR metadata and
488
+ the base/head commit range to the installed publication adapters. Metadata edits and
489
+ draft-state changes rerun CI. Maintainers must keep this existing job in `main`'s
490
+ required status checks alongside the other required checks. These publication choices
491
+ belong to this consumer; the shared lifecycle does not impose a naming policy.
492
+
444
493
  At any point:
445
494
 
446
495
  processctl change status --change-id change-123 --json
447
496
 
448
497
  ## Release to consumer PR
449
498
 
499
+ Each release includes [reviewed release contents](RELEASE_NOTES.md) generated from
500
+ the canonical manifest: shipped features/fixes, their source issues or changes, and
501
+ upgrade guidance. The release PR reviews this file; the GitHub Release publishes the
502
+ same contents. See [the release procedure](RELEASING.md) for authoring and checks.
503
+
450
504
  This producer's release identity inputs and text assets declared by
451
505
  `tool.setuptools.data-files` use UTF-8 without BOM and LF, matching `.gitattributes`.
452
506
  Writers select that representation explicitly; JSON writers use
@@ -0,0 +1,23 @@
1
+ # Engineering Process v2.1.0
2
+
3
+ Changes since v2.0.2.
4
+
5
+ ## Features
6
+
7
+ - Pin comparison refs in new lifecycle runs\, require explicit blocker closure\, and wire the producer\'s actual publication metadata into required verification while retaining older run readers\. ([#169](https://github.com/phuongnse/engineering-process/issues/169))
8
+
9
+ ## Fixes
10
+
11
+ - Carry consumer design quality through accepted criteria\, planning\, implementation\, and independent review\, with proactive cohesive abstractions and evidence\-based maintenance judgment\. ([#119](https://github.com/phuongnse/engineering-process/issues/119))
12
+ - Clarify real independent reviewer dispatch\, neutral context and reviewer\-owned report handoff using the existing runner\. ([#166](https://github.com/phuongnse/engineering-process/issues/166))
13
+ - Publish reviewed release contents with grouped changes\, source issues and upgrade guidance generated from the canonical release manifest\. ([#171](https://github.com/phuongnse/engineering-process/issues/171))
14
+
15
+ ## Upgrade and compatibility
16
+
17
+ Merge the complete hash-locked package/adoption PR, update the local and CI environments to the selected version, and start a fresh agent session.
18
+
19
+ Consumer CI, naming conventions and branch-protection settings remain consumer-owned; adoption does not configure them automatically.
20
+
21
+ See [versioning and compatibility](https://github.com/phuongnse/engineering-process/blob/v2.1.0/VERSIONING.md) and [adoption guidance](https://github.com/phuongnse/engineering-process/blob/v2.1.0/SELF_HOSTING.md).
22
+
23
+ [Full change comparison](https://github.com/phuongnse/engineering-process/compare/v2.0.2...v2.1.0)
@@ -1,3 +1,3 @@
1
1
  """Agent-neutral engineering process."""
2
2
 
3
- VERSION = "2.0.1"
3
+ VERSION = "2.1.0"
@@ -85,6 +85,7 @@ def _state_result(command: str, state: dict[str, Any], **details: Any) -> dict[s
85
85
  changeId=state["changeId"],
86
86
  phase=state["phase"],
87
87
  cycle=state["cycle"],
88
+ **({"comparisonBaseCommit": state["comparisonBaseCommit"]} if "comparisonBaseCommit" in state else {}),
88
89
  **details,
89
90
  )
90
91
 
@@ -33,7 +33,7 @@ from .production_engineering import (
33
33
  validate_plan_assessments,
34
34
  validate_review_assessments,
35
35
  )
36
- from .repository import repository_snapshot, same_checkpoint
36
+ from .repository import repository_snapshot, resolve_commit, same_checkpoint
37
37
 
38
38
 
39
39
  NEXT_COMMAND = {
@@ -182,12 +182,14 @@ def start_change(
182
182
  raise ProcessError("change affectedProjects must include the current project")
183
183
 
184
184
  actor = _actor(actor_id, context_id, kind)
185
+ comparison_base = resolve_commit(project_root, contract["comparisonBase"])
185
186
  state: dict[str, Any] = {
186
187
  "schemaVersion": 1,
187
188
  "changeId": change_id,
188
189
  "phase": "specified",
189
190
  "cycle": 0,
190
191
  "contract": {"digest": digest_json(contract), "document": contract},
192
+ "comparisonBaseCommit": comparison_base,
191
193
  "plan": None,
192
194
  "implementations": [],
193
195
  "currentImplementation": None,
@@ -481,6 +483,19 @@ def submit_review(
481
483
  ):
482
484
  raise ProcessError("critical-late blockers must be P0 or P1")
483
485
 
486
+ current_findings = {finding["id"]: finding for finding in review["findings"]}
487
+ for finding_id, prior in prior_findings.items():
488
+ if prior["severity"] != "blocking":
489
+ continue
490
+ current_finding = current_findings.get(finding_id)
491
+ if current_finding is None:
492
+ raise ProcessError(f"prior blocking finding must not be omitted: {finding_id}")
493
+ if (
494
+ current_finding["severity"] != "blocking"
495
+ and current_finding.get("disposition", {}).get("status") != "resolved"
496
+ ):
497
+ raise ProcessError(f"prior blocking finding must remain blocking or be resolved: {finding_id}")
498
+
484
499
  state["review"] = {"digest": digest_json(review), "document": review}
485
500
  state["reviewHistory"].append(
486
501
  {
@@ -50,6 +50,12 @@ def _head(root: Path) -> str | None:
50
50
  return decoded
51
51
 
52
52
 
53
+ def resolve_commit(root: Path, reference: str) -> str:
54
+ return _git(
55
+ root, ["rev-parse", "--verify", "--end-of-options", f"{reference}^{{commit}}"]
56
+ ).decode("ascii").strip()
57
+
58
+
53
59
  def repository_snapshot(root: Path) -> dict[str, Any]:
54
60
  root = root.resolve()
55
61
  if not (root / ".git").exists():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: engineering-process
3
- Version: 2.0.1
3
+ Version: 2.1.0
4
4
  Summary: A small agent-neutral engineering lifecycle with managed adoption
5
5
  License-Expression: MIT
6
6
  Project-URL: Homepage, https://github.com/phuongnse/engineering-process
@@ -69,6 +69,14 @@ may have implemented the current cycle. There is no attestation hierarchy,
69
69
  recommendation chain, authority-transition protocol, remote-evidence federation, or
70
70
  second handwritten validator.
71
71
 
72
+ The coordinator hands review to an actual reviewer. A new agent review starts in a
73
+ fresh context with the accepted source artifacts and no suggested verdict; the same
74
+ reviewer continues corrections. The reviewer inspects the change and authors its
75
+ own report. The runner's existing task/session interaction and returned result make
76
+ that work inspectable. Sharing a model, provider, or account is allowed; this is a
77
+ workflow for independent judgment, not authenticated identity or merge enforcement.
78
+ See [change-review](process_assets/skills/change-review/SKILL.md) for the handoff.
79
+
72
80
  Runtime architecture is enforced by semantic fitness functions, not module or source-
73
81
  line quotas. Every module has an explicit dependency layer, imports point toward lower
74
82
  layers, the internal graph remains acyclic, and lifecycle.py alone owns state
@@ -174,6 +182,25 @@ runtime/license delivery, Linux advisory resolution, real-host workspace securit
174
182
  updater, incident recovery, and independent security review remain planned.
175
183
  Consumers without readiness remain compatible during that evidence-backed rollout.
176
184
 
185
+ ### Design quality
186
+
187
+ Changes that materially alter logic, state, or collaboration boundaries carry
188
+ consumer design standards in their existing acceptance criteria. The shared
189
+ [design quality guidance](process_assets/skills/production-engineering/SKILL.md#design-quality)
190
+ requires understandable responsibilities, data and state, ownership, and contracts.
191
+ Agents actively introduce or refine cohesive abstractions when current requirements
192
+ justify them, weighing comprehension and change locality against indirection.
193
+ Consumer architecture and language choices remain authoritative.
194
+
195
+ Start defines scoped design outcomes; the plan explains material choices in its
196
+ existing approach and work items; implementation revisits the affected flow before
197
+ verification. Independent review traces behavior and a concrete maintenance scenario
198
+ against the actual code. Demonstrated violations of accepted criteria can block
199
+ completion despite passing tests. Routine edits stay proportional, and a clear
200
+ direct implementation remains valid. The existing lifecycle enforces criterion-bound
201
+ findings and evidence freshness; contextual design quality remains the reviewer's
202
+ judgment, without another gate, artifact, or canonical invariant.
203
+
177
204
  ### Production engineering invariants
178
205
 
179
206
  Every new plan and independent review applies one small, versioned invariant floor:
@@ -440,6 +467,19 @@ approved can finish only while the repository still matches the reviewed snapsho
440
467
  --actor coordinator \
441
468
  --context finish-123
442
469
 
470
+ New runs preserve the accepted `comparisonBase` ref and contract digest, and record
471
+ its resolved commit separately as `comparisonBaseCommit`. Start rejects missing or
472
+ non-commit refs before writing the run. Lifecycle output supplies the recorded commit
473
+ for review even after commits or branch movement. Older runs without this field stay
474
+ readable; their original review boundary must be established from available history,
475
+ not retrospectively claimed as pinned. If that boundary cannot be established, use
476
+ an owner-selected replacement contract.
477
+
478
+ Correction reports must retain every previously open blocker until its unchanged
479
+ identity receives an explicit `resolved` disposition. Omitting it or changing it to
480
+ `accepted-risk` or `tracked-follow-up` cannot retire the blocker. This applies to all
481
+ supported review schemas; ordinary legacy non-blocking observations remain readable.
482
+
443
483
  ### Public pull-request evidence
444
484
 
445
485
  The managed pull-request template keeps public assurance separate from local
@@ -465,12 +505,26 @@ and authors plus independent review keep it out of free-form values. The validat
465
505
  a positive grammar for public fields; it deliberately does not guess identities from
466
506
  an open-ended vocabulary of names or labels.
467
507
 
508
+ This producer's local `review` profile runs `verification/verify_publication.py`
509
+ against the actual Git branch. `main` is the consumer's integration branch, not a
510
+ proposal; detached local checkouts require explicit PR context instead of a guessed
511
+ branch name. In CI, the `Adopted public process` job supplies actual PR metadata and
512
+ the base/head commit range to the installed publication adapters. Metadata edits and
513
+ draft-state changes rerun CI. Maintainers must keep this existing job in `main`'s
514
+ required status checks alongside the other required checks. These publication choices
515
+ belong to this consumer; the shared lifecycle does not impose a naming policy.
516
+
468
517
  At any point:
469
518
 
470
519
  processctl change status --change-id change-123 --json
471
520
 
472
521
  ## Release to consumer PR
473
522
 
523
+ Each release includes [reviewed release contents](RELEASE_NOTES.md) generated from
524
+ the canonical manifest: shipped features/fixes, their source issues or changes, and
525
+ upgrade guidance. The release PR reviews this file; the GitHub Release publishes the
526
+ same contents. See [the release procedure](RELEASING.md) for authoring and checks.
527
+
474
528
  This producer's release identity inputs and text assets declared by
475
529
  `tool.setuptools.data-files` use UTF-8 without BOM and LF, matching `.gitattributes`.
476
530
  Writers select that representation explicitly; JSON writers use
@@ -1,6 +1,7 @@
1
1
  LICENSE
2
2
  MANIFEST.in
3
3
  README.md
4
+ RELEASE_NOTES.md
4
5
  process-graph.json
5
6
  pyproject.toml
6
7
  engineering_process/__init__.py
@@ -68,6 +69,7 @@ tests/test_distribution.py
68
69
  tests/test_lifecycle.py
69
70
  tests/test_production_engineering.py
70
71
  tests/test_publication_compat.py
72
+ tests/test_publication_workflow.py
71
73
  tests/test_pypi_cache_horizon.py
72
74
  tests/test_release.py
73
75
  tests/test_repository.py
@@ -7,7 +7,11 @@ description: Complete an approved change when routed by deliver-change, only whi
7
7
 
8
8
  Confirm the lifecycle is approved, every required profile passed, every blocking
9
9
  finding is closed, every non-blocking finding has its required disposition, and the
10
- repository still matches the reviewed snapshot. Then run:
10
+ repository still matches the reviewed snapshot.
11
+ Every previously open blocker must have remained visible until the reviewer recorded
12
+ its explicit resolution; an omitted finding is not a closed finding.
13
+
14
+ Run:
11
15
 
12
16
  processctl change finish --change-id ID --actor ACTOR --context CONTEXT
13
17
 
@@ -16,6 +20,12 @@ marks the run completed.
16
20
  Completion does not itself grant merge, deployment, or release authority; those
17
21
  remain project-owned operations. Never report completion from prose alone.
18
22
 
23
+ When the accepted work includes a release, make its contents reviewable: what ships,
24
+ user impact, source issues or changes, and required upgrade/compatibility actions.
25
+ Use the consumer's reviewed release records as the authority. The consumer owns
26
+ format, tooling and publication decisions; a list of internal execution events or
27
+ version-bump PR titles does not explain shipped behavior.
28
+
19
29
  Use a normal trailing `Refs ISSUE.` line for producer and intermediate pull requests.
20
30
  Only a contract-identified final consumer adoption that has verified the released
21
31
  behavior may use `Closes ISSUE, closes ISSUE.` after the completed public checklist.
@@ -21,6 +21,13 @@ items produce the planned objective evidence. If implementation proves an
21
21
  applicability decision wrong, preserve the accepted contract and implement the
22
22
  required structure; the independent review records the corrected semantic result.
23
23
 
24
+ Complete the accepted design work before final verification. Re-read the affected
25
+ end-to-end flow and its callers using **production-engineering** design guidance;
26
+ refactor within scope when the implemented structure obscures responsibility,
27
+ weakens contracts, or adds unnecessary coupling or indirection. Preserve behavior
28
+ and protective checks during refactoring. Working code and passing tests do not
29
+ replace meeting accepted design criteria.
30
+
24
31
  Do not weaken an affected enforced readiness capability or silently change its pack,
25
32
  version, profile mapping, state, or gap. A planned-to-enforced transition must be an
26
33
  explicit implementation diff backed by the planned checks. Never auto-promote a
@@ -10,6 +10,14 @@ approach, bounded work items with owned paths, and concrete risks with mitigatio
10
10
  The plan must bind the exact contract digest and must not add behavior that the
11
11
  contract did not accept.
12
12
 
13
+ Use the existing `approach` to explain material design decisions against the accepted
14
+ criteria and inspected consumer code: responsibility and state ownership,
15
+ collaboration contracts, reusable structures, and actual sources of variation.
16
+ Explain how the chosen structure helps trace the behavior and contains a concrete
17
+ maintenance change, accounting for indirection and coupling. Bind needed design work
18
+ to existing work-item outcomes. Keep reasoning proportional; retaining a clear
19
+ existing structure is a valid choice.
20
+
13
21
  Read **production-engineering** and add one `productionEngineering` assessment for
14
22
  each canonical invariant in its defined order. Decide applicability from the stated
15
23
  trigger, give a concrete rationale, and bind every applicable invariant to the work
@@ -6,7 +6,29 @@ description: Review the exact verified snapshot from an independent actor and co
6
6
  # Review a change
7
7
 
8
8
  The reviewer must not share either actor identity or execution context with an
9
- implementer in the current cycle. Read `processctl change status --change-id ID`.
9
+ implementer in the current cycle. An implementer must hand off this phase to an
10
+ actual reviewer, not perform it under another identity.
11
+
12
+ For a new agent review, spawn a fresh agent/session without the implementation
13
+ conversation. Supply the accepted contract and plan, recorded `comparisonBaseCommit`, candidate
14
+ path/checkpoint, and verification evidence. Request an independent assessment of
15
+ the complete diff and relevant code/tests without suggesting a verdict. The same
16
+ model, provider, or account may be used. If the environment cannot run or reach an
17
+ independent reviewer, leave the change awaiting review and report that missing
18
+ handoff.
19
+
20
+ Use `comparisonBaseCommit` from lifecycle output or the run state; never re-resolve
21
+ the original moving ref after implementation. Older runs may lack this field. Keep
22
+ their accepted comparison boundary explicit and establish the complete diff from
23
+ available history; if it cannot be established, request an owner-selected replacement
24
+ contract rather than claiming the base was pinned at start.
25
+
26
+ Use the runner's returned reviewer handle to continue the real reviewer. Record its
27
+ actor/context in the existing assignment and retain the native task/session
28
+ interaction and returned result for inspection. Distinct identity strings alone do
29
+ not demonstrate that a review ran.
30
+
31
+ Read `processctl change status --change-id ID`.
10
32
  When the phase is `verified`, start the assignment:
11
33
 
12
34
  processctl change review start --change-id ID --actor REVIEWER --context REVIEW_CONTEXT
@@ -28,6 +50,22 @@ the contract are proposals, not blocking findings. approved may contain non-bloc
28
50
  observations but no blocking finding; changes-requested requires at least one blocking
29
51
  finding.
30
52
 
53
+ Carry every previously open blocking finding into the next report with its identity
54
+ unchanged. It must remain blocking or have a `resolved` disposition with the reason
55
+ the reviewed snapshot closes it. Omission, `accepted-risk`, and `tracked-follow-up`
56
+ cannot retire a blocker. This also applies to older report versions; their ordinary
57
+ non-blocking observations keep the existing compatibility rules.
58
+
59
+ Assess accepted design criteria separately from passing checks. Use
60
+ **production-engineering** design guidance to trace a significant behavior and a
61
+ concrete maintenance scenario grounded in current requirements through the affected
62
+ code, callers, and dependencies. Evaluate both the effort to understand the flow and
63
+ the reach of a change. A design finding must identify the violated criterion, source
64
+ location, and concrete correctness, comprehension, or maintenance consequence.
65
+ Apply the existing blocking rules to demonstrated violations even when tests pass;
66
+ preference for a pattern, shorter code, or a different valid structure is insufficient.
67
+ Do not retrofit new design criteria into the frozen contract.
68
+
31
69
  Read **production-engineering** and independently reassess every canonical invariant.
32
70
  Use the report's `productionEngineering` entries to record `satisfied`,
33
71
  `not-applicable`, or `violated`; cite concrete snapshot evidence for each satisfied
@@ -60,7 +98,10 @@ For a planned-to-enforced transition, require the explicit readiness diff and cu
60
98
  consumer-owned evidence; reject promotion by prose, stale evidence, or renamed gap.
61
99
  Do not block the change merely because unrelated planned capabilities still exist.
62
100
 
63
- Validate and submit the report:
101
+ The reviewer authors the verdict, findings, and assessments, then validates and
102
+ submits its report. If only the coordinator can submit, it transports the reviewer's
103
+ returned report unchanged. Report errors go back to the assigned reviewer for
104
+ correction; the coordinator must not fill in or rewrite the review content.
64
105
 
65
106
  processctl contract validate --kind review REPORT_PATH
66
107
  processctl change review submit --change-id ID --review REPORT_PATH
@@ -10,6 +10,17 @@ behavior. Write a change contract containing the source request, comparison base
10
10
  risk, affected projects, observable acceptance criteria, and required verification
11
11
  profiles. Do not decide unresolved product behavior silently.
12
12
 
13
+ Choose the consumer's comparison ref deliberately. Start resolves it once to an
14
+ existing commit and returns `comparisonBaseCommit`; use that recorded commit for
15
+ later diff/review work. The accepted contract and its digest retain the original ref.
16
+
17
+ When the accepted change adds or materially changes logic, state, or collaboration
18
+ boundaries, read the design quality guidance in **production-engineering**. Express
19
+ applicable consumer design standards as observable outcomes in the existing
20
+ acceptance criteria: identify the responsibility or contract that must be clear and
21
+ the supported behavior it must make understandable. Keep those outcomes within the
22
+ accepted behavior and affected code; routine edits need no separate design exercise.
23
+
13
24
  Read the readiness result from `processctl project validate --json`. Use the accepted
14
25
  request, consumer rules, and inspected behavior to identify only capabilities this
15
26
  change affects or explicitly advances. State that relationship in the summary and
@@ -18,9 +18,10 @@ change status when a change already exists, then route exactly one current phase
18
18
  2. specified: use **change-plan**.
19
19
  3. planned or changes-requested: use **change-implement**.
20
20
  4. implementing: use **change-verify**.
21
- 5. verified or review-pending: use **change-review**, resuming the existing assignment
22
- when review is pending; if the repository changed after evidence was recorded,
23
- use **change-implement** to open a new cycle.
21
+ 5. verified or review-pending: hand off to an actual independent reviewer through
22
+ **change-review**, resuming the existing assignment when review is pending; if the
23
+ repository changed after evidence was recorded, use **change-implement** to open a
24
+ new cycle.
24
25
  6. approved: use **change-complete**; a later repository change also reopens through
25
26
  **change-implement**.
26
27
  7. blocked: stop. The current contract cannot merge; the owner may narrow or
@@ -30,10 +31,10 @@ When changing this process itself, first use **process-improve** to prove the re
30
31
  came from a real consumer incident or need; the change still follows the same six
31
32
  phases afterward.
32
33
 
33
- From planning through independent review, use **production-engineering** as the
34
- shared correctness floor. Its canonical definitions drive the plan and review
35
- contracts; do not replace their contextual assessment with keyword or naming
36
- heuristics.
34
+ Use **production-engineering** design guidance when defining acceptance criteria for
35
+ material changes. From planning through independent review, also apply its shared
36
+ correctness floor. Its canonical definitions drive the invariant assessments; do not
37
+ replace contextual judgment with keyword or naming heuristics.
37
38
 
38
39
  The project's nearest AGENTS.md owns product decisions and .process/project.json owns
39
40
  exact argument-array commands. Skills guide the work; only processctl advances
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: production-engineering
3
- description: Apply the small production-engineering invariant floor during planning, implementation, verification, and independent review without replacing semantic judgment with keyword checks.
3
+ description: Apply intentional design guidance and the small production-engineering invariant floor without replacing contextual judgment with keyword checks.
4
4
  ---
5
5
 
6
- # Production engineering invariants
6
+ # Production engineering
7
7
 
8
8
  Assess the [canonical invariant definitions](invariants.json) for every new plan. They
9
9
  are a small correctness floor, not a design-pattern catalog and not a claim that one
@@ -13,6 +13,33 @@ Keep the core floor at no more than seven invariants. Adding one requires eviden
13
13
  from a real consumer; first prefer clarifying or consolidating an existing invariant.
14
14
  This is a design budget, not an assessment or a substitute for evidence.
15
15
 
16
+ ## Design quality
17
+
18
+ Use the consumer's architecture, domain model, and accepted design criteria to judge
19
+ the affected code. Responsibilities, valid data and state, ownership of rules and
20
+ side effects, and contracts between collaborators must be understandable from the
21
+ source. A reader should be able to trace a supported behavior and locate its rules
22
+ without reconstructing the implementation conversation.
23
+
24
+ Actively introduce or refine cohesive abstractions when current requirements expose
25
+ a hidden responsibility, duplicated policy, or coordination and consistency
26
+ obligations leaking into callers. Use consumer-native constructs and reuse sound
27
+ existing boundaries. An abstraction earns its place by clarifying behavior or
28
+ containing a real change, with its indirection and coupling costs accounted for.
29
+ A small caller count does not disqualify an abstraction that clarifies responsibility
30
+ or protects a contract.
31
+
32
+ Preserve clear direct implementations where further separation adds no present
33
+ benefit. Judge both the effort to follow a behavior and the reach of a change;
34
+ shorter code, more layers, and named patterns do not establish design quality.
35
+ Keep refactoring within the accepted scope and avoid unused flexibility. Record
36
+ material rationale near the owned code when the structure cannot express it.
37
+
38
+ Assess these outcomes through the existing accepted criteria. They do not add entries
39
+ to the canonical invariant assessments or expand an in-flight contract.
40
+
41
+ ## Invariant assessments
42
+
16
43
  At plan time, assess every invariant as `applicable` or `not-applicable`. Explain the
17
44
  decision from the invariant's trigger. Every applicable assessment names the work
18
45
  items that will establish its required structure and evidence. `not-applicable` is a
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "engineering-process"
7
- version = "2.0.1"
7
+ version = "2.1.0"
8
8
  description = "A small agent-neutral engineering lifecycle with managed adoption"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -11,6 +11,7 @@
11
11
  "phase": {"enum": ["specified", "planned", "implementing", "verified", "review-pending", "approved", "changes-requested", "completed", "blocked"]},
12
12
  "cycle": {"type": "integer", "minimum": 0},
13
13
  "contract": {"$ref": "#/$defs/boundDocument"},
14
+ "comparisonBaseCommit": {"type": "string", "pattern": "^[0-9a-f]{40}(?:[0-9a-f]{24})?$"},
14
15
  "plan": {"oneOf": [{"$ref": "#/$defs/boundDocument"}, {"type": "null"}]},
15
16
  "implementations": {
16
17
  "type": "array",