engineering-process 1.2.6__tar.gz → 2.0.1__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.
- {engineering_process-1.2.6/engineering_process.egg-info → engineering_process-2.0.1}/PKG-INFO +35 -5
- {engineering_process-1.2.6 → engineering_process-2.0.1}/README.md +34 -4
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/__init__.py +1 -1
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/cli.py +17 -1
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/commands.py +45 -4
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/skills.py +15 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1/engineering_process.egg-info}/PKG-INFO +35 -5
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process.egg-info/SOURCES.txt +8 -8
- {engineering_process-1.2.6 → engineering_process-2.0.1}/process-graph.json +23 -23
- {engineering_process-1.2.6/process_assets/skills/finish-change → engineering_process-2.0.1/process_assets/skills/change-complete}/SKILL.md +5 -4
- {engineering_process-1.2.6/process_assets/skills/implement-change → engineering_process-2.0.1/process_assets/skills/change-implement}/SKILL.md +3 -3
- {engineering_process-1.2.6/process_assets/skills/plan-change → engineering_process-2.0.1/process_assets/skills/change-plan}/SKILL.md +2 -2
- {engineering_process-1.2.6/process_assets/skills/review-change → engineering_process-2.0.1/process_assets/skills/change-review}/SKILL.md +15 -6
- {engineering_process-1.2.6/process_assets/skills/start-change → engineering_process-2.0.1/process_assets/skills/change-start}/SKILL.md +2 -2
- {engineering_process-1.2.6/process_assets/skills/verify-change → engineering_process-2.0.1/process_assets/skills/change-verify}/SKILL.md +8 -3
- {engineering_process-1.2.6/process_assets/skills/run-change → engineering_process-2.0.1/process_assets/skills/deliver-change}/SKILL.md +16 -15
- {engineering_process-1.2.6/process_assets/skills/improve-process → engineering_process-2.0.1/process_assets/skills/process-improve}/SKILL.md +2 -2
- {engineering_process-1.2.6 → engineering_process-2.0.1}/pyproject.toml +9 -9
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/run.schema.json +47 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/templates/AGENTS.process.md +1 -1
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_adoption.py +83 -3
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_cli.py +7 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_commands.py +122 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_contracts.py +56 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_distribution.py +19 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_lifecycle.py +43 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_skills.py +64 -19
- {engineering_process-1.2.6 → engineering_process-2.0.1}/LICENSE +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/MANIFEST.in +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/__main__.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/_supervisor_contract.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/_supervisor_posix.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/_supervisor_windows.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/_windows_job.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/adoption.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/contracts.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/distribution.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/helper_launch.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/lifecycle.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/production_engineering.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/project.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/publication_compat.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/release.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/repository.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/requirements-dev.txt +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/requirements-runtime.txt +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process/supervision.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process.egg-info/dependency_links.txt +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process.egg-info/entry_points.txt +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process.egg-info/requires.txt +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process.egg-info/top_level.txt +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/process_assets/skills/production-engineering/SKILL.md +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/process_assets/skills/production-engineering/invariants.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/change.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/plan.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/process-graph.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/process-lock.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/production-engineering.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/project-legacy.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/project.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/receipt.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/release-change.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/release.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/schemas/review.schema.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/setup.cfg +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/templates/PULL_REQUEST_TEMPLATE.md +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/templates/adopt-process-windows-job.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/templates/adopt-process.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/templates/renovate.json +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_architecture.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_automation.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_production_engineering.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_publication_compat.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_pypi_cache_horizon.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_release.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_repository.py +0 -0
- {engineering_process-1.2.6 → engineering_process-2.0.1}/tests/test_supervisor_posix.py +0 -0
{engineering_process-1.2.6/engineering_process.egg-info → engineering_process-2.0.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: engineering-process
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.1
|
|
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
|
|
@@ -33,11 +33,27 @@ Portable skills explain what to do. processctl owns state transitions and curren
|
|
|
33
33
|
evidence. Each consumer owns its product rules, exact commands, merge policy, and
|
|
34
34
|
release decisions.
|
|
35
35
|
|
|
36
|
+
Start delivery work with [deliver-change](process_assets/skills/deliver-change/SKILL.md).
|
|
37
|
+
It selects the current phase from lifecycle state; callers do not select a phase skill:
|
|
38
|
+
|
|
39
|
+
deliver-change
|
|
40
|
+
change-start -> change-plan -> change-implement -> change-verify
|
|
41
|
+
-> change-review -> change-complete
|
|
42
|
+
|
|
43
|
+
[process-improve](process_assets/skills/process-improve/SKILL.md) handles a reusable
|
|
44
|
+
process problem, then returns delivery to the same lifecycle.
|
|
45
|
+
[production-engineering](process_assets/skills/production-engineering/SKILL.md) supplies
|
|
46
|
+
the invariant floor consulted from planning through independent review. Both are
|
|
47
|
+
reachable specializations; neither advances lifecycle state. `change-complete` calls
|
|
48
|
+
the existing `processctl change finish` command.
|
|
49
|
+
|
|
50
|
+
For migration from the previous skill identifiers, see [Versioning](VERSIONING.md#skill-namespace-migration).
|
|
51
|
+
|
|
36
52
|
## Architecture
|
|
37
53
|
|
|
38
54
|
The distribution has four live parts:
|
|
39
55
|
|
|
40
|
-
1. Managed skills under process_assets/skills, all reachable from
|
|
56
|
+
1. Managed skills under process_assets/skills, all reachable from deliver-change.
|
|
41
57
|
2. One processctl state machine under engineering_process/lifecycle.py.
|
|
42
58
|
3. JSON Schemas that are loaded directly by the runtime.
|
|
43
59
|
4. One adoption transaction that synchronizes managed skills and configuration from
|
|
@@ -98,6 +114,20 @@ Commands are argument arrays, never shell strings. Each command has a finite tim
|
|
|
98
114
|
Output has a hard aggregate budget; evidence stores byte counts and hashes, never raw
|
|
99
115
|
stdout or stderr that could contain secrets.
|
|
100
116
|
|
|
117
|
+
A failed profile also reports a safe `diagnostic` descriptor containing only its
|
|
118
|
+
validated profile identifier, check identifier, canonical one-based profile position,
|
|
119
|
+
and a fixed `processctl` argument array. The position remains unambiguous even when a
|
|
120
|
+
compatible project has duplicate check identifiers. Run that array from the project
|
|
121
|
+
root to reproduce only the failed configured check through the same bounded runner,
|
|
122
|
+
for example:
|
|
123
|
+
|
|
124
|
+
processctl verify --profile rust --check-position 3
|
|
125
|
+
|
|
126
|
+
This selective run is diagnostic only: it does not expose captured output, replace a
|
|
127
|
+
required full-profile run, or count as lifecycle verification evidence. Maintainers
|
|
128
|
+
who need semantic tool output must use a tool-owned structured report or run the
|
|
129
|
+
consumer command in an appropriately trusted environment.
|
|
130
|
+
|
|
101
131
|
### Production readiness
|
|
102
132
|
|
|
103
133
|
A consumer declares `.process/readiness.json` with production as its direction, its
|
|
@@ -175,7 +205,7 @@ This assessment is not a production certificate. Production still requires the
|
|
|
175
205
|
consumer's immutable readiness pack, every required capability in `enforced` state,
|
|
176
206
|
fresh consumer-owned verification on the exact candidate, and independent review.
|
|
177
207
|
|
|
178
|
-
For each ordinary change, `
|
|
208
|
+
For each ordinary change, `deliver-change` first surfaces this readiness view. The accepted
|
|
179
209
|
request and consumer rules determine which capabilities are affected. Every change
|
|
180
210
|
retains the project's baseline `requiredProfiles`; start and plan add any conditional
|
|
181
211
|
evidence profiles needed by affected capabilities and include a planned gap only when
|
|
@@ -184,7 +214,7 @@ floor. A planned-to-enforced promotion is a reviewed consumer source diff with f
|
|
|
184
214
|
evidence. Unrelated planned gaps remain visible but do not block development, and no
|
|
185
215
|
skill chooses product priorities or changes readiness automatically.
|
|
186
216
|
|
|
187
|
-
When a consumer incident exposes a reusable process gap, `improve
|
|
217
|
+
When a consumer incident exposes a reusable process gap, `process-improve` first keeps
|
|
188
218
|
the consumer safe, then prepares a sanitized GitHub issue draft from that checkout.
|
|
189
219
|
It deduplicates by consumer/process-version/invariant, requires owner authorization
|
|
190
220
|
before `gh issue create`, and uses an accepted issue as the later process change source
|
|
@@ -352,7 +382,7 @@ URL; without it, the review remains pending. Earlier plan and review documents r
|
|
|
352
382
|
readable, and their runs remain registrable or finishable with the version selected by
|
|
353
383
|
the authority that started the relevant phase.
|
|
354
384
|
|
|
355
|
-
The [finding priority definitions](process_assets/skills/review
|
|
385
|
+
The [finding priority definitions](process_assets/skills/change-review/SKILL.md#finding-priority)
|
|
356
386
|
are the canonical P0-P3 impact convention for this process, including examples and
|
|
357
387
|
their relationship to blocking decisions.
|
|
358
388
|
|
|
@@ -9,11 +9,27 @@ Portable skills explain what to do. processctl owns state transitions and curren
|
|
|
9
9
|
evidence. Each consumer owns its product rules, exact commands, merge policy, and
|
|
10
10
|
release decisions.
|
|
11
11
|
|
|
12
|
+
Start delivery work with [deliver-change](process_assets/skills/deliver-change/SKILL.md).
|
|
13
|
+
It selects the current phase from lifecycle state; callers do not select a phase skill:
|
|
14
|
+
|
|
15
|
+
deliver-change
|
|
16
|
+
change-start -> change-plan -> change-implement -> change-verify
|
|
17
|
+
-> change-review -> change-complete
|
|
18
|
+
|
|
19
|
+
[process-improve](process_assets/skills/process-improve/SKILL.md) handles a reusable
|
|
20
|
+
process problem, then returns delivery to the same lifecycle.
|
|
21
|
+
[production-engineering](process_assets/skills/production-engineering/SKILL.md) supplies
|
|
22
|
+
the invariant floor consulted from planning through independent review. Both are
|
|
23
|
+
reachable specializations; neither advances lifecycle state. `change-complete` calls
|
|
24
|
+
the existing `processctl change finish` command.
|
|
25
|
+
|
|
26
|
+
For migration from the previous skill identifiers, see [Versioning](VERSIONING.md#skill-namespace-migration).
|
|
27
|
+
|
|
12
28
|
## Architecture
|
|
13
29
|
|
|
14
30
|
The distribution has four live parts:
|
|
15
31
|
|
|
16
|
-
1. Managed skills under process_assets/skills, all reachable from
|
|
32
|
+
1. Managed skills under process_assets/skills, all reachable from deliver-change.
|
|
17
33
|
2. One processctl state machine under engineering_process/lifecycle.py.
|
|
18
34
|
3. JSON Schemas that are loaded directly by the runtime.
|
|
19
35
|
4. One adoption transaction that synchronizes managed skills and configuration from
|
|
@@ -74,6 +90,20 @@ Commands are argument arrays, never shell strings. Each command has a finite tim
|
|
|
74
90
|
Output has a hard aggregate budget; evidence stores byte counts and hashes, never raw
|
|
75
91
|
stdout or stderr that could contain secrets.
|
|
76
92
|
|
|
93
|
+
A failed profile also reports a safe `diagnostic` descriptor containing only its
|
|
94
|
+
validated profile identifier, check identifier, canonical one-based profile position,
|
|
95
|
+
and a fixed `processctl` argument array. The position remains unambiguous even when a
|
|
96
|
+
compatible project has duplicate check identifiers. Run that array from the project
|
|
97
|
+
root to reproduce only the failed configured check through the same bounded runner,
|
|
98
|
+
for example:
|
|
99
|
+
|
|
100
|
+
processctl verify --profile rust --check-position 3
|
|
101
|
+
|
|
102
|
+
This selective run is diagnostic only: it does not expose captured output, replace a
|
|
103
|
+
required full-profile run, or count as lifecycle verification evidence. Maintainers
|
|
104
|
+
who need semantic tool output must use a tool-owned structured report or run the
|
|
105
|
+
consumer command in an appropriately trusted environment.
|
|
106
|
+
|
|
77
107
|
### Production readiness
|
|
78
108
|
|
|
79
109
|
A consumer declares `.process/readiness.json` with production as its direction, its
|
|
@@ -151,7 +181,7 @@ This assessment is not a production certificate. Production still requires the
|
|
|
151
181
|
consumer's immutable readiness pack, every required capability in `enforced` state,
|
|
152
182
|
fresh consumer-owned verification on the exact candidate, and independent review.
|
|
153
183
|
|
|
154
|
-
For each ordinary change, `
|
|
184
|
+
For each ordinary change, `deliver-change` first surfaces this readiness view. The accepted
|
|
155
185
|
request and consumer rules determine which capabilities are affected. Every change
|
|
156
186
|
retains the project's baseline `requiredProfiles`; start and plan add any conditional
|
|
157
187
|
evidence profiles needed by affected capabilities and include a planned gap only when
|
|
@@ -160,7 +190,7 @@ floor. A planned-to-enforced promotion is a reviewed consumer source diff with f
|
|
|
160
190
|
evidence. Unrelated planned gaps remain visible but do not block development, and no
|
|
161
191
|
skill chooses product priorities or changes readiness automatically.
|
|
162
192
|
|
|
163
|
-
When a consumer incident exposes a reusable process gap, `improve
|
|
193
|
+
When a consumer incident exposes a reusable process gap, `process-improve` first keeps
|
|
164
194
|
the consumer safe, then prepares a sanitized GitHub issue draft from that checkout.
|
|
165
195
|
It deduplicates by consumer/process-version/invariant, requires owner authorization
|
|
166
196
|
before `gh issue create`, and uses an accepted issue as the later process change source
|
|
@@ -328,7 +358,7 @@ URL; without it, the review remains pending. Earlier plan and review documents r
|
|
|
328
358
|
readable, and their runs remain registrable or finishable with the version selected by
|
|
329
359
|
the authority that started the relevant phase.
|
|
330
360
|
|
|
331
|
-
The [finding priority definitions](process_assets/skills/review
|
|
361
|
+
The [finding priority definitions](process_assets/skills/change-review/SKILL.md#finding-priority)
|
|
332
362
|
are the canonical P0-P3 impact convention for this process, including examples and
|
|
333
363
|
their relationship to blocking decisions.
|
|
334
364
|
|
|
@@ -61,6 +61,16 @@ def _root(value: str) -> Path:
|
|
|
61
61
|
return path
|
|
62
62
|
|
|
63
63
|
|
|
64
|
+
def _check_position(value: str) -> int:
|
|
65
|
+
try:
|
|
66
|
+
position = int(value)
|
|
67
|
+
except ValueError as error:
|
|
68
|
+
raise argparse.ArgumentTypeError("check position must be an integer") from error
|
|
69
|
+
if position < 1 or position > 32:
|
|
70
|
+
raise argparse.ArgumentTypeError("check position must be between 1 and 32")
|
|
71
|
+
return position
|
|
72
|
+
|
|
73
|
+
|
|
64
74
|
def _process_root(args: argparse.Namespace) -> Path:
|
|
65
75
|
return distribution_root(args.process_root)
|
|
66
76
|
|
|
@@ -209,7 +219,12 @@ def command_verify(args: argparse.Namespace) -> Result:
|
|
|
209
219
|
process_root = _process_root(args)
|
|
210
220
|
project = load_project(args.project_root, process_root)
|
|
211
221
|
before = repository_snapshot(args.project_root)
|
|
212
|
-
report = run_profile(
|
|
222
|
+
report = run_profile(
|
|
223
|
+
args.project_root,
|
|
224
|
+
project,
|
|
225
|
+
args.profile,
|
|
226
|
+
check_position=args.check_position,
|
|
227
|
+
)
|
|
213
228
|
after = repository_snapshot(args.project_root)
|
|
214
229
|
if not same_checkpoint(before, after):
|
|
215
230
|
report["status"] = "failed"
|
|
@@ -433,6 +448,7 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
433
448
|
setup.add_argument("--allow", action="append", default=[])
|
|
434
449
|
verify = _leaf(commands, "verify", command_verify, help="Run a project verification profile")
|
|
435
450
|
verify.add_argument("--profile", required=True)
|
|
451
|
+
verify.add_argument("--check-position", type=_check_position)
|
|
436
452
|
adoption = commands.add_parser("adoption", help="Apply or check managed adoption")
|
|
437
453
|
adoption_commands = adoption.add_subparsers(dest="adoption_command", required=True)
|
|
438
454
|
for name, handler in (("apply", command_adoption_apply), ("check", command_adoption_check)):
|
|
@@ -199,20 +199,61 @@ def run_profile(
|
|
|
199
199
|
project_root: Path,
|
|
200
200
|
project: dict[str, Any],
|
|
201
201
|
profile: str,
|
|
202
|
+
*,
|
|
203
|
+
check_position: int | None = None,
|
|
202
204
|
) -> dict[str, Any]:
|
|
203
|
-
|
|
204
|
-
if
|
|
205
|
+
configured_checks = project["profiles"].get(profile)
|
|
206
|
+
if configured_checks is None:
|
|
205
207
|
raise ProcessError(f"unknown verification profile: {profile}")
|
|
208
|
+
if check_position is None:
|
|
209
|
+
checks = configured_checks
|
|
210
|
+
positions = range(1, len(checks) + 1)
|
|
211
|
+
else:
|
|
212
|
+
if check_position < 1 or check_position > len(configured_checks):
|
|
213
|
+
raise ProcessError(
|
|
214
|
+
f"profile {profile} has no check at position: {check_position}"
|
|
215
|
+
)
|
|
216
|
+
checks = [configured_checks[check_position - 1]]
|
|
217
|
+
positions = [check_position]
|
|
206
218
|
reports: list[dict[str, Any]] = []
|
|
207
|
-
|
|
219
|
+
failed_position: int | None = None
|
|
220
|
+
for position, check in zip(positions, checks, strict=True):
|
|
208
221
|
report = run_check(project_root, check)
|
|
209
222
|
reports.append(report)
|
|
210
223
|
if report["status"] != "passed":
|
|
224
|
+
failed_position = position
|
|
211
225
|
break
|
|
212
|
-
|
|
226
|
+
result = {
|
|
213
227
|
"profile": profile,
|
|
214
228
|
"status": "passed" if len(reports) == len(checks) and all(
|
|
215
229
|
report["status"] == "passed" for report in reports
|
|
216
230
|
) else "failed",
|
|
231
|
+
"scope": (
|
|
232
|
+
{"kind": "profile"}
|
|
233
|
+
if check_position is None
|
|
234
|
+
else {
|
|
235
|
+
"kind": "check",
|
|
236
|
+
"check": checks[0]["id"],
|
|
237
|
+
"position": check_position,
|
|
238
|
+
}
|
|
239
|
+
),
|
|
217
240
|
"checks": reports,
|
|
218
241
|
}
|
|
242
|
+
failed = next((report for report in reports if report["status"] == "failed"), None)
|
|
243
|
+
if failed is not None:
|
|
244
|
+
assert failed_position is not None
|
|
245
|
+
result["diagnostic"] = {
|
|
246
|
+
"kind": "selective-check-reproduction",
|
|
247
|
+
"profile": profile,
|
|
248
|
+
"check": failed["id"],
|
|
249
|
+
"position": failed_position,
|
|
250
|
+
"command": [
|
|
251
|
+
"processctl",
|
|
252
|
+
"verify",
|
|
253
|
+
"--profile",
|
|
254
|
+
profile,
|
|
255
|
+
"--check-position",
|
|
256
|
+
str(failed_position),
|
|
257
|
+
],
|
|
258
|
+
}
|
|
259
|
+
return result
|
|
@@ -90,6 +90,21 @@ def validate_skills(
|
|
|
90
90
|
graph = load_and_validate(
|
|
91
91
|
graph_path, "process-graph", schema_root=schemas_root(process_root)
|
|
92
92
|
)
|
|
93
|
+
owners = {state["id"]: state["ownerSkill"] for state in graph["states"]}
|
|
94
|
+
if len(owners) != len(graph["states"]):
|
|
95
|
+
raise ProcessError("process graph state ids must be unique")
|
|
96
|
+
for state in graph["states"]:
|
|
97
|
+
for transition in state["transitions"]:
|
|
98
|
+
destination = transition["nextState"]
|
|
99
|
+
skill = transition["nextSkill"]
|
|
100
|
+
if (destination is None) != (skill is None):
|
|
101
|
+
raise ProcessError("process graph terminal transitions must have both targets null")
|
|
102
|
+
if destination is not None and destination not in owners:
|
|
103
|
+
raise ProcessError(f"process graph references missing state: {destination}")
|
|
104
|
+
if skill is not None and skill not in names:
|
|
105
|
+
raise ProcessError(
|
|
106
|
+
f"process graph transition from {state['id']} references missing skill: {skill}"
|
|
107
|
+
)
|
|
93
108
|
routed = {graph["entrySkill"]}
|
|
94
109
|
routed.update(state["ownerSkill"] for state in graph["states"])
|
|
95
110
|
routed.update(graph.get("specializations", {}).values())
|
{engineering_process-1.2.6 → engineering_process-2.0.1/engineering_process.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: engineering-process
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.1
|
|
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
|
|
@@ -33,11 +33,27 @@ Portable skills explain what to do. processctl owns state transitions and curren
|
|
|
33
33
|
evidence. Each consumer owns its product rules, exact commands, merge policy, and
|
|
34
34
|
release decisions.
|
|
35
35
|
|
|
36
|
+
Start delivery work with [deliver-change](process_assets/skills/deliver-change/SKILL.md).
|
|
37
|
+
It selects the current phase from lifecycle state; callers do not select a phase skill:
|
|
38
|
+
|
|
39
|
+
deliver-change
|
|
40
|
+
change-start -> change-plan -> change-implement -> change-verify
|
|
41
|
+
-> change-review -> change-complete
|
|
42
|
+
|
|
43
|
+
[process-improve](process_assets/skills/process-improve/SKILL.md) handles a reusable
|
|
44
|
+
process problem, then returns delivery to the same lifecycle.
|
|
45
|
+
[production-engineering](process_assets/skills/production-engineering/SKILL.md) supplies
|
|
46
|
+
the invariant floor consulted from planning through independent review. Both are
|
|
47
|
+
reachable specializations; neither advances lifecycle state. `change-complete` calls
|
|
48
|
+
the existing `processctl change finish` command.
|
|
49
|
+
|
|
50
|
+
For migration from the previous skill identifiers, see [Versioning](VERSIONING.md#skill-namespace-migration).
|
|
51
|
+
|
|
36
52
|
## Architecture
|
|
37
53
|
|
|
38
54
|
The distribution has four live parts:
|
|
39
55
|
|
|
40
|
-
1. Managed skills under process_assets/skills, all reachable from
|
|
56
|
+
1. Managed skills under process_assets/skills, all reachable from deliver-change.
|
|
41
57
|
2. One processctl state machine under engineering_process/lifecycle.py.
|
|
42
58
|
3. JSON Schemas that are loaded directly by the runtime.
|
|
43
59
|
4. One adoption transaction that synchronizes managed skills and configuration from
|
|
@@ -98,6 +114,20 @@ Commands are argument arrays, never shell strings. Each command has a finite tim
|
|
|
98
114
|
Output has a hard aggregate budget; evidence stores byte counts and hashes, never raw
|
|
99
115
|
stdout or stderr that could contain secrets.
|
|
100
116
|
|
|
117
|
+
A failed profile also reports a safe `diagnostic` descriptor containing only its
|
|
118
|
+
validated profile identifier, check identifier, canonical one-based profile position,
|
|
119
|
+
and a fixed `processctl` argument array. The position remains unambiguous even when a
|
|
120
|
+
compatible project has duplicate check identifiers. Run that array from the project
|
|
121
|
+
root to reproduce only the failed configured check through the same bounded runner,
|
|
122
|
+
for example:
|
|
123
|
+
|
|
124
|
+
processctl verify --profile rust --check-position 3
|
|
125
|
+
|
|
126
|
+
This selective run is diagnostic only: it does not expose captured output, replace a
|
|
127
|
+
required full-profile run, or count as lifecycle verification evidence. Maintainers
|
|
128
|
+
who need semantic tool output must use a tool-owned structured report or run the
|
|
129
|
+
consumer command in an appropriately trusted environment.
|
|
130
|
+
|
|
101
131
|
### Production readiness
|
|
102
132
|
|
|
103
133
|
A consumer declares `.process/readiness.json` with production as its direction, its
|
|
@@ -175,7 +205,7 @@ This assessment is not a production certificate. Production still requires the
|
|
|
175
205
|
consumer's immutable readiness pack, every required capability in `enforced` state,
|
|
176
206
|
fresh consumer-owned verification on the exact candidate, and independent review.
|
|
177
207
|
|
|
178
|
-
For each ordinary change, `
|
|
208
|
+
For each ordinary change, `deliver-change` first surfaces this readiness view. The accepted
|
|
179
209
|
request and consumer rules determine which capabilities are affected. Every change
|
|
180
210
|
retains the project's baseline `requiredProfiles`; start and plan add any conditional
|
|
181
211
|
evidence profiles needed by affected capabilities and include a planned gap only when
|
|
@@ -184,7 +214,7 @@ floor. A planned-to-enforced promotion is a reviewed consumer source diff with f
|
|
|
184
214
|
evidence. Unrelated planned gaps remain visible but do not block development, and no
|
|
185
215
|
skill chooses product priorities or changes readiness automatically.
|
|
186
216
|
|
|
187
|
-
When a consumer incident exposes a reusable process gap, `improve
|
|
217
|
+
When a consumer incident exposes a reusable process gap, `process-improve` first keeps
|
|
188
218
|
the consumer safe, then prepares a sanitized GitHub issue draft from that checkout.
|
|
189
219
|
It deduplicates by consumer/process-version/invariant, requires owner authorization
|
|
190
220
|
before `gh issue create`, and uses an accepted issue as the later process change source
|
|
@@ -352,7 +382,7 @@ URL; without it, the review remains pending. Earlier plan and review documents r
|
|
|
352
382
|
readable, and their runs remain registrable or finishable with the version selected by
|
|
353
383
|
the authority that started the relevant phase.
|
|
354
384
|
|
|
355
|
-
The [finding priority definitions](process_assets/skills/review
|
|
385
|
+
The [finding priority definitions](process_assets/skills/change-review/SKILL.md#finding-priority)
|
|
356
386
|
are the canonical P0-P3 impact convention for this process, including examples and
|
|
357
387
|
their relationship to blocking decisions.
|
|
358
388
|
|
{engineering_process-1.2.6 → engineering_process-2.0.1}/engineering_process.egg-info/SOURCES.txt
RENAMED
|
@@ -31,16 +31,16 @@ engineering_process.egg-info/dependency_links.txt
|
|
|
31
31
|
engineering_process.egg-info/entry_points.txt
|
|
32
32
|
engineering_process.egg-info/requires.txt
|
|
33
33
|
engineering_process.egg-info/top_level.txt
|
|
34
|
-
process_assets/skills/
|
|
35
|
-
process_assets/skills/implement
|
|
36
|
-
process_assets/skills/
|
|
37
|
-
process_assets/skills/
|
|
34
|
+
process_assets/skills/change-complete/SKILL.md
|
|
35
|
+
process_assets/skills/change-implement/SKILL.md
|
|
36
|
+
process_assets/skills/change-plan/SKILL.md
|
|
37
|
+
process_assets/skills/change-review/SKILL.md
|
|
38
|
+
process_assets/skills/change-start/SKILL.md
|
|
39
|
+
process_assets/skills/change-verify/SKILL.md
|
|
40
|
+
process_assets/skills/deliver-change/SKILL.md
|
|
41
|
+
process_assets/skills/process-improve/SKILL.md
|
|
38
42
|
process_assets/skills/production-engineering/SKILL.md
|
|
39
43
|
process_assets/skills/production-engineering/invariants.json
|
|
40
|
-
process_assets/skills/review-change/SKILL.md
|
|
41
|
-
process_assets/skills/run-change/SKILL.md
|
|
42
|
-
process_assets/skills/start-change/SKILL.md
|
|
43
|
-
process_assets/skills/verify-change/SKILL.md
|
|
44
44
|
schemas/change.schema.json
|
|
45
45
|
schemas/plan.schema.json
|
|
46
46
|
schemas/process-graph.schema.json
|
|
@@ -1,83 +1,83 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
|
-
"entrySkill": "
|
|
3
|
+
"entrySkill": "deliver-change",
|
|
4
4
|
"specializations": {
|
|
5
|
-
"processChange": "improve
|
|
5
|
+
"processChange": "process-improve",
|
|
6
6
|
"productionEngineering": "production-engineering"
|
|
7
7
|
},
|
|
8
8
|
"states": [
|
|
9
9
|
{
|
|
10
10
|
"id": "unregistered",
|
|
11
|
-
"ownerSkill": "start
|
|
11
|
+
"ownerSkill": "change-start",
|
|
12
12
|
"commands": ["change start"],
|
|
13
13
|
"transitions": [
|
|
14
|
-
{"result": "success", "nextState": "specified", "nextSkill": "plan
|
|
14
|
+
{"result": "success", "nextState": "specified", "nextSkill": "change-plan"}
|
|
15
15
|
]
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"id": "specified",
|
|
19
|
-
"ownerSkill": "plan
|
|
19
|
+
"ownerSkill": "change-plan",
|
|
20
20
|
"commands": ["change plan"],
|
|
21
21
|
"transitions": [
|
|
22
|
-
{"result": "success", "nextState": "planned", "nextSkill": "implement
|
|
22
|
+
{"result": "success", "nextState": "planned", "nextSkill": "change-implement"}
|
|
23
23
|
]
|
|
24
24
|
},
|
|
25
25
|
{
|
|
26
26
|
"id": "planned",
|
|
27
|
-
"ownerSkill": "implement
|
|
27
|
+
"ownerSkill": "change-implement",
|
|
28
28
|
"commands": ["change implement"],
|
|
29
29
|
"transitions": [
|
|
30
|
-
{"result": "success", "nextState": "implementing", "nextSkill": "verify
|
|
30
|
+
{"result": "success", "nextState": "implementing", "nextSkill": "change-verify"}
|
|
31
31
|
]
|
|
32
32
|
},
|
|
33
33
|
{
|
|
34
34
|
"id": "implementing",
|
|
35
|
-
"ownerSkill": "verify
|
|
35
|
+
"ownerSkill": "change-verify",
|
|
36
36
|
"commands": ["change implement", "change verify"],
|
|
37
37
|
"transitions": [
|
|
38
|
-
{"result": "profile-passed", "nextState": "implementing", "nextSkill": "verify
|
|
39
|
-
{"result": "all-passed", "nextState": "verified", "nextSkill": "review
|
|
38
|
+
{"result": "profile-passed", "nextState": "implementing", "nextSkill": "change-verify"},
|
|
39
|
+
{"result": "all-passed", "nextState": "verified", "nextSkill": "change-review"}
|
|
40
40
|
]
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
43
|
"id": "verified",
|
|
44
|
-
"ownerSkill": "review
|
|
44
|
+
"ownerSkill": "change-review",
|
|
45
45
|
"commands": ["change implement", "change review start"],
|
|
46
46
|
"transitions": [
|
|
47
|
-
{"result": "assigned", "nextState": "review-pending", "nextSkill": "review
|
|
48
|
-
{"result": "source-changed", "nextState": "implementing", "nextSkill": "implement
|
|
47
|
+
{"result": "assigned", "nextState": "review-pending", "nextSkill": "change-review"},
|
|
48
|
+
{"result": "source-changed", "nextState": "implementing", "nextSkill": "change-implement"}
|
|
49
49
|
]
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"id": "review-pending",
|
|
53
|
-
"ownerSkill": "review
|
|
53
|
+
"ownerSkill": "change-review",
|
|
54
54
|
"commands": ["change implement", "change review submit"],
|
|
55
55
|
"transitions": [
|
|
56
|
-
{"result": "approved", "nextState": "approved", "nextSkill": "
|
|
57
|
-
{"result": "changes-requested", "nextState": "changes-requested", "nextSkill": "implement
|
|
58
|
-
{"result": "source-changed", "nextState": "implementing", "nextSkill": "implement
|
|
56
|
+
{"result": "approved", "nextState": "approved", "nextSkill": "change-complete"},
|
|
57
|
+
{"result": "changes-requested", "nextState": "changes-requested", "nextSkill": "change-implement"},
|
|
58
|
+
{"result": "source-changed", "nextState": "implementing", "nextSkill": "change-implement"}
|
|
59
59
|
]
|
|
60
60
|
},
|
|
61
61
|
{
|
|
62
62
|
"id": "changes-requested",
|
|
63
|
-
"ownerSkill": "implement
|
|
63
|
+
"ownerSkill": "change-implement",
|
|
64
64
|
"commands": ["change implement"],
|
|
65
65
|
"transitions": [
|
|
66
|
-
{"result": "success", "nextState": "implementing", "nextSkill": "verify
|
|
66
|
+
{"result": "success", "nextState": "implementing", "nextSkill": "change-verify"}
|
|
67
67
|
]
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"id": "approved",
|
|
71
|
-
"ownerSkill": "
|
|
71
|
+
"ownerSkill": "change-complete",
|
|
72
72
|
"commands": ["change finish", "change implement"],
|
|
73
73
|
"transitions": [
|
|
74
74
|
{"result": "success", "nextState": null, "nextSkill": null},
|
|
75
|
-
{"result": "source-changed", "nextState": "implementing", "nextSkill": "implement
|
|
75
|
+
{"result": "source-changed", "nextState": "implementing", "nextSkill": "change-implement"}
|
|
76
76
|
]
|
|
77
77
|
},
|
|
78
78
|
{
|
|
79
79
|
"id": "blocked",
|
|
80
|
-
"ownerSkill": "
|
|
80
|
+
"ownerSkill": "deliver-change",
|
|
81
81
|
"commands": [],
|
|
82
82
|
"transitions": []
|
|
83
83
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Complete an approved change only while
|
|
2
|
+
name: change-complete
|
|
3
|
+
description: Complete an approved change when routed by deliver-change, only while verification and independent review still match the repository snapshot.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# Complete a change
|
|
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
|
|
@@ -11,7 +11,8 @@ repository still matches the reviewed snapshot. Then run:
|
|
|
11
11
|
|
|
12
12
|
processctl change finish --change-id ID --actor ACTOR --context CONTEXT
|
|
13
13
|
|
|
14
|
-
The
|
|
14
|
+
The existing `change finish` CLI operation writes one bounded completion receipt and
|
|
15
|
+
marks the run completed.
|
|
15
16
|
Completion does not itself grant merge, deployment, or release authority; those
|
|
16
17
|
remain project-owned operations. Never report completion from prose alone.
|
|
17
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: implement
|
|
3
|
-
description: Implement the accepted plan or resolve blocking review findings without changing the contract implicitly.
|
|
2
|
+
name: change-implement
|
|
3
|
+
description: Implement the accepted plan or resolve blocking review findings when routed by deliver-change, without changing the contract implicitly.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Implement a change
|
|
@@ -29,4 +29,4 @@ gaps merely because they are listed.
|
|
|
29
29
|
|
|
30
30
|
When evidence exposes a contract gap, stop and ask the project owner to supersede the
|
|
31
31
|
contract. Do not make review prose into new scope. When implementation is ready,
|
|
32
|
-
route to **verify
|
|
32
|
+
route to **change-verify**.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: plan
|
|
3
|
-
description:
|
|
2
|
+
name: change-plan
|
|
3
|
+
description: Plan the registered change and its verification boundary when deliver-change routes a specified change.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Plan a change
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: review
|
|
3
|
-
description: Review the exact verified snapshot from an actor and context
|
|
2
|
+
name: change-review
|
|
3
|
+
description: Review the exact verified snapshot from an independent actor and context when routed by deliver-change.
|
|
4
4
|
---
|
|
5
5
|
|
|
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.
|
|
9
|
+
implementer in the current cycle. Read `processctl change status --change-id ID`.
|
|
10
|
+
When the phase is `verified`, start the assignment:
|
|
10
11
|
|
|
11
12
|
processctl change review start --change-id ID --actor REVIEWER --context REVIEW_CONTEXT
|
|
12
13
|
|
|
14
|
+
When the phase is `review-pending`, resume the existing assignment; do not run
|
|
15
|
+
`change review start` again. Read `.process/runs/ID/run.json` for its `cycle` and
|
|
16
|
+
`reviewAssignment`, including the assigned reviewer, checkpoint, and
|
|
17
|
+
`reportSchemaVersion`. Continue with the assigned independent actor/context and the
|
|
18
|
+
existing report path, `.process/runs/ID/review-CYCLE.json`. If that reviewer is
|
|
19
|
+
unavailable, report the pending assignment as a blocker; never impersonate its
|
|
20
|
+
identity or create a replacement assignment from another context.
|
|
21
|
+
|
|
13
22
|
Review the accepted contract, plan, complete diff, focused tests, and verification
|
|
14
23
|
evidence. The first pass is comprehensive within that frozen contract. Every finding
|
|
15
24
|
maps to one accepted criterion and records priority, origin, severity, and location.
|
|
@@ -41,7 +50,7 @@ consider consumer evidence that the lifecycle cannot observe. Every schema-versi
|
|
|
41
50
|
report classifies `processImprovement` as `none`, `consumer-specific`, or
|
|
42
51
|
`shared-process` and gives a concrete rationale. Consumer-specific behavior stays in
|
|
43
52
|
the consumer. For `shared-process`, keep the assignment `review-pending` and route the
|
|
44
|
-
candidate through **improve
|
|
53
|
+
candidate through **process-improve**. Submit only after an existing or owner-authorized
|
|
45
54
|
issue supplies the stable HTTPS `recordUrl`; the review itself remains read-only.
|
|
46
55
|
|
|
47
56
|
Read the consumer readiness result and repository rules. Check the complete diff for
|
|
@@ -56,8 +65,8 @@ Validate and submit the report:
|
|
|
56
65
|
processctl contract validate --kind review REPORT_PATH
|
|
57
66
|
processctl change review submit --change-id ID --review REPORT_PATH
|
|
58
67
|
|
|
59
|
-
Review is read-only. Requested changes route back to **implement
|
|
60
|
-
routes to **
|
|
68
|
+
Review is read-only. Requested changes route back to **change-implement**; approval
|
|
69
|
+
routes to **change-complete**. Keep the same independent reviewer for corrections.
|
|
61
70
|
Follow-up scope is only carried findings, remediation diffs, and regressions against
|
|
62
71
|
the frozen contract. A new blocker must be either remediation-caused or a P0/P1 late
|
|
63
72
|
violation with a rationale. After two correction cycles, another changes-requested
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
name: start
|
|
3
|
-
description: Turn an accepted request into a bounded change contract
|
|
2
|
+
name: change-start
|
|
3
|
+
description: Turn an accepted request into a bounded change contract when deliver-change routes a new change to lifecycle start.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Start a change
|