engineering-process 1.2.0__tar.gz → 1.2.2__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.0/engineering_process.egg-info → engineering_process-1.2.2}/PKG-INFO +5 -1
- {engineering_process-1.2.0 → engineering_process-1.2.2}/README.md +4 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/__init__.py +1 -1
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/distribution.py +8 -3
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/publication_compat.py +6 -1
- {engineering_process-1.2.0 → engineering_process-1.2.2/engineering_process.egg-info}/PKG-INFO +5 -1
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process.egg-info/SOURCES.txt +1 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/finish-change/SKILL.md +6 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/pyproject.toml +1 -1
- {engineering_process-1.2.0 → engineering_process-1.2.2}/templates/PULL_REQUEST_TEMPLATE.md +2 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_automation.py +11 -0
- engineering_process-1.2.2/tests/test_distribution.py +54 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_publication_compat.py +36 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_skills.py +2 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/LICENSE +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/MANIFEST.in +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/__main__.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/_supervisor_contract.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/_supervisor_posix.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/_supervisor_windows.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/_windows_job.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/adoption.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/cli.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/commands.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/contracts.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/helper_launch.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/lifecycle.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/production_engineering.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/project.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/release.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/repository.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/requirements-dev.txt +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/requirements-runtime.txt +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/skills.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/supervision.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process.egg-info/dependency_links.txt +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process.egg-info/entry_points.txt +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process.egg-info/requires.txt +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process.egg-info/top_level.txt +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process-graph.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/implement-change/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/improve-process/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/plan-change/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/production-engineering/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/production-engineering/invariants.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/review-change/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/run-change/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/start-change/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/verify-change/SKILL.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/change.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/plan.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/process-graph.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/process-lock.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/production-engineering.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/project-legacy.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/project.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/receipt.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/release-change.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/release.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/review.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/run.schema.json +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/setup.cfg +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/templates/AGENTS.process.md +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/templates/adopt-process-windows-job.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/templates/adopt-process.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_adoption.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_architecture.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_cli.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_commands.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_contracts.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_lifecycle.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_production_engineering.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_release.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_repository.py +0 -0
- {engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_supervisor_posix.py +0 -0
{engineering_process-1.2.0/engineering_process.egg-info → engineering_process-1.2.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: engineering-process
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
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
|
|
@@ -422,6 +422,10 @@ review identities.
|
|
|
422
422
|
It rejects missing, repeated, misplaced, hidden, unordered, or unsupported visible
|
|
423
423
|
structure. Completion checkboxes belong only to the Completion gate section. Ready
|
|
424
424
|
pull requests must have every checkbox checked; drafts may retain unchecked work.
|
|
425
|
+
One trailing `Refs ISSUE.` line remains optional. A ready, contract-identified final
|
|
426
|
+
consumer adoption may instead use `Closes ISSUE, closes OWNER/REPOSITORY#NUMBER.` with
|
|
427
|
+
the complete keyword/reference syntax repeated for every issue; drafts cannot close
|
|
428
|
+
issues. Producer and intermediate pull requests do not close release-source issues.
|
|
425
429
|
The managed template never solicits execution identity,
|
|
426
430
|
and authors plus independent review keep it out of free-form values. The validator is
|
|
427
431
|
a positive grammar for public fields; it deliberately does not guess identities from
|
|
@@ -398,6 +398,10 @@ review identities.
|
|
|
398
398
|
It rejects missing, repeated, misplaced, hidden, unordered, or unsupported visible
|
|
399
399
|
structure. Completion checkboxes belong only to the Completion gate section. Ready
|
|
400
400
|
pull requests must have every checkbox checked; drafts may retain unchecked work.
|
|
401
|
+
One trailing `Refs ISSUE.` line remains optional. A ready, contract-identified final
|
|
402
|
+
consumer adoption may instead use `Closes ISSUE, closes OWNER/REPOSITORY#NUMBER.` with
|
|
403
|
+
the complete keyword/reference syntax repeated for every issue; drafts cannot close
|
|
404
|
+
issues. Producer and intermediate pull requests do not close release-source issues.
|
|
401
405
|
The managed template never solicits execution identity,
|
|
402
406
|
and authors plus independent review keep it out of free-form values. The validator is
|
|
403
407
|
a positive grammar for public fields; it deliberately does not guess identities from
|
|
@@ -65,12 +65,17 @@ def skill_names(root: Path) -> tuple[str, ...]:
|
|
|
65
65
|
return names
|
|
66
66
|
|
|
67
67
|
|
|
68
|
+
def _ordered_paths(root: Path, paths: Iterable[Path]) -> list[Path]:
|
|
69
|
+
return sorted(paths, key=lambda path: path.relative_to(root).as_posix())
|
|
70
|
+
|
|
71
|
+
|
|
68
72
|
def _asset_paths(root: Path) -> Iterable[tuple[str, Path]]:
|
|
69
73
|
skill_directory = skills_root(root)
|
|
70
|
-
for path in
|
|
74
|
+
for path in _ordered_paths(skill_directory, skill_directory.rglob("*")):
|
|
71
75
|
if path.is_file():
|
|
72
76
|
yield f"skills/{path.relative_to(skill_directory).as_posix()}", path
|
|
73
|
-
|
|
77
|
+
schema_directory = schemas_root(root)
|
|
78
|
+
for path in _ordered_paths(schema_directory, schema_directory.glob("*.json")):
|
|
74
79
|
yield f"schemas/{path.name}", path
|
|
75
80
|
for name in (
|
|
76
81
|
"AGENTS.process.md",
|
|
@@ -110,7 +115,7 @@ def distribution_digest(root: Path) -> str:
|
|
|
110
115
|
|
|
111
116
|
def skill_digest(path: Path) -> str:
|
|
112
117
|
digest = hashlib.sha256()
|
|
113
|
-
for file_path in
|
|
118
|
+
for file_path in _ordered_paths(path, path.rglob("*")):
|
|
114
119
|
if not file_path.is_file() or file_path.name == ".engineering-process.json":
|
|
115
120
|
continue
|
|
116
121
|
relative = file_path.relative_to(path).as_posix().encode("utf-8")
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/publication_compat.py
RENAMED
|
@@ -53,8 +53,9 @@ PR_CHECKS = (
|
|
|
53
53
|
)
|
|
54
54
|
FENCE = re.compile(r"^ {0,3}(`{3,}|~{3,})(.*)$")
|
|
55
55
|
NON_MARKDOWN_LINE_SEPARATOR = re.compile("[\v\f\x85\u2028\u2029]")
|
|
56
|
+
ISSUE_TARGET = r"(?:[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+)?#[1-9][0-9]*"
|
|
56
57
|
ISSUE_REFERENCE = re.compile(
|
|
57
|
-
|
|
58
|
+
rf"^(?:Refs {ISSUE_TARGET}|Closes {ISSUE_TARGET}(?:, closes {ISSUE_TARGET})*)\.$"
|
|
58
59
|
)
|
|
59
60
|
|
|
60
61
|
|
|
@@ -232,6 +233,10 @@ def _pull_request_body_issues(body: str, state: str) -> list[str]:
|
|
|
232
233
|
and reference_positions[0] <= checklist_positions[-1]
|
|
233
234
|
):
|
|
234
235
|
issues.append("pull request body issue reference must follow the checklist")
|
|
236
|
+
if state == "draft" and any(
|
|
237
|
+
lines[position].startswith("Closes ") for position in reference_positions
|
|
238
|
+
):
|
|
239
|
+
issues.append("draft pull request cannot close issues")
|
|
235
240
|
field_patterns = tuple(
|
|
236
241
|
re.compile(rf"^- {re.escape(field)}:\s*.*$")
|
|
237
242
|
for fields in PR_FIELDS.values()
|
{engineering_process-1.2.0 → engineering_process-1.2.2/engineering_process.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: engineering-process
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.2
|
|
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
|
|
@@ -422,6 +422,10 @@ review identities.
|
|
|
422
422
|
It rejects missing, repeated, misplaced, hidden, unordered, or unsupported visible
|
|
423
423
|
structure. Completion checkboxes belong only to the Completion gate section. Ready
|
|
424
424
|
pull requests must have every checkbox checked; drafts may retain unchecked work.
|
|
425
|
+
One trailing `Refs ISSUE.` line remains optional. A ready, contract-identified final
|
|
426
|
+
consumer adoption may instead use `Closes ISSUE, closes OWNER/REPOSITORY#NUMBER.` with
|
|
427
|
+
the complete keyword/reference syntax repeated for every issue; drafts cannot close
|
|
428
|
+
issues. Producer and intermediate pull requests do not close release-source issues.
|
|
425
429
|
The managed template never solicits execution identity,
|
|
426
430
|
and authors plus independent review keep it out of free-form values. The validator is
|
|
427
431
|
a positive grammar for public fields; it deliberately does not guess identities from
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/finish-change/SKILL.md
RENAMED
|
@@ -15,6 +15,12 @@ The command writes one bounded completion receipt and marks the run completed.
|
|
|
15
15
|
Completion does not itself grant merge, deployment, or release authority; those
|
|
16
16
|
remain project-owned operations. Never report completion from prose alone.
|
|
17
17
|
|
|
18
|
+
Use a normal trailing `Refs ISSUE.` line for producer and intermediate pull requests.
|
|
19
|
+
Only a contract-identified final consumer adoption that has verified the released
|
|
20
|
+
behavior may use `Closes ISSUE, closes ISSUE.` after the completed public checklist.
|
|
21
|
+
Repeat the full keyword and local or `OWNER/REPOSITORY#NUMBER` reference for every
|
|
22
|
+
issue; never close source issues merely because the producer release merged.
|
|
23
|
+
|
|
18
24
|
Report the readiness capabilities protected or advanced and the remaining planned
|
|
19
25
|
gaps after completion. Carry the owner and stable record URL for every accepted-risk
|
|
20
26
|
or tracked-follow-up disposition into the durable handoff. Finish never edits
|
|
@@ -34,4 +34,6 @@ tracked-follow-up entries need an owner and durable HTTPS record. -->
|
|
|
34
34
|
- [ ] Required profiles pass on the reviewed snapshot.
|
|
35
35
|
- [ ] Independent review approved with no blocking finding.
|
|
36
36
|
- [ ] Every non-blocking finding has a recorded disposition.
|
|
37
|
+
<!-- Producer/intermediate PR: Refs ISSUE. Final verified consumer adoption only:
|
|
38
|
+
Closes ISSUE, closes OWNER/REPOSITORY#NUMBER. Repeat the keyword for every issue. -->
|
|
37
39
|
<!-- engineering-process:pr-description:end -->
|
|
@@ -55,6 +55,8 @@ class AutomationTests(unittest.TestCase):
|
|
|
55
55
|
template.index("## Completion gate"),
|
|
56
56
|
)
|
|
57
57
|
self.assertIn("Every non-blocking finding has a recorded disposition.", template)
|
|
58
|
+
self.assertIn("Final verified consumer adoption only", template)
|
|
59
|
+
self.assertIn("Closes ISSUE, closes OWNER/REPOSITORY#NUMBER", template)
|
|
58
60
|
|
|
59
61
|
def test_renovate_process_rule_materializes_the_complete_adoption(self) -> None:
|
|
60
62
|
config = json.loads((ROOT / ".github" / "renovate.json").read_text(encoding="utf-8"))
|
|
@@ -104,6 +106,15 @@ class AutomationTests(unittest.TestCase):
|
|
|
104
106
|
)
|
|
105
107
|
self.assertIn("needs: [metadata, publish]", workflow)
|
|
106
108
|
self.assertIn("Verify PyPI exposes the exact built hashes", workflow)
|
|
109
|
+
visibility = workflow.split(
|
|
110
|
+
" - name: Verify PyPI exposes the exact built hashes\n", maxsplit=1
|
|
111
|
+
)[1].split(" - name: Create short-lived release token\n", maxsplit=1)[0]
|
|
112
|
+
self.assertIn("for attempt in range(12)", visibility)
|
|
113
|
+
self.assertIn('"Accept": "application/vnd.pypi.simple.v1+json"', visibility)
|
|
114
|
+
self.assertIn(
|
|
115
|
+
"if actual == expected and simple_actual == expected:", visibility
|
|
116
|
+
)
|
|
117
|
+
self.assertIn("PyPI Simple API did not return PEP 691 JSON", visibility)
|
|
107
118
|
self.assertIn("SOURCE_DATE_EPOCH", workflow)
|
|
108
119
|
self.assertIn("verification/normalize_sdist.py", workflow)
|
|
109
120
|
self.assertIn("points to a different commit", workflow)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import hashlib
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import tempfile
|
|
6
|
+
import unittest
|
|
7
|
+
|
|
8
|
+
from engineering_process.distribution import distribution_digest, skill_digest
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def framed_digest(entries: list[tuple[str, bytes]]) -> str:
|
|
12
|
+
digest = hashlib.sha256()
|
|
13
|
+
for relative, data in entries:
|
|
14
|
+
encoded = relative.encode("utf-8")
|
|
15
|
+
digest.update(len(encoded).to_bytes(4, "big"))
|
|
16
|
+
digest.update(encoded)
|
|
17
|
+
digest.update(len(data).to_bytes(8, "big"))
|
|
18
|
+
digest.update(data)
|
|
19
|
+
return "sha256:" + digest.hexdigest()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class DistributionTests(unittest.TestCase):
|
|
23
|
+
def test_digests_follow_canonical_relative_posix_order(self) -> None:
|
|
24
|
+
entries = [
|
|
25
|
+
("skills/sample/SKILL.md", b"skill\n"),
|
|
26
|
+
("skills/sample/invariants.json", b"{}\n"),
|
|
27
|
+
("schemas/sample.json", b"{}\n"),
|
|
28
|
+
("templates/AGENTS.process.md", b"agents\n"),
|
|
29
|
+
("templates/PULL_REQUEST_TEMPLATE.md", b"pull request\n"),
|
|
30
|
+
("templates/adopt-process.py", b"adopt\n"),
|
|
31
|
+
("templates/adopt-process-windows-job.py", b"windows\n"),
|
|
32
|
+
("process-graph.json", b"{}\n"),
|
|
33
|
+
]
|
|
34
|
+
with tempfile.TemporaryDirectory() as directory:
|
|
35
|
+
root = Path(directory)
|
|
36
|
+
for relative, data in entries:
|
|
37
|
+
path = root / relative.replace("skills/", "process_assets/skills/", 1)
|
|
38
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
39
|
+
path.write_bytes(data)
|
|
40
|
+
|
|
41
|
+
self.assertEqual(framed_digest(entries), distribution_digest(root))
|
|
42
|
+
self.assertEqual(
|
|
43
|
+
framed_digest(
|
|
44
|
+
[
|
|
45
|
+
("SKILL.md", b"skill\n"),
|
|
46
|
+
("invariants.json", b"{}\n"),
|
|
47
|
+
]
|
|
48
|
+
),
|
|
49
|
+
skill_digest(root / "process_assets" / "skills" / "sample"),
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
if __name__ == "__main__":
|
|
54
|
+
unittest.main()
|
|
@@ -290,6 +290,42 @@ class PublicationCompatibilityTests(unittest.TestCase):
|
|
|
290
290
|
self.validate_body(repeated),
|
|
291
291
|
)
|
|
292
292
|
|
|
293
|
+
def test_final_adoption_can_close_multiple_issues_only_when_ready(self) -> None:
|
|
294
|
+
closing = (
|
|
295
|
+
f"{CANONICAL_BODY}\n"
|
|
296
|
+
"Closes example/process#123, closes #456, closes other/repository#789.\n"
|
|
297
|
+
)
|
|
298
|
+
self.assertEqual([], self.validate_body(closing))
|
|
299
|
+
self.assertIn(
|
|
300
|
+
"draft pull request cannot close issues",
|
|
301
|
+
self.validate_body(closing, state="draft"),
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
unchecked = closing.replace(
|
|
305
|
+
"- [x] Required profiles", "- [ ] Required profiles", 1
|
|
306
|
+
)
|
|
307
|
+
self.assertIn(
|
|
308
|
+
"ready pull request has unchecked item: Required profiles pass on the reviewed snapshot.",
|
|
309
|
+
self.validate_body(unchecked),
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
for malformed in (
|
|
313
|
+
"Closes example/process#123, #456.",
|
|
314
|
+
"Closes example/process#123, Closes #456.",
|
|
315
|
+
"Fixes example/process#123.",
|
|
316
|
+
"Closes example/process#0.",
|
|
317
|
+
):
|
|
318
|
+
with self.subTest(malformed=malformed):
|
|
319
|
+
issues = self.validate_body(f"{CANONICAL_BODY}\n{malformed}\n")
|
|
320
|
+
self.assertTrue(
|
|
321
|
+
any(
|
|
322
|
+
issue.startswith(
|
|
323
|
+
"pull request body has unsupported visible content at line "
|
|
324
|
+
)
|
|
325
|
+
for issue in issues
|
|
326
|
+
)
|
|
327
|
+
)
|
|
328
|
+
|
|
293
329
|
def test_pull_request_ignores_template_comments(self) -> None:
|
|
294
330
|
body = CANONICAL_BODY.replace(
|
|
295
331
|
"- Outcome: Preserve the requested behavior.",
|
|
@@ -78,6 +78,8 @@ class SkillTests(unittest.TestCase):
|
|
|
78
78
|
"Finish never edits\nreadiness",
|
|
79
79
|
"remaining planned\ngaps",
|
|
80
80
|
"owner and stable record URL",
|
|
81
|
+
"contract-identified final consumer adoption",
|
|
82
|
+
"Closes ISSUE, closes ISSUE",
|
|
81
83
|
),
|
|
82
84
|
"improve-process": (
|
|
83
85
|
"new immutable pack version",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/_supervisor_contract.py
RENAMED
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/_supervisor_posix.py
RENAMED
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/_supervisor_windows.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/helper_launch.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/requirements-dev.txt
RENAMED
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process/requirements-runtime.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process.egg-info/requires.txt
RENAMED
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/engineering_process.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/plan-change/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/review-change/SKILL.md
RENAMED
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/run-change/SKILL.md
RENAMED
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/start-change/SKILL.md
RENAMED
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/process_assets/skills/verify-change/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/schemas/production-engineering.schema.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/templates/adopt-process-windows-job.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{engineering_process-1.2.0 → engineering_process-1.2.2}/tests/test_production_engineering.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|