its-magic 0.1.3-1 → 0.1.3-2
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.
- package/installer.ps1 +8 -0
- package/installer.py +8 -0
- package/installer.sh +1 -0
- package/package.json +1 -1
- package/template/.cursor/commands/auto.md +90 -0
- package/template/.cursor/commands/execute.md +26 -0
- package/template/.cursor/commands/refresh-context.md +32 -0
- package/template/.cursor/commands/sovereign-critic.md +104 -0
- package/template/.cursor/rules/sovereign-role-manifest.mdc.example +27 -0
- package/template/.cursor/scratchpad.md +141 -0
- package/template/.cursor/sovereign-role-manifest.yaml.example +53 -0
- package/template/decisions/DEC-0104.md +279 -0
- package/template/decisions/DEC-0105.md +231 -0
- package/template/decisions/DEC-0107.md +246 -0
- package/template/docs/engineering/architecture.md +78 -0
- package/template/docs/engineering/auto-orchestration-reference.md +7 -0
- package/template/docs/engineering/context/installer-owned-paths.manifest +8 -0
- package/template/docs/engineering/reason_codes.md +411 -0
- package/template/docs/engineering/runbook.md +922 -0
- package/template/docs/engineering/sovereign-memory/.gitkeep +0 -0
- package/template/docs/engineering/sovereign-memory/retrospectives/.gitkeep +0 -0
- package/template/handoffs/sovereign_decisions/.gitkeep +0 -0
- package/template/handoffs/sovereign_deferrals/.gitkeep +0 -0
- package/template/handoffs/sovereign_role_reviews.jsonl +0 -0
- package/template/scripts/__pycache__/decision_ledger_lib.cpython-312.pyc +0 -0
- package/template/scripts/check_intake_template_parity.py +119 -0
- package/template/scripts/decision_ledger_lib.py +732 -0
- package/template/scripts/ledger_validate.py +153 -0
- package/template/scripts/parallel_dev_arbiter.py +923 -0
- package/template/scripts/release_trigger_adapters.py +843 -0
- package/template/scripts/self_healing_deploy_lib.py +463 -0
- package/template/scripts/self_healing_deploy_validate.py +78 -0
- package/template/scripts/sovereign_convergence_lib.py +994 -0
- package/template/scripts/sovereign_convergence_validate.py +206 -0
- package/template/scripts/sovereign_critic_lib.py +629 -0
- package/template/scripts/sovereign_critic_validate.py +131 -0
- package/template/scripts/sovereign_loop_lib.py +828 -0
- package/template/scripts/sovereign_loop_validate.py +122 -0
- package/template/scripts/sovereign_memory_lib.py +869 -0
- package/template/scripts/sovereign_memory_validate.py +153 -0
- package/template/scripts/sovereign_role_manifest_lib.py +547 -0
- package/template/scripts/sovereign_role_manifest_validate.py +105 -0
- package/template/tests/us0108_contract_test.py +207 -0
- package/template/tests/us0109_contract_test.py +209 -0
- package/template/tests/us0109_us0110_compose_test.py +34 -0
- package/template/tests/us0111_contract_test.py +345 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# DEC-0107: Sovereign Loop Mode (US-0107)
|
|
2
|
+
|
|
3
|
+
- **Date**: 2026-06-29
|
|
4
|
+
- **Status**: Accepted
|
|
5
|
+
- **Story**: `US-0107`
|
|
6
|
+
- **Composes on**: **US-0088** (quiet mode), **US-0092** (full-autonomy outer driver), **US-0095** (native-chain segments), **US-0044** (backlog drain), **US-0103** (decision ledger), **US-0105** (sovereign memory), **US-0110** (goal convergence) — **do not amend**; US-0107 **layers** orchestration only
|
|
7
|
+
- **Related**: `R-0094` (research anchor), **US-0109** (deploy smoke — downstream deferral writer), **US-0069** (spawn-only), **US-0045** (status authority), **US-0017** (template parity)
|
|
8
|
+
- **Supersedes**: none
|
|
9
|
+
- **Default-off**: `AUTO_SOVEREIGN=0` — zero overhead when off
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
Project-level autonomous delivery orchestration for the sovereign-loop batch. When operators enable **`AUTO_SOVEREIGN`**, the outer driver owns **deferral register**, **drain-generate** (PO proposals when backlog empty but not converged), **notification dispatch** on terminal events, and **convergence hooks** via **US-0110**. **US-0088 / US-0092 / US-0095 / US-0044 / US-0103 / US-0105 / US-0110 are UNCHANGED** — US-0107 adds scratchpad keys, JSONL deferral register, loop lib API, sidecar run-state, and compose hooks only.
|
|
14
|
+
|
|
15
|
+
Research basis: `R-0094` Q1–Q7 closed.
|
|
16
|
+
|
|
17
|
+
## Decision
|
|
18
|
+
|
|
19
|
+
### §1 — Scratchpad keys + goal-mode coupling (AC-1)
|
|
20
|
+
|
|
21
|
+
| Key | Values | Default | Notes |
|
|
22
|
+
|-----|--------|---------|-------|
|
|
23
|
+
| **`AUTO_SOVEREIGN`** | **`0`** \| **`1`** | **`0`** | When `0`, zero overhead — no deferral reads/writes, no advance, no notifications. |
|
|
24
|
+
| **`AUTO_SOVEREIGN_DEFERRAL_MAX`** | int ≥ **1** | **`50`** | Max open deferral rows; append rejected at cap. |
|
|
25
|
+
| **`AUTO_SOVEREIGN_DRAIN_GENERATE_MAX`** | int ≥ **0** | **`3`** | Max drain-generate PO iterations per `orchestrator_run_id`. |
|
|
26
|
+
| **`AUTO_SOVEREIGN_DEFERRAL_POLICY`** | **`stop`** \| **`skip`** \| **`resolve_first`** | **`resolve_first`** | How open deferrals gate advance. |
|
|
27
|
+
| **`SOVEREIGN_NOTIFY_TARGET`** | **`off`** \| **`ntfy`** \| **`email`** \| **`hook`** | **`off`** | Notification adapter selection. |
|
|
28
|
+
| **`SOVEREIGN_NOTIFY_NTFY_TOPIC`** | string | *(empty)* | ntfy topic — **local-only** value. |
|
|
29
|
+
| **`SOVEREIGN_NOTIFY_NTFY_BASE`** | URL | *(empty)* | Optional ntfy base URL override — **local-only**. |
|
|
30
|
+
| **`SOVEREIGN_NOTIFY_HOOK_URL`** | URL | *(empty)* | Webhook POST target — **local-only**. |
|
|
31
|
+
| **`SOVEREIGN_NOTIFY_EMAIL_TO`** | email | *(empty)* | Email v1 deferred — **local-only** name. |
|
|
32
|
+
|
|
33
|
+
Published in **`.cursor/scratchpad.md`** (+ **`template/.cursor/scratchpad.md`** byte-parity per **US-0017**). Config key **names** in committed scratchpad; **values** in `.cursor/scratchpad.local.md` or env vars only.
|
|
34
|
+
|
|
35
|
+
**Goal-mode coupling (fail-closed)**: `is_sovereign_loop_enabled(scratchpad)` requires **`AUTO_SOVEREIGN=1` AND `SOVEREIGN_GOAL_MODE=goal_convergence`** (via `is_goal_convergence_enabled()` from **US-0110**). When sovereign flag on but goal mode `phase_driven` → `advance_sovereign_loop` returns `action=blocked`, `reason_code=SOVEREIGN_LOOP_GOAL_MODE_REQUIRED` **before** convergence eval.
|
|
36
|
+
|
|
37
|
+
**Rejected**: auto-enable `goal_convergence` when `AUTO_SOVEREIGN=1` — silently changes terminal semantics without operator intent (**R1**).
|
|
38
|
+
**Rejected**: sovereign loop without goal mode — undefined terminal condition.
|
|
39
|
+
|
|
40
|
+
**Operator recipe**: set both `AUTO_SOVEREIGN=1` and `SOVEREIGN_GOAL_MODE=goal_convergence` in `.cursor/scratchpad.local.md`.
|
|
41
|
+
|
|
42
|
+
### §2 — Deferral register JSONL v1 (AC-2)
|
|
43
|
+
|
|
44
|
+
**Path**: **`handoffs/sovereign_deferrals.jsonl`** (+ template **`handoffs/sovereign_deferrals/`** `.gitkeep` only).
|
|
45
|
+
|
|
46
|
+
**Bootstrap**: **create-on-first-write**; ship **`.gitkeep`** — no empty tracked JSONL seed.
|
|
47
|
+
|
|
48
|
+
**Required fields** (each JSONL line):
|
|
49
|
+
|
|
50
|
+
| Field | Type | Notes |
|
|
51
|
+
|-------|------|-------|
|
|
52
|
+
| **`schema_version`** | int | **`1`** |
|
|
53
|
+
| **`deferral_id`** | UUIDv4 | Stable id across lifecycle rows |
|
|
54
|
+
| **`ts`** | ISO 8601 UTC | Sortable timestamp |
|
|
55
|
+
| **`reason_code`** | string | Orchestrator reason (e.g. `DEPLOY_DEFERRED`, `BLOCK_RETRY_CAP_EXHAUSTED`) |
|
|
56
|
+
| **`work_item_kind`** | enum | **`story`** \| **`bug`** \| **`deploy`** \| **`block`** |
|
|
57
|
+
| **`work_item_ref`** | string | Max **128** chars — `US-xxxx`, `BUG-xxxx`, deploy target, phase token |
|
|
58
|
+
| **`state`** | enum | **`open`** \| **`resolved`** \| **`superseded`** |
|
|
59
|
+
| **`source_orchestrator_run_id`** | string | Non-empty provenance |
|
|
60
|
+
| **`remediation_hint`** | string | Non-empty, max **512** chars |
|
|
61
|
+
|
|
62
|
+
**Optional fields**: `blocked_by_phase` (canonical phase id), `retry_count` (int ≥ 0), `ledger_decision_id` (UUID — **US-0103** provenance only; no ledger schema change).
|
|
63
|
+
|
|
64
|
+
**Lifecycle (append-only)**: `append_deferral` writes `state=open`; `resolve_deferral(deferral_id)` appends new row with same `deferral_id`, `state=resolved`, fresh `ts`; supersede uses `state=superseded`. **Latest-state-wins** per `deferral_id` when computing open set.
|
|
65
|
+
|
|
66
|
+
**Open-row cap**: reject append when `len(list_open_deferrals()) >= AUTO_SOVEREIGN_DEFERRAL_MAX` → **`SOVEREIGN_DEFERRAL_CAP_EXCEEDED`**.
|
|
67
|
+
|
|
68
|
+
**Secret scan**: reject when `remediation_hint` or `work_item_ref` match secret heuristics (mirror **US-0103** / **US-0105**: `api_key=`, PEM, `sk-`, `ghp_`).
|
|
69
|
+
|
|
70
|
+
**Sidecar run-state**: **`handoffs/sovereign_loop_state.json`** v1 — per-`orchestrator_run_id` drain-generate iteration counter (not git-tracked content in template; schema documented only).
|
|
71
|
+
|
|
72
|
+
**Rejected**: in-place mutation of deferral rows (**rejected** — breaks audit trail).
|
|
73
|
+
**Rejected**: empty tracked JSONL seed (**rejected** — create-on-first-write).
|
|
74
|
+
|
|
75
|
+
### §3 — Validator CLI (AC-2, AC-7)
|
|
76
|
+
|
|
77
|
+
**Script**: **`scripts/sovereign_loop_validate.py`** (+ template mirror).
|
|
78
|
+
|
|
79
|
+
| Flag | Purpose |
|
|
80
|
+
|------|---------|
|
|
81
|
+
| **`--file`** | Validate single JSONL file |
|
|
82
|
+
| **`--repo`** | Validate repo deferrals path |
|
|
83
|
+
| **`--self-test`** | Contract self-test |
|
|
84
|
+
| **`--enforce`** | Fail-closed exit on first invalid line |
|
|
85
|
+
|
|
86
|
+
Exit **0/1/2** mirrors **DEC-0103** / **DEC-0105**. Success token: **`[SOVEREIGN_LOOP_VALIDATION_OK]`**.
|
|
87
|
+
|
|
88
|
+
Lib helper: `schema_check_deferral(entry) -> (bool, error|None)`.
|
|
89
|
+
|
|
90
|
+
### §4 — Helper library API (AC-3)
|
|
91
|
+
|
|
92
|
+
**Script**: **`scripts/sovereign_loop_lib.py`** (+ template mirror). Research stub ships schemas, gates, dataclasses + self-test (`[SOVEREIGN_LOOP_SELF_TEST_OK]`); advance/dispatch bodies finalized at execute tranche B.
|
|
93
|
+
|
|
94
|
+
**`SovereignLoopStepResult` v1** fields: `schema_version=1`, `action` ∈ {`noop`,`continue`,`defer`,`drain_generate`,`terminal_converged`,`terminal_timeout`,`terminal_cap`,`blocked`}, optional `reason_code`, optional `stop_reason` (native-chain breadcrumb), `orchestrator_run_id`, `evaluated_at` (ISO UTC), optional `deferral_id`, optional `drain_generate_bundle`, optional `notification_dispatched` (bool), optional `convergence` (embedded **US-0110** `ConvergenceResult.to_dict()` snapshot).
|
|
95
|
+
|
|
96
|
+
| Function | Purpose |
|
|
97
|
+
|----------|---------|
|
|
98
|
+
| **`is_sovereign_loop_enabled(scratchpad) -> bool`** | `AUTO_SOVEREIGN=1` **and** `is_goal_convergence_enabled(scratchpad)` |
|
|
99
|
+
| **`resolve_deferrals_path(repo_root) -> Path`** | `handoffs/sovereign_deferrals.jsonl` |
|
|
100
|
+
| **`schema_check_deferral(entry) -> (bool, error\|None)`** | v1 field validation + secret scan |
|
|
101
|
+
| **`list_open_deferrals(repo, *, scratchpad) -> (rows, reason\|None)`** | Latest-state-wins open rows; empty when disabled |
|
|
102
|
+
| **`append_deferral(repo, scratchpad, *, fields...) -> (deferral_id\|None, reason\|None)`** | Append-only + cap enforcement |
|
|
103
|
+
| **`resolve_deferral(repo, deferral_id, *, orchestrator_run_id) -> (ok, reason\|None)`** | Append resolved row |
|
|
104
|
+
| **`count_drain_generate_iterations(repo, orchestrator_run_id) -> int`** | Per-run counter from sidecar |
|
|
105
|
+
| **`advance_sovereign_loop(repo, scratchpad, *, orchestrator_run_id, iteration=None) -> SovereignLoopStepResult`** | Main orchestrator advance — §5 |
|
|
106
|
+
| **`build_drain_generate_spawn_inputs(repo, scratchpad, convergence) -> dict`** | Vision narrow-read + optional memory digest |
|
|
107
|
+
| **`dispatch_notification(scratchpad, event_type, payload) -> (ok, reason\|None)`** | Fail-open adapters — §7 |
|
|
108
|
+
| **`self_test() -> bool`** | **`[SOVEREIGN_LOOP_SELF_TEST_OK]`** |
|
|
109
|
+
|
|
110
|
+
### §5 — `advance_sovereign_loop` algorithm (AC-3)
|
|
111
|
+
|
|
112
|
+
1. If `AUTO_SOVEREIGN≠1` → `action=noop` (zero overhead; do not import convergence).
|
|
113
|
+
2. If `SOVEREIGN_GOAL_MODE≠goal_convergence` → `action=blocked`, `reason_code=SOVEREIGN_LOOP_GOAL_MODE_REQUIRED`.
|
|
114
|
+
3. `result = evaluate_convergence(repo, scratchpad, orchestrator_run_id=...)`.
|
|
115
|
+
4. If `result.converged` → `action=terminal_converged` + `dispatch_notification(convergence)` + sovereign terminal stop **`converged`**.
|
|
116
|
+
5. If `check_timeout(scratchpad, iteration)` → `action=terminal_timeout` + `write_partial_delivery_report` (**US-0110**) + notification.
|
|
117
|
+
6. Apply **`AUTO_SOVEREIGN_DEFERRAL_POLICY`**: `stop` → block advance when open deferrals; `skip` → informational only; `resolve_first` → block until open deferrals empty (default).
|
|
118
|
+
7. If backlog has OPEN stories → `action=continue` (delegate to native **US-0044** drain — no bypass).
|
|
119
|
+
8. If OPEN stories **0** and `not result.converged` and iterations `< AUTO_SOVEREIGN_DRAIN_GENERATE_MAX` → `action=drain_generate` + spawn bundle (§6).
|
|
120
|
+
9. Else cap/terminal paths → `SOVEREIGN_DRAIN_GENERATE_CAP` or deferral cap + notification.
|
|
121
|
+
|
|
122
|
+
**Sovereign terminal stops** (additive to **US-0088**/**US-0092** matrix): `converged`, `SOVEREIGN_GOAL_TIMEOUT`, `SOVEREIGN_DEFERRAL_CAP_EXCEEDED`, `SOVEREIGN_DRAIN_GENERATE_CAP` — do **not** replace `decision_gate`, `loop_max`, `security deny`, or `BLOCK_RETRY_CAP_EXHAUSTED`.
|
|
123
|
+
|
|
124
|
+
**`drain_terminated`**: set only on sovereign terminal stops — **not** on OPEN-story exhaustion alone (**R5**).
|
|
125
|
+
|
|
126
|
+
### §6 — Drain-generate contract (AC-4)
|
|
127
|
+
|
|
128
|
+
**Trigger** (all required): `is_sovereign_loop_enabled`, backlog OPEN story count **0**, `evaluate_convergence(...).converged=false`, drain-generate iterations `< AUTO_SOVEREIGN_DRAIN_GENERATE_MAX`, no blocking deferral policy conflict.
|
|
129
|
+
|
|
130
|
+
**Spawn surface**: **`/auto`** outer driver spawns fresh **PO** subagent (spawn-only per **US-0095** / **US-0069**) with ephemeral work item id `drain-gen-{orchestrator_run_id}-{iteration}` — **not** a backlog row until accepted.
|
|
131
|
+
|
|
132
|
+
**PO inputs** (`build_drain_generate_spawn_inputs`): narrow-read `docs/product/vision.md` (exclude Discovery/Intake note sections — same skip rules as **US-0110** goal derive); optional `sovereign_memory_digest` when **`SOVEREIGN_MEMORY=1`** via `build_injection_digest_block()` only; attach `unmet_conditions[]`, `blocked_by[]`, `goal_text` from convergence eval.
|
|
133
|
+
|
|
134
|
+
**`DrainGenerateCandidateBundle` v1** (ephemeral — **not persisted** pre-gate): `schema_version=1`, `orchestrator_run_id`, `iteration`, `generated_at`, `candidates[]` (max **3** per iteration) each with `candidate_id` (UUIDv4), `title` (max **120**), `summary` (max **512**), `ac_sketch` (string[], max **8** items × **256** chars), optional `plan_area_id`, `priority` (default **`P2`**), `provenance` ∈ {`vision`,`memory`,`both`}.
|
|
135
|
+
|
|
136
|
+
**Decision gate (mandatory per candidate)**: PO output → standard **`decision_gate`** in **`/auto`** — operator accept → **`/intake`** or controlled backlog append; reject → discard candidate. **Rejected**: auto-append without gate — violates **US-0092** hard gates (**R2**).
|
|
137
|
+
|
|
138
|
+
**Cap exhausted**: `SOVEREIGN_DRAIN_GENERATE_CAP` sovereign terminal + optional `dispatch_notification(drain_generate_cap)`.
|
|
139
|
+
|
|
140
|
+
### §7 — Notification adapters (AC-5)
|
|
141
|
+
|
|
142
|
+
**`SOVEREIGN_NOTIFY_TARGET`**: `off` (zero overhead) \| `ntfy` \| `hook` \| `email`.
|
|
143
|
+
|
|
144
|
+
**Event types**: `convergence`, `timeout`, `deferral_cap`, `drain_generate_cap`.
|
|
145
|
+
|
|
146
|
+
**Payload envelope v1**: `{schema_version, event_type, ts, orchestrator_run_id, reason_code, unmet_conditions[], blocked_by[], goal_progress}` where `goal_progress` embeds **US-0110** block when available.
|
|
147
|
+
|
|
148
|
+
**ntfy v1**: stdlib `urllib.request` POST plain-text body to `{SOVEREIGN_NOTIFY_NTFY_BASE or https://ntfy.sh}/{SOVEREIGN_NOTIFY_NTFY_TOPIC}`; headers `Title`, `Priority` (4 for cap/timeout, 3 for convergence), `Tags: sovereign,auto`; timeout **10s**.
|
|
149
|
+
|
|
150
|
+
**hook v1**: POST `application/json` to `SOVEREIGN_NOTIFY_HOOK_URL` with payload envelope; timeout **10s**.
|
|
151
|
+
|
|
152
|
+
**email v1**: **deferred** — `dispatch_notification` returns `(False, SOVEREIGN_NOTIFY_TARGET_INVALID)` with info log; runbook documents v1.1 SMTP stub. **Rejected**: stdlib SMTP in v1 (credential handling + deliverability risk).
|
|
153
|
+
|
|
154
|
+
**Fail-open**: any adapter exception → log **`SOVEREIGN_NOTIFY_DISPATCH_FAILED`**, return `(True, None)` — notification must not block loop.
|
|
155
|
+
|
|
156
|
+
**Secret handling (R4)**: topic/URL values local-only; never write into git-tracked handoffs or JSONL.
|
|
157
|
+
|
|
158
|
+
### §8 — US-0109 integration declaration (AC-6)
|
|
159
|
+
|
|
160
|
+
**US-0109** implements post-deploy smoke + bounded repair. On cap exhaustion writes **`DEPLOY_DEFERRED`** row to **`sovereign_deferrals.jsonl`** using §2 schema (`work_item_kind=deploy`). **US-0107** owns register schema, validator, read paths, and documents integration contract — **no** deploy smoke logic in US-0107 scope.
|
|
161
|
+
|
|
162
|
+
**`DEPLOY_DEFERRED`**: reserved reason_code for **US-0109** writer; non-blocking deferral row (not advance-block by itself unless policy applies).
|
|
163
|
+
|
|
164
|
+
### §9 — Reason code inventory (AC-8)
|
|
165
|
+
|
|
166
|
+
| Code | Blocking? | Surface |
|
|
167
|
+
|------|-----------|---------|
|
|
168
|
+
| **`SOVEREIGN_LOOP_DISABLED`** | no (info) | `AUTO_SOVEREIGN=0` zero overhead |
|
|
169
|
+
| **`SOVEREIGN_LOOP_GOAL_MODE_REQUIRED`** | yes | sovereign on without `goal_convergence` |
|
|
170
|
+
| **`SOVEREIGN_DEFERRAL_CAP_EXCEEDED`** | yes | append cap / sovereign terminal |
|
|
171
|
+
| **`SOVEREIGN_DEFERRAL_SCHEMA_INVALID`** | yes | validator / append |
|
|
172
|
+
| **`SOVEREIGN_DEFERRAL_APPEND_FAILED`** | yes | I/O |
|
|
173
|
+
| **`SOVEREIGN_DRAIN_GENERATE_CAP`** | yes | drain-generate iterations exhausted |
|
|
174
|
+
| **`SOVEREIGN_DRAIN_GENERATE_BLOCKED`** | yes | policy/deferral gate blocks spawn |
|
|
175
|
+
| **`SOVEREIGN_NOTIFY_DISPATCH_FAILED`** | no (fail-open log) | adapter errors |
|
|
176
|
+
| **`SOVEREIGN_NOTIFY_TARGET_INVALID`** | no | unknown target / email v1 defer |
|
|
177
|
+
| **`SOVEREIGN_NOTIFY_CONFIG_MISSING`** | no (skip notify) | target on but config absent |
|
|
178
|
+
| **`SOVEREIGN_LOOP_ADVANCE_BLOCKED`** | yes | deferral policy `stop`/`resolve_first` |
|
|
179
|
+
| **`DEPLOY_DEFERRED`** | no (deferral row) | **US-0109** writer (integration) |
|
|
180
|
+
|
|
181
|
+
### §10 — Contract tests + parity (AC-7, AC-8)
|
|
182
|
+
|
|
183
|
+
Eight **`test_us0107_*`** markers in **`tests/us0107_contract_test.py`**:
|
|
184
|
+
|
|
185
|
+
1. `test_us0107_scratchpad_keys_literals`
|
|
186
|
+
2. `test_us0107_deferral_jsonl_schema_contract`
|
|
187
|
+
3. `test_us0107_advance_deferral_policy_literals`
|
|
188
|
+
4. `test_us0107_drain_generate_gate_contract`
|
|
189
|
+
5. `test_us0107_notification_fail_open_literals`
|
|
190
|
+
6. `test_us0107_goal_mode_coupling_fail_closed`
|
|
191
|
+
7. `test_us0107_zero_overhead_default`
|
|
192
|
+
8. `test_us0107_compose_no_stop_matrix_change`
|
|
193
|
+
|
|
194
|
+
Compose regression guards (AC-8):
|
|
195
|
+
|
|
196
|
+
- `test_us0107_us0110_convergence_import_contract`
|
|
197
|
+
- `test_us0107_us0095_spawn_only_regression_guard`
|
|
198
|
+
|
|
199
|
+
**`SOVEREIGN_LOOP_PAIRS`** for `check_intake_template_parity.py --scope=sovereign-loop`:
|
|
200
|
+
|
|
201
|
+
- `scripts/sovereign_loop_lib.py` ↔ `template/scripts/sovereign_loop_lib.py`
|
|
202
|
+
- `scripts/sovereign_loop_validate.py` ↔ `template/scripts/sovereign_loop_validate.py`
|
|
203
|
+
- `.cursor/scratchpad.md` ↔ `template/.cursor/scratchpad.md` (`AUTO_SOVEREIGN_*` + `SOVEREIGN_NOTIFY_*` block)
|
|
204
|
+
- `handoffs/sovereign_deferrals/.gitkeep` ↔ `template/handoffs/sovereign_deferrals/.gitkeep`
|
|
205
|
+
- `decisions/DEC-0107.md` ↔ `template/decisions/DEC-0107.md`
|
|
206
|
+
- `scripts/check_intake_template_parity.py` ↔ `template/scripts/check_intake_template_parity.py` (scope registration)
|
|
207
|
+
|
|
208
|
+
### §11 — Composition rules
|
|
209
|
+
|
|
210
|
+
| Story | Compose rule |
|
|
211
|
+
|-------|--------------|
|
|
212
|
+
| **US-0088** / **US-0092** / **US-0095** | Stop matrix, spawn-only, native chain **unchanged**; sovereign terminal stops additive only. |
|
|
213
|
+
| **US-0044** / **US-0087** | Drain mutex unchanged; sovereign advance consults deferrals before story selection. |
|
|
214
|
+
| **US-0103** | Optional deferral provenance via `ledger_decision_id`; ledger schema unchanged. |
|
|
215
|
+
| **US-0105** | Drain-generate reads `build_injection_digest_block()` only when `SOVEREIGN_MEMORY=1`. |
|
|
216
|
+
| **US-0110** | Import `evaluate_convergence`, `is_goal_convergence_enabled`, `build_goal_progress_block`, `check_timeout`, `write_partial_delivery_report`; export `list_open_deferrals()` for `zero_deferrals` conjunct wiring — **do not amend** five-conjunct set or **DEC-0110**. |
|
|
217
|
+
| **US-0109** | Downstream `DEPLOY_DEFERRED` writer — schema stable in US-0107 first (**R6**). |
|
|
218
|
+
| **US-0069** | Spawn-only PO for drain-generate — no in-chat chain bypass. |
|
|
219
|
+
| **US-0045** | US-0107 remains **OPEN** until release closure. |
|
|
220
|
+
|
|
221
|
+
### §12 — Risks
|
|
222
|
+
|
|
223
|
+
| Risk | Mitigation |
|
|
224
|
+
|------|------------|
|
|
225
|
+
| **R1** Goal-mode coupling | Fail-closed **`SOVEREIGN_LOOP_GOAL_MODE_REQUIRED`**; operator recipe in runbook §1 |
|
|
226
|
+
| **R2** Drain-generate scope creep | Max **3** candidates/iteration + mandatory decision gate per candidate §6 |
|
|
227
|
+
| **R3** Deferral cap vs **`CONVERGENCE_DEFERRALS_PENDING`** | Shared `list_open_deferrals()` latest-state-wins; cap blocks append, open rows block convergence |
|
|
228
|
+
| **R4** Notification secrets | Local-only config; payload excludes hook URLs/topics |
|
|
229
|
+
| **R5** Sovereign terminal vs **US-0095** segments | Terminal stops additive post-segment eval; `drain_terminated` only on sovereign terminal |
|
|
230
|
+
| **R6** **US-0109** ordering | Deferral v1 schema + validator stable in US-0107; **`DEPLOY_DEFERRED`** reserved |
|
|
231
|
+
|
|
232
|
+
### §13 — Implementation tranche order
|
|
233
|
+
|
|
234
|
+
1. **Tranche A** — scratchpad keys + reason codes + `DEC-0107` template mirror + deferrals `.gitkeep`
|
|
235
|
+
2. **Tranche B** — **`sovereign_loop_lib.py`** deferral CRUD + `list_open_deferrals` + self-test core
|
|
236
|
+
3. **Tranche C** — **`advance_sovereign_loop`** + **`sovereign_loop_validate.py`** + sidecar run-state
|
|
237
|
+
4. **Tranche D** — drain-generate spawn inputs + notification adapters + **`/auto`** advance wiring + **US-0110** `zero_deferrals` compose
|
|
238
|
+
5. **Tranche E** — eight `test_us0107_*` + compose guards + **`SOVEREIGN_LOOP_PAIRS`** parity + runbook + architecture `# US-0107`
|
|
239
|
+
|
|
240
|
+
## References
|
|
241
|
+
|
|
242
|
+
- `docs/engineering/research.md` — **`R-0094`**
|
|
243
|
+
- `docs/product/backlog.md` — **`## US-0107`**
|
|
244
|
+
- `handoffs/intake_evidence/intake-sovereign-20260627-01.json`
|
|
245
|
+
- `scripts/sovereign_loop_lib.py` — research stub + self-test
|
|
246
|
+
- Shipped compose: `scripts/sovereign_convergence_lib.py` (**US-0110**), `scripts/sovereign_memory_lib.py` (**US-0105**), `scripts/decision_ledger_lib.py` (**US-0103**)
|
|
@@ -7,3 +7,81 @@
|
|
|
7
7
|
## Risks
|
|
8
8
|
|
|
9
9
|
## Decisions
|
|
10
|
+
|
|
11
|
+
# US-0112 — Model-catalog example preset delivery
|
|
12
|
+
|
|
13
|
+
**Story**: US-0112 (Ship model-catalog example presets on install/upgrade)
|
|
14
|
+
**Decision**: DEC-0112 (Accepted)
|
|
15
|
+
**Research anchor**: R-0090 (delivered, Q1–Q8 closed)
|
|
16
|
+
|
|
17
|
+
## Framework vs operator boundary
|
|
18
|
+
|
|
19
|
+
The 8 `model-catalog.local.example*.json` presets are **framework files** under installer manifest control. They ship on install/upgrade and are refreshed when stale (same semantics as `scratchpad.local.example.md` per US-0075/US-0018/US-0057).
|
|
20
|
+
|
|
21
|
+
The active operator-owned `.cursor/model-catalog.local.json` is **gitignored**, outside `install_include_paths` and `clean_paths`, and never touched by any installer mode. This is a DEC-0086/DEC-0087 boundary — US-0112 completes delivery of existing presets without altering catalog schema (US-0101) or role precedence (US-0102).
|
|
22
|
+
|
|
23
|
+
## Manifest rows (8 paths)
|
|
24
|
+
|
|
25
|
+
Under `[install_include_paths]` in both `docs/engineering/context/installer-owned-paths.manifest` and `template/docs/engineering/context/installer-owned-paths.manifest` (16 rows total, byte-parity):
|
|
26
|
+
|
|
27
|
+
1. `.cursor/model-catalog.local.example.json`
|
|
28
|
+
2. `.cursor/model-catalog.local.example.cursor-only.json`
|
|
29
|
+
3. `.cursor/model-catalog.local.example.level-1-easy.json`
|
|
30
|
+
4. `.cursor/model-catalog.local.example.level-2-complex.json`
|
|
31
|
+
5. `.cursor/model-catalog.local.example.level-3-mega.json`
|
|
32
|
+
6. `.cursor/model-catalog.local.example.level-4-super.json`
|
|
33
|
+
7. `.cursor/model-catalog.local.example.role-based-balanced.json`
|
|
34
|
+
8. `.cursor/model-catalog.local.example.role-based-highend.json`
|
|
35
|
+
|
|
36
|
+
## Upgrade classification (framework files)
|
|
37
|
+
|
|
38
|
+
- **Missing mode**: copies all 8 examples when absent; no-op when present; deterministic log/status per file.
|
|
39
|
+
- **Upgrade mode**: refreshes stale framework files (template content differs); skips byte-identical files; never touches `.cursor/model-catalog.local.json`.
|
|
40
|
+
- **Triple installer parity**: `installer.py`, `installer.ps1`, `installer.sh` all classify `.cursor/model-catalog.local.example*.json` as `framework` via explicit enumeration in `FRAMEWORK_EXACT` (Python) / `$frameworkExact` (PowerShell) / case pattern (Bash).
|
|
41
|
+
|
|
42
|
+
## DEC-0086 / DEC-0087 compose
|
|
43
|
+
|
|
44
|
+
US-0112 does **not** amend:
|
|
45
|
+
- US-0101 (catalog schema, DEC-0086)
|
|
46
|
+
- US-0102 (role catalog precedence, DEC-0087)
|
|
47
|
+
- US-0054 (publish confirmation gates)
|
|
48
|
+
- US-0057 (example-first refresh)
|
|
49
|
+
- US-0075 (scratchpad example-first)
|
|
50
|
+
|
|
51
|
+
US-0112 only extends the installer manifest to include the 8 example presets as framework files, completing DEC-0086/DEC-0087 delivery path.
|
|
52
|
+
|
|
53
|
+
## Active catalog protection invariant
|
|
54
|
+
|
|
55
|
+
`.cursor/model-catalog.local.json` is:
|
|
56
|
+
- Gitignored (not tracked)
|
|
57
|
+
- Outside `install_include_paths` (not manifest-copied)
|
|
58
|
+
- Outside `clean_paths` (not manifest-cleaned)
|
|
59
|
+
- Never auto-populated by any installer mode
|
|
60
|
+
- Operator-owned; installer respects DEC-0086/DEC-0087 ownership boundary
|
|
61
|
+
|
|
62
|
+
## Test markers (8+)
|
|
63
|
+
|
|
64
|
+
`tests/us0112_contract_test.py` provides:
|
|
65
|
+
- `test_us0112_manifest_lists_eight_paths` (active + template)
|
|
66
|
+
- `test_us0112_missing_mode_adds_absent_framework_files` (Python/PS1/Bash)
|
|
67
|
+
- `test_us0112_upgrade_mode_refreshes_stale_framework_files`
|
|
68
|
+
- `test_us0112_upgrade_mode_preserves_unchanged_files`
|
|
69
|
+
- `test_us0112_upgrade_mode_never_touches_local_catalog`
|
|
70
|
+
- `test_us0112_active_catalog_protection_invariant`
|
|
71
|
+
- `test_us0112_parity_scope_model_catalog_examples`
|
|
72
|
+
- `test_us0112_runbook_lists_eight_preset_literals`
|
|
73
|
+
|
|
74
|
+
## Parity scope
|
|
75
|
+
|
|
76
|
+
`scripts/check_intake_template_parity.py --scope=model-catalog-examples` validates active vs template byte-parity for the manifest rows (16 rows total). Constant: `MODEL_CATALOG_EXAMPLE_PAIRS` includes the manifest pair.
|
|
77
|
+
|
|
78
|
+
## Reason codes
|
|
79
|
+
|
|
80
|
+
- `MODEL_CATALOG_EXAMPLE_PARITY_SCOPE_OK`
|
|
81
|
+
- `MODEL_CATALOG_EXAMPLE_PARITY_SCOPE_MISMATCH`
|
|
82
|
+
|
|
83
|
+
## Compose guards (non-negotiable)
|
|
84
|
+
|
|
85
|
+
DO NOT amend: US-0008, US-0018, US-0040, US-0054, US-0057, US-0075, US-0100, US-0101, US-0102, US-0103, US-0107, US-0110.
|
|
86
|
+
|
|
87
|
+
US-0112 is additive only — extends manifest + installer classification; no schema/precedence changes.
|
|
@@ -1126,6 +1126,13 @@ when stack cannot be resolved. Connect block fields align with
|
|
|
1126
1126
|
`AUTO_ROLE_REFRESH_CONTEXT`), enforce execute default deny / override
|
|
1127
1127
|
contract, and run the preflight capability gate; on failure stop with
|
|
1128
1128
|
`PHASE_ROLE_CAPABILITY_MISSING` (no unrelated-role spawn).
|
|
1129
|
+
- **US-0105 / DEC-0105**: When `SOVEREIGN_MEMORY=1`, after phase-context
|
|
1130
|
+
narrow-read and **before** role instructions, append read-only
|
|
1131
|
+
**`sovereign_memory_digest`** block assembled via
|
|
1132
|
+
`build_injection_digest_block(...)` from `scripts/sovereign_memory_lib.py`
|
|
1133
|
+
(bounded top-N/top-K merge; char cap `SOVEREIGN_MEMORY_MAX_CHARS`). When
|
|
1134
|
+
`SOVEREIGN_MEMORY=0` (default), skip with zero overhead — **US-0023**
|
|
1135
|
+
fresh-context boundary unchanged.
|
|
1129
1136
|
- **US-0069 / DEC-0051**: After each phase completes, validate isolation
|
|
1130
1137
|
`role` and strict-proof `role` against the preflight-resolved expected
|
|
1131
1138
|
role; on conflict stop with `PHASE_ROLE_MISMATCH`.
|
|
@@ -14,6 +14,14 @@
|
|
|
14
14
|
.cursor/hooks
|
|
15
15
|
.cursor/hooks.json
|
|
16
16
|
.cursor/scratchpad.local.example.md
|
|
17
|
+
.cursor/model-catalog.local.example.json
|
|
18
|
+
.cursor/model-catalog.local.example.cursor-only.json
|
|
19
|
+
.cursor/model-catalog.local.example.level-1-easy.json
|
|
20
|
+
.cursor/model-catalog.local.example.level-2-complex.json
|
|
21
|
+
.cursor/model-catalog.local.example.level-3-mega.json
|
|
22
|
+
.cursor/model-catalog.local.example.level-4-super.json
|
|
23
|
+
.cursor/model-catalog.local.example.role-based-balanced.json
|
|
24
|
+
.cursor/model-catalog.local.example.role-based-highend.json
|
|
17
25
|
docs
|
|
18
26
|
sprints
|
|
19
27
|
handoffs
|