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.
- specromancy_engine-0.1.3/LICENSE +21 -0
- specromancy_engine-0.1.3/MANIFEST.in +21 -0
- specromancy_engine-0.1.3/PKG-INFO +122 -0
- specromancy_engine-0.1.3/README.md +106 -0
- specromancy_engine-0.1.3/build_readme.py +87 -0
- specromancy_engine-0.1.3/docs/README.md +55 -0
- specromancy_engine-0.1.3/docs/guides/authoring-pipelines.md +222 -0
- specromancy_engine-0.1.3/docs/guides/distribution-verification.md +176 -0
- specromancy_engine-0.1.3/docs/guides/harnesses.md +137 -0
- specromancy_engine-0.1.3/docs/guides/installation.md +177 -0
- specromancy_engine-0.1.3/docs/guides/releasing.md +192 -0
- specromancy_engine-0.1.3/docs/reference/architecture.md +340 -0
- specromancy_engine-0.1.3/docs/reference/cli.md +138 -0
- specromancy_engine-0.1.3/docs/reference/contracts.md +464 -0
- specromancy_engine-0.1.3/docs/reference/harness-compatibility.md +63 -0
- specromancy_engine-0.1.3/examples/release-documentation/.agents/skills/draft-release-notes/SKILL.md +28 -0
- specromancy_engine-0.1.3/examples/release-documentation/.agents/skills/pipeline/SKILL.md +44 -0
- specromancy_engine-0.1.3/examples/release-documentation/.agents/skills/review-release-notes/SKILL.md +31 -0
- specromancy_engine-0.1.3/examples/release-documentation/.gitignore +8 -0
- specromancy_engine-0.1.3/examples/release-documentation/AGENTS.md +9 -0
- specromancy_engine-0.1.3/examples/release-documentation/README.md +174 -0
- specromancy_engine-0.1.3/examples/release-documentation/sample-changes.md +11 -0
- specromancy_engine-0.1.3/examples/release-documentation/workflow/pipelines/release-documentation.toml +48 -0
- specromancy_engine-0.1.3/examples/release-documentation/workflow/pipelines.toml +5 -0
- specromancy_engine-0.1.3/examples/release-documentation/workflow/templates/release-notes.md +13 -0
- specromancy_engine-0.1.3/examples/release-documentation/workflow/templates/review.md +13 -0
- specromancy_engine-0.1.3/pyproject.toml +31 -0
- specromancy_engine-0.1.3/setup.cfg +4 -0
- specromancy_engine-0.1.3/setup.py +9 -0
- specromancy_engine-0.1.3/src/specromancy_engine/__init__.py +32 -0
- specromancy_engine-0.1.3/src/specromancy_engine/__main__.py +8 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_adapters/__init__.py +1 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_contracts.py +81 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_ownership.py +302 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_rendering.py +218 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_adapters/adapter_sources.py +140 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_cli/__init__.py +1 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_cli/cli_commands.py +136 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_cli/pipeline_selection.py +28 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_config/__init__.py +1 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_config/config_errors.py +57 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_config/config_fields.py +228 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_config/config_loader.py +246 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_config/config_models.py +97 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_config/config_phase_parser.py +497 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_config/config_serialization.py +76 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/__init__.py +1 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/approval_service.py +278 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/approvals.py +248 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/command_decisions.py +81 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/engine_errors.py +22 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/provenance.py +58 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/responses.py +129 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_engine/validation_service.py +112 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/__init__.py +1 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_errors.py +51 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_identity.py +66 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_persistence.py +303 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_records.py +159 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/run_validation.py +241 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/visit_preparation.py +61 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_runs/visit_transitions.py +311 -0
- specromancy_engine-0.1.3/src/specromancy_engine/_version.py +18 -0
- specromancy_engine-0.1.3/src/specromancy_engine/actions.py +118 -0
- specromancy_engine-0.1.3/src/specromancy_engine/adapters.py +97 -0
- specromancy_engine-0.1.3/src/specromancy_engine/artifacts.py +303 -0
- specromancy_engine-0.1.3/src/specromancy_engine/cli.py +338 -0
- specromancy_engine-0.1.3/src/specromancy_engine/commands.py +140 -0
- specromancy_engine-0.1.3/src/specromancy_engine/config.py +63 -0
- specromancy_engine-0.1.3/src/specromancy_engine/contracts.py +20 -0
- specromancy_engine-0.1.3/src/specromancy_engine/engine.py +423 -0
- specromancy_engine-0.1.3/src/specromancy_engine/errors.py +42 -0
- specromancy_engine-0.1.3/src/specromancy_engine/exit_codes.py +53 -0
- specromancy_engine-0.1.3/src/specromancy_engine/git.py +264 -0
- specromancy_engine-0.1.3/src/specromancy_engine/graph.py +321 -0
- specromancy_engine-0.1.3/src/specromancy_engine/hashing.py +95 -0
- specromancy_engine-0.1.3/src/specromancy_engine/locking.py +107 -0
- specromancy_engine-0.1.3/src/specromancy_engine/registry.py +134 -0
- specromancy_engine-0.1.3/src/specromancy_engine/run_store.py +643 -0
- specromancy_engine-0.1.3/src/specromancy_engine/schema_validation.py +178 -0
- specromancy_engine-0.1.3/src/specromancy_engine/schemas/event.schema.json +34 -0
- specromancy_engine-0.1.3/src/specromancy_engine/schemas/pipeline.schema.json +154 -0
- specromancy_engine-0.1.3/src/specromancy_engine/schemas/pipelines.schema.json +38 -0
- specromancy_engine-0.1.3/src/specromancy_engine/schemas/run.schema.json +152 -0
- specromancy_engine-0.1.3/src/specromancy_engine/status.py +106 -0
- specromancy_engine-0.1.3/src/specromancy_engine/validation.py +241 -0
- specromancy_engine-0.1.3/src/specromancy_engine.egg-info/PKG-INFO +122 -0
- specromancy_engine-0.1.3/src/specromancy_engine.egg-info/SOURCES.txt +89 -0
- specromancy_engine-0.1.3/src/specromancy_engine.egg-info/dependency_links.txt +1 -0
- specromancy_engine-0.1.3/src/specromancy_engine.egg-info/entry_points.txt +2 -0
- 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.
|