specsmither-lifecycle 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- specsmither_lifecycle-0.1.0/.gitignore +38 -0
- specsmither_lifecycle-0.1.0/CHANGELOG.md +40 -0
- specsmither_lifecycle-0.1.0/PKG-INFO +42 -0
- specsmither_lifecycle-0.1.0/README.md +18 -0
- specsmither_lifecycle-0.1.0/pyproject.toml +44 -0
- specsmither_lifecycle-0.1.0/src/specsmither/domain/__init__.py +6 -0
- specsmither_lifecycle-0.1.0/src/specsmither/domain/enums.py +266 -0
- specsmither_lifecycle-0.1.0/src/specsmither/domain/records.py +489 -0
- specsmither_lifecycle-0.1.0/src/specsmither/domain/status.py +102 -0
- specsmither_lifecycle-0.1.0/src/specsmither/ids.py +53 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/__init__.py +6 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/audit/__init__.py +26 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/audit/action_builder.py +219 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/audit/operation_mapper.py +128 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/audit/transition_builder.py +69 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/config.py +134 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/dispatch.py +100 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/gate.py +418 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/__init__.py +9 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/catalogs/cross_validation.yaml +87 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/catalogs/epic_decomposition.yaml +177 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/catalogs/epic_expansion.yaml +197 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/catalogs/planning_spec.yaml +247 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/catalogs/ticket_decomposition.yaml +137 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/catalogs/ticket_expansion.yaml +221 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/compose.py +624 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/field_instructions.py +275 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/guidance/types.py +130 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/operations_projector.py +631 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/operations_registry.py +471 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/ports.py +383 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/__init__.py +82 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/blueprint_epic_ratio.py +70 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/blueprint_link_refs_exist.py +68 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/cascade_rules.py +70 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/content_shape_valid.py +120 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/count_bounds.py +134 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/cross_cut_references.py +62 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/dependencies_batch.py +223 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/entity_refs_exist.py +96 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/enum_field_guards.py +112 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/field_shape_soft_deny.py +73 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/gate_currently_passing.py +154 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/operation_allowed.py +110 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/result.py +75 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/schema_validate.py +173 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/prechecks/spec_status_check.py +89 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/session_record.py +82 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/state_machine.py +90 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/__init__.py +13 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/_common.py +74 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/action.py +472 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/approve.py +191 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/complete.py +215 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/inspect.py +106 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/reject.py +88 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/reject_with_feedback.py +102 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/start.py +271 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/support.py +208 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/verbs/types.py +118 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/write_plan.py +1146 -0
- specsmither_lifecycle-0.1.0/src/specsmither/lifecycle/write_plan_types.py +225 -0
- specsmither_lifecycle-0.1.0/src/specsmither/py.typed +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# --- Local-only planning docs (milestone breakdowns; not published) ---
|
|
2
|
+
planner/
|
|
3
|
+
|
|
4
|
+
# --- Throwaway CLI/TUI prototype (milestone 02 mock; not published) ---
|
|
5
|
+
playground/
|
|
6
|
+
|
|
7
|
+
# Python
|
|
8
|
+
__pycache__/
|
|
9
|
+
*.py[cod]
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
*.egg-info/
|
|
13
|
+
dist/
|
|
14
|
+
build/
|
|
15
|
+
.mypy_cache/
|
|
16
|
+
.ruff_cache/
|
|
17
|
+
.pytest_cache/
|
|
18
|
+
.coverage
|
|
19
|
+
htmlcov/
|
|
20
|
+
|
|
21
|
+
# Local SQLite databases / config
|
|
22
|
+
*.db
|
|
23
|
+
*.sqlite3
|
|
24
|
+
*.sqlite3-wal
|
|
25
|
+
*.sqlite3-shm
|
|
26
|
+
.specsmither/
|
|
27
|
+
|
|
28
|
+
# Dev-only uv overrides (e.g. an editable ../crucible source) — kept local so
|
|
29
|
+
# CI + published builds resolve crucible-forge from PyPI.
|
|
30
|
+
uv.toml
|
|
31
|
+
|
|
32
|
+
# Node (only used by tools/gen_*_golden.mjs to regenerate golden fixtures)
|
|
33
|
+
node_modules/
|
|
34
|
+
|
|
35
|
+
# Editor / OS
|
|
36
|
+
.DS_Store
|
|
37
|
+
.idea/
|
|
38
|
+
.vscode/
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `specsmither-lifecycle` are documented here.
|
|
4
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/); this project
|
|
5
|
+
adheres to [Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## 0.1.0
|
|
8
|
+
|
|
9
|
+
First release — the pure planning-lifecycle core, extracted from the `specsmither`
|
|
10
|
+
product into its own publishable distribution with **no persistence and no UI/server
|
|
11
|
+
dependency** (no SQLAlchemy, no Textual, no MCP). A host embeds the planning state
|
|
12
|
+
machine in-process and provides its own persistence through the `WritePlan` seam.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Pure verb surface** — `start_planning_session`, `action_planning_session`,
|
|
17
|
+
`complete_planning_session`, `inspect_planning_session`, and the handover verbs
|
|
18
|
+
(`approve_handover` / `reject_handover` / `reject_handover_with_feedback`). Each is
|
|
19
|
+
a pure `(payload, ports) -> {response, WritePlan}` function: it reads state through
|
|
20
|
+
injected ports and returns the mutation as a `WritePlan` — it performs no I/O.
|
|
21
|
+
- **`LifecyclePorts`** — the injection contract: the `PlanningSessionStore` /
|
|
22
|
+
`SpecStore` / `ConfigStore` read ports, the `Validator` (crucible), the pure
|
|
23
|
+
operations projector, and the optional `persist_write_plan` / `clock` /
|
|
24
|
+
`id_generator`. The host implements the stores over its own database.
|
|
25
|
+
- **`WritePlan` data contract** (`lifecycle.write_plan_types`) — an ordered list of
|
|
26
|
+
serializable item kinds (`specMutation`, `sessionUpdate`, `actionAppend`,
|
|
27
|
+
score/transition datapoints, …). Any executor — the product's SQLite one or an
|
|
28
|
+
external Postgres one — consumes it as plain data.
|
|
29
|
+
- **`PlanningSessionRecord`** — a pure, DB-free frozen record for the session state
|
|
30
|
+
the verbs read/return (replaces the ORM row on the verb boundary).
|
|
31
|
+
- **In-memory operations projector** — computes post-mutation state for the
|
|
32
|
+
validator/gate without touching a database.
|
|
33
|
+
- **Phase-gate evaluator + guidance composer + prechecks** — the deterministic gate
|
|
34
|
+
and the agent-facing guidance, driven entirely by `crucible.validate`.
|
|
35
|
+
|
|
36
|
+
### Dependencies
|
|
37
|
+
|
|
38
|
+
`crucible-forge`, `pydantic`, `python-ulid`, `pyyaml` only. This distribution shares
|
|
39
|
+
the `specsmither` PEP 420 namespace with the `specsmither` product distribution; both
|
|
40
|
+
build and publish independently from the same repository.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: specsmither-lifecycle
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: The PURE planning-lifecycle core of SpecSmither — the crucible-gated verb surface (start/action/complete/inspect + handovers), the in-memory operations projector, the WritePlan data contract, and the domain records. No SQLAlchemy, no Textual, no MCP.
|
|
5
|
+
Project-URL: Homepage, https://github.com/blacksmithers/specsmither
|
|
6
|
+
Project-URL: Repository, https://github.com/blacksmithers/specsmither
|
|
7
|
+
Project-URL: Issues, https://github.com/blacksmithers/specsmither/issues
|
|
8
|
+
Author-email: Gabriel Augusto Gonçalves <gab.augustog@gmail.com>
|
|
9
|
+
License: Apache-2.0
|
|
10
|
+
Keywords: crucible,lifecycle,planning,spec,specforge,specsmither
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: crucible-forge>=0.2.0
|
|
20
|
+
Requires-Dist: pydantic>=2.6
|
|
21
|
+
Requires-Dist: python-ulid>=2.0
|
|
22
|
+
Requires-Dist: pyyaml>=6.0
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# specsmither-lifecycle
|
|
26
|
+
|
|
27
|
+
The **pure** planning-lifecycle core of [SpecSmither](https://github.com/blacksmithers/specsmither).
|
|
28
|
+
|
|
29
|
+
This distribution contributes the `specsmither.lifecycle`, `specsmither.domain`, and
|
|
30
|
+
`specsmither.ids` modules to the shared `specsmither` PEP 420 namespace. It is the
|
|
31
|
+
crucible-gated verb surface — `start` / `action` / `complete` / `inspect` plus the
|
|
32
|
+
handover verbs — together with the in-memory operations projector, the `WritePlan`
|
|
33
|
+
data contract, and the domain records/enums.
|
|
34
|
+
|
|
35
|
+
It is deliberately **dependency-light**: `crucible-forge`, `pydantic`, `python-ulid`,
|
|
36
|
+
and `pyyaml` only. It pulls in **no** SQLAlchemy, Textual, or MCP — those live in the
|
|
37
|
+
`specsmither` product distribution, which depends on this package and wires it to a
|
|
38
|
+
concrete SQLite store, TUI, and MCP server.
|
|
39
|
+
|
|
40
|
+
The verb surface satisfies a pure `(payload, ports) -> {response, WritePlan}` contract:
|
|
41
|
+
a host embeds it by providing the `LifecyclePorts` seam (stores, validator, operations
|
|
42
|
+
projector, clock, id generator) and consuming the returned `WritePlan`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# specsmither-lifecycle
|
|
2
|
+
|
|
3
|
+
The **pure** planning-lifecycle core of [SpecSmither](https://github.com/blacksmithers/specsmither).
|
|
4
|
+
|
|
5
|
+
This distribution contributes the `specsmither.lifecycle`, `specsmither.domain`, and
|
|
6
|
+
`specsmither.ids` modules to the shared `specsmither` PEP 420 namespace. It is the
|
|
7
|
+
crucible-gated verb surface — `start` / `action` / `complete` / `inspect` plus the
|
|
8
|
+
handover verbs — together with the in-memory operations projector, the `WritePlan`
|
|
9
|
+
data contract, and the domain records/enums.
|
|
10
|
+
|
|
11
|
+
It is deliberately **dependency-light**: `crucible-forge`, `pydantic`, `python-ulid`,
|
|
12
|
+
and `pyyaml` only. It pulls in **no** SQLAlchemy, Textual, or MCP — those live in the
|
|
13
|
+
`specsmither` product distribution, which depends on this package and wires it to a
|
|
14
|
+
concrete SQLite store, TUI, and MCP server.
|
|
15
|
+
|
|
16
|
+
The verb surface satisfies a pure `(payload, ports) -> {response, WritePlan}` contract:
|
|
17
|
+
a host embeds it by providing the `LifecyclePorts` seam (stores, validator, operations
|
|
18
|
+
projector, clock, id generator) and consuming the returned `WritePlan`.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "specsmither-lifecycle"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "The PURE planning-lifecycle core of SpecSmither — the crucible-gated verb surface (start/action/complete/inspect + handovers), the in-memory operations projector, the WritePlan data contract, and the domain records. No SQLAlchemy, no Textual, no MCP."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
authors = [{ name = "Gabriel Augusto Gonçalves", email = "gab.augustog@gmail.com" }]
|
|
13
|
+
keywords = ["spec", "specforge", "specsmither", "planning", "lifecycle", "crucible"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: Apache Software License",
|
|
18
|
+
"Programming Language :: Python :: 3.11",
|
|
19
|
+
"Programming Language :: Python :: 3.12",
|
|
20
|
+
"Programming Language :: Python :: 3.13",
|
|
21
|
+
"Typing :: Typed",
|
|
22
|
+
]
|
|
23
|
+
# The PURE core deps ONLY — the whole point of the split. NO sqlalchemy/textual/mcp.
|
|
24
|
+
dependencies = [
|
|
25
|
+
"crucible-forge>=0.2.0",
|
|
26
|
+
"pydantic>=2.6",
|
|
27
|
+
"python-ulid>=2.0",
|
|
28
|
+
"pyyaml>=6.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Homepage = "https://github.com/blacksmithers/specsmither"
|
|
33
|
+
Repository = "https://github.com/blacksmithers/specsmither"
|
|
34
|
+
Issues = "https://github.com/blacksmithers/specsmither/issues"
|
|
35
|
+
|
|
36
|
+
# PEP 420 namespace package: this dist contributes ``specsmither.lifecycle`` /
|
|
37
|
+
# ``specsmither.domain`` / ``specsmither.ids`` to the shared ``specsmither`` namespace
|
|
38
|
+
# (there is intentionally NO src/specsmither/__init__.py). The product dist
|
|
39
|
+
# ``specsmither`` contributes the rest of the namespace.
|
|
40
|
+
[tool.hatch.build.targets.wheel]
|
|
41
|
+
packages = ["src/specsmither"]
|
|
42
|
+
|
|
43
|
+
[tool.hatch.build.targets.sdist]
|
|
44
|
+
include = ["src/specsmither", "README.md", "CHANGELOG.md"]
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"""Domain layer: enums, status transitions, and runtime DB-row records.
|
|
2
|
+
|
|
3
|
+
Pure (no SQLAlchemy, no I/O). Defines the type vocabulary the whole engine
|
|
4
|
+
shares. ``records.py`` rebuilds crucible's ``Specification`` shape from DB rows
|
|
5
|
+
(``SpecFull``) so the planning gate can score a persisted spec.
|
|
6
|
+
"""
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"""Runtime / lifecycle / status enum vocabulary for SpecSmither.
|
|
2
|
+
|
|
3
|
+
These are the enums that crucible does NOT provide. The OpenSpec *authoring*
|
|
4
|
+
vocabulary (TicketType, Complexity, EpicCategory, TestType, …) is the single
|
|
5
|
+
source of truth in ``crucible.models.enums`` and is reused from there — it is
|
|
6
|
+
deliberately NOT redefined in this module.
|
|
7
|
+
|
|
8
|
+
Ground truth (ported verbatim so values round-trip with the TS/JSON wire):
|
|
9
|
+
- ``session-types/src/runtime/enums.ts`` (lifecycle / planning / cross-val vocab)
|
|
10
|
+
- ``api-types/src/runtime/status.ts`` (the 4-value ticket status surface)
|
|
11
|
+
- ``api-types/src/runtime/ticket-record.ts`` (ticket file-change ``kind``)
|
|
12
|
+
|
|
13
|
+
All members are :class:`enum.StrEnum`, so a member compares equal to and is
|
|
14
|
+
usable anywhere its verbatim string value is expected.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from enum import StrEnum
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"ActorType",
|
|
23
|
+
"ActualAction",
|
|
24
|
+
"DatapointTrigger",
|
|
25
|
+
"EpicStatus",
|
|
26
|
+
"ExpectedAction",
|
|
27
|
+
"FieldState",
|
|
28
|
+
"FileChangeKind",
|
|
29
|
+
"FileChangeStatus",
|
|
30
|
+
"FindingCategory",
|
|
31
|
+
"GateResult",
|
|
32
|
+
"GuidanceVariant",
|
|
33
|
+
"JustificationApproved",
|
|
34
|
+
"Outcome",
|
|
35
|
+
"PlanningPhase",
|
|
36
|
+
"PlanningSessionStatus",
|
|
37
|
+
"SpecStatus",
|
|
38
|
+
"TicketStatus",
|
|
39
|
+
"TransitionTrigger",
|
|
40
|
+
"WorkSessionStatus",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class TicketStatus(StrEnum):
|
|
45
|
+
"""Canonical 4-value ticket status (api-types ``TICKET_STATUSES``).
|
|
46
|
+
|
|
47
|
+
"Blocked" is not a status — it is signalled via ``block_reason`` on a
|
|
48
|
+
``pending`` ticket.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
PENDING = "pending"
|
|
52
|
+
READY = "ready"
|
|
53
|
+
ACTIVE = "active"
|
|
54
|
+
DONE = "done"
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class SpecStatus(StrEnum):
|
|
58
|
+
"""Spec lifecycle (session-types ``SPEC_STATUSES``) — all 8 values verbatim.
|
|
59
|
+
|
|
60
|
+
SpecSmither has NO review lifecycle, so ``ready_for_review`` / ``in_review``
|
|
61
|
+
/ ``reviewed`` are UNREACHABLE here. They are kept because the M0 CRUD freeze
|
|
62
|
+
guards (#18) reference them: ``reviewed`` is treated as read-only and
|
|
63
|
+
``in_review`` blocks create. Do not drop them.
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
DRAFT = "draft"
|
|
67
|
+
PLANNING = "planning"
|
|
68
|
+
READY = "ready"
|
|
69
|
+
IN_PROGRESS = "in_progress"
|
|
70
|
+
# Unreachable in SpecSmither (no review lifecycle) — retained for the
|
|
71
|
+
# CRUD-freeze guards (#18): `reviewed` = read-only, `in_review` = blocks create.
|
|
72
|
+
READY_FOR_REVIEW = "ready_for_review"
|
|
73
|
+
IN_REVIEW = "in_review"
|
|
74
|
+
REVIEWED = "reviewed"
|
|
75
|
+
DONE = "done"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class PlanningSessionStatus(StrEnum):
|
|
79
|
+
"""Planning-session status (session-types ``PLANNING_SESSION_STATUSES``)."""
|
|
80
|
+
|
|
81
|
+
ACTIVE = "active"
|
|
82
|
+
AWAITING_HUMAN_REVIEW = "awaiting_human_review"
|
|
83
|
+
CLOSED = "closed"
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
class WorkSessionStatus(StrEnum):
|
|
87
|
+
"""Work-session status (session-types ``WORK_SESSION_STATUSES``)."""
|
|
88
|
+
|
|
89
|
+
ACTIVE = "active"
|
|
90
|
+
COMPLETED = "completed"
|
|
91
|
+
CLOSED = "closed"
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class PlanningPhase(StrEnum):
|
|
95
|
+
"""Planning phase machine (session-types ``PLANNING_PHASES``)."""
|
|
96
|
+
|
|
97
|
+
PLANNING_SPEC = "planning_spec"
|
|
98
|
+
EPIC_DECOMPOSITION = "epic_decomposition"
|
|
99
|
+
EPIC_EXPANSION = "epic_expansion"
|
|
100
|
+
TICKET_DECOMPOSITION = "ticket_decomposition"
|
|
101
|
+
TICKET_EXPANSION = "ticket_expansion"
|
|
102
|
+
CROSS_VALIDATION = "cross_validation"
|
|
103
|
+
PLANNED = "planned"
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class TransitionTrigger(StrEnum):
|
|
107
|
+
"""Phase-transition trigger (session-types ``TRANSITION_TRIGGERS``)."""
|
|
108
|
+
|
|
109
|
+
AUTO_INITIAL = "auto_initial"
|
|
110
|
+
AI_AGENT = "ai_agent"
|
|
111
|
+
HUMAN_APPROVE = "human_approve"
|
|
112
|
+
HUMAN_COMPLETE = "human_complete"
|
|
113
|
+
HUMAN_REJECT_WITH_FEEDBACK = "human_reject_with_feedback"
|
|
114
|
+
HUMAN_REJECT_NO_FEEDBACK = "human_reject_no_feedback"
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class Outcome(StrEnum):
|
|
118
|
+
"""Audited action outcome (session-types ``OUTCOMES``)."""
|
|
119
|
+
|
|
120
|
+
SUCCESS = "success"
|
|
121
|
+
DENIED = "denied"
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class DatapointTrigger(StrEnum):
|
|
125
|
+
"""Score-datapoint trigger (session-types ``DATAPOINT_TRIGGERS``)."""
|
|
126
|
+
|
|
127
|
+
CREATED = "created"
|
|
128
|
+
METADATA_UPDATED = "metadata_updated"
|
|
129
|
+
EPIC_FIELD_UPDATED = "epic_field_updated"
|
|
130
|
+
TICKET_FIELD_UPDATED = "ticket_field_updated"
|
|
131
|
+
BLUEPRINT_FIELD_UPDATED = "blueprint_field_updated"
|
|
132
|
+
DEPENDENCY_ADDED = "dependency_added"
|
|
133
|
+
DEPENDENCY_REMOVED = "dependency_removed"
|
|
134
|
+
BLUEPRINT_LINKED = "blueprint_linked"
|
|
135
|
+
BLUEPRINT_UNLINKED = "blueprint_unlinked"
|
|
136
|
+
CROSS_VAL_RECOMPUTE = "cross_val_recompute"
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class GuidanceVariant(StrEnum):
|
|
140
|
+
"""Guidance-message variant (session-types ``GUIDANCE_VARIANTS``).
|
|
141
|
+
|
|
142
|
+
Includes the six M6.6 additions consumed exclusively by
|
|
143
|
+
``get_planning_status``.
|
|
144
|
+
"""
|
|
145
|
+
|
|
146
|
+
DENIED = "denied"
|
|
147
|
+
GATE_FAILED = "gate_failed"
|
|
148
|
+
GATE_PASSED = "gate_passed"
|
|
149
|
+
HUMAN_HANDOVER = "human_handover"
|
|
150
|
+
HUMAN_FEEDBACK = "human_feedback"
|
|
151
|
+
PHASE_ADVANCE = "phase_advance"
|
|
152
|
+
PHASE_ROLLBACK = "phase_rollback"
|
|
153
|
+
PHASE_COMPLETE = "phase_complete"
|
|
154
|
+
# M6.6 additions.
|
|
155
|
+
PHASE_STATUS_REPORT = "phase_status_report"
|
|
156
|
+
AWAITING_HUMAN_REVIEW_HANDOVER = "awaiting_human_review_handover"
|
|
157
|
+
HUMAN_FEEDBACK_RECEIVED = "human_feedback_received"
|
|
158
|
+
HUMAN_REJECTED_NO_FEEDBACK = "human_rejected_no_feedback"
|
|
159
|
+
PHASE_ADVANCED_AFTER_APPROVE = "phase_advanced_after_approve"
|
|
160
|
+
SESSION_CLOSED = "session_closed"
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
class FindingCategory(StrEnum):
|
|
164
|
+
"""Cross-validation finding category (session-types ``FINDING_CATEGORIES``)."""
|
|
165
|
+
|
|
166
|
+
RUBRIC = "rubric"
|
|
167
|
+
COUNT = "count"
|
|
168
|
+
CROSS_CUT = "cross-cut"
|
|
169
|
+
CASCADE = "cascade"
|
|
170
|
+
CROSS_VALIDATION = "cross-validation"
|
|
171
|
+
SCHEMA = "schema"
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class GateResult(StrEnum):
|
|
175
|
+
"""Gate result (session-types ``GATE_RESULTS``)."""
|
|
176
|
+
|
|
177
|
+
PASS = "pass"
|
|
178
|
+
FAIL = "fail"
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class FieldState(StrEnum):
|
|
182
|
+
"""Field-presence state (session-types ``FIELD_STATES``)."""
|
|
183
|
+
|
|
184
|
+
EMPTY = "empty"
|
|
185
|
+
PARTIAL = "partial"
|
|
186
|
+
FILLED = "filled"
|
|
187
|
+
NA = "na"
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class ExpectedAction(StrEnum):
|
|
191
|
+
"""Planned file action (session-types ``EXPECTED_ACTIONS``)."""
|
|
192
|
+
|
|
193
|
+
CREATE = "create"
|
|
194
|
+
MODIFY = "modify"
|
|
195
|
+
DELETE = "delete"
|
|
196
|
+
REFERENCE = "reference"
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class ActualAction(StrEnum):
|
|
200
|
+
"""Observed file action (session-types ``ACTUAL_ACTIONS``)."""
|
|
201
|
+
|
|
202
|
+
CREATED = "created"
|
|
203
|
+
MODIFIED = "modified"
|
|
204
|
+
DELETED = "deleted"
|
|
205
|
+
REFERENCED = "referenced"
|
|
206
|
+
ABSENT = "absent"
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
class FileChangeStatus(StrEnum):
|
|
210
|
+
"""Expected-vs-actual reconciliation (session-types ``FILE_CHANGE_STATUSES``)."""
|
|
211
|
+
|
|
212
|
+
MATCHED = "matched"
|
|
213
|
+
MISSING = "missing"
|
|
214
|
+
MISMATCHED = "mismatched"
|
|
215
|
+
EXTRA = "extra"
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class JustificationApproved(StrEnum):
|
|
219
|
+
"""Justification approval state (session-types ``JUSTIFICATION_APPROVED_VALUES``)."""
|
|
220
|
+
|
|
221
|
+
PENDING = "pending"
|
|
222
|
+
APPROVED = "approved"
|
|
223
|
+
REJECTED = "rejected"
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
class FileChangeKind(StrEnum):
|
|
227
|
+
"""Ticket PLAN-side file-change kind (api-types ``TicketFileChangeKind``).
|
|
228
|
+
|
|
229
|
+
Drives ``ticket_file_changes.kind`` (schema §3). Distinct from the work-side
|
|
230
|
+
:class:`ExpectedAction` / :class:`ActualAction` vocabulary — these are the
|
|
231
|
+
``toBeX`` camelCase literals from ``api-types/runtime/ticket-record.ts``.
|
|
232
|
+
"""
|
|
233
|
+
|
|
234
|
+
TO_BE_CREATED = "toBeCreated"
|
|
235
|
+
TO_BE_MODIFIED = "toBeModified"
|
|
236
|
+
TO_BE_DELETED = "toBeDeleted"
|
|
237
|
+
TO_BE_REFERENCED = "toBeReferenced"
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class EpicStatus(StrEnum):
|
|
241
|
+
"""Epic lifecycle status.
|
|
242
|
+
|
|
243
|
+
A DISTINCT enum exists in the TS (``types/src/schema/epic.ts`` →
|
|
244
|
+
``'todo' | 'in_progress' | 'completed'``), and the planning verbs that
|
|
245
|
+
SpecSmither ports create epics with ``status: 'todo'`` and explicitly comment
|
|
246
|
+
that this is "a constrained EpicStatus enum (todo|in_progress|completed)"
|
|
247
|
+
(``lifecycle/.../action-planning-session.ts``). So epics do NOT share the
|
|
248
|
+
ticket vocabulary — these three values are ported verbatim.
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
TODO = "todo"
|
|
252
|
+
IN_PROGRESS = "in_progress"
|
|
253
|
+
COMPLETED = "completed"
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class ActorType(StrEnum):
|
|
257
|
+
"""Audit actor identity (§6 actor model).
|
|
258
|
+
|
|
259
|
+
Confirmed against the TS: ``actor: 'agent' | 'human'`` throughout the
|
|
260
|
+
planning verbs / ``action-builder.ts``. There is no named ``ACTOR_TYPES``
|
|
261
|
+
array — the union is inlined — so the two members are defined here. MCP tool
|
|
262
|
+
calls resolve to ``agent``; explicit CLI handover/approve commands to ``human``.
|
|
263
|
+
"""
|
|
264
|
+
|
|
265
|
+
AGENT = "agent"
|
|
266
|
+
HUMAN = "human"
|