its-magic 0.1.3-2 → 0.1.3-3
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/package.json
CHANGED
|
@@ -13,6 +13,9 @@ Scoped modes (DEC-0073 §10 / US-0090):
|
|
|
13
13
|
--scope=us-0096 DEC-0082 delivery modes surfaces (US-0096).
|
|
14
14
|
--scope=project-readme DEC-0083 project README bootstrap surfaces (US-0097).
|
|
15
15
|
--scope=dev-environment DEC-0084 dev auto-launch profile surfaces (US-0098).
|
|
16
|
+
--scope=sovereign-parallel-dev DEC-0108 parallel instance arbitrage surfaces (US-0108).
|
|
17
|
+
--scope=sovereign-self-healing-deploy DEC-0109 self-healing deploy loop surfaces (US-0109).
|
|
18
|
+
--scope=release-trigger-adapter DEC-0111 release trigger adapter surfaces (US-0111).
|
|
16
19
|
--scope=all union of all tables.
|
|
17
20
|
"""
|
|
18
21
|
|
|
@@ -297,6 +300,115 @@ DOWNSTREAM_CI_GUARD_PAIRS: tuple[tuple[str, str], ...] = (
|
|
|
297
300
|
),
|
|
298
301
|
)
|
|
299
302
|
|
|
303
|
+
SOVEREIGN_ROLE_MANIFEST_PAIRS: tuple[tuple[str, str], ...] = (
|
|
304
|
+
(
|
|
305
|
+
".cursor/sovereign-role-manifest.yaml",
|
|
306
|
+
"template/.cursor/sovereign-role-manifest.yaml.example",
|
|
307
|
+
),
|
|
308
|
+
(
|
|
309
|
+
".cursor/scratchpad.md",
|
|
310
|
+
"template/.cursor/scratchpad.md",
|
|
311
|
+
),
|
|
312
|
+
(
|
|
313
|
+
"scripts/sovereign_role_manifest_validate.py",
|
|
314
|
+
"template/scripts/sovereign_role_manifest_validate.py",
|
|
315
|
+
),
|
|
316
|
+
(
|
|
317
|
+
"scripts/sovereign_role_manifest_lib.py",
|
|
318
|
+
"template/scripts/sovereign_role_manifest_lib.py",
|
|
319
|
+
),
|
|
320
|
+
(
|
|
321
|
+
"docs/engineering/runbook.md",
|
|
322
|
+
"template/docs/engineering/runbook.md",
|
|
323
|
+
),
|
|
324
|
+
(
|
|
325
|
+
"docs/engineering/reason_codes.md",
|
|
326
|
+
"template/docs/engineering/reason_codes.md",
|
|
327
|
+
),
|
|
328
|
+
(
|
|
329
|
+
"handoffs/sovereign_role_reviews.jsonl",
|
|
330
|
+
"template/handoffs/sovereign_role_reviews.jsonl",
|
|
331
|
+
),
|
|
332
|
+
)
|
|
333
|
+
|
|
334
|
+
SOVEREIGN_PARALLEL_DEV_PAIRS: tuple[tuple[str, str], ...] = (
|
|
335
|
+
(
|
|
336
|
+
".cursor/scratchpad.md",
|
|
337
|
+
"template/.cursor/scratchpad.md",
|
|
338
|
+
),
|
|
339
|
+
(
|
|
340
|
+
"scripts/parallel_dev_arbiter.py",
|
|
341
|
+
"template/scripts/parallel_dev_arbiter.py",
|
|
342
|
+
),
|
|
343
|
+
(
|
|
344
|
+
"tests/us0108_contract_test.py",
|
|
345
|
+
"template/tests/us0108_contract_test.py",
|
|
346
|
+
),
|
|
347
|
+
(
|
|
348
|
+
"docs/engineering/runbook.md",
|
|
349
|
+
"template/docs/engineering/runbook.md",
|
|
350
|
+
),
|
|
351
|
+
(
|
|
352
|
+
"docs/engineering/reason_codes.md",
|
|
353
|
+
"template/docs/engineering/reason_codes.md",
|
|
354
|
+
),
|
|
355
|
+
(
|
|
356
|
+
"scripts/check_intake_template_parity.py",
|
|
357
|
+
"template/scripts/check_intake_template_parity.py",
|
|
358
|
+
),
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
SOVEREIGN_SELF_HEALING_DEPLOY_PAIRS: tuple[tuple[str, str], ...] = (
|
|
362
|
+
(
|
|
363
|
+
".cursor/scratchpad.md",
|
|
364
|
+
"template/.cursor/scratchpad.md",
|
|
365
|
+
),
|
|
366
|
+
(
|
|
367
|
+
"scripts/self_healing_deploy_lib.py",
|
|
368
|
+
"template/scripts/self_healing_deploy_lib.py",
|
|
369
|
+
),
|
|
370
|
+
(
|
|
371
|
+
"scripts/self_healing_deploy_validate.py",
|
|
372
|
+
"template/scripts/self_healing_deploy_validate.py",
|
|
373
|
+
),
|
|
374
|
+
(
|
|
375
|
+
"tests/us0109_contract_test.py",
|
|
376
|
+
"template/tests/us0109_contract_test.py",
|
|
377
|
+
),
|
|
378
|
+
(
|
|
379
|
+
"docs/engineering/runbook.md",
|
|
380
|
+
"template/docs/engineering/runbook.md",
|
|
381
|
+
),
|
|
382
|
+
(
|
|
383
|
+
"docs/engineering/reason_codes.md",
|
|
384
|
+
"template/docs/engineering/reason_codes.md",
|
|
385
|
+
),
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
# US-0111 release trigger adapter parity pairs
|
|
389
|
+
RELEASE_TRIGGER_ADAPTER_PAIRS: tuple[tuple[str, str], ...] = (
|
|
390
|
+
(
|
|
391
|
+
"scripts/release_trigger_adapters.py",
|
|
392
|
+
"template/scripts/release_trigger_adapters.py",
|
|
393
|
+
),
|
|
394
|
+
(
|
|
395
|
+
"tests/us0111_contract_test.py",
|
|
396
|
+
"template/tests/us0111_contract_test.py",
|
|
397
|
+
),
|
|
398
|
+
(
|
|
399
|
+
"docs/engineering/runbook.md",
|
|
400
|
+
"template/docs/engineering/runbook.md",
|
|
401
|
+
),
|
|
402
|
+
(
|
|
403
|
+
"docs/engineering/reason_codes.md",
|
|
404
|
+
"template/docs/engineering/reason_codes.md",
|
|
405
|
+
),
|
|
406
|
+
(
|
|
407
|
+
"scripts/check_intake_template_parity.py",
|
|
408
|
+
"template/scripts/check_intake_template_parity.py",
|
|
409
|
+
),
|
|
410
|
+
)
|
|
411
|
+
|
|
300
412
|
SCOPES: dict[str, tuple[tuple[str, str], ...]] = {
|
|
301
413
|
"intake": INTAKE_TEMPLATE_PAIRS,
|
|
302
414
|
"caveman-compress": CAVEMAN_COMPRESS_PAIRS,
|
|
@@ -312,6 +424,10 @@ SCOPES: dict[str, tuple[tuple[str, str], ...]] = {
|
|
|
312
424
|
"release-changelog": RELEASE_CHANGELOG_PAIRS,
|
|
313
425
|
"model-tier": MODEL_TIER_PAIRS,
|
|
314
426
|
"model-tier-overrides": MODEL_TIER_OVERRIDES_PAIRS,
|
|
427
|
+
"sovereign-role-manifest": SOVEREIGN_ROLE_MANIFEST_PAIRS,
|
|
428
|
+
"sovereign-parallel-dev": SOVEREIGN_PARALLEL_DEV_PAIRS,
|
|
429
|
+
"sovereign-self-healing-deploy": SOVEREIGN_SELF_HEALING_DEPLOY_PAIRS,
|
|
430
|
+
"release-trigger-adapter": RELEASE_TRIGGER_ADAPTER_PAIRS,
|
|
315
431
|
"all": (
|
|
316
432
|
INTAKE_TEMPLATE_PAIRS
|
|
317
433
|
+ CAVEMAN_COMPRESS_PAIRS
|
|
@@ -327,6 +443,9 @@ SCOPES: dict[str, tuple[tuple[str, str], ...]] = {
|
|
|
327
443
|
+ RELEASE_CHANGELOG_PAIRS
|
|
328
444
|
+ MODEL_TIER_PAIRS
|
|
329
445
|
+ MODEL_TIER_OVERRIDES_PAIRS
|
|
446
|
+
+ SOVEREIGN_ROLE_MANIFEST_PAIRS
|
|
447
|
+
+ SOVEREIGN_SELF_HEALING_DEPLOY_PAIRS
|
|
448
|
+
+ RELEASE_TRIGGER_ADAPTER_PAIRS
|
|
330
449
|
),
|
|
331
450
|
}
|
|
332
451
|
|
|
@@ -1,378 +1,539 @@
|
|
|
1
|
-
# its-magic scratchpad (framework default catalog — Model B / DEC-0055)
|
|
2
|
-
#
|
|
3
|
-
# Copy this file to `.cursor/scratchpad.local.md` for personal overrides (gitignored).
|
|
4
|
-
# Merge precedence: local > materialized `.cursor/scratchpad.md` > this example
|
|
5
|
-
# (installers materialize the baseline from template when missing).
|
|
6
|
-
#
|
|
7
|
-
# Core behavior
|
|
8
|
-
# - MAGIC_CONTEXT_STRICT: 0|1 (require context refresh after code changes)
|
|
9
|
-
# - LOOP_UNTIL_GREEN: 0|1 (optional test loop)
|
|
10
|
-
# - RUN_TESTS_ON_EDIT: 0|1 (run tests after edits)
|
|
11
|
-
# - AUTO_IMPLEMENTATION_LOOP: 0|1 (auto cycle execute->qa->execute)
|
|
12
|
-
# - AUTO_LOOP_MAX_CYCLES: integer >= 1 (safety guard)
|
|
13
|
-
# - AUTO_PAUSE_REQUEST: 0|1 (request graceful stop at next safe boundary)
|
|
14
|
-
# - AUTO_PAUSE_POLICY: after_task|after_phase (safe stop boundary)
|
|
15
|
-
# - DONE: 0|1 (stop hook loops)
|
|
16
|
-
MAGIC_CONTEXT_STRICT=1
|
|
17
|
-
LOOP_UNTIL_GREEN=
|
|
18
|
-
RUN_TESTS_ON_EDIT=
|
|
19
|
-
AUTO_IMPLEMENTATION_LOOP=
|
|
20
|
-
AUTO_LOOP_MAX_CYCLES=5
|
|
21
|
-
AUTO_PAUSE_REQUEST=0
|
|
22
|
-
AUTO_PAUSE_POLICY=after_phase
|
|
23
|
-
DONE=0
|
|
24
|
-
#
|
|
25
|
-
# Benchmarking
|
|
26
|
-
# - MAGIC_BENCH_SESSION: free-form id for live benchmark logging
|
|
27
|
-
MAGIC_BENCH_SESSION=
|
|
28
|
-
#
|
|
29
|
-
# Automation
|
|
30
|
-
# - AUTO_FLOW_MODE: manual|auto_until_decision|full_autonomy
|
|
31
|
-
# - manual: operator invokes phases explicitly (default when unset)
|
|
32
|
-
# - auto_until_decision: continuous until decision_gate
|
|
33
|
-
# - full_autonomy: outer-driver loop + relaxable transient stops + drain-without-pause (default-off; US-0092 / DEC-0078)
|
|
34
|
-
# - opt-in enablement: AUTO_FLOW_MODE=full_autonomy
|
|
35
|
-
# - AUTO_BLOCK_RETRY_MAX: integer >= 1 (default 3; per (story_id, stop_reason) recoverable retries before BLOCK_RETRY_CAP_EXHAUSTED)
|
|
36
|
-
# - AUTO_OUTER_DRIVER_TIMEOUT_SECONDS: optional integer; unset = no hook timeout (timeout -> exit 124)
|
|
37
|
-
# Interaction (full_autonomy): PHASE_MODE/PERMISSION_MODE orthogonal; AUTO_BACKLOG_DRAIN/AUTO_BUG_QUEUE per US-0044/US-0087;
|
|
38
|
-
# AUTO_LOOP_MAX_CYCLES/AUTO_BACKLOG_MAX_STORIES hard caps; TOKEN_PROFILE = context breadth / token cost only (DEC-0062 / US-0092).
|
|
39
|
-
# - PHASE_MODE: interactive|auto
|
|
40
|
-
# - PERMISSION_MODE: interactive|auto
|
|
41
|
-
# - AUTO_INSTALL_DEPS: 0|1
|
|
42
|
-
# - AUTO_RELEASE_NOTES: 0|1
|
|
43
|
-
# - AUTO_BACKLOG_DRAIN: 0|1 (continue across multiple stories when enabled)
|
|
44
|
-
# - AUTO_BACKLOG_MAX_STORIES: integer >= 1 (max stories per auto run when drain enabled)
|
|
45
|
-
# - AUTO_BACKLOG_ON_BLOCK: stop|skip (behavior when a story blocks)
|
|
46
|
-
# - AUTO_STORY_SELECTION: priority_then_backlog_order
|
|
47
|
-
# - AUTO_EXECUTE_BULK: 0|1 (explicit bulk execute orchestration mode)
|
|
48
|
-
# - AUTO_EXECUTE_MAX_ITEMS: integer >= 1 (max planned items per bulk execute run)
|
|
49
|
-
# - AUTO_EXECUTE_ON_BLOCK: stop|skip (behavior when a planned item blocks)
|
|
50
|
-
# - AUTO_EXECUTE_SELECTION: planned_then_priority
|
|
51
|
-
# - AUTO_TEAM_SCOPE_ENFORCE: 0|1 (when TEAM_MODE=1, enforce TEAM_MEMBER + ACTIVE_TASK_IDS)
|
|
52
|
-
# Optional bug-queue mode (US-0087) — default-off when absent/unset after merge
|
|
53
|
-
# - AUTO_BUG_QUEUE: 0|1 (1 = enable bug-targeted /auto; mutex vs AUTO_BACKLOG_DRAIN without bug-target argv)
|
|
54
|
-
# - AUTO_BUG_TARGET: all-open|BUG-#### (required when AUTO_BUG_QUEUE=1 unless bug-target= argv supplies target)
|
|
55
|
-
# - AUTO_BUG_MAX_ITEMS: non-negative integer (0 or unset = no cap for all-open queue per run)
|
|
56
|
-
# - AUTO_BUG_ON_BLOCK: stop|skip (bug segment pause/stop boundary)
|
|
57
|
-
# Quiet mode (US-0088) — suppress routine per-phase success chatter only
|
|
58
|
-
# - AUTO_QUIET: 0|1 (default 0; 1 = quiet routine notifications)
|
|
59
|
-
# Non-suppressible: decision_gate, errors, pause, loop_max, blocked, missing inputs.
|
|
60
|
-
# Orthogonal to TOKEN_PROFILE (DEC-0035 / US-0080) — TOKEN_PROFILE controls
|
|
61
|
-
# context breadth / token cost, not notification policy.
|
|
62
|
-
AUTO_QUIET=
|
|
63
|
-
AUTO_FLOW_MODE=
|
|
64
|
-
PHASE_MODE=
|
|
65
|
-
PERMISSION_MODE=
|
|
66
|
-
AUTO_INSTALL_DEPS=
|
|
67
|
-
AUTO_RELEASE_NOTES=1
|
|
68
|
-
AUTO_BACKLOG_DRAIN=
|
|
69
|
-
AUTO_BACKLOG_MAX_STORIES=
|
|
70
|
-
AUTO_BACKLOG_ON_BLOCK=
|
|
71
|
-
AUTO_STORY_SELECTION=priority_then_backlog_order
|
|
72
|
-
AUTO_EXECUTE_BULK=0
|
|
73
|
-
AUTO_EXECUTE_MAX_ITEMS=1
|
|
74
|
-
AUTO_EXECUTE_ON_BLOCK=
|
|
75
|
-
AUTO_EXECUTE_SELECTION=planned_then_priority
|
|
76
|
-
AUTO_TEAM_SCOPE_ENFORCE=1
|
|
77
|
-
AUTO_BUG_QUEUE=0
|
|
78
|
-
AUTO_BUG_TARGET=
|
|
79
|
-
AUTO_BUG_MAX_ITEMS=0
|
|
80
|
-
AUTO_BUG_ON_BLOCK=
|
|
81
|
-
AUTO_BLOCK_RETRY_MAX=
|
|
82
|
-
#
|
|
83
|
-
# `/auto` phase role policy (US-0069 / DEC-0051)
|
|
84
|
-
# - AUTO_ROLE_RESEARCH: po|tech-lead (empty -> default tech-lead)
|
|
85
|
-
# - AUTO_ROLE_PLAN_VERIFY: qa|tech-lead (empty -> default qa)
|
|
86
|
-
# - AUTO_ROLE_REFRESH_CONTEXT: curator|po (empty -> default curator)
|
|
87
|
-
# - AUTO_EXECUTE_ROLE_OVERRIDE: empty or allowed_non_dev_execute (execute default is dev)
|
|
88
|
-
# - EXECUTE_OVERRIDE_GOVERNANCE_REF: parseable waiver pointer (DEC-xxxx / state anchor) when override set
|
|
89
|
-
AUTO_ROLE_RESEARCH=
|
|
90
|
-
AUTO_ROLE_PLAN_VERIFY=
|
|
91
|
-
AUTO_ROLE_REFRESH_CONTEXT=
|
|
92
|
-
AUTO_EXECUTE_ROLE_OVERRIDE=
|
|
93
|
-
EXECUTE_OVERRIDE_GOVERNANCE_REF=
|
|
94
|
-
#
|
|
95
|
-
# `/auto` phase selection policy (US-0070 / DEC-0052)
|
|
96
|
-
# Exactly one active mode after merge; conflict -> PHASE_POLICY_CONFLICT (no plan).
|
|
97
|
-
# - AUTO_PHASE_PLAN: unset or full (default full canonical lifecycle)
|
|
98
|
-
# - AUTO_PHASE_EXCLUDE: csv of canonical phase ids (exclude from full)
|
|
99
|
-
# - AUTO_PHASE_INCLUDE: csv of canonical phase ids (re-sorted to canonical order)
|
|
100
|
-
# - AUTO_PHASE_PROFILE: named profile (see /auto + DEC-0052; unknown -> fail closed)
|
|
101
|
-
# - AUTO_PHASE_HIGH_RISK_ACK: required token when a high-risk profile demands it
|
|
102
|
-
AUTO_PHASE_PLAN=
|
|
103
|
-
AUTO_PHASE_EXCLUDE=
|
|
104
|
-
AUTO_PHASE_INCLUDE=
|
|
105
|
-
AUTO_PHASE_PROFILE=
|
|
106
|
-
AUTO_PHASE_HIGH_RISK_ACK=
|
|
107
|
-
#
|
|
108
|
-
# Team mode
|
|
109
|
-
# - TEAM_MODE: 0|1 (enable task/member scoped team workflow)
|
|
110
|
-
# - TEAM_MEMBER: short id for current developer
|
|
111
|
-
# - ACTIVE_TASK_IDS: comma-separated task ids (for example T-12,T-13)
|
|
112
|
-
TEAM_MODE=0
|
|
113
|
-
TEAM_MEMBER=
|
|
114
|
-
ACTIVE_TASK_IDS=
|
|
115
|
-
#
|
|
116
|
-
# Sprint planning
|
|
117
|
-
# - SPRINT_MAX_TASKS: integer >= 1 (max atomic tasks per sprint, default 12)
|
|
118
|
-
# - SPRINT_AUTO_SPLIT: 0|1 (propose splitting when over threshold)
|
|
119
|
-
# - SPRINT_BULK_MAX_STORIES: integer >= 1 (candidate stories when /sprint-plan --bulk)
|
|
120
|
-
# - SPRINT_BULK_MAX_SPRINTS: integer >= 1 (generated sprints per /sprint-plan --bulk run)
|
|
121
|
-
# - SPRINT_BULK_SELECTION: priority_then_backlog_order
|
|
122
|
-
SPRINT_MAX_TASKS=12
|
|
123
|
-
SPRINT_AUTO_SPLIT=1
|
|
124
|
-
SPRINT_BULK_MAX_STORIES=5
|
|
125
|
-
SPRINT_BULK_MAX_SPRINTS=3
|
|
126
|
-
SPRINT_BULK_SELECTION=priority_then_backlog_order
|
|
127
|
-
#
|
|
128
|
-
# Remote execution (US-0086 / US-0084 / US-0064)
|
|
129
|
-
# - REMOTE_EXECUTION: 0|1
|
|
130
|
-
# - REMOTE_CONFIG: path to remote config
|
|
131
|
-
# - AUTO_REMOTE_AUTOMATION_PROFILE: off|deterministic_v1 (default off/manual-safe)
|
|
132
|
-
# - AUTO_REMOTE_ENVIRONMENT_LABEL: local|docker|ssh (names-only evidence label)
|
|
133
|
-
REMOTE_EXECUTION=0
|
|
134
|
-
REMOTE_CONFIG=.cursor/remote.json
|
|
135
|
-
AUTO_REMOTE_AUTOMATION_PROFILE=off
|
|
136
|
-
AUTO_REMOTE_ENVIRONMENT_LABEL=local
|
|
137
|
-
#
|
|
138
|
-
# Sync policy
|
|
139
|
-
# - SYNC_POLICY_MODE: disabled|manual|by_phase|by_milestone|custom_phase_list
|
|
140
|
-
# - SYNC_CUSTOM_PHASES: comma-separated canonical phase IDs; only used when
|
|
141
|
-
# SYNC_POLICY_MODE=custom_phase_list
|
|
142
|
-
# - ALLOW_AUTO_PUSH: 0|1 (default off; explicit opt-in required)
|
|
143
|
-
# - AUTO_PUSH_BRANCH_ALLOWLIST: comma-separated branches/patterns eligible for
|
|
144
|
-
# auto-push. Protected/default branches are denied unless allowlisted.
|
|
145
|
-
SYNC_POLICY_MODE=
|
|
146
|
-
SYNC_CUSTOM_PHASES=
|
|
147
|
-
ALLOW_AUTO_PUSH=
|
|
148
|
-
AUTO_PUSH_BRANCH_ALLOWLIST=
|
|
149
|
-
#
|
|
150
|
-
# Knowledge curation
|
|
151
|
-
# - EARLY_RESEARCH: 0|1 (PO/TL search web during intake/architecture)
|
|
152
|
-
# - INTAKE_GUIDED_MODE: 0|1 (guided intake follow-up/options/research behavior)
|
|
153
|
-
# - INTAKE_SUBAGENT_FALLBACK: deny|allow (deny by default; when deny, missing
|
|
154
|
-
# role-specific intake subagent capability fails fast)
|
|
155
|
-
# - INTAKE_WORK_ITEM_KIND: story|bug (default story; bug selects BUG-#### path per DEC-0061 / US-0079)
|
|
156
|
-
# - ID_NAMESPACE_BOOTSTRAP: 0|1 (optional fresh-project ID bootstrap mode; when 1, allow first IDs to start at 0001 only if deterministic freshness checks pass)
|
|
157
|
-
# - TOKEN_PROFILE: lean|balanced|full (tiered token-cost profile defaults)
|
|
158
|
-
# TOKEN_PROFILE controls context breadth / token cost only (DEC-0062 / US-0092).
|
|
159
|
-
# - lean: lowest context breadth / token cost defaults
|
|
160
|
-
# - balanced: default profile; moderate context breadth
|
|
161
|
-
# - full: highest context breadth / token cost for complex work
|
|
162
|
-
# - STATE_HOT_MAX_LINES: integer >= 200 (hot-surface soft cap trigger for
|
|
163
|
-
# archival rollover checks)
|
|
164
|
-
# - STATE_HOT_MAX_CHECKPOINTS: integer >= 10 (max recent checkpoints to retain
|
|
165
|
-
# in `state.md` after rollover)
|
|
166
|
-
# - PO_TO_TL_HOT_MAX_LINES: integer >= 200 (handoff hot-surface line cap)
|
|
167
|
-
# - PO_TO_TL_HOT_MAX_SECTIONS: integer >= 10 (max top-level ## sections retained)
|
|
168
|
-
# - ARCH_HOT_MAX_LINES: integer >= 500 (architecture hot-surface line cap)
|
|
169
|
-
# - ARCH_HOT_MAX_STORY_SECTIONS: integer >= 20 (max # US-xxxx story sections retained)
|
|
170
|
-
# - Manual-override precedence: explicit flag values in this file remain authoritative
|
|
171
|
-
# for that flag and override profile defaults.
|
|
172
|
-
#
|
|
173
|
-
# Delivery mode (US-0096 / DEC-0082)
|
|
174
|
-
# - DELIVERY_MODE: standard|ultra_lean|mega_quick (default standard; unset = standard)
|
|
175
|
-
# - LEAN_MEMORY_READ: 0|1 (default 1 when pack/active-context paths exist)
|
|
176
|
-
# - LEAN_MEMORY_WRITE: 0|1 (default 1 when pack/active-context paths exist)
|
|
177
|
-
# - LEAN_COLD_READ_MAX_SECTIONS: int >= 1 (default 4)
|
|
178
|
-
# - LEAN_STATE_INDEX_ROWS: int >= 30 (default 80)
|
|
179
|
-
# - AUTO_DELIVERY_ROUTING: scratchpad_only|backlog_then_scratchpad (default scratchpad_only)
|
|
180
|
-
# Tranche A default hot caps (US-0096): 1000/650/3000
|
|
181
|
-
DELIVERY_MODE=standard
|
|
182
|
-
LEAN_MEMORY_READ=1
|
|
183
|
-
LEAN_MEMORY_WRITE=1
|
|
184
|
-
LEAN_COLD_READ_MAX_SECTIONS=4
|
|
185
|
-
LEAN_STATE_INDEX_ROWS=80
|
|
186
|
-
AUTO_DELIVERY_ROUTING=scratchpad_only
|
|
187
|
-
EARLY_RESEARCH=1
|
|
188
|
-
INTAKE_GUIDED_MODE=1
|
|
189
|
-
INTAKE_SUBAGENT_FALLBACK=deny
|
|
190
|
-
INTAKE_WORK_ITEM_KIND=story
|
|
191
|
-
ID_NAMESPACE_BOOTSTRAP=0
|
|
192
|
-
TOKEN_PROFILE=balanced
|
|
193
|
-
STATE_HOT_MAX_LINES=1000
|
|
194
|
-
STATE_HOT_MAX_CHECKPOINTS=80
|
|
195
|
-
PO_TO_TL_HOT_MAX_LINES=650
|
|
196
|
-
PO_TO_TL_HOT_MAX_SECTIONS=60
|
|
197
|
-
ARCH_HOT_MAX_LINES=3000
|
|
198
|
-
ARCH_HOT_MAX_STORY_SECTIONS=120
|
|
199
|
-
|
|
200
|
-
# Publish targets (US-0054)
|
|
201
|
-
# - RELEASE_PUBLISH_MODE: disabled|confirm|auto
|
|
202
|
-
# - disabled: skip post-release publish target execution
|
|
203
|
-
# - confirm: require explicit operator confirmation before publish (default)
|
|
204
|
-
# - auto: allow publish without confirmation (explicit opt-in)
|
|
205
|
-
# - RELEASE_TARGETS_FILE: canonical target config path
|
|
206
|
-
# - RELEASE_TARGETS_DEFAULT: comma-separated default target IDs (optional)
|
|
207
|
-
RELEASE_PUBLISH_MODE=
|
|
208
|
-
RELEASE_TARGETS_FILE=docs/engineering/release-targets.json
|
|
209
|
-
RELEASE_TARGETS_DEFAULT=
|
|
210
|
-
|
|
211
|
-
#
|
|
212
|
-
# Security review
|
|
213
|
-
# - SECURITY_REVIEW: 0|1 (enable optional security/compliance review; default off)
|
|
214
|
-
# - COMPLIANCE_PROFILES: comma-separated values (GDPR,SOC2,HIPAA,PCI-DSS,ISO27001)
|
|
215
|
-
# Empty value means general security best practices only.
|
|
216
|
-
# When SECURITY_REVIEW=0, the workflow adds zero security-review overhead.
|
|
217
|
-
SECURITY_REVIEW=0
|
|
218
|
-
COMPLIANCE_PROFILES=GDPR
|
|
219
|
-
|
|
220
|
-
# Cross-repo compatibility observability
|
|
221
|
-
# - CROSS_REPO_OBSERVABILITY: 0|1 (enable compatibility visibility and checks)
|
|
222
|
-
# - COMPATIBILITY_GATE_ON_CRITICAL: 0|1 (when enabled, critical unresolved
|
|
223
|
-
# compatibility findings trigger decision gate before release)
|
|
224
|
-
# - COMPATIBILITY_SOURCES: semicolon-separated sources
|
|
225
|
-
# (repo=<path|url>,module=<id>,contract=<path|url>,docs=<path|url>)
|
|
226
|
-
CROSS_REPO_OBSERVABILITY=0
|
|
227
|
-
COMPATIBILITY_GATE_ON_CRITICAL=1
|
|
228
|
-
COMPATIBILITY_SOURCES=
|
|
229
|
-
|
|
230
|
-
# Component-scoped execution mode
|
|
231
|
-
# - COMPONENT_SCOPE_MODE: 0|1 (enable scoped planning/execution guardrails)
|
|
232
|
-
# - TARGET_COMPONENTS: comma-separated component IDs intended in scope
|
|
233
|
-
COMPONENT_SCOPE_MODE=0
|
|
234
|
-
TARGET_COMPONENTS=
|
|
235
|
-
|
|
236
|
-
# Optional spec-pack documentation (US-0031)
|
|
237
|
-
# - SPEC_PACK_MODE: 0|1 (enable Design Concept, CRS, Technical Spec generation/validation; default 0)
|
|
238
|
-
# When 0, intake/architecture/release add no required spec-pack steps.
|
|
239
|
-
SPEC_PACK_MODE=0
|
|
240
|
-
|
|
241
|
-
# Optional user-guide documentation (US-0032)
|
|
242
|
-
# - USER_GUIDE_MODE: 0|1 (enable per-feature user guides at docs/user-guides/US-xxxx.md; default 0)
|
|
243
|
-
# When 0, intake/architecture/sprint-plan/execute/qa/release add no required user-guide steps or blocking checks.
|
|
244
|
-
USER_GUIDE_MODE=0
|
|
245
|
-
|
|
246
|
-
# Documentation audience profile (DEC-0059)
|
|
247
|
-
# - DOC_AUDIENCE_PROFILE: user|developer|both (empty -> both during transition)
|
|
248
|
-
# - DOC_DETAIL_LEVEL: concise|balanced|technical-deep (empty -> balanced during transition)
|
|
249
|
-
DOC_AUDIENCE_PROFILE=both
|
|
250
|
-
DOC_DETAIL_LEVEL=balanced
|
|
251
|
-
|
|
252
|
-
# README feature coverage gate (US-0091 / DEC-0074)
|
|
253
|
-
# - README_FEATURE_COVERAGE_ENFORCE: 0|1 (default 0 until backfill + --report green)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
#
|
|
258
|
-
# Project
|
|
259
|
-
# -
|
|
260
|
-
#
|
|
261
|
-
#
|
|
262
|
-
#
|
|
263
|
-
#
|
|
264
|
-
#
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
#
|
|
270
|
-
#
|
|
271
|
-
# -
|
|
272
|
-
#
|
|
273
|
-
# -
|
|
274
|
-
# -
|
|
275
|
-
#
|
|
276
|
-
# -
|
|
277
|
-
# -
|
|
278
|
-
# -
|
|
279
|
-
# -
|
|
280
|
-
#
|
|
281
|
-
#
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
#
|
|
291
|
-
#
|
|
292
|
-
#
|
|
293
|
-
#
|
|
294
|
-
#
|
|
295
|
-
# -
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
#
|
|
301
|
-
#
|
|
302
|
-
#
|
|
303
|
-
# TOKEN_PROFILE
|
|
304
|
-
#
|
|
305
|
-
#
|
|
306
|
-
# -
|
|
307
|
-
#
|
|
308
|
-
#
|
|
309
|
-
#
|
|
310
|
-
#
|
|
311
|
-
#
|
|
312
|
-
#
|
|
313
|
-
# -
|
|
314
|
-
#
|
|
315
|
-
# *
|
|
316
|
-
# *
|
|
317
|
-
# *
|
|
318
|
-
#
|
|
319
|
-
#
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
#
|
|
327
|
-
#
|
|
328
|
-
# MODEL_TIER
|
|
329
|
-
#
|
|
330
|
-
#
|
|
331
|
-
# -
|
|
332
|
-
#
|
|
333
|
-
#
|
|
334
|
-
#
|
|
335
|
-
#
|
|
336
|
-
#
|
|
337
|
-
#
|
|
338
|
-
#
|
|
339
|
-
#
|
|
340
|
-
# -
|
|
341
|
-
#
|
|
342
|
-
#
|
|
343
|
-
#
|
|
344
|
-
#
|
|
345
|
-
#
|
|
346
|
-
#
|
|
347
|
-
#
|
|
348
|
-
#
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
#
|
|
356
|
-
#
|
|
357
|
-
#
|
|
358
|
-
#
|
|
359
|
-
#
|
|
360
|
-
#
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
#
|
|
367
|
-
|
|
368
|
-
#
|
|
369
|
-
#
|
|
370
|
-
#
|
|
371
|
-
#
|
|
372
|
-
|
|
373
|
-
#
|
|
374
|
-
#
|
|
375
|
-
#
|
|
376
|
-
#
|
|
377
|
-
#
|
|
378
|
-
#
|
|
1
|
+
# its-magic scratchpad (framework default catalog — Model B / DEC-0055)
|
|
2
|
+
#
|
|
3
|
+
# Copy this file to `.cursor/scratchpad.local.md` for personal overrides (gitignored).
|
|
4
|
+
# Merge precedence: local > materialized `.cursor/scratchpad.md` > this example
|
|
5
|
+
# (installers materialize the baseline from template when missing).
|
|
6
|
+
#
|
|
7
|
+
# Core behavior
|
|
8
|
+
# - MAGIC_CONTEXT_STRICT: 0|1 (require context refresh after code changes)
|
|
9
|
+
# - LOOP_UNTIL_GREEN: 0|1 (optional test loop)
|
|
10
|
+
# - RUN_TESTS_ON_EDIT: 0|1 (run tests after edits)
|
|
11
|
+
# - AUTO_IMPLEMENTATION_LOOP: 0|1 (auto cycle execute->qa->execute)
|
|
12
|
+
# - AUTO_LOOP_MAX_CYCLES: integer >= 1 (safety guard)
|
|
13
|
+
# - AUTO_PAUSE_REQUEST: 0|1 (request graceful stop at next safe boundary)
|
|
14
|
+
# - AUTO_PAUSE_POLICY: after_task|after_phase (safe stop boundary)
|
|
15
|
+
# - DONE: 0|1 (stop hook loops)
|
|
16
|
+
MAGIC_CONTEXT_STRICT=1
|
|
17
|
+
LOOP_UNTIL_GREEN=1
|
|
18
|
+
RUN_TESTS_ON_EDIT=1
|
|
19
|
+
AUTO_IMPLEMENTATION_LOOP=1
|
|
20
|
+
AUTO_LOOP_MAX_CYCLES=5
|
|
21
|
+
AUTO_PAUSE_REQUEST=0
|
|
22
|
+
AUTO_PAUSE_POLICY=after_phase
|
|
23
|
+
DONE=0
|
|
24
|
+
#
|
|
25
|
+
# Benchmarking
|
|
26
|
+
# - MAGIC_BENCH_SESSION: free-form id for live benchmark logging
|
|
27
|
+
MAGIC_BENCH_SESSION=
|
|
28
|
+
#
|
|
29
|
+
# Automation
|
|
30
|
+
# - AUTO_FLOW_MODE: manual|auto_until_decision|full_autonomy
|
|
31
|
+
# - manual: operator invokes phases explicitly (default when unset)
|
|
32
|
+
# - auto_until_decision: continuous until decision_gate
|
|
33
|
+
# - full_autonomy: outer-driver loop + relaxable transient stops + drain-without-pause (default-off; US-0092 / DEC-0078)
|
|
34
|
+
# - opt-in enablement: AUTO_FLOW_MODE=full_autonomy
|
|
35
|
+
# - AUTO_BLOCK_RETRY_MAX: integer >= 1 (default 3; per (story_id, stop_reason) recoverable retries before BLOCK_RETRY_CAP_EXHAUSTED)
|
|
36
|
+
# - AUTO_OUTER_DRIVER_TIMEOUT_SECONDS: optional integer; unset = no hook timeout (timeout -> exit 124)
|
|
37
|
+
# Interaction (full_autonomy): PHASE_MODE/PERMISSION_MODE orthogonal; AUTO_BACKLOG_DRAIN/AUTO_BUG_QUEUE per US-0044/US-0087;
|
|
38
|
+
# AUTO_LOOP_MAX_CYCLES/AUTO_BACKLOG_MAX_STORIES hard caps; TOKEN_PROFILE = context breadth / token cost only (DEC-0062 / US-0092).
|
|
39
|
+
# - PHASE_MODE: interactive|auto
|
|
40
|
+
# - PERMISSION_MODE: interactive|auto
|
|
41
|
+
# - AUTO_INSTALL_DEPS: 0|1
|
|
42
|
+
# - AUTO_RELEASE_NOTES: 0|1
|
|
43
|
+
# - AUTO_BACKLOG_DRAIN: 0|1 (continue across multiple stories when enabled)
|
|
44
|
+
# - AUTO_BACKLOG_MAX_STORIES: integer >= 1 (max stories per auto run when drain enabled)
|
|
45
|
+
# - AUTO_BACKLOG_ON_BLOCK: stop|skip (behavior when a story blocks)
|
|
46
|
+
# - AUTO_STORY_SELECTION: priority_then_backlog_order
|
|
47
|
+
# - AUTO_EXECUTE_BULK: 0|1 (explicit bulk execute orchestration mode)
|
|
48
|
+
# - AUTO_EXECUTE_MAX_ITEMS: integer >= 1 (max planned items per bulk execute run)
|
|
49
|
+
# - AUTO_EXECUTE_ON_BLOCK: stop|skip (behavior when a planned item blocks)
|
|
50
|
+
# - AUTO_EXECUTE_SELECTION: planned_then_priority
|
|
51
|
+
# - AUTO_TEAM_SCOPE_ENFORCE: 0|1 (when TEAM_MODE=1, enforce TEAM_MEMBER + ACTIVE_TASK_IDS)
|
|
52
|
+
# Optional bug-queue mode (US-0087) — default-off when absent/unset after merge
|
|
53
|
+
# - AUTO_BUG_QUEUE: 0|1 (1 = enable bug-targeted /auto; mutex vs AUTO_BACKLOG_DRAIN without bug-target argv)
|
|
54
|
+
# - AUTO_BUG_TARGET: all-open|BUG-#### (required when AUTO_BUG_QUEUE=1 unless bug-target= argv supplies target)
|
|
55
|
+
# - AUTO_BUG_MAX_ITEMS: non-negative integer (0 or unset = no cap for all-open queue per run)
|
|
56
|
+
# - AUTO_BUG_ON_BLOCK: stop|skip (bug segment pause/stop boundary)
|
|
57
|
+
# Quiet mode (US-0088) — suppress routine per-phase success chatter only
|
|
58
|
+
# - AUTO_QUIET: 0|1 (default 0; 1 = quiet routine notifications)
|
|
59
|
+
# Non-suppressible: decision_gate, errors, pause, loop_max, blocked, missing inputs.
|
|
60
|
+
# Orthogonal to TOKEN_PROFILE (DEC-0035 / US-0080) — TOKEN_PROFILE controls
|
|
61
|
+
# context breadth / token cost, not notification policy.
|
|
62
|
+
AUTO_QUIET=1
|
|
63
|
+
AUTO_FLOW_MODE=full_autonomy
|
|
64
|
+
PHASE_MODE=auto
|
|
65
|
+
PERMISSION_MODE=auto
|
|
66
|
+
AUTO_INSTALL_DEPS=1
|
|
67
|
+
AUTO_RELEASE_NOTES=1
|
|
68
|
+
AUTO_BACKLOG_DRAIN=1
|
|
69
|
+
AUTO_BACKLOG_MAX_STORIES=10
|
|
70
|
+
AUTO_BACKLOG_ON_BLOCK=skip
|
|
71
|
+
AUTO_STORY_SELECTION=priority_then_backlog_order
|
|
72
|
+
AUTO_EXECUTE_BULK=0
|
|
73
|
+
AUTO_EXECUTE_MAX_ITEMS=1
|
|
74
|
+
AUTO_EXECUTE_ON_BLOCK=skip
|
|
75
|
+
AUTO_EXECUTE_SELECTION=planned_then_priority
|
|
76
|
+
AUTO_TEAM_SCOPE_ENFORCE=1
|
|
77
|
+
AUTO_BUG_QUEUE=0
|
|
78
|
+
AUTO_BUG_TARGET=
|
|
79
|
+
AUTO_BUG_MAX_ITEMS=0
|
|
80
|
+
AUTO_BUG_ON_BLOCK=skip
|
|
81
|
+
AUTO_BLOCK_RETRY_MAX=5
|
|
82
|
+
#
|
|
83
|
+
# `/auto` phase role policy (US-0069 / DEC-0051)
|
|
84
|
+
# - AUTO_ROLE_RESEARCH: po|tech-lead (empty -> default tech-lead)
|
|
85
|
+
# - AUTO_ROLE_PLAN_VERIFY: qa|tech-lead (empty -> default qa)
|
|
86
|
+
# - AUTO_ROLE_REFRESH_CONTEXT: curator|po (empty -> default curator)
|
|
87
|
+
# - AUTO_EXECUTE_ROLE_OVERRIDE: empty or allowed_non_dev_execute (execute default is dev)
|
|
88
|
+
# - EXECUTE_OVERRIDE_GOVERNANCE_REF: parseable waiver pointer (DEC-xxxx / state anchor) when override set
|
|
89
|
+
AUTO_ROLE_RESEARCH=
|
|
90
|
+
AUTO_ROLE_PLAN_VERIFY=
|
|
91
|
+
AUTO_ROLE_REFRESH_CONTEXT=
|
|
92
|
+
AUTO_EXECUTE_ROLE_OVERRIDE=
|
|
93
|
+
EXECUTE_OVERRIDE_GOVERNANCE_REF=
|
|
94
|
+
#
|
|
95
|
+
# `/auto` phase selection policy (US-0070 / DEC-0052)
|
|
96
|
+
# Exactly one active mode after merge; conflict -> PHASE_POLICY_CONFLICT (no plan).
|
|
97
|
+
# - AUTO_PHASE_PLAN: unset or full (default full canonical lifecycle)
|
|
98
|
+
# - AUTO_PHASE_EXCLUDE: csv of canonical phase ids (exclude from full)
|
|
99
|
+
# - AUTO_PHASE_INCLUDE: csv of canonical phase ids (re-sorted to canonical order)
|
|
100
|
+
# - AUTO_PHASE_PROFILE: named profile (see /auto + DEC-0052; unknown -> fail closed)
|
|
101
|
+
# - AUTO_PHASE_HIGH_RISK_ACK: required token when a high-risk profile demands it
|
|
102
|
+
AUTO_PHASE_PLAN=
|
|
103
|
+
AUTO_PHASE_EXCLUDE=
|
|
104
|
+
AUTO_PHASE_INCLUDE=
|
|
105
|
+
AUTO_PHASE_PROFILE=
|
|
106
|
+
AUTO_PHASE_HIGH_RISK_ACK=
|
|
107
|
+
#
|
|
108
|
+
# Team mode
|
|
109
|
+
# - TEAM_MODE: 0|1 (enable task/member scoped team workflow)
|
|
110
|
+
# - TEAM_MEMBER: short id for current developer
|
|
111
|
+
# - ACTIVE_TASK_IDS: comma-separated task ids (for example T-12,T-13)
|
|
112
|
+
TEAM_MODE=0
|
|
113
|
+
TEAM_MEMBER=
|
|
114
|
+
ACTIVE_TASK_IDS=
|
|
115
|
+
#
|
|
116
|
+
# Sprint planning
|
|
117
|
+
# - SPRINT_MAX_TASKS: integer >= 1 (max atomic tasks per sprint, default 12)
|
|
118
|
+
# - SPRINT_AUTO_SPLIT: 0|1 (propose splitting when over threshold)
|
|
119
|
+
# - SPRINT_BULK_MAX_STORIES: integer >= 1 (candidate stories when /sprint-plan --bulk)
|
|
120
|
+
# - SPRINT_BULK_MAX_SPRINTS: integer >= 1 (generated sprints per /sprint-plan --bulk run)
|
|
121
|
+
# - SPRINT_BULK_SELECTION: priority_then_backlog_order
|
|
122
|
+
SPRINT_MAX_TASKS=12
|
|
123
|
+
SPRINT_AUTO_SPLIT=1
|
|
124
|
+
SPRINT_BULK_MAX_STORIES=5
|
|
125
|
+
SPRINT_BULK_MAX_SPRINTS=3
|
|
126
|
+
SPRINT_BULK_SELECTION=priority_then_backlog_order
|
|
127
|
+
#
|
|
128
|
+
# Remote execution (US-0086 / US-0084 / US-0064)
|
|
129
|
+
# - REMOTE_EXECUTION: 0|1
|
|
130
|
+
# - REMOTE_CONFIG: path to remote config
|
|
131
|
+
# - AUTO_REMOTE_AUTOMATION_PROFILE: off|deterministic_v1 (default off/manual-safe)
|
|
132
|
+
# - AUTO_REMOTE_ENVIRONMENT_LABEL: local|docker|ssh (names-only evidence label)
|
|
133
|
+
REMOTE_EXECUTION=0
|
|
134
|
+
REMOTE_CONFIG=.cursor/remote.json
|
|
135
|
+
AUTO_REMOTE_AUTOMATION_PROFILE=off
|
|
136
|
+
AUTO_REMOTE_ENVIRONMENT_LABEL=local
|
|
137
|
+
#
|
|
138
|
+
# Sync policy
|
|
139
|
+
# - SYNC_POLICY_MODE: disabled|manual|by_phase|by_milestone|custom_phase_list
|
|
140
|
+
# - SYNC_CUSTOM_PHASES: comma-separated canonical phase IDs; only used when
|
|
141
|
+
# SYNC_POLICY_MODE=custom_phase_list
|
|
142
|
+
# - ALLOW_AUTO_PUSH: 0|1 (default off; explicit opt-in required)
|
|
143
|
+
# - AUTO_PUSH_BRANCH_ALLOWLIST: comma-separated branches/patterns eligible for
|
|
144
|
+
# auto-push. Protected/default branches are denied unless allowlisted.
|
|
145
|
+
SYNC_POLICY_MODE=disabled
|
|
146
|
+
SYNC_CUSTOM_PHASES=
|
|
147
|
+
ALLOW_AUTO_PUSH=1
|
|
148
|
+
AUTO_PUSH_BRANCH_ALLOWLIST=main
|
|
149
|
+
#
|
|
150
|
+
# Knowledge curation
|
|
151
|
+
# - EARLY_RESEARCH: 0|1 (PO/TL search web during intake/architecture)
|
|
152
|
+
# - INTAKE_GUIDED_MODE: 0|1 (guided intake follow-up/options/research behavior)
|
|
153
|
+
# - INTAKE_SUBAGENT_FALLBACK: deny|allow (deny by default; when deny, missing
|
|
154
|
+
# role-specific intake subagent capability fails fast)
|
|
155
|
+
# - INTAKE_WORK_ITEM_KIND: story|bug (default story; bug selects BUG-#### path per DEC-0061 / US-0079)
|
|
156
|
+
# - ID_NAMESPACE_BOOTSTRAP: 0|1 (optional fresh-project ID bootstrap mode; when 1, allow first IDs to start at 0001 only if deterministic freshness checks pass)
|
|
157
|
+
# - TOKEN_PROFILE: lean|balanced|full (tiered token-cost profile defaults)
|
|
158
|
+
# TOKEN_PROFILE controls context breadth / token cost only (DEC-0062 / US-0092).
|
|
159
|
+
# - lean: lowest context breadth / token cost defaults
|
|
160
|
+
# - balanced: default profile; moderate context breadth
|
|
161
|
+
# - full: highest context breadth / token cost for complex work
|
|
162
|
+
# - STATE_HOT_MAX_LINES: integer >= 200 (hot-surface soft cap trigger for
|
|
163
|
+
# archival rollover checks)
|
|
164
|
+
# - STATE_HOT_MAX_CHECKPOINTS: integer >= 10 (max recent checkpoints to retain
|
|
165
|
+
# in `state.md` after rollover)
|
|
166
|
+
# - PO_TO_TL_HOT_MAX_LINES: integer >= 200 (handoff hot-surface line cap)
|
|
167
|
+
# - PO_TO_TL_HOT_MAX_SECTIONS: integer >= 10 (max top-level ## sections retained)
|
|
168
|
+
# - ARCH_HOT_MAX_LINES: integer >= 500 (architecture hot-surface line cap)
|
|
169
|
+
# - ARCH_HOT_MAX_STORY_SECTIONS: integer >= 20 (max # US-xxxx story sections retained)
|
|
170
|
+
# - Manual-override precedence: explicit flag values in this file remain authoritative
|
|
171
|
+
# for that flag and override profile defaults.
|
|
172
|
+
#
|
|
173
|
+
# Delivery mode (US-0096 / DEC-0082)
|
|
174
|
+
# - DELIVERY_MODE: standard|ultra_lean|mega_quick (default standard; unset = standard)
|
|
175
|
+
# - LEAN_MEMORY_READ: 0|1 (default 1 when pack/active-context paths exist)
|
|
176
|
+
# - LEAN_MEMORY_WRITE: 0|1 (default 1 when pack/active-context paths exist)
|
|
177
|
+
# - LEAN_COLD_READ_MAX_SECTIONS: int >= 1 (default 4)
|
|
178
|
+
# - LEAN_STATE_INDEX_ROWS: int >= 30 (default 80)
|
|
179
|
+
# - AUTO_DELIVERY_ROUTING: scratchpad_only|backlog_then_scratchpad (default scratchpad_only)
|
|
180
|
+
# Tranche A default hot caps (US-0096): example uses 1000/650/3000; explicit values here override.
|
|
181
|
+
DELIVERY_MODE=standard
|
|
182
|
+
LEAN_MEMORY_READ=1
|
|
183
|
+
LEAN_MEMORY_WRITE=1
|
|
184
|
+
LEAN_COLD_READ_MAX_SECTIONS=4
|
|
185
|
+
LEAN_STATE_INDEX_ROWS=80
|
|
186
|
+
AUTO_DELIVERY_ROUTING=scratchpad_only
|
|
187
|
+
EARLY_RESEARCH=1
|
|
188
|
+
INTAKE_GUIDED_MODE=1
|
|
189
|
+
INTAKE_SUBAGENT_FALLBACK=deny
|
|
190
|
+
INTAKE_WORK_ITEM_KIND=story
|
|
191
|
+
ID_NAMESPACE_BOOTSTRAP=0
|
|
192
|
+
TOKEN_PROFILE=balanced
|
|
193
|
+
STATE_HOT_MAX_LINES=1000
|
|
194
|
+
STATE_HOT_MAX_CHECKPOINTS=80
|
|
195
|
+
PO_TO_TL_HOT_MAX_LINES=650
|
|
196
|
+
PO_TO_TL_HOT_MAX_SECTIONS=60
|
|
197
|
+
ARCH_HOT_MAX_LINES=3000
|
|
198
|
+
ARCH_HOT_MAX_STORY_SECTIONS=120
|
|
199
|
+
|
|
200
|
+
# Publish targets (US-0054)
|
|
201
|
+
# - RELEASE_PUBLISH_MODE: disabled|confirm|auto
|
|
202
|
+
# - disabled: skip post-release publish target execution
|
|
203
|
+
# - confirm: require explicit operator confirmation before publish (default)
|
|
204
|
+
# - auto: allow publish without confirmation (explicit opt-in)
|
|
205
|
+
# - RELEASE_TARGETS_FILE: canonical target config path
|
|
206
|
+
# - RELEASE_TARGETS_DEFAULT: comma-separated default target IDs (optional)
|
|
207
|
+
RELEASE_PUBLISH_MODE=disabled
|
|
208
|
+
RELEASE_TARGETS_FILE=docs/engineering/release-targets.json
|
|
209
|
+
RELEASE_TARGETS_DEFAULT=
|
|
210
|
+
|
|
211
|
+
#
|
|
212
|
+
# Security review
|
|
213
|
+
# - SECURITY_REVIEW: 0|1 (enable optional security/compliance review; default off)
|
|
214
|
+
# - COMPLIANCE_PROFILES: comma-separated values (GDPR,SOC2,HIPAA,PCI-DSS,ISO27001)
|
|
215
|
+
# Empty value means general security best practices only.
|
|
216
|
+
# When SECURITY_REVIEW=0, the workflow adds zero security-review overhead.
|
|
217
|
+
SECURITY_REVIEW=0
|
|
218
|
+
COMPLIANCE_PROFILES=GDPR
|
|
219
|
+
|
|
220
|
+
# Cross-repo compatibility observability
|
|
221
|
+
# - CROSS_REPO_OBSERVABILITY: 0|1 (enable compatibility visibility and checks)
|
|
222
|
+
# - COMPATIBILITY_GATE_ON_CRITICAL: 0|1 (when enabled, critical unresolved
|
|
223
|
+
# compatibility findings trigger decision gate before release)
|
|
224
|
+
# - COMPATIBILITY_SOURCES: semicolon-separated sources
|
|
225
|
+
# (repo=<path|url>,module=<id>,contract=<path|url>,docs=<path|url>)
|
|
226
|
+
CROSS_REPO_OBSERVABILITY=0
|
|
227
|
+
COMPATIBILITY_GATE_ON_CRITICAL=1
|
|
228
|
+
COMPATIBILITY_SOURCES=
|
|
229
|
+
|
|
230
|
+
# Component-scoped execution mode
|
|
231
|
+
# - COMPONENT_SCOPE_MODE: 0|1 (enable scoped planning/execution guardrails)
|
|
232
|
+
# - TARGET_COMPONENTS: comma-separated component IDs intended in scope
|
|
233
|
+
COMPONENT_SCOPE_MODE=0
|
|
234
|
+
TARGET_COMPONENTS=
|
|
235
|
+
|
|
236
|
+
# Optional spec-pack documentation (US-0031)
|
|
237
|
+
# - SPEC_PACK_MODE: 0|1 (enable Design Concept, CRS, Technical Spec generation/validation; default 0)
|
|
238
|
+
# When 0, intake/architecture/release add no required spec-pack steps.
|
|
239
|
+
SPEC_PACK_MODE=0
|
|
240
|
+
|
|
241
|
+
# Optional user-guide documentation (US-0032)
|
|
242
|
+
# - USER_GUIDE_MODE: 0|1 (enable per-feature user guides at docs/user-guides/US-xxxx.md; default 0)
|
|
243
|
+
# When 0, intake/architecture/sprint-plan/execute/qa/release add no required user-guide steps or blocking checks.
|
|
244
|
+
USER_GUIDE_MODE=0
|
|
245
|
+
|
|
246
|
+
# Documentation audience profile (DEC-0059)
|
|
247
|
+
# - DOC_AUDIENCE_PROFILE: user|developer|both (empty -> both during transition)
|
|
248
|
+
# - DOC_DETAIL_LEVEL: concise|balanced|technical-deep (empty -> balanced during transition)
|
|
249
|
+
DOC_AUDIENCE_PROFILE=both
|
|
250
|
+
DOC_DETAIL_LEVEL=balanced
|
|
251
|
+
|
|
252
|
+
# README feature coverage gate (US-0091 / DEC-0074)
|
|
253
|
+
# - README_FEATURE_COVERAGE_ENFORCE: 0|1 (default 0 until backfill + --report green)
|
|
254
|
+
# When 0, /release step 3f skips (grandfathering). When 1, static coverage is blocking.
|
|
255
|
+
README_FEATURE_COVERAGE_ENFORCE=1
|
|
256
|
+
|
|
257
|
+
#
|
|
258
|
+
# ## Project README coverage (US-0097 / DEC-0083)
|
|
259
|
+
# Project-owned root README bootstrap + per-story catalog growth.
|
|
260
|
+
# - PROJECT_README_ENFORCE: 0|1 (default 1 post-bootstrap)
|
|
261
|
+
# When 0, /release step 3g skips (migration/grandfathering only). When 1, blocking.
|
|
262
|
+
# Flip 0→1 only after validate_project_readme_coverage.py --report shows coverage_missing: [].
|
|
263
|
+
# - FRAMEWORK_KIT_REPO: 0|1 (default 0)
|
|
264
|
+
# When 1 (its-magic dev kit repo only), skip execute 23a/23b and project validator root check.
|
|
265
|
+
# Consumer repos never set FRAMEWORK_KIT_REPO=1.
|
|
266
|
+
PROJECT_README_ENFORCE=1
|
|
267
|
+
FRAMEWORK_KIT_REPO=0
|
|
268
|
+
|
|
269
|
+
#
|
|
270
|
+
# ## Browser UAT self-test (US-0093 / DEC-0079)
|
|
271
|
+
# Two-tier browser probe: stdlib lib classifies + agent owns Cursor browser MCP (BUG-0006).
|
|
272
|
+
# - UAT_BROWSER_PROBE_MODE: cursor|http_fallback|playwright_fallback (default cursor)
|
|
273
|
+
# - cursor: agent executes MCP sequence; lib emits plan + UAT_PROBE_UNRESOLVED until evidence
|
|
274
|
+
# - http_fallback: stdlib HTTP GET (CI recipe — set this in CI)
|
|
275
|
+
# - playwright_fallback: subprocess Playwright primary; HTTP fallback when missing
|
|
276
|
+
# - UAT_BROWSER_FALLBACK_CHAIN: 0|1 (default 1; enable HTTP → Playwright after MCP unavailable)
|
|
277
|
+
# - UAT_PROCESS_HEALTH_POLL_SECONDS: positive int (default 60; process_health readiness cap)
|
|
278
|
+
# - UAT_PROCESS_HEALTH_POLL_INTERVAL_SECONDS: positive int (default 2; poll interval)
|
|
279
|
+
# - DEV_SERVER_PORT: int (optional; URL/port inference override)
|
|
280
|
+
# - DEV_SERVER_COMMAND: shell command (optional; process_health startup override)
|
|
281
|
+
# Interaction: orthogonal to PERMISSION_MODE and Cursor browser approval modes (manual / allow-list /
|
|
282
|
+
# auto-run per vendor docs). Health URLs from docs/engineering/runtime-connectivity.md first.
|
|
283
|
+
UAT_BROWSER_PROBE_MODE=cursor
|
|
284
|
+
UAT_BROWSER_FALLBACK_CHAIN=1
|
|
285
|
+
UAT_PROCESS_HEALTH_POLL_SECONDS=60
|
|
286
|
+
UAT_PROCESS_HEALTH_POLL_INTERVAL_SECONDS=2
|
|
287
|
+
DEV_SERVER_PORT=
|
|
288
|
+
DEV_SERVER_COMMAND=
|
|
289
|
+
|
|
290
|
+
#
|
|
291
|
+
# ## Dev environment auto-launch (US-0098 / DEC-0084)
|
|
292
|
+
# Execute-phase bounded rebuild/relaunch + Connect surfacing — distinct from US-0065 phase QA,
|
|
293
|
+
# US-0086 test routing, and US-0067 release hints. Orthogonal to AUTO_REMOTE_AUTOMATION_PROFILE.
|
|
294
|
+
# When off, execute step 24 skipped with zero overhead.
|
|
295
|
+
# - DEV_AUTO_LAUNCH_PROFILE: off|deterministic_v1 (default off)
|
|
296
|
+
# - DEV_ENVIRONMENT_CONFIG: repo-relative path (default .cursor/dev-environment.json)
|
|
297
|
+
DEV_AUTO_LAUNCH_PROFILE=off
|
|
298
|
+
DEV_ENVIRONMENT_CONFIG=.cursor/dev-environment.json
|
|
299
|
+
|
|
300
|
+
#
|
|
301
|
+
# ## Caveman mode (US-0089)
|
|
302
|
+
# Response-side voice toggle. Default off. Composition is orthogonal to
|
|
303
|
+
# TOKEN_PROFILE (DEC-0035 / US-0080) and AUTO_QUIET (US-0088) --
|
|
304
|
+
# TOKEN_PROFILE controls context breadth, CAVEMAN_MODE controls reply voice;
|
|
305
|
+
# neither substitutes for the other.
|
|
306
|
+
# - CAVEMAN_MODE: 0|1 (default 0; absence = 0)
|
|
307
|
+
# - CAVEMAN_LEVEL: lite|full|ultra (empty; with MODE=1 empty -> treat as full;
|
|
308
|
+
# unknown value -> CAVEMAN_LEVEL_UNKNOWN and fall back to pre-US-0089 voice)
|
|
309
|
+
#
|
|
310
|
+
# ## Caveman input compression (US-0090 / DEC-0073)
|
|
311
|
+
# Input-side prose minification via scripts/caveman_compress_input.py. Default off.
|
|
312
|
+
# Orthogonal to CAVEMAN_MODE (reply voice) and TOKEN_PROFILE (context breadth).
|
|
313
|
+
# - CAVEMAN_COMPRESS_INPUT: 0|1 (default 0) -- activation gate; must be 1 for --write
|
|
314
|
+
# - CAVEMAN_FILE_SCOPE: string (empty default) -- allow-list of files eligible for compression:
|
|
315
|
+
# * empty: no files in scope (fail-closed on --write with CAVEMAN_COMPRESS_SCOPE_EMPTY)
|
|
316
|
+
# * named profile: e.g. docs-prose-only (user-guides, runbook, state-archive, handoffs/archive)
|
|
317
|
+
# * raw globs: e.g. docs/user-guides/**/*.md,handoffs/archive/*.md (forward slashes only)
|
|
318
|
+
# * hybrid: profile:docs-prose-only;globs:handoffs/archive/*.md
|
|
319
|
+
# Mutation requires COMPRESS_INPUT=1 + non-empty scope + CLI --write; use --dry-run first.
|
|
320
|
+
# Originals land in docs/.caveman-originals/<path>; deny-list always wins over allow.
|
|
321
|
+
CAVEMAN_MODE=0
|
|
322
|
+
CAVEMAN_LEVEL=
|
|
323
|
+
CAVEMAN_COMPRESS_INPUT=0
|
|
324
|
+
CAVEMAN_FILE_SCOPE=
|
|
325
|
+
|
|
326
|
+
#
|
|
327
|
+
# ## Per-phase model tier selection (US-0101 / DEC-0086)
|
|
328
|
+
# MODEL_TIER selects LLM model strength (which model runs).
|
|
329
|
+
# MODEL_TIER ≠ TOKEN_PROFILE ≠ DELIVERY_MODE — these are independent axes;
|
|
330
|
+
# none substitutes for the other (DEC-0062 / US-0080 / US-0096).
|
|
331
|
+
# - MODEL_TIER_DEFAULT: cheap|balanced|strong (default balanced)
|
|
332
|
+
# - MODEL_TIER_<PHASE>: cheap|balanced|strong (per-phase override; PHASE = canonical phase id)
|
|
333
|
+
# Examples: MODEL_TIER_EXECUTE=cheap, MODEL_TIER_QA=strong, MODEL_TIER_RESEARCH=balanced
|
|
334
|
+
# Set in .cursor/scratchpad.local.md to override per phase without touching committed defaults.
|
|
335
|
+
# Default matrix (architecture-locked):
|
|
336
|
+
# cheap — ask, refresh-context, memory-audit, status-reconcile, pause
|
|
337
|
+
# balanced — intake, discovery, research, release, plan-verify
|
|
338
|
+
# strong — architecture, execute, quick, qa, verify-work, security-review
|
|
339
|
+
# (inherit parent) — auto (orchestrator always inherits parent model)
|
|
340
|
+
# - MODEL_CATALOG: path to local slug catalog (default .cursor/model-catalog.local.json)
|
|
341
|
+
# - MODEL_RESOLVE: alias_only|local_catalog|role_catalog (default alias_only)
|
|
342
|
+
# alias_only = use Cursor-stable aliases (cheap->fast, balanced->inherit, strong->omit model:)
|
|
343
|
+
# local_catalog = look up vendor model slugs from MODEL_CATALOG; requires valid JSON catalog
|
|
344
|
+
# role_catalog = opt-in phase→role→catalog slug lookup (US-0102 / DEC-0087); falls through on miss
|
|
345
|
+
# - MODEL_FALLBACK: fallback when catalog lookup fails (default inherit)
|
|
346
|
+
# - MODEL_PROVIDER_MODE: cursor|api (default cursor)
|
|
347
|
+
# cursor = all subagents route through Cursor-managed infrastructure
|
|
348
|
+
# api = operator uses BYOK via Cursor Settings → Models → API Key
|
|
349
|
+
# Known limitation: subagents do NOT inherit custom API keys/base URLs.
|
|
350
|
+
#
|
|
351
|
+
# Example catalogs for 4 software-complexity levels + a Cursor-only variant:
|
|
352
|
+
# .cursor/model-catalog.local.example.json — minimal placeholder template
|
|
353
|
+
# .cursor/model-catalog.local.example.cursor-only.json — only Cursor-integrated Composer models
|
|
354
|
+
# .cursor/model-catalog.local.example.level-1-easy.json — small/simple apps
|
|
355
|
+
# .cursor/model-catalog.local.example.level-2-complex.json — complex multi-service apps
|
|
356
|
+
# .cursor/model-catalog.local.example.level-3-mega.json — mega-complex / modular monoliths
|
|
357
|
+
# .cursor/model-catalog.local.example.level-4-super.json — super-high-sophisticated / mission-critical
|
|
358
|
+
# .cursor/model-catalog.local.example.role-based-balanced.json — v2 role preset (balanced)
|
|
359
|
+
# .cursor/model-catalog.local.example.role-based-highend.json — v2 role preset (high-end)
|
|
360
|
+
# Copy one to .cursor/model-catalog.local.json and set MODEL_RESOLVE=local_catalog or role_catalog to activate.
|
|
361
|
+
MODEL_TIER_DEFAULT=balanced
|
|
362
|
+
MODEL_CATALOG=.cursor/model-catalog.local.json
|
|
363
|
+
MODEL_RESOLVE=alias_only
|
|
364
|
+
MODEL_FALLBACK=inherit
|
|
365
|
+
MODEL_PROVIDER_MODE=cursor
|
|
366
|
+
#
|
|
367
|
+
# ## Direct per-phase model slug override + role catalog (US-0102 / DEC-0087)
|
|
368
|
+
# Composes on US-0101 / DEC-0086 — tier baseline unchanged; overlays are optional.
|
|
369
|
+
# Precedence chain (deterministic, per canonical phase_id):
|
|
370
|
+
# 1. MODEL_<PHASE> — direct vendor slug override (highest priority)
|
|
371
|
+
# 2. MODEL_TIER_<PHASE> — DEC-0086 tier→alias / local_catalog chain
|
|
372
|
+
# 3. role_catalog lookup — only when MODEL_RESOLVE=role_catalog; miss falls through
|
|
373
|
+
# 4. MODEL_TIER_DEFAULT — DEC-0086 tier chain
|
|
374
|
+
# 5. Cursor stable alias — DEC-0086 built-in mapping (fast / inherit / omit)
|
|
375
|
+
# Scratchpad merge precedence for all MODEL_* keys: MODEL_<PHASE> > MODEL_TIER_<PHASE> > MODEL_TIER_DEFAULT
|
|
376
|
+
# - MODEL_<PHASE>: direct vendor slug; <PHASE> = canonical phase id (same list as MODEL_TIER_<PHASE>)
|
|
377
|
+
# Set in .cursor/scratchpad.local.md only — use <your-vendor-slug> placeholders in committed files.
|
|
378
|
+
# Canonical phase ids: ask, refresh-context, memory-audit, status-reconcile, pause,
|
|
379
|
+
# intake, discovery, research, release, plan-verify, architecture, execute, quick,
|
|
380
|
+
# qa, verify-work, security-review, auto
|
|
381
|
+
# Examples (placeholders — replace in scratchpad.local.md):
|
|
382
|
+
# MODEL_ASK=<your-vendor-slug>
|
|
383
|
+
# MODEL_EXECUTE=<your-vendor-slug>
|
|
384
|
+
# MODEL_QA=<your-vendor-slug>
|
|
385
|
+
# MODEL_REFRESH-CONTEXT=<your-vendor-slug>
|
|
386
|
+
# MODEL_ASK participates in step 1 like any other phase (no special-case bypass).
|
|
387
|
+
#
|
|
388
|
+
# AI Decision Ledger + Plan Fidelity (US-0103 / DEC-0103)
|
|
389
|
+
# Sovereign-loop foundation. Default-off — zero overhead when AI_DECISION_LEDGER=0.
|
|
390
|
+
# - AI_DECISION_LEDGER: 0|1 (default 0) — when 0: no ledger reads/writes/schema checks.
|
|
391
|
+
# - AUTO_PLAN_FIDELITY: strict|relaxed|extended (default strict) — active only when ledger enabled.
|
|
392
|
+
# strict = any unapproved drop/reorder/scope-add → PLAN_FIDELITY_VIOLATION hard stop
|
|
393
|
+
# relaxed = drop/reorder allowed (ledger entry); scope-add still hard stop
|
|
394
|
+
# extended = scope-add allowed (extension report); drop/reorder allowed
|
|
395
|
+
AI_DECISION_LEDGER=0
|
|
396
|
+
AUTO_PLAN_FIDELITY=strict
|
|
397
|
+
#
|
|
398
|
+
# Goal-Based Convergence (US-0110 / DEC-0110)
|
|
399
|
+
# Default-off sovereign-loop terminal predicate. When SOVEREIGN_GOAL_MODE=phase_driven,
|
|
400
|
+
# zero overhead — no evaluation, no goal_progress block, no partial-delivery write.
|
|
401
|
+
# Compose do NOT amend US-0088 / US-0092 / US-0095 / US-0044 / US-0103 (read-only surfaces).
|
|
402
|
+
# - SOVEREIGN_GOAL_MODE: phase_driven|goal_convergence (default phase_driven)
|
|
403
|
+
# - SOVEREIGN_GOAL: explicit goal text (wins over vision auto-derive; default empty)
|
|
404
|
+
# - SOVEREIGN_GOAL_TOP_N: int >= 1 vision paragraph count for auto-derive (default 3)
|
|
405
|
+
# - SOVEREIGN_GOAL_MAX_CHARS: int >= 64 truncation cap (default 512)
|
|
406
|
+
# - SOVEREIGN_GOAL_TIMEOUT_MAX: int >= 0 iteration-count cap (0 = disabled; not wall-clock)
|
|
407
|
+
SOVEREIGN_GOAL_MODE=phase_driven
|
|
408
|
+
SOVEREIGN_GOAL=
|
|
409
|
+
SOVEREIGN_GOAL_TOP_N=3
|
|
410
|
+
SOVEREIGN_GOAL_MAX_CHARS=512
|
|
411
|
+
SOVEREIGN_GOAL_TIMEOUT_MAX=0
|
|
412
|
+
#
|
|
413
|
+
# Cross-Model Adversarial Critic (US-0104 / DEC-0104)
|
|
414
|
+
# Default-off cross-model review. When CROSS_MODEL_REVIEW=0, zero overhead — no critic
|
|
415
|
+
# spawn, no findings writes, no anti-slop gate. Compose do NOT amend US-0048 / US-0069 /
|
|
416
|
+
# US-0023 / US-0110 / US-0103 (additive surfaces only).
|
|
417
|
+
# - CROSS_MODEL_REVIEW: 0|1 (default 0)
|
|
418
|
+
# - CROSS_MODEL_ANTISLOP_THRESHOLD: int 0-10 aggregate floor (default 6)
|
|
419
|
+
# - CROSS_MODEL_REWORK_MAX: int >= 0 producer re-spawns per (run, phase) (default 2)
|
|
420
|
+
CROSS_MODEL_REVIEW=0
|
|
421
|
+
CROSS_MODEL_ANTISLOP_THRESHOLD=6
|
|
422
|
+
CROSS_MODEL_REWORK_MAX=2
|
|
423
|
+
#
|
|
424
|
+
# Sovereign Memory (US-0105 / DEC-0105)
|
|
425
|
+
# Default-off institutional memory. When SOVEREIGN_MEMORY=0, zero overhead —
|
|
426
|
+
# no JSONL writes, no injection reads, no spawn digest assembly.
|
|
427
|
+
# Compose do NOT amend US-0029 / US-0080 / US-0103 / US-0072 / US-0096.
|
|
428
|
+
# - SOVEREIGN_MEMORY: 0|1 (default 0)
|
|
429
|
+
# - SOVEREIGN_MEMORY_TOP_N: int >= 0 (default 5) — global recent pool (all four JSONL families)
|
|
430
|
+
# - SOVEREIGN_MEMORY_TOP_K: int >= 0 (default 3) — high-impact pool (patterns + mistakes only)
|
|
431
|
+
# - SOVEREIGN_MEMORY_MAX_CHARS: int >= 0 (default 2048) — hard cap on assembled digest_text
|
|
432
|
+
# - SOVEREIGN_MEMORY_JSONL_MAX_LINES: int >= 1 (default 500) — active JSONL line cap before archive rollover
|
|
433
|
+
SOVEREIGN_MEMORY=0
|
|
434
|
+
SOVEREIGN_MEMORY_TOP_N=5
|
|
435
|
+
SOVEREIGN_MEMORY_TOP_K=3
|
|
436
|
+
SOVEREIGN_MEMORY_MAX_CHARS=2048
|
|
437
|
+
SOVEREIGN_MEMORY_JSONL_MAX_LINES=500
|
|
438
|
+
#
|
|
439
|
+
# Sovereign Loop Mode (US-0107 / DEC-0107)
|
|
440
|
+
# Default-off project orchestration. When AUTO_SOVEREIGN=0, zero overhead — no deferral
|
|
441
|
+
# reads/writes, no advance, no notifications. Requires SOVEREIGN_GOAL_MODE=goal_convergence
|
|
442
|
+
# when enabled (fail-closed SOVEREIGN_LOOP_GOAL_MODE_REQUIRED). Compose do NOT amend
|
|
443
|
+
# US-0088 / US-0092 / US-0095 / US-0044 / US-0103 / US-0105 / US-0110 (additive hooks only).
|
|
444
|
+
# - AUTO_SOVEREIGN: 0|1 (default 0)
|
|
445
|
+
# - AUTO_SOVEREIGN_DEFERRAL_MAX: int >= 1 (default 50) — max open deferral rows
|
|
446
|
+
# - AUTO_SOVEREIGN_DRAIN_GENERATE_MAX: int >= 0 (default 3) — drain-generate iterations per run
|
|
447
|
+
# - AUTO_SOVEREIGN_DEFERRAL_POLICY: stop|skip|resolve_first (default resolve_first)
|
|
448
|
+
# - SOVEREIGN_NOTIFY_TARGET: off|ntfy|email|hook (default off)
|
|
449
|
+
# - SOVEREIGN_NOTIFY_NTFY_TOPIC: string (default empty — local-only)
|
|
450
|
+
# - SOVEREIGN_NOTIFY_NTFY_BASE: URL (default empty — local-only ntfy base override)
|
|
451
|
+
# - SOVEREIGN_NOTIFY_HOOK_URL: URL (default empty — local-only webhook)
|
|
452
|
+
# - SOVEREIGN_NOTIFY_EMAIL_TO: email (default empty — email v1 deferred)
|
|
453
|
+
AUTO_SOVEREIGN=0
|
|
454
|
+
AUTO_SOVEREIGN_DEFERRAL_MAX=50
|
|
455
|
+
AUTO_SOVEREIGN_DRAIN_GENERATE_MAX=3
|
|
456
|
+
AUTO_SOVEREIGN_DEFERRAL_POLICY=resolve_first
|
|
457
|
+
SOVEREIGN_NOTIFY_TARGET=off
|
|
458
|
+
SOVEREIGN_NOTIFY_NTFY_TOPIC=
|
|
459
|
+
SOVEREIGN_NOTIFY_NTFY_BASE=
|
|
460
|
+
SOVEREIGN_NOTIFY_HOOK_URL=
|
|
461
|
+
SOVEREIGN_NOTIFY_EMAIL_TO=
|
|
462
|
+
#
|
|
463
|
+
# Sovereign Role-Behavior Manifest (US-0106 / DEC-0106)
|
|
464
|
+
# Default-off per-role objective + inter-role review obligations. When SOVEREIGN_ROLE_MANIFEST=0,
|
|
465
|
+
# zero overhead — no manifest reads, no objective injection, no review dispatch.
|
|
466
|
+
# Compose do NOT amend US-0069 (phase→role matrix unchanged; review spawns supplementary),
|
|
467
|
+
# US-0104 (critic lenses + findings schema unchanged; role reviews additive),
|
|
468
|
+
# US-0003 / US-0023 / US-0103 / US-0105 / US-0107 (unchanged surfaces).
|
|
469
|
+
# - SOVEREIGN_ROLE_MANIFEST: 0|1 (default 0)
|
|
470
|
+
# - SOVEREIGN_ROLE_OBJECTIVE_MAX_CHARS: int >= 1 (default 512) — hard truncate for injection
|
|
471
|
+
# - SOVEREIGN_ROLE_REVIEW_MAX_PER_PHASE: int >= 0 (default 2) — per-phase review cap
|
|
472
|
+
# - SOVEREIGN_ROLE_REVIEW_REWORK_MAX: int >= 0 (default 1) — bounded rework before decision gate
|
|
473
|
+
SOVEREIGN_ROLE_MANIFEST=0
|
|
474
|
+
SOVEREIGN_ROLE_OBJECTIVE_MAX_CHARS=512
|
|
475
|
+
SOVEREIGN_ROLE_REVIEW_MAX_PER_PHASE=2
|
|
476
|
+
SOVEREIGN_ROLE_REVIEW_REWORK_MAX=1
|
|
477
|
+
#
|
|
478
|
+
# Parallel Instance Arbitrage (US-0108 / DEC-0108)
|
|
479
|
+
# Default-off parallel execute-phase instance orchestration. When SOVEREIGN_PARALLEL_DEV=0,
|
|
480
|
+
# zero overhead — no worktrees, no parallel QA, no pick JSON, no resource guard.
|
|
481
|
+
# Compose do NOT amend US-0047 (bulk execute unchanged), US-0092 (full autonomy unchanged),
|
|
482
|
+
# US-0103 (ledger schema unchanged; read-only consumer), US-0104 (critic schema unchanged;
|
|
483
|
+
# read-only anti_slop_score consumer), US-0107 (sovereign loop unchanged; consumer only).
|
|
484
|
+
# - SOVEREIGN_PARALLEL_DEV: 0|1 (default 0) — global enable gate
|
|
485
|
+
# - AUTO_SOVEREIGN_PARALLEL_N: int >= 1 (default 3) — instances per execute cycle
|
|
486
|
+
# - AUTO_SOVEREIGN_PARALLEL_MAX_TOTAL: int >= 1 (default 6) — system-wide instance cap
|
|
487
|
+
# - AUTO_SOVEREIGN_MERGE_RESOLVE: first_pass_wins|last_pass_wins|winner_takes_all|manual (default first_pass_wins)
|
|
488
|
+
# - AUTO_SOVEREIGN_WORKTREE_KEEP: 0|1 (default 0) — retain loser worktrees for debugging
|
|
489
|
+
# - AUTO_SOVEREIGN_PARALLEL_QA: 0|1 (default 0) — enable parallel QA cross-review (v2)
|
|
490
|
+
# - AUTO_SOVEREIGN_PARALLEL_QA_ARBITER: critic_first_pass|majority_vote (default critic_first_pass)
|
|
491
|
+
# - AUTO_SOVEREIGN_PARALLEL_ANTI_SLOP_THRESHOLD: int 0-10 (default 6) — anti-slop floor
|
|
492
|
+
# - AUTO_SOVEREIGN_PARALLEL_REWORK_MAX: int >= 0 (default 2) — per-instance rework cap
|
|
493
|
+
# - AUTO_SOVEREIGN_PARALLEL_MERGE_TIMEOUT_SEC: int >= 10 (default 60) — merge timeout
|
|
494
|
+
# - AUTO_SOVEREIGN_PARALLEL_MODEL_<idx>: model slug per instance (optional)
|
|
495
|
+
# - AUTO_SOVEREIGN_PARALLEL_LENS_<idx>: lens config per instance (optional)
|
|
496
|
+
SOVEREIGN_PARALLEL_DEV=0
|
|
497
|
+
AUTO_SOVEREIGN_PARALLEL_N=3
|
|
498
|
+
AUTO_SOVEREIGN_PARALLEL_MAX_TOTAL=6
|
|
499
|
+
AUTO_SOVEREIGN_MERGE_RESOLVE=first_pass_wins
|
|
500
|
+
AUTO_SOVEREIGN_WORKTREE_KEEP=0
|
|
501
|
+
AUTO_SOVEREIGN_PARALLEL_QA=0
|
|
502
|
+
AUTO_SOVEREIGN_PARALLEL_QA_ARBITER=critic_first_pass
|
|
503
|
+
AUTO_SOVEREIGN_PARALLEL_ANTI_SLOP_THRESHOLD=6
|
|
504
|
+
AUTO_SOVEREIGN_PARALLEL_REWORK_MAX=2
|
|
505
|
+
AUTO_SOVEREIGN_PARALLEL_MERGE_TIMEOUT_SEC=60
|
|
506
|
+
#
|
|
507
|
+
# Self-Healing Deploy Loop (US-0109 / DEC-0109)
|
|
508
|
+
# Default-off auto-heal post-publish probe + bounded retry + DEPLOY_DEFERRED.
|
|
509
|
+
# When AUTO_SOVEREIGN_SELF_HEALING_DEPLOY=0 zero overhead, byte-identical US-0054 publish path —
|
|
510
|
+
# no probe, no retry, no deferral, no execute steps 29-31. Compose do NOT amend US-0054 / US-0100 /
|
|
511
|
+
# US-0103 / US-0107 / US-0110 (US-0109 consumer-only hook after US-0054 publish PASS).
|
|
512
|
+
# - AUTO_SOVEREIGN_SELF_HEALING_DEPLOY: 0|1 (default 0) — global gate
|
|
513
|
+
# - AUTO_SOVEREIGN_DEPLOY_RETRY_MAX: int >= 1 (default 3) — max retry attempts after probe FAIL
|
|
514
|
+
# - AUTO_SOVEREIGN_DEPLOY_SMOKE_TIMEOUT_SEC: int >= 1 (default 30) — per-stage probe HTTP timeout
|
|
515
|
+
# - AUTO_SOVEREIGN_DEPLOY_PROBE_KIND: health_endpoint|acceptance_smoke|both (default both)
|
|
516
|
+
# - SOVEREIGN_DEPLOY_ACCEPTANCE_SMOKE_PATH: repo-relative path (default tests/deploy_smoke/)
|
|
517
|
+
# - AUTO_SOVEREIGN_DEPLOY_HEALTH_ENDPOINT: names-only env ref (US-0085 compose); empty = unresolvable
|
|
518
|
+
# Reason codes (DEC-0109 §7): DEPLOY_HEALING_DISABLED (info), DEPLOY_HEALING_SMOKE_HEALTH_FAIL,
|
|
519
|
+
# DEPLOY_HEALING_SMOKE_ACCEPTANCE_FAIL, DEPLOY_HEALING_RETRY_ATTEMPT,
|
|
520
|
+
# DEPLOY_HEALING_RETRY_CAP_EXHAUSTED, DEPLOY_HEALING_DEFERRED,
|
|
521
|
+
# DEPLOY_HEALING_PROBE_TARGET_MISSING, DEPLOY_HEALING_TIMEOUT.
|
|
522
|
+
AUTO_SOVEREIGN_SELF_HEALING_DEPLOY=0
|
|
523
|
+
AUTO_SOVEREIGN_DEPLOY_RETRY_MAX=3
|
|
524
|
+
AUTO_SOVEREIGN_DEPLOY_SMOKE_TIMEOUT_SEC=30
|
|
525
|
+
AUTO_SOVEREIGN_DEPLOY_PROBE_KIND=both
|
|
526
|
+
SOVEREIGN_DEPLOY_ACCEPTANCE_SMOKE_PATH=tests/deploy_smoke/
|
|
527
|
+
AUTO_SOVEREIGN_DEPLOY_HEALTH_ENDPOINT=
|
|
528
|
+
#
|
|
529
|
+
# Release Trigger Adapters (US-0111 / DEC-0111)
|
|
530
|
+
# Dispatch release flow by trigger source (GitHub webhook, npm publish, Git tag
|
|
531
|
+
# push, manual /release). Default source is manual (zero behavior change vs
|
|
532
|
+
# pre-US-0111 /release path — byte-identical). Compose with US-0100; reuses
|
|
533
|
+
# release_changelog_lib APIs without modification.
|
|
534
|
+
# - RELEASE_TRIGGER_SOURCE: manual|github|npm|git_tag|auto (default manual)
|
|
535
|
+
# - RELEASE_TRIGGER_TIMEOUT_SEC: int >= 1 (default 10; adapter subprocess timeout)
|
|
536
|
+
# - RELEASE_TRIGGER_FALLBACK_TO_LOCAL: 0|1 (default 0; npm adapter offline fallback)
|
|
537
|
+
RELEASE_TRIGGER_SOURCE=manual
|
|
538
|
+
RELEASE_TRIGGER_TIMEOUT_SEC=10
|
|
539
|
+
RELEASE_TRIGGER_FALLBACK_TO_LOCAL=0
|
|
@@ -1946,6 +1946,15 @@ Multi-segment operator E2E recipe — validates native-chain orchestrator compli
|
|
|
1946
1946
|
Normative detail: **`.cursor/commands/auto.md`** § **Orchestrator post-subagent continuation
|
|
1947
1947
|
mandate (BUG-0012)** and architecture **`# BUG-0012`**.
|
|
1948
1948
|
|
|
1949
|
+
### Scratchpad example parity
|
|
1950
|
+
|
|
1951
|
+
Verifies `template/.cursor/scratchpad.local.example.md` stays byte-identical with canonical `.cursor/scratchpad.md`:
|
|
1952
|
+
|
|
1953
|
+
- **Single-source-of-truth**: canonical is `.cursor/scratchpad.md`; template example is the consumer-shipped packaged copy.
|
|
1954
|
+
- **Sync procedure**: copy canonical `.cursor/scratchpad.md` to `template/.cursor/scratchpad.local.example.md`, preserving the example-only header (first 5 lines) and excluding project-local override section (consumer-specific `#MODEL_TIER_*`, `# Per-phase tier overrides for this project`, etc.).
|
|
1955
|
+
- **Verification**: `pytest tests/scratchpad_example_parity_test.py -v`
|
|
1956
|
+
- **Installer contract**: `installer.py materialize_scratchpad_example()` reads from `template/.cursor/scratchpad.local.example.md` on every install/upgrade, ensuring consumers get the latest framework defaults without overwriting their personal overrides in `.cursor/scratchpad.local.md`.
|
|
1957
|
+
|
|
1949
1958
|
### Full-autonomy outer driver (US-0092) — fallback
|
|
1950
1959
|
|
|
1951
1960
|
Opt-in **`AUTO_FLOW_MODE=full_autonomy`** (exact literal, default-off) also enables
|
|
@@ -3501,6 +3510,63 @@ US-0109 does not participate in convergence evaluation.
|
|
|
3501
3510
|
|
|
3502
3511
|
---
|
|
3503
3512
|
|
|
3513
|
+
## Scratchpad Example Parity (BUG-0013)
|
|
3514
|
+
|
|
3515
|
+
**Goal**: `template/.cursor/scratchpad.local.example.md` must stay in structural parity with the canonical `.cursor/scratchpad.md` (current source of truth), while preserving the example-only header (L1–L5) and excluding project-local flag overrides (which belong in consumer `.cursor/scratchpad.local.md`).
|
|
3516
|
+
|
|
3517
|
+
### Single source of truth
|
|
3518
|
+
|
|
3519
|
+
- Canonical scratchpad: `.cursor/scratchpad.md` (read-only for installers).
|
|
3520
|
+
- Template example: `template/.cursor/scratchpad.local.example.md` (mirror — must stay in sync structurally; project-local value overrides must be reset to safe defaults).
|
|
3521
|
+
- Active example: `.cursor/scratchpad.local.example.md` (body must be byte-identical to template mirror from L6 onwards).
|
|
3522
|
+
|
|
3523
|
+
### When to re-sync
|
|
3524
|
+
|
|
3525
|
+
Whenever `.cursor/scratchpad.md` gains a new `## Section` / key block, the template example must be refreshed (copy canonical, then reset project-local values):
|
|
3526
|
+
|
|
3527
|
+
- Copy canonical to template.
|
|
3528
|
+
- Preserve the example-only header comment (first 5 lines).
|
|
3529
|
+
- Reset framework/project-local keys to their safe example defaults:
|
|
3530
|
+
|
|
3531
|
+
| Key | Example default | Canonical (framework) value |
|
|
3532
|
+
|---|---|---|
|
|
3533
|
+
| `FRAMEWORK_KIT_REPO` | `0` | `1` |
|
|
3534
|
+
| `CAVEMAN_LEVEL` | *(empty)* | `full` |
|
|
3535
|
+
| `TOKEN_PROFILE` | `balanced` | `lean` |
|
|
3536
|
+
| `CAVEMAN_MODE` | `0` | `1` |
|
|
3537
|
+
|
|
3538
|
+
### Verification command
|
|
3539
|
+
|
|
3540
|
+
```bash
|
|
3541
|
+
python -m pytest tests/scratchpad_example_parity_test.py -v
|
|
3542
|
+
```
|
|
3543
|
+
|
|
3544
|
+
Three regression test markers cover this contract:
|
|
3545
|
+
|
|
3546
|
+
- `test_bug0013_parity_check`: all canonical keys present in template (canonical keys ⊆ template example keys).
|
|
3547
|
+
- `test_bug0013_header_preserved`: example-only header comment (L1–L5) intact.
|
|
3548
|
+
- `test_bug0013_local_overrides_preserved`: no project-local override values leak into the template example.
|
|
3549
|
+
|
|
3550
|
+
### Reason codes
|
|
3551
|
+
|
|
3552
|
+
| Reason | Meaning |
|
|
3553
|
+
|---|---|
|
|
3554
|
+
| `SCRATCHPAD_EXAMPLE_OUT_OF_SYNC` | Template example is missing one or more canonical sections/keys. |
|
|
3555
|
+
| `SCRATCHPAD_HEADER_DRIFT` | Example-only header (L1–L5) was overwritten or drifted. |
|
|
3556
|
+
| `SCRATCHPAD_LOCAL_VALUES_LEAKED` | Project-local override values (e.g. `FRAMEWORK_KIT_REPO=1`, `CAVEMAN_LEVEL=full`) are present in the template example. |
|
|
3557
|
+
|
|
3558
|
+
### Normative architecture
|
|
3559
|
+
|
|
3560
|
+
- **Backlog**: `docs/product/backlog.md` § `BUG-0013` (scratchpad-example-stale).
|
|
3561
|
+
- **Sprint**: `sprints/S-BUG0013/`.
|
|
3562
|
+
- **Test**: `tests/scratchpad_example_parity_test.py`.
|
|
3563
|
+
|
|
3564
|
+
### Compose guards (unchanged)
|
|
3565
|
+
|
|
3566
|
+
US-0008, US-0040, US-0054, US-0100, US-0101, US-0102, US-0103, US-0107, US-0110 (as per sprint constraints — all UNCHANGED during BUG-0013).
|
|
3567
|
+
|
|
3568
|
+
---
|
|
3569
|
+
|
|
3504
3570
|
## Project run steps
|
|
3505
3571
|
|
|
3506
3572
|
### Prerequisites
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
BUG-0013: Scratchpad example parity tests.
|
|
3
|
+
|
|
4
|
+
Verifies template/.cursor/scratchpad.local.example.md stays in sync
|
|
5
|
+
with canonical .cursor/scratchpad.md, excluding project-local overrides.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import re
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
import pytest
|
|
12
|
+
|
|
13
|
+
CANONICAL = Path(__file__).parent.parent / ".cursor" / "scratchpad.md"
|
|
14
|
+
TEMPLATE = (
|
|
15
|
+
Path(__file__).parent.parent
|
|
16
|
+
/ "template"
|
|
17
|
+
/ ".cursor"
|
|
18
|
+
/ "scratchpad.local.example.md"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def extract_keys(text):
|
|
23
|
+
"""Extract KEY=value keys from scratchpad text."""
|
|
24
|
+
pattern = re.compile(r"^([A-Z_][A-Z0-9_]*)=", re.MULTILINE)
|
|
25
|
+
return set(pattern.findall(text))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def extract_sections(text):
|
|
29
|
+
"""Extract # Section headers from scratchpad text."""
|
|
30
|
+
pattern = re.compile(r"^(#+\s+.+)$", re.MULTILINE)
|
|
31
|
+
return [m.strip() for m in pattern.findall(text)]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
# ---------------------------------------------------------------------------
|
|
35
|
+
# Fixtures
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
|
|
38
|
+
@pytest.fixture
|
|
39
|
+
def canonical_text():
|
|
40
|
+
return CANONICAL.read_text(encoding="utf-8")
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@pytest.fixture
|
|
44
|
+
def template_text():
|
|
45
|
+
return TEMPLATE.read_text(encoding="utf-8")
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
# Test markers
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
def test_bug0013_parity_check(canonical_text, template_text):
|
|
53
|
+
"""AC-1: All canonical sections keys present in template example."""
|
|
54
|
+
# 1) Section headers should be present
|
|
55
|
+
canonical_sections = extract_sections(canonical_text)
|
|
56
|
+
template_sections = extract_sections(template_text)
|
|
57
|
+
missing_sections = set(canonical_sections) - set(template_sections)
|
|
58
|
+
|
|
59
|
+
# 2) Keys (canonical keys ⊆ template example keys)
|
|
60
|
+
canonical_keys = extract_keys(canonical_text)
|
|
61
|
+
template_keys = extract_keys(template_text)
|
|
62
|
+
missing_keys = canonical_keys - template_keys
|
|
63
|
+
|
|
64
|
+
msg = []
|
|
65
|
+
if missing_sections:
|
|
66
|
+
msg.append(
|
|
67
|
+
f"Template missing {len(missing_sections)} canonical section(s):\n"
|
|
68
|
+
+ "\n".join(f" - {s}" for s in sorted(missing_sections))
|
|
69
|
+
)
|
|
70
|
+
if missing_keys:
|
|
71
|
+
msg.append(
|
|
72
|
+
f"Template missing {len(missing_keys)} canonical key(s):\n"
|
|
73
|
+
+ "\n".join(f" - {k}" for k in sorted(missing_keys))
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
assert not msg, "\n".join(msg)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def test_bug0013_header_preserved(template_text):
|
|
80
|
+
"""AC-1: Example-only header comment (L1-L5) preserved intact."""
|
|
81
|
+
lines = template_text.splitlines()[:5]
|
|
82
|
+
|
|
83
|
+
expected_patterns = [
|
|
84
|
+
r"^#", # L1: comment line
|
|
85
|
+
r"its-magic", # L2: contains "its-magic"
|
|
86
|
+
r"DEC-", # L3: contains DEC reference
|
|
87
|
+
r"Copy this file",# L4: contains copy instruction
|
|
88
|
+
r"local>", # L5: contains "local>" reference
|
|
89
|
+
]
|
|
90
|
+
assert len(lines) >= 5, (
|
|
91
|
+
f"Template header must have at least 5 lines; only {len(lines)} found"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
for idx, pattern in enumerate(expected_patterns, start=1):
|
|
95
|
+
assert pattern in lines[idx - 1] or re.match(pattern, lines[idx - 1]), (
|
|
96
|
+
f"Header line {idx} missing expected pattern '{pattern}'.\n"
|
|
97
|
+
f"Found: {lines[idx - 1]}"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_bug0013_local_overrides_preserved(template_text):
|
|
102
|
+
"""AC-1: Project-local overrides NOT leaked into template example."""
|
|
103
|
+
# Patterns indicating project-local overrides that should NOT be in template
|
|
104
|
+
forbidden = [
|
|
105
|
+
r"^MODEL_[A-Z]+=", # Direct per-phase model overrides (e.g., MODEL_EXECUTE=...)
|
|
106
|
+
r"^#MODEL_", # Commented per-phase slug overrides
|
|
107
|
+
r"^#MODEL_RESOLVE=local_catalog", # Local catalog override (commented)
|
|
108
|
+
r"^#MODEL_RESOLVE=role_catalog", # Role catalog override (commented)
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
violations = []
|
|
112
|
+
for pattern in forbidden:
|
|
113
|
+
matches = re.findall(pattern, template_text, re.MULTILINE)
|
|
114
|
+
if matches:
|
|
115
|
+
violations.append((pattern, matches[:3])) # up to 3 examples
|
|
116
|
+
|
|
117
|
+
assert not violations, (
|
|
118
|
+
f"Template contains {len(violations)} project-local override pattern(s) "
|
|
119
|
+
"that should NOT be present:\n"
|
|
120
|
+
+ "\n".join(
|
|
121
|
+
f" - {pat} (examples: {ex})" for pat, ex in violations
|
|
122
|
+
)
|
|
123
|
+
+ "\nProject-local overrides belong in consumer's .cursor/scratchpad.local.md"
|
|
124
|
+
)
|