specromancy-engine 0.1.3__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 (91) hide show
  1. specromancy_engine-0.1.3/LICENSE +21 -0
  2. specromancy_engine-0.1.3/MANIFEST.in +21 -0
  3. specromancy_engine-0.1.3/PKG-INFO +122 -0
  4. specromancy_engine-0.1.3/README.md +106 -0
  5. specromancy_engine-0.1.3/build_readme.py +87 -0
  6. specromancy_engine-0.1.3/docs/README.md +55 -0
  7. specromancy_engine-0.1.3/docs/guides/authoring-pipelines.md +222 -0
  8. specromancy_engine-0.1.3/docs/guides/distribution-verification.md +176 -0
  9. specromancy_engine-0.1.3/docs/guides/harnesses.md +137 -0
  10. specromancy_engine-0.1.3/docs/guides/installation.md +177 -0
  11. specromancy_engine-0.1.3/docs/guides/releasing.md +192 -0
  12. specromancy_engine-0.1.3/docs/reference/architecture.md +340 -0
  13. specromancy_engine-0.1.3/docs/reference/cli.md +138 -0
  14. specromancy_engine-0.1.3/docs/reference/contracts.md +464 -0
  15. specromancy_engine-0.1.3/docs/reference/harness-compatibility.md +63 -0
  16. specromancy_engine-0.1.3/examples/release-documentation/.agents/skills/draft-release-notes/SKILL.md +28 -0
  17. specromancy_engine-0.1.3/examples/release-documentation/.agents/skills/pipeline/SKILL.md +44 -0
  18. specromancy_engine-0.1.3/examples/release-documentation/.agents/skills/review-release-notes/SKILL.md +31 -0
  19. specromancy_engine-0.1.3/examples/release-documentation/.gitignore +8 -0
  20. specromancy_engine-0.1.3/examples/release-documentation/AGENTS.md +9 -0
  21. specromancy_engine-0.1.3/examples/release-documentation/README.md +174 -0
  22. specromancy_engine-0.1.3/examples/release-documentation/sample-changes.md +11 -0
  23. specromancy_engine-0.1.3/examples/release-documentation/workflow/pipelines/release-documentation.toml +48 -0
  24. specromancy_engine-0.1.3/examples/release-documentation/workflow/pipelines.toml +5 -0
  25. specromancy_engine-0.1.3/examples/release-documentation/workflow/templates/release-notes.md +13 -0
  26. specromancy_engine-0.1.3/examples/release-documentation/workflow/templates/review.md +13 -0
  27. specromancy_engine-0.1.3/pyproject.toml +31 -0
  28. specromancy_engine-0.1.3/setup.cfg +4 -0
  29. specromancy_engine-0.1.3/setup.py +9 -0
  30. specromancy_engine-0.1.3/src/specromancy_engine/__init__.py +32 -0
  31. specromancy_engine-0.1.3/src/specromancy_engine/__main__.py +8 -0
  32. specromancy_engine-0.1.3/src/specromancy_engine/_adapters/__init__.py +1 -0
  33. specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_contracts.py +81 -0
  34. specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_ownership.py +302 -0
  35. specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_rendering.py +218 -0
  36. specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_sources.py +140 -0
  37. specromancy_engine-0.1.3/src/specromancy_engine/_cli/__init__.py +1 -0
  38. specromancy_engine-0.1.3/src/specromancy_engine/_cli/cli_commands.py +136 -0
  39. specromancy_engine-0.1.3/src/specromancy_engine/_cli/pipeline_selection.py +28 -0
  40. specromancy_engine-0.1.3/src/specromancy_engine/_config/__init__.py +1 -0
  41. specromancy_engine-0.1.3/src/specromancy_engine/_config/config_errors.py +57 -0
  42. specromancy_engine-0.1.3/src/specromancy_engine/_config/config_fields.py +228 -0
  43. specromancy_engine-0.1.3/src/specromancy_engine/_config/config_loader.py +246 -0
  44. specromancy_engine-0.1.3/src/specromancy_engine/_config/config_models.py +97 -0
  45. specromancy_engine-0.1.3/src/specromancy_engine/_config/config_phase_parser.py +497 -0
  46. specromancy_engine-0.1.3/src/specromancy_engine/_config/config_serialization.py +76 -0
  47. specromancy_engine-0.1.3/src/specromancy_engine/_engine/__init__.py +1 -0
  48. specromancy_engine-0.1.3/src/specromancy_engine/_engine/approval_service.py +278 -0
  49. specromancy_engine-0.1.3/src/specromancy_engine/_engine/approvals.py +248 -0
  50. specromancy_engine-0.1.3/src/specromancy_engine/_engine/command_decisions.py +81 -0
  51. specromancy_engine-0.1.3/src/specromancy_engine/_engine/engine_errors.py +22 -0
  52. specromancy_engine-0.1.3/src/specromancy_engine/_engine/provenance.py +58 -0
  53. specromancy_engine-0.1.3/src/specromancy_engine/_engine/responses.py +129 -0
  54. specromancy_engine-0.1.3/src/specromancy_engine/_engine/validation_service.py +112 -0
  55. specromancy_engine-0.1.3/src/specromancy_engine/_runs/__init__.py +1 -0
  56. specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_errors.py +51 -0
  57. specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_identity.py +66 -0
  58. specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_persistence.py +303 -0
  59. specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_records.py +159 -0
  60. specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_validation.py +241 -0
  61. specromancy_engine-0.1.3/src/specromancy_engine/_runs/visit_preparation.py +61 -0
  62. specromancy_engine-0.1.3/src/specromancy_engine/_runs/visit_transitions.py +311 -0
  63. specromancy_engine-0.1.3/src/specromancy_engine/_version.py +18 -0
  64. specromancy_engine-0.1.3/src/specromancy_engine/actions.py +118 -0
  65. specromancy_engine-0.1.3/src/specromancy_engine/adapters.py +97 -0
  66. specromancy_engine-0.1.3/src/specromancy_engine/artifacts.py +303 -0
  67. specromancy_engine-0.1.3/src/specromancy_engine/cli.py +338 -0
  68. specromancy_engine-0.1.3/src/specromancy_engine/commands.py +140 -0
  69. specromancy_engine-0.1.3/src/specromancy_engine/config.py +63 -0
  70. specromancy_engine-0.1.3/src/specromancy_engine/contracts.py +20 -0
  71. specromancy_engine-0.1.3/src/specromancy_engine/engine.py +423 -0
  72. specromancy_engine-0.1.3/src/specromancy_engine/errors.py +42 -0
  73. specromancy_engine-0.1.3/src/specromancy_engine/exit_codes.py +53 -0
  74. specromancy_engine-0.1.3/src/specromancy_engine/git.py +264 -0
  75. specromancy_engine-0.1.3/src/specromancy_engine/graph.py +321 -0
  76. specromancy_engine-0.1.3/src/specromancy_engine/hashing.py +95 -0
  77. specromancy_engine-0.1.3/src/specromancy_engine/locking.py +107 -0
  78. specromancy_engine-0.1.3/src/specromancy_engine/registry.py +134 -0
  79. specromancy_engine-0.1.3/src/specromancy_engine/run_store.py +643 -0
  80. specromancy_engine-0.1.3/src/specromancy_engine/schema_validation.py +178 -0
  81. specromancy_engine-0.1.3/src/specromancy_engine/schemas/event.schema.json +34 -0
  82. specromancy_engine-0.1.3/src/specromancy_engine/schemas/pipeline.schema.json +154 -0
  83. specromancy_engine-0.1.3/src/specromancy_engine/schemas/pipelines.schema.json +38 -0
  84. specromancy_engine-0.1.3/src/specromancy_engine/schemas/run.schema.json +152 -0
  85. specromancy_engine-0.1.3/src/specromancy_engine/status.py +106 -0
  86. specromancy_engine-0.1.3/src/specromancy_engine/validation.py +241 -0
  87. specromancy_engine-0.1.3/src/specromancy_engine.egg-info/PKG-INFO +122 -0
  88. specromancy_engine-0.1.3/src/specromancy_engine.egg-info/SOURCES.txt +89 -0
  89. specromancy_engine-0.1.3/src/specromancy_engine.egg-info/dependency_links.txt +1 -0
  90. specromancy_engine-0.1.3/src/specromancy_engine.egg-info/entry_points.txt +2 -0
  91. specromancy_engine-0.1.3/src/specromancy_engine.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pavel Golitsyn
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,21 @@
1
+ # Start from an allowlist, including when setuptools has a cached SOURCES.txt.
2
+ global-exclude *
3
+ include pyproject.toml MANIFEST.in README.md LICENSE setup.py build_readme.py
4
+ recursive-include src/specromancy_engine *.py
5
+ include src/specromancy_engine/schemas/*.json
6
+ include src/specromancy_engine.egg-info/PKG-INFO
7
+ include src/specromancy_engine.egg-info/SOURCES.txt
8
+ include src/specromancy_engine.egg-info/dependency_links.txt
9
+ include src/specromancy_engine.egg-info/entry_points.txt
10
+ include src/specromancy_engine.egg-info/top_level.txt
11
+ include examples/release-documentation/README.md
12
+ include examples/release-documentation/AGENTS.md
13
+ include examples/release-documentation/.gitignore
14
+ include examples/release-documentation/sample-changes.md
15
+ recursive-include examples/release-documentation/workflow *.toml *.md
16
+ include examples/release-documentation/.agents/skills/pipeline/SKILL.md
17
+ include examples/release-documentation/.agents/skills/draft-release-notes/SKILL.md
18
+ include examples/release-documentation/.agents/skills/review-release-notes/SKILL.md
19
+ include docs/README.md
20
+ recursive-include docs/guides *.md
21
+ recursive-include docs/reference *.md
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: specromancy-engine
3
+ Version: 0.1.3
4
+ Summary: Harness-agnostic agentic pipeline framework
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/PavelGolitsyn/specromancy-engine
7
+ Project-URL: Documentation, https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/README.md
8
+ Project-URL: Issues, https://github.com/PavelGolitsyn/specromancy-engine/issues
9
+ Requires-Python: >=3.11
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: description
13
+ Dynamic: description-content-type
14
+ Dynamic: license-file
15
+ Dynamic: project-url
16
+
17
+ # Specromancy Engine
18
+
19
+ Specromancy Engine is a dependency-free Python 3.11+ framework for portable,
20
+ artifact-based agent workflows. A declarative pipeline and canonical skills
21
+ define the work; a small CLI validates transitions and persists recoverable run
22
+ state independently of any harness conversation.
23
+
24
+ Specromancy Engine targets Linux and macOS. The release verification matrix covers
25
+ Ubuntu 24.04 and macOS 15 with Python 3.11.15 and 3.14.4. Windows is unverified
26
+ and is not claimed as supported in this release.
27
+
28
+ ## Use the engine in another project
29
+
30
+ Install from PyPI into your project's Python environment:
31
+
32
+ ```sh
33
+ python -m pip install specromancy-engine
34
+ specromancy --help
35
+ ```
36
+
37
+ Follow the [installation guide][installation] to create an isolated
38
+ environment, add the engine to an existing Python project's dependencies, or
39
+ install a local wheel. The
40
+ [release-documentation consumer][consumer-example]
41
+ provides an executable two-phase example.
42
+
43
+ Your project explicitly supplies its registry, graphs, templates, instructions,
44
+ and skills. The engine emits actions and verifies agent output; it does not
45
+ launch an LLM, provide credentials, generate prose, or publish results.
46
+
47
+ ## Contributor quickstart
48
+
49
+ From a Git checkout, create a dedicated development environment and install
50
+ the package in editable mode:
51
+
52
+ ```bash
53
+ python3 -m venv .venv
54
+ source .venv/bin/activate
55
+ python -m pip install -e .
56
+ bin/specromancy init "describe the requested change" --pipeline implementation
57
+ bin/specromancy status RUN_ID
58
+ bin/specromancy resume RUN_ID
59
+ python -m unittest discover
60
+ bin/specromancy adapters generate --check
61
+ ```
62
+
63
+ `init` returns the run ID and next action. Follow the emitted action packet and
64
+ use its exact output path, skill, mutation policy, and final validation command.
65
+ Runtime data is written only under ignored `.specromancy/runs/` storage.
66
+
67
+ The `specromancy-engine` package provides the `specromancy` console
68
+ command and `python -m specromancy_engine`. The checkout wrappers
69
+ `bin/specromancy` and `adapters/generate.py` also work without installation as
70
+ producer-checkout conveniences. Consumers install the dependency; they do not
71
+ copy engine source or launchers into their projects.
72
+ Python consumers import `specromancy_engine`. Run and event formats use schema
73
+ version 1. See the [public contracts][contracts] for supported
74
+ interfaces, persistence, and ownership rules.
75
+
76
+ ## Customize the workflow
77
+
78
+ Register pipelines in `workflow/pipelines.toml` and keep their graphs under
79
+ `workflow/pipelines/`. Every new run requires `--pipeline ID`; there is no default.
80
+ Adapters generate a `specromancy-<id>` launch skill for each registration.
81
+ The editable graphs and shared artifact templates live in [`workflow/`][workflow-directory].
82
+ These top-level resources configure this repository's own development workflow;
83
+ they are not automatically installed consumer defaults.
84
+ Phase procedures live in [`.agents/skills/`][skills-directory] for native harness
85
+ discovery, and repository-wide agent constraints live in [`AGENTS.md`][agent-instructions].
86
+ The Python package under `src/specromancy_engine/` is the generic engine, not a workflow
87
+ customization surface. Start with the
88
+ [`workflow/README.md`][workflow-guide] customization map.
89
+
90
+ ## Documentation
91
+
92
+ - [Documentation and repository map][documentation]
93
+ - [Consumer installation][installation]
94
+ - [Distribution verification and CI][distribution-verification]
95
+ - [Publishing a release][releasing]
96
+ - [Architecture][architecture]
97
+ - [CLI reference][cli]
98
+ - [Pipeline authoring][pipeline-authoring]
99
+ - [Harness usage][harnesses]
100
+ - [Public contracts][contracts]
101
+ - [Historical plans and refactoring records][history]
102
+
103
+ The engine intentionally does not launch harnesses, migrate active runs between
104
+ pipeline versions, provide remote storage or distributed locking, authenticate
105
+ approvers, or implement parallel graph joins. See the architecture document for
106
+ the complete limitations and safety boundary.
107
+
108
+ [installation]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/guides/installation.md
109
+ [consumer-example]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/examples/release-documentation/README.md
110
+ [contracts]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/reference/contracts.md
111
+ [workflow-directory]: https://github.com/PavelGolitsyn/specromancy-engine/tree/v0.1.3/workflow
112
+ [skills-directory]: https://github.com/PavelGolitsyn/specromancy-engine/tree/v0.1.3/.agents/skills
113
+ [agent-instructions]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/AGENTS.md
114
+ [workflow-guide]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/workflow/README.md
115
+ [documentation]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/README.md
116
+ [distribution-verification]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/guides/distribution-verification.md
117
+ [releasing]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/guides/releasing.md
118
+ [architecture]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/reference/architecture.md
119
+ [cli]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/reference/cli.md
120
+ [pipeline-authoring]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/guides/authoring-pipelines.md
121
+ [harnesses]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/guides/harnesses.md
122
+ [history]: https://github.com/PavelGolitsyn/specromancy-engine/blob/v0.1.3/docs/implementation-history/README.md
@@ -0,0 +1,106 @@
1
+ # Specromancy Engine
2
+
3
+ Specromancy Engine is a dependency-free Python 3.11+ framework for portable,
4
+ artifact-based agent workflows. A declarative pipeline and canonical skills
5
+ define the work; a small CLI validates transitions and persists recoverable run
6
+ state independently of any harness conversation.
7
+
8
+ Specromancy Engine targets Linux and macOS. The release verification matrix covers
9
+ Ubuntu 24.04 and macOS 15 with Python 3.11.15 and 3.14.4. Windows is unverified
10
+ and is not claimed as supported in this release.
11
+
12
+ ## Use the engine in another project
13
+
14
+ Install from PyPI into your project's Python environment:
15
+
16
+ ```sh
17
+ python -m pip install specromancy-engine
18
+ specromancy --help
19
+ ```
20
+
21
+ Follow the [installation guide][installation] to create an isolated
22
+ environment, add the engine to an existing Python project's dependencies, or
23
+ install a local wheel. The
24
+ [release-documentation consumer][consumer-example]
25
+ provides an executable two-phase example.
26
+
27
+ Your project explicitly supplies its registry, graphs, templates, instructions,
28
+ and skills. The engine emits actions and verifies agent output; it does not
29
+ launch an LLM, provide credentials, generate prose, or publish results.
30
+
31
+ ## Contributor quickstart
32
+
33
+ From a Git checkout, create a dedicated development environment and install
34
+ the package in editable mode:
35
+
36
+ ```bash
37
+ python3 -m venv .venv
38
+ source .venv/bin/activate
39
+ python -m pip install -e .
40
+ bin/specromancy init "describe the requested change" --pipeline implementation
41
+ bin/specromancy status RUN_ID
42
+ bin/specromancy resume RUN_ID
43
+ python -m unittest discover
44
+ bin/specromancy adapters generate --check
45
+ ```
46
+
47
+ `init` returns the run ID and next action. Follow the emitted action packet and
48
+ use its exact output path, skill, mutation policy, and final validation command.
49
+ Runtime data is written only under ignored `.specromancy/runs/` storage.
50
+
51
+ The `specromancy-engine` package provides the `specromancy` console
52
+ command and `python -m specromancy_engine`. The checkout wrappers
53
+ `bin/specromancy` and `adapters/generate.py` also work without installation as
54
+ producer-checkout conveniences. Consumers install the dependency; they do not
55
+ copy engine source or launchers into their projects.
56
+ Python consumers import `specromancy_engine`. Run and event formats use schema
57
+ version 1. See the [public contracts][contracts] for supported
58
+ interfaces, persistence, and ownership rules.
59
+
60
+ ## Customize the workflow
61
+
62
+ Register pipelines in `workflow/pipelines.toml` and keep their graphs under
63
+ `workflow/pipelines/`. Every new run requires `--pipeline ID`; there is no default.
64
+ Adapters generate a `specromancy-<id>` launch skill for each registration.
65
+ The editable graphs and shared artifact templates live in [`workflow/`][workflow-directory].
66
+ These top-level resources configure this repository's own development workflow;
67
+ they are not automatically installed consumer defaults.
68
+ Phase procedures live in [`.agents/skills/`][skills-directory] for native harness
69
+ discovery, and repository-wide agent constraints live in [`AGENTS.md`][agent-instructions].
70
+ The Python package under `src/specromancy_engine/` is the generic engine, not a workflow
71
+ customization surface. Start with the
72
+ [`workflow/README.md`][workflow-guide] customization map.
73
+
74
+ ## Documentation
75
+
76
+ - [Documentation and repository map][documentation]
77
+ - [Consumer installation][installation]
78
+ - [Distribution verification and CI][distribution-verification]
79
+ - [Publishing a release][releasing]
80
+ - [Architecture][architecture]
81
+ - [CLI reference][cli]
82
+ - [Pipeline authoring][pipeline-authoring]
83
+ - [Harness usage][harnesses]
84
+ - [Public contracts][contracts]
85
+ - [Historical plans and refactoring records][history]
86
+
87
+ The engine intentionally does not launch harnesses, migrate active runs between
88
+ pipeline versions, provide remote storage or distributed locking, authenticate
89
+ approvers, or implement parallel graph joins. See the architecture document for
90
+ the complete limitations and safety boundary.
91
+
92
+ [installation]: docs/guides/installation.md
93
+ [consumer-example]: examples/release-documentation/README.md
94
+ [contracts]: docs/reference/contracts.md
95
+ [workflow-directory]: workflow/
96
+ [skills-directory]: .agents/skills/
97
+ [agent-instructions]: AGENTS.md
98
+ [workflow-guide]: workflow/README.md
99
+ [documentation]: docs/README.md
100
+ [distribution-verification]: docs/guides/distribution-verification.md
101
+ [releasing]: docs/guides/releasing.md
102
+ [architecture]: docs/reference/architecture.md
103
+ [cli]: docs/reference/cli.md
104
+ [pipeline-authoring]: docs/guides/authoring-pipelines.md
105
+ [harnesses]: docs/guides/harnesses.md
106
+ [history]: docs/implementation-history/README.md
@@ -0,0 +1,87 @@
1
+ """Build-only README metadata, independent of Git and the engine runtime.
2
+
3
+ Local README destinations use single-line Markdown reference definitions.
4
+ Directory destinations end in '/'; image references use labels beginning with
5
+ 'image-'. These explicit conventions also work in an sdist that omits the
6
+ linked repository files. Inline links should use absolute URLs.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from pathlib import Path
11
+ import posixpath
12
+ import re
13
+ import tomllib
14
+ from urllib.parse import quote, urlsplit, urlunsplit
15
+
16
+
17
+ REFERENCE = re.compile(r"^( {0,3}\[([^\]\n]+)\]:[ \t]*)(<[^>\n]+>|\S+)(.*)$")
18
+ FENCE = re.compile(r"^ {0,3}(`{3,}|~{3,})(.*)$")
19
+
20
+
21
+ def absolute_url(destination: str, repository: str, version: str, *, image: bool = False) -> str:
22
+ """Resolve a repository-root destination without inspecting the filesystem."""
23
+ parts = urlsplit(destination)
24
+ if parts.scheme or parts.netloc:
25
+ return destination
26
+ path = posixpath.normpath(parts.path.lstrip("/") or "README.md")
27
+ if path == ".." or path.startswith("../") or "\\" in path:
28
+ raise ValueError(f"README link escapes the repository: {destination}")
29
+ tag = quote(f"v{version}", safe="")
30
+ kind = "tree" if parts.path.endswith("/") else "blob"
31
+ if image:
32
+ # GitHub's raw endpoint serves image bytes instead of an HTML file view.
33
+ kind = "raw"
34
+ path = quote(path, safe="/%:@!$&'()*+,;=-._~")
35
+ base = f"{repository.rstrip('/')}/{kind}/{tag}/{path}"
36
+ return urlunsplit((*urlsplit(base)[:3], parts.query, parts.fragment))
37
+
38
+
39
+ def render_readme(source: str, repository: str, version: str) -> str:
40
+ """Rewrite reference destinations, preserving prose, titles, and code blocks."""
41
+ result = []
42
+ fence = ""
43
+ for line in source.splitlines(keepends=True):
44
+ marker = FENCE.match(line)
45
+ if fence:
46
+ if marker and marker[1][0] == fence[0] and len(marker[1]) >= len(fence) and not marker[2].strip():
47
+ fence = ""
48
+ result.append(line)
49
+ continue
50
+ if marker:
51
+ fence = marker[1]
52
+ result.append(line)
53
+ continue
54
+ match = REFERENCE.match(line)
55
+ if match:
56
+ target = match[3]
57
+ angled = target.startswith("<")
58
+ url = absolute_url(target[1:-1] if angled else target, repository, version,
59
+ image=match[2].lower().startswith("image-"))
60
+ if angled:
61
+ url = f"<{url}>"
62
+ line = line[:match.start(3)] + url + line[match.end(3):]
63
+ elif not line.startswith((" ", "\t")):
64
+ prose = re.sub(r"(`+).*?\1", "", line)
65
+ for inline in re.finditer(r"\]\(<?([^\s)>]+)", prose):
66
+ parts = urlsplit(inline[1])
67
+ if not parts.scheme and not parts.netloc:
68
+ raise ValueError("Use a Markdown reference definition for local README links: "
69
+ + inline[1])
70
+ result.append(line)
71
+ return "".join(result)
72
+
73
+
74
+ def build_metadata(root: Path) -> dict:
75
+ config = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))
76
+ version = config["project"]["version"]
77
+ repository = config["tool"]["specromancy-engine-build"]["repository"]
78
+ return {
79
+ "long_description": render_readme((root / "README.md").read_text(encoding="utf-8"),
80
+ repository, version),
81
+ "long_description_content_type": "text/markdown",
82
+ "project_urls": {
83
+ "Homepage": repository,
84
+ "Documentation": absolute_url("docs/README.md", repository, version),
85
+ "Issues": f"{repository}/issues",
86
+ },
87
+ }
@@ -0,0 +1,55 @@
1
+ # Documentation
2
+
3
+ Current documentation is organized by purpose:
4
+
5
+ - [Installation](guides/installation.md): CLI-only and Python dependency consumer routes.
6
+ - [Publishing a release](guides/releasing.md): manual GitHub Actions release, registry setup, and recovery.
7
+ - [Release-documentation example](../examples/release-documentation/README.md): wheel-only lifecycle walkthrough.
8
+ - [Architecture](reference/architecture.md): runtime responsibilities and dependencies.
9
+ - [Public contracts](reference/contracts.md): stable imports, CLI behavior, and persisted data.
10
+ - [CLI reference](reference/cli.md): commands, responses, and exit codes.
11
+ - [Harness compatibility](reference/harness-compatibility.md): supported discovery surfaces.
12
+ - [Pipeline authoring](guides/authoring-pipelines.md): configure graphs and validators.
13
+ - [Harness usage](guides/harnesses.md): run workflows from supported agent harnesses.
14
+ - [Workflow customization](../workflow/README.md): editable sources and pipeline registration.
15
+
16
+ [Historical plans and refactoring records](implementation-history/README.md) document prior work;
17
+ use the references and guides above for current behavior.
18
+
19
+ ## Repository map
20
+
21
+ | Location | Purpose |
22
+ | --- | --- |
23
+ | `pyproject.toml` | Build metadata, package discovery, schema data, and installed CLI |
24
+ | `src/specromancy_engine/` | Public Python entry points and shared runtime utilities |
25
+ | `src/specromancy_engine/_config/` | Private configuration parsing, models, and serialization |
26
+ | `src/specromancy_engine/_runs/` | Private run records, persistence, and visit preparation/decisions |
27
+ | `src/specromancy_engine/_engine/` | Private approval, validation, provenance, and response orchestration |
28
+ | `src/specromancy_engine/_adapters/` | Private adapter source capture, rendering, and ownership |
29
+ | `src/specromancy_engine/_cli/` | Private command metadata and pipeline selection |
30
+ | `src/specromancy_engine/schemas/` | Published JSON schemas |
31
+ | `bin/` | Executable launcher |
32
+ | `workflow/` | This repository's configured development registry, graphs, and templates |
33
+ | `.agents/skills/` | This repository's canonical procedures and manifest-owned launch skills |
34
+ | `adapters/` | Generation entry point and generated-file ownership manifest |
35
+ | `.claude/`, `.github/`, `.opencode/` | Harness discovery files owned by the adapter manifest |
36
+ | `tests/engine/` | Engine unit/contract tests, evaluations, and test-owned fixtures |
37
+ | `tests/shipped_configuration/` | Validation of the shipped workflow and generated adapters |
38
+ | `tests/packaging/` | Installed consumer contracts and executable documentation checks |
39
+ | `examples/release-documentation/` | Consumer-owned registry, graph, skills, templates, and sample request; outside the wheel |
40
+ | `docs/reference/`, `docs/guides/` | Current documentation |
41
+ | `docs/implementation-history/` | Implementation records |
42
+ | `.specromancy/runs/` | Ignored local run state and immutable visit artifacts |
43
+
44
+ The underscore-prefixed Python packages are internal implementation details.
45
+ Public imports use `specromancy_engine`, including its `config`, `engine`,
46
+ `run_store`, `registry`, `adapters`, and `cli` facades. See the
47
+ [public contracts](reference/contracts.md). Internal package initializers do not import
48
+ public facades or eagerly load sibling components.
49
+
50
+ See the [test guide](../tests/README.md) for discovery commands and compatibility
51
+ coverage. Generated adapters remain in harness-required locations; edit their
52
+ canonical sources and regenerate them through the CLI.
53
+
54
+ The [distribution verification guide](guides/distribution-verification.md) covers
55
+ the offline installed-artifact gates, sdist contents, pinned tooling, and CI.
@@ -0,0 +1,222 @@
1
+ # Authoring pipelines
2
+
3
+ Start with the [release-documentation consumer](../../examples/release-documentation/README.md)
4
+ and [installation guide](installation.md). The example supplies a registry,
5
+ two read-only phases, canonical skills, templates, and a complete walkthrough.
6
+ The producer's implementation pipeline provides richer approval and repair
7
+ examples. Test-owned replacement fixtures independently verify replaceability;
8
+ they are not the consumer onboarding template.
9
+
10
+ Register each graph in mandatory `workflow/pipelines.toml`, with a unique ID
11
+ and a path under `workflow/pipelines/`. There is no default; use
12
+ `specromancy init DESCRIPTION --pipeline ID`. See
13
+ [Workflow customization](../../workflow/README.md) for add/edit/remove steps.
14
+
15
+ With the package installed in your environment, use `specromancy init DESCRIPTION
16
+ --pipeline ID` from the consumer root or a nested directory. Discovery recognizes
17
+ both `.git` directories and worktree marker files. From an unrelated directory,
18
+ use `specromancy --root /absolute/path/to/consumer init DESCRIPTION --pipeline ID`.
19
+ A non-Git consumer needs both `--root` and `allow_non_git = true` in its graph.
20
+ Installation supplies the engine and its four published schemas; author the
21
+ registry, graph, skills, templates, and validator schemas in the consumer project.
22
+ Nothing is implicitly loaded from the engine's source checkout or home directory.
23
+
24
+ Adapter generation also requires the project-owned generic
25
+ `.agents/skills/pipeline/SKILL.md`. Explicitly copy the
26
+ [reusable procedure](../../.agents/skills/pipeline/SKILL.md) to that path in the
27
+ consumer; review existing content before replacing it. Installation does not
28
+ create it. The procedure resolves phases from persisted CLI packets and needs
29
+ no example phase names. See [Harness usage](harnesses.md) for command environment
30
+ setup, including GUI harnesses.
31
+
32
+ Pipeline files use TOML so Python 3.11 can load them without a dependency. A
33
+ pipeline declares schema version, identity, start phase, terminal outcomes,
34
+ artifact naming, Git policy, and an ordered `[[phases]]` array. Every phase
35
+ names a canonical skill, inputs, output, mutation policy, validator, gates, and
36
+ transitions.
37
+
38
+ ## Add, delete, reorder, or replace phases
39
+
40
+ To add a phase:
41
+
42
+ 1. add `.agents/skills/<name>/SKILL.md` with portable frontmatter;
43
+ 2. add any output template under the pipeline's directory;
44
+ 3. add `[[phases]]` with a unique lowercase identifier;
45
+ 4. route an existing transition to it and give it at least one transition;
46
+ 5. make every symbolic input available on every incoming route;
47
+ 6. regenerate adapters and run tests.
48
+
49
+ Delete a phase by removing all inbound transitions first, then its phase table,
50
+ skill, and unused template. Reordering table text alone does not change graph
51
+ behavior: change transition targets and, when necessary, `start`. The loader
52
+ rejects unreachable phases and unknown targets.
53
+
54
+ Replacing the whole workflow follows the same rules. The replacement fixture's
55
+ unrelated names and order are the contract test for this operation.
56
+
57
+ ## Branches and bounded loops
58
+
59
+ Add one transition table per allowed outcome:
60
+
61
+ ```toml
62
+ [[phases.transitions]]
63
+ outcome = "accepted"
64
+
65
+ [[phases.transitions]]
66
+ outcome = "rejected"
67
+ target = "transform"
68
+ max_traversals = 2
69
+ ```
70
+
71
+ A transition without `target` must be listed in `terminal_outcomes`. A cycle
72
+ must be bounded by a positive `max_traversals` on the cyclic edge or a positive
73
+ `max_visits` on a phase that bounds the cycle. Limits count persisted visits or
74
+ edge traversals and block before creating an excess visit.
75
+
76
+ Set `pause = true` on a nonterminal transition to create a durable checkpoint:
77
+
78
+ ```toml
79
+ [[phases.transitions]]
80
+ outcome = "validated"
81
+ target = "implement"
82
+ pause = true
83
+ ```
84
+
85
+ The source visit completes and the target visit is prepared atomically, but the
86
+ run remains `paused` until `specromancy resume RUN_ID` releases it. Pauses are
87
+ independent from approvals and are rejected on terminal transitions. Omitting
88
+ `pause`, or setting it to `false`, preserves ordinary transition behavior and
89
+ the canonical hash of an otherwise unchanged version-1 pipeline.
90
+
91
+ ## Skills and templates
92
+
93
+ `skill = "inspect"` resolves to `.agents/skills/inspect/SKILL.md` at the
94
+ repository root. Canonical skill frontmatter is limited to portable Agent
95
+ Skills fields (`name`, `description`, `license`, `compatibility`, and optional
96
+ `metadata`). Keep vendor models, tool allowlists, and slash-command syntax in
97
+ generated harness surfaces, never canonical skills.
98
+
99
+ `output_template` is relative to the pipeline file. `../templates/result.md`
100
+ can reference shared `workflow/templates/`; multiple graphs may use the same
101
+ canonical skill or template. The resolved file must remain inside the repository.
102
+ The `.agents/skills/specromancy-*` namespace holds generated launch skills and
103
+ is not a phase-procedure customization surface. A Markdown validator can
104
+ declare `required_headings` and `heading_occurrence`; a JSON validator may use
105
+ the documented project-owned schema subset. Templates should contain every
106
+ required heading exactly once and meaningful placeholder content that a valid
107
+ artifact must replace.
108
+
109
+ JSON validator `path` (or `schema`) resolves relative to the pipeline file and
110
+ must stay inside the consumer root, including after symlink resolution. The
111
+ `load_json_schema(path)` API still reads these project-owned files and rejects
112
+ unsupported keywords. The four published engine schemas are a separate package
113
+ resource contract, not artifact validators for that subset; see
114
+ [installed resources](../reference/contracts.md#installed-resources-and-consumer-roots).
115
+
116
+ ## Embed the installed engine
117
+
118
+ Use an explicit absolute consumer root so the caller's working directory does
119
+ not select the project. Given a registered `shared` pipeline, this initializes a
120
+ run and reads its durable status through the public facades:
121
+
122
+ ```python
123
+ from pathlib import Path
124
+ from specromancy_engine import Engine, RunStore, load_registry
125
+
126
+ root = Path("/absolute/path/to/consumer").resolve()
127
+ pipeline = load_registry(root).load("shared")
128
+ store = RunStore(root)
129
+ engine = Engine(pipeline, store)
130
+ response = engine.initialize("Record the consumer result.")
131
+ run_id = response["action"]["run_id"]
132
+ status = engine.status(run_id)
133
+ manifest = store.load(run_id)
134
+ ```
135
+
136
+ `Engine(pipeline)` also constructs a store at `pipeline.repository_root` when
137
+ one is not supplied. For an existing run, load its recorded graph rather than
138
+ selecting today's registration, which might point somewhere else:
139
+
140
+ ```python
141
+ from specromancy_engine import load_pipeline
142
+
143
+ saved = store.load(run_id, verify_artifacts=False)["pipeline"]
144
+ pipeline = load_pipeline(root / saved["path"], repository_root=root)
145
+ engine = Engine(pipeline, store)
146
+ status = engine.status(run_id)
147
+ ```
148
+
149
+ The low-level `load_pipeline(path, repository_root=...)` API does not require a
150
+ registry. CLI commands continue to require one. Neither API executes a phase's
151
+ agent procedure: call `start_phase(run_id, phase_id)`, use its action packet to
152
+ produce the artifact, then call `validate(run_id, phase_id)`. Construct a
153
+ separate pipeline and store for each consumer; no new builder API is required.
154
+
155
+ ## Approvals and stops
156
+
157
+ Declare stable kebab-case reason codes:
158
+
159
+ ```toml
160
+ approval_conditions = ["external-side-effect", "material-scope-change"]
161
+ stop_conditions = ["insufficient-information"]
162
+ ```
163
+
164
+ The phase skill explains when each code applies. It must call
165
+ `request-approval` or `block` rather than merely mentioning a concern in prose.
166
+ Changing or adding a reason changes the pipeline hash.
167
+
168
+ ## Mutation policies
169
+
170
+ - `read-only` rejects every repository path change during the visit, including
171
+ a second edit to a file that was dirty at visit start.
172
+ - `repository-write` records all changes but permits them.
173
+ - `allowlist` permits only paths matched by the phase's `allowlist` globs and
174
+ rejects the rest.
175
+
176
+ CLI-owned `.specromancy/` files are outside repository mutation comparison.
177
+ Read-only phases may write their designated visit output there. Completed
178
+ outputs are immutable. In the release-documentation example the reviewed notes
179
+ stay in run storage; explicitly copying them into release docs is a user action
180
+ outside that lifecycle.
181
+ None of these policies grants permission to delete, reset, stage, or commit
182
+ work; repository instructions still apply.
183
+
184
+ ## Validation commands
185
+
186
+ Commands are arrays, never shell strings:
187
+
188
+ ```toml
189
+ [[phases.commands]]
190
+ argv = ["python", "-m", "unittest", "discover"]
191
+ timeout_seconds = 300
192
+ required = true
193
+ ```
194
+
195
+ They run in order from the repository root. A required failure prevents phase
196
+ completion. Use explicit executables and arguments; shell operators, pipes, and
197
+ redirections are not interpreted.
198
+
199
+ ## Regeneration and active runs
200
+
201
+ After changing `AGENTS.md`, a canonical skill, the registry, a pipeline or its
202
+ referenced templates/schemas, or CLI help
203
+ metadata, run:
204
+
205
+ ```bash
206
+ specromancy adapters generate
207
+ specromancy adapters generate --check
208
+ python -m unittest discover
209
+ ```
210
+
211
+ A run stores its pipeline hash. Any pipeline change causes `resume`, `phase`,
212
+ and transition commands to reject that run with `pipeline-hash-mismatch`.
213
+ Approval records also become stale. The engine deliberately has no active-run
214
+ migration: finish the old run before editing its pipeline, restore the exact
215
+ old configuration to resume it, or initialize a new run under the new hash.
216
+ Never edit `run.json` to force compatibility.
217
+
218
+ Removing a registration disables new runs and removes unchanged generated
219
+ launch skills on regeneration. Keep original graph, skill, and template files
220
+ for active runs, which continue to resolve their persisted provenance. Removing
221
+ the files or moving the graph prevents continuation. Registry order and edits
222
+ to another graph do not change the selected run.