specsmither-lifecycle 0.1.0__py3-none-any.whl
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/domain/__init__.py +6 -0
- specsmither/domain/enums.py +266 -0
- specsmither/domain/records.py +489 -0
- specsmither/domain/status.py +102 -0
- specsmither/ids.py +53 -0
- specsmither/lifecycle/__init__.py +6 -0
- specsmither/lifecycle/audit/__init__.py +26 -0
- specsmither/lifecycle/audit/action_builder.py +219 -0
- specsmither/lifecycle/audit/operation_mapper.py +128 -0
- specsmither/lifecycle/audit/transition_builder.py +69 -0
- specsmither/lifecycle/config.py +134 -0
- specsmither/lifecycle/dispatch.py +100 -0
- specsmither/lifecycle/gate.py +418 -0
- specsmither/lifecycle/guidance/__init__.py +9 -0
- specsmither/lifecycle/guidance/catalogs/cross_validation.yaml +87 -0
- specsmither/lifecycle/guidance/catalogs/epic_decomposition.yaml +177 -0
- specsmither/lifecycle/guidance/catalogs/epic_expansion.yaml +197 -0
- specsmither/lifecycle/guidance/catalogs/planning_spec.yaml +247 -0
- specsmither/lifecycle/guidance/catalogs/ticket_decomposition.yaml +137 -0
- specsmither/lifecycle/guidance/catalogs/ticket_expansion.yaml +221 -0
- specsmither/lifecycle/guidance/compose.py +624 -0
- specsmither/lifecycle/guidance/field_instructions.py +275 -0
- specsmither/lifecycle/guidance/types.py +130 -0
- specsmither/lifecycle/operations_projector.py +631 -0
- specsmither/lifecycle/operations_registry.py +471 -0
- specsmither/lifecycle/ports.py +383 -0
- specsmither/lifecycle/prechecks/__init__.py +82 -0
- specsmither/lifecycle/prechecks/blueprint_epic_ratio.py +70 -0
- specsmither/lifecycle/prechecks/blueprint_link_refs_exist.py +68 -0
- specsmither/lifecycle/prechecks/cascade_rules.py +70 -0
- specsmither/lifecycle/prechecks/content_shape_valid.py +120 -0
- specsmither/lifecycle/prechecks/count_bounds.py +134 -0
- specsmither/lifecycle/prechecks/cross_cut_references.py +62 -0
- specsmither/lifecycle/prechecks/dependencies_batch.py +223 -0
- specsmither/lifecycle/prechecks/entity_refs_exist.py +96 -0
- specsmither/lifecycle/prechecks/enum_field_guards.py +112 -0
- specsmither/lifecycle/prechecks/field_shape_soft_deny.py +73 -0
- specsmither/lifecycle/prechecks/gate_currently_passing.py +154 -0
- specsmither/lifecycle/prechecks/operation_allowed.py +110 -0
- specsmither/lifecycle/prechecks/result.py +75 -0
- specsmither/lifecycle/prechecks/schema_validate.py +173 -0
- specsmither/lifecycle/prechecks/spec_status_check.py +89 -0
- specsmither/lifecycle/session_record.py +82 -0
- specsmither/lifecycle/state_machine.py +90 -0
- specsmither/lifecycle/verbs/__init__.py +13 -0
- specsmither/lifecycle/verbs/_common.py +74 -0
- specsmither/lifecycle/verbs/action.py +472 -0
- specsmither/lifecycle/verbs/approve.py +191 -0
- specsmither/lifecycle/verbs/complete.py +215 -0
- specsmither/lifecycle/verbs/inspect.py +106 -0
- specsmither/lifecycle/verbs/reject.py +88 -0
- specsmither/lifecycle/verbs/reject_with_feedback.py +102 -0
- specsmither/lifecycle/verbs/start.py +271 -0
- specsmither/lifecycle/verbs/support.py +208 -0
- specsmither/lifecycle/verbs/types.py +118 -0
- specsmither/lifecycle/write_plan.py +1146 -0
- specsmither/lifecycle/write_plan_types.py +225 -0
- specsmither/py.typed +0 -0
- specsmither_lifecycle-0.1.0.dist-info/METADATA +42 -0
- specsmither_lifecycle-0.1.0.dist-info/RECORD +61 -0
- specsmither_lifecycle-0.1.0.dist-info/WHEEL +4 -0
|
@@ -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"
|