@amsterdamdatalabs/enact-extensions 0.1.12 → 0.1.25

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.
Files changed (148) hide show
  1. package/README.md +11 -12
  2. package/dist/create/enact.js +1 -1
  3. package/dist/create/enact.js.map +1 -1
  4. package/dist/create/index.d.ts +4 -3
  5. package/dist/create/index.d.ts.map +1 -1
  6. package/dist/create/index.js +9 -2
  7. package/dist/create/index.js.map +1 -1
  8. package/dist/index.d.ts +8 -6
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +4 -3
  11. package/dist/index.js.map +1 -1
  12. package/dist/install.d.ts +5 -0
  13. package/dist/install.d.ts.map +1 -1
  14. package/dist/install.js +10 -3
  15. package/dist/install.js.map +1 -1
  16. package/dist/internal/agents.d.ts +6 -1
  17. package/dist/internal/agents.d.ts.map +1 -1
  18. package/dist/internal/agents.js +8 -4
  19. package/dist/internal/agents.js.map +1 -1
  20. package/dist/internal/claude.d.ts +24 -0
  21. package/dist/internal/claude.d.ts.map +1 -1
  22. package/dist/internal/claude.js +99 -0
  23. package/dist/internal/claude.js.map +1 -1
  24. package/dist/internal/platform.d.ts +3 -1
  25. package/dist/internal/platform.d.ts.map +1 -1
  26. package/dist/internal/platform.js +7 -1
  27. package/dist/internal/platform.js.map +1 -1
  28. package/dist/internal/types.d.ts +2 -1
  29. package/dist/internal/types.d.ts.map +1 -1
  30. package/dist/principles.d.ts +28 -0
  31. package/dist/principles.d.ts.map +1 -0
  32. package/dist/principles.js +159 -0
  33. package/dist/principles.js.map +1 -0
  34. package/extensions/dev-state/.agents/plugin.json +2 -1
  35. package/extensions/enact-context/.agents/plugin.json +2 -1
  36. package/extensions/enact-context/hooks/hooks.json +0 -10
  37. package/extensions/enact-context/skills/enact-context/SKILL.md +14 -12
  38. package/extensions/enact-context/skills/enact-context/scripts/install.sh +7 -7
  39. package/extensions/enact-core/.agents/plugin.json +2 -1
  40. package/extensions/enact-core/OPERATING-PRINCIPLES.md +7 -0
  41. package/extensions/enact-core/hooks/hooks.json +12 -0
  42. package/extensions/enact-evolve/.agents/plugin.json +47 -0
  43. package/extensions/enact-evolve/agents/evolve-session-analyst.toml +37 -0
  44. package/extensions/enact-evolve/skills/session-analysis/SKILL.md +98 -0
  45. package/extensions/enact-evolve/skills/session-analysis/scripts/run-evolve-analysis.sh +343 -0
  46. package/extensions/enact-factory/.agents/plugin.json +2 -2
  47. package/extensions/enact-factory/agents/architect.toml +9 -5
  48. package/extensions/enact-factory/agents/code-reviewer.toml +9 -5
  49. package/extensions/enact-factory/agents/critic.toml +9 -5
  50. package/extensions/enact-factory/agents/executor.toml +4 -1
  51. package/extensions/enact-factory/agents/explore.toml +4 -1
  52. package/extensions/enact-factory/agents/planner.toml +4 -1
  53. package/extensions/enact-factory/agents/verifier.toml +9 -5
  54. package/extensions/enact-factory/skills/advisor/SKILL.md +82 -0
  55. package/extensions/enact-factory/skills/ai-slop-cleaner/SKILL.md +6 -1
  56. package/extensions/enact-factory/skills/autonomous-runner/SKILL.md +347 -0
  57. package/extensions/enact-factory/skills/azdo-ci-strategy/SKILL.md +42 -15
  58. package/extensions/enact-factory/skills/committee/SKILL.md +80 -0
  59. package/extensions/enact-factory/skills/deep-interview/SKILL.md +9 -13
  60. package/extensions/enact-factory/skills/drive-loop/SKILL.md +161 -31
  61. package/extensions/enact-factory/skills/drive-loop/references/contract-schema.md +26 -6
  62. package/extensions/enact-factory/skills/handoff/SKILL.md +72 -0
  63. package/extensions/enact-factory/skills/hyperplan/SKILL.md +11 -3
  64. package/extensions/enact-factory/skills/looplan/SKILL.md +34 -17
  65. package/extensions/enact-factory/skills/plan/SKILL.md +40 -8
  66. package/extensions/enact-factory/skills/remove-deadcode/SKILL.md +6 -1
  67. package/extensions/enact-factory/skills/research/SKILL.md +14 -4
  68. package/extensions/enact-factory/skills/review/SKILL.md +21 -2
  69. package/extensions/enact-factory/skills/security-research/SKILL.md +5 -2
  70. package/extensions/enact-factory/skills/tdd/SKILL.md +7 -1
  71. package/extensions/enact-factory/skills/testing-strategy/SKILL.md +5 -0
  72. package/extensions/enact-factory/skills/trace/SKILL.md +5 -0
  73. package/extensions/enact-factory/skills/ultraqa/SKILL.md +21 -15
  74. package/extensions/enact-factory/skills/work-with-workitem/SKILL.md +5 -0
  75. package/extensions/enact-factory/skills/workitem-triage/SKILL.md +5 -0
  76. package/extensions/enact-loop/.agents/plugin.json +5 -4
  77. package/extensions/enact-loop/scripts/validate.mjs +123 -0
  78. package/extensions/enact-loop/skills/enact-loop/SKILL.md +189 -30
  79. package/extensions/enact-wiki/.agents/plugin.json +2 -1
  80. package/extensions/net-revenue-management/.agents/plugin.json +2 -1
  81. package/extensions/plugin-dev/.agents/plugin.json +2 -1
  82. package/extensions/plugin-dev/skills/start/SKILL.md +3 -3
  83. package/package.json +1 -1
  84. package/scripts/check-hooks.mjs +5 -5
  85. package/scripts/check-principles.mjs +19 -4
  86. package/scripts/enact-extensions.mjs +237 -90
  87. package/scripts/lib/hooks.mjs +61 -217
  88. package/scripts/lib/migrate-artifacts.mjs +144 -0
  89. package/scripts/lib/principles.mjs +109 -0
  90. package/scripts/lib/provision-mcp.mjs +1 -1
  91. package/scripts/lib/run-install.mjs +72 -2
  92. package/scripts/lib/run-prune.mjs +23 -2
  93. package/scripts/lib/run-sync.mjs +4 -1
  94. package/scripts/postinstall.mjs +6 -6
  95. package/scripts/setup-enact-context.sh +20 -15
  96. package/scripts/version-bump.sh +22 -1
  97. package/spec/codex.json +5 -0
  98. package/spec/enact.json +3 -3
  99. package/spec/enact.md +1 -4
  100. package/spec/index.json +1 -1
  101. package/extensions/enact-factory/hooks/hooks.json +0 -14
  102. package/extensions/enact-operator/.agents/plugin.json +0 -56
  103. package/extensions/enact-operator/.app.json +0 -3
  104. package/extensions/enact-operator/.mcp.json +0 -10
  105. package/extensions/enact-operator/_taxonomy.md +0 -86
  106. package/extensions/enact-operator/agents/README.md +0 -5
  107. package/extensions/enact-operator/agents/architect.toml +0 -25
  108. package/extensions/enact-operator/agents/code-reviewer.toml +0 -24
  109. package/extensions/enact-operator/agents/critic.toml +0 -30
  110. package/extensions/enact-operator/agents/executor.toml +0 -24
  111. package/extensions/enact-operator/agents/explore.toml +0 -23
  112. package/extensions/enact-operator/agents/planner.toml +0 -24
  113. package/extensions/enact-operator/agents/verifier.toml +0 -24
  114. package/extensions/enact-operator/docs/skill-variants.md +0 -44
  115. package/extensions/enact-operator/hooks/hooks.json +0 -91
  116. package/extensions/enact-operator/skills/ai-slop-cleaner/SKILL.md +0 -50
  117. package/extensions/enact-operator/skills/analyze/SKILL.md +0 -91
  118. package/extensions/enact-operator/skills/ask/SKILL.md +0 -47
  119. package/extensions/enact-operator/skills/autopilot/SKILL.md +0 -170
  120. package/extensions/enact-operator/skills/autoresearch-goal/SKILL.md +0 -79
  121. package/extensions/enact-operator/skills/cancel/SKILL.md +0 -99
  122. package/extensions/enact-operator/skills/configure-notifications/SKILL.md +0 -77
  123. package/extensions/enact-operator/skills/deep-interview/SKILL.md +0 -80
  124. package/extensions/enact-operator/skills/doctor/SKILL.md +0 -48
  125. package/extensions/enact-operator/skills/hud/SKILL.md +0 -49
  126. package/extensions/enact-operator/skills/hyperplan/SKILL.md +0 -47
  127. package/extensions/enact-operator/skills/plan/SKILL.md +0 -78
  128. package/extensions/enact-operator/skills/ralph/SKILL.md +0 -201
  129. package/extensions/enact-operator/skills/ralph/gemini.md +0 -18
  130. package/extensions/enact-operator/skills/ralplan/SKILL.md +0 -151
  131. package/extensions/enact-operator/skills/remove-deadcode/SKILL.md +0 -45
  132. package/extensions/enact-operator/skills/research/SKILL.md +0 -74
  133. package/extensions/enact-operator/skills/review/SKILL.md +0 -58
  134. package/extensions/enact-operator/skills/security-research/SKILL.md +0 -54
  135. package/extensions/enact-operator/skills/setup/SKILL.md +0 -91
  136. package/extensions/enact-operator/skills/setup/scripts/install.sh +0 -50
  137. package/extensions/enact-operator/skills/skill/SKILL.md +0 -82
  138. package/extensions/enact-operator/skills/tdd/SKILL.md +0 -59
  139. package/extensions/enact-operator/skills/team/SKILL.md +0 -199
  140. package/extensions/enact-operator/skills/trace/SKILL.md +0 -41
  141. package/extensions/enact-operator/skills/ultragoal/SKILL.md +0 -99
  142. package/extensions/enact-operator/skills/ultraqa/SKILL.md +0 -113
  143. package/extensions/enact-operator/skills/ultrawork/SKILL.md +0 -145
  144. package/extensions/enact-operator/skills/ultrawork/planner.md +0 -28
  145. package/extensions/enact-operator/skills/wiki/SKILL.md +0 -41
  146. package/extensions/enact-operator/skills/work-with-workitem/SKILL.md +0 -51
  147. /package/extensions/{enact-operator → enact-evolve}/assets/icon.png +0 -0
  148. /package/extensions/{enact-operator → enact-evolve}/assets/logo.png +0 -0
@@ -1,9 +1,12 @@
1
1
  name = "explore"
2
2
  description = "Codebase sweep agent for absolute-path findings and quote-friendly evidence"
3
+ model = "gpt-5.3-codex-spark"
4
+ claude_model = "haiku"
5
+ cursor_model = "default"
3
6
  model_reasoning_effort = "medium"
4
7
  sandbox_mode = "danger-full-access"
5
8
  developer_instructions = """
6
- You are the Enact Loop explore agent.
9
+ Agent definition: codebase sweep agent for absolute-path findings and quote-friendly evidence.
7
10
 
8
11
  Role:
9
12
  - Find relevant files, symbols, and relationships quickly.
@@ -1,9 +1,12 @@
1
1
  name = "planner"
2
2
  description = "Structured implementation planner that never writes production code"
3
+ model = "gpt-5.5"
4
+ claude_model = "opus"
5
+ cursor_model = "default"
3
6
  model_reasoning_effort = "medium"
4
7
  sandbox_mode = "danger-full-access"
5
8
  developer_instructions = """
6
- You are the Enact Loop planner agent.
9
+ Agent definition: structured implementation planner that never writes production code.
7
10
 
8
11
  Role:
9
12
  - Turn a goal into a small, reviewable execution plan with clear acceptance criteria.
@@ -1,14 +1,18 @@
1
1
  name = "verifier"
2
2
  description = "Evidence-first verifier for real-surface QA and completion claims — independent grader"
3
+ model = "gpt-5.3-codex-spark"
4
+ claude_model = "haiku"
5
+ cursor_model = "default"
3
6
  model_reasoning_effort = "high"
4
7
  sandbox_mode = "danger-full-access"
5
8
  tools = "Read, Grep, Glob, Bash"
6
9
  developer_instructions = """
7
- You are the Enact Loop verifier agent. You are an INDEPENDENT GRADER.
10
+ Agent definition: evidence-first verifier for real-surface QA and completion claims independent grader.
8
11
 
9
- You run on a different model and vendor from the executor. You must reach your own verdict
10
- independently — do not defer to the executor's self-assessment. Your verdict is recorded by
11
- `loop_grader_verdict` and is required before the judgment stage can close.
12
+ You run on a different model and vendor from the executor. Reach your own verdict
13
+ independently — do not defer to the executor's self-assessment. Return a verdict envelope to the
14
+ driver (default) or call `loop_grader_verdict` directly with the dispatch-minted continuationId.
15
+ You have NO closure authority — do not call loop_complete, summary write, pause/resume, or retarget.
12
16
 
13
17
  Role:
14
18
  - Check whether completion claims are supported by fresh evidence.
@@ -19,7 +23,7 @@ Rules:
19
23
  - Do not trust prior claims without rerunning or directly reading evidence.
20
24
  - Mark each requirement VERIFIED, PARTIAL, or MISSING.
21
25
  - Separate missing evidence from failing behavior.
22
- - Record your GO/NO-GO verdict via loop_grader_verdict do not self-report on behalf of the executor.
26
+ - Return verdict envelope to driver (captureSource=relayed) or call loop_grader_verdict directly with continuationId from dispatch. No closure tools.
23
27
 
24
28
  Output contract:
25
29
  - verdict: PASS, FAIL, or INCOMPLETE
@@ -0,0 +1,82 @@
1
+ ---
2
+ name: advisor
3
+ description: >-
4
+ Single independent cross-vendor advisory pass on a WorkItem or decision —
5
+ GO / CONCERNS / NO-GO with rationale. Use when asked to "get advice on",
6
+ "sanity-check", "second opinion", "advisor", or when the driver hits an
7
+ uncertain judgment call (visual/UX, risk, approach) mid-drive. Read-only:
8
+ no code changes, no board mutation, no loop drive.
9
+ metadata:
10
+ author: Amsterdam Data Labs
11
+ version: 1.0.0
12
+ ---
13
+
14
+ # advisor
15
+
16
+ > **Storage is GLOBAL — never write to a repo-local `.enact` dir.** Resolve the project's global dir:
17
+ > 1. `ROOT="$(git rev-parse --show-toplevel)"`
18
+ > 2. In `~/.enact/workspaces.json` → `workspaces`, find the entry whose `.root` == `$ROOT`; its object key is `<name>-<id>`.
19
+ > 3. Factory planning artifacts go under `~/.enact/factory/projects/<key>/…`; loop runtime state and closure summaries go under `~/.enact/loop/projects/<key>/…`.
20
+
21
+ A **single** independent opinion from one strong cross-vendor agent. This is the
22
+ lightest **escalation** path: the default cheap graders (minimax M3 / kimi K2.7) handle routine
23
+ judgment; advisor is invoked when the driver hits a high-risk judgment call that cheap graders
24
+ are unlikely to catch — visual/UX fidelity, a11y subtlety, public-API surface, or any decision
25
+ where a false-GO from a cheap model would be costly. Not a full review, not a debate.
26
+
27
+ ## When to escalate to advisor
28
+
29
+ - **Frontend / UI:** a11y (contrast, focus, ARIA) · visual / UX judgment · consumer-API surface
30
+ - **Any tier:** a judgment call where the executor is uncertain and cheap grader false-GO would be harmful
31
+
32
+ The validated 3-wave run evidence: strong graders caught five real defects (faked-AA contrast,
33
+ missing focus, `{...rest}` a11y override, untested variant, theme flash) that every mechanical gate
34
+ passed AND that cheap graders would likely have false-GO'd.
35
+
36
+ ## Model selection
37
+
38
+ Advisor runs on a **strong cross-vendor** model:
39
+ - **gpt-5.5** — preferred for Frontend / UI a11y / visual judgment (distinct from sonnet executor)
40
+ - **opus 4.8** — preferred when executor is codex / gpt lineage (cross-vendor from OpenAI)
41
+
42
+ If the strong escalation model is unavailable, say so and STOP — do not substitute a cheap or
43
+ same-lineage model and call it independent.
44
+
45
+ ## Boundaries (hard)
46
+
47
+ - **Read-only.** No edits, no commits, no worktree, no board mutation, no
48
+ `loop_*` calls. Advice only.
49
+ - **Cross-vendor.** The advisor runs on a **different model/vendor** from
50
+ whoever is driving (independence). If a distinct model is unavailable, say so
51
+ and STOP — do not give a same-model "opinion" and call it independent.
52
+ - **One agent, one pass.** For a debate or root-cause use [`committee`](../committee/SKILL.md).
53
+
54
+ ## Sequence
55
+
56
+ 1. Load context: `factory_workitem_get` for the WorkItem (goal, acceptance
57
+ criteria, current state), plus the specific question/artifact in doubt.
58
+ 2. Spawn ONE `audit`-tier grader subagent on a strong cross-vendor model:
59
+
60
+ ```
61
+ Agent({
62
+ subagent_type: "critic" | "architect" | "verifier", // fit the question
63
+ model: "gpt-5.5" | "claude-opus-4-8", // strong cross-vendor; ≠ executor model
64
+ prompt: "<WorkItem context + the exact decision/artifact +
65
+ acceptance criteria + 'Return GO / CONCERNS / NO-GO with
66
+ rationale and the single most important risk.'>"
67
+ })
68
+ ```
69
+
70
+ 3. Return the verdict verbatim to the driver: **GO** (proceed), **CONCERNS**
71
+ (proceed with the listed mitigations), or **NO-GO** (do not proceed; reason).
72
+
73
+ ## Output
74
+
75
+ `{ verdict: GO | CONCERNS | NO-GO, rationale, topRisk, advisorModel }` — and the
76
+ `advisorModel` must visibly differ from the driver's model.
77
+
78
+ ## Related
79
+
80
+ - [`committee`](../committee/SKILL.md) — two contrasting agents debate a stuck item.
81
+ - [`drive-loop`](../drive-loop/SKILL.md) — for a binding judgment gate, use a
82
+ contract grader (`loop_grader_verdict`), not advisor. Advisor is non-binding.
@@ -5,6 +5,11 @@ description: "Walk the diff for TODO/placeholder/silent-catch noise and replace
5
5
 
6
6
  # AI Slop Cleaner
7
7
 
8
+ > **Storage is GLOBAL — never write to a repo-local `.enact` dir.** Resolve the project's global dir:
9
+ > 1. `ROOT="$(git rev-parse --show-toplevel)"`
10
+ > 2. In `~/.enact/workspaces.json` → `workspaces`, find the entry whose `.root` == `$ROOT`; its object key is `<name>-<id>` (e.g. `enact-evolve-a38d1e`).
11
+ > 3. Loop artifacts go under `~/.enact/factory/projects/<key>/…`.
12
+
8
13
  ## Purpose
9
14
 
10
15
  Removes low-quality AI-generated residue from code produced in a loop session: `// TODO`,
@@ -41,7 +46,7 @@ deleted.
41
46
  ## State Contract
42
47
 
43
48
  - Reads: changed files in the working tree
44
- - Writes: same files (in-place edits only); no new files, no new state in `.enact/loop/`
49
+ - Writes: same files (in-place edits only); no new files, no new state in `~/.enact/factory/projects/<key>/`
45
50
 
46
51
  ## Final Check
47
52
 
@@ -0,0 +1,347 @@
1
+ ---
2
+ name: autonomous-runner
3
+ description: >-
4
+ Makes Claude the factory DRIVER. Use when asked to "drive factory workitems",
5
+ "run the factory", "drive the board", "work the queue", "drain the queue", or
6
+ "be the factory driver". Picks ready, in-scope, dependency-ordered WorkItems
7
+ and drives each to closure through the enact-loop contract (work-with-workitem
8
+ + drive-loop), lands them via the Azure DevOps CI strategy, and repeats until
9
+ the in-scope queue is drained or a stop condition is hit. This is the MANUAL
10
+ driver path (Claude as driver, no daemon).
11
+ metadata:
12
+ author: Amsterdam Data Labs
13
+ version: 1.0.0
14
+ ---
15
+
16
+ # autonomous-runner
17
+
18
+ > **Storage is GLOBAL — never write to a repo-local `.enact` dir.** Resolve the project's global dir:
19
+ > 1. `ROOT="$(git rev-parse --show-toplevel)"`
20
+ > 2. In `~/.enact/workspaces.json` → `workspaces`, find the entry whose `.root` == `$ROOT`; its object key is `<name>-<id>`.
21
+ > 3. Factory artifacts go under `~/.enact/factory/projects/<key>/…`; loop runtime state and closure summaries go under `~/.enact/loop/projects/<key>/…`.
22
+
23
+ You are the factory **DRIVER**. The factory picks work and owns the board;
24
+ Paseo supervises the agents; **enact-loop** runs each WorkItem's contract and
25
+ enforces the gates. This skill is the OUTER loop that drains the queue. Each
26
+ item is delivered with [`work-with-workitem`](../work-with-workitem/SKILL.md) +
27
+ [`drive-loop`](../drive-loop/SKILL.md), landed with
28
+ [`azdo-ci-strategy`](../azdo-ci-strategy/SKILL.md).
29
+
30
+ ```
31
+ in-scope queue ──▶ pick next ready (dep-ordered) ──▶ classify + route ──▶
32
+ build contract ──▶ drive-loop (dispatch → grade → close) ──▶ PR to integration
33
+ ──▶ CI green ──▶ auto-merge ──▶ next item ──▶ … ──▶ queue empty → STOP
34
+ ```
35
+
36
+ ---
37
+
38
+ ## The operating contract — STATE THIS AT START, THEN OBEY IT
39
+
40
+ Before driving anything, print this contract so the human sees the boundaries
41
+ you will hold. These are **hard gates and hard stops**, not guidelines. The
42
+ governing principle: **when reality does not match the contract, fail loud and
43
+ stop — never degrade to fake progress.** A weakened gate is worse than a
44
+ stopped gate.
45
+
46
+ ### Scope (hard boundary)
47
+ - **DO** drain only the **already in-scope** queue — the items returned by
48
+ `GET /api/factory/queue` (the repos the human toggled ON).
49
+ - **DON'T** ever toggle a repo, change `enabledProjects`, or otherwise pull
50
+ more items from the pool. **The human owns scope.** There is no condition —
51
+ empty queue, "almost done", "one more would help" — under which you flip a
52
+ toggle. Empty in-scope queue → STOP, report, done.
53
+ - **DON'T** scope-creep an item. Discovered follow-up / out-of-scope / tech-debt
54
+ → **create a NEW Azure DevOps WorkItem** so it re-enters the queue and ships
55
+ properly. Keep each diff to the item's stated scope.
56
+
57
+ ### Dependencies (hard ordering)
58
+ - **DO** pick only items whose predecessors are done; drive in dependency
59
+ (topo) order. The queue endpoint already resolves this — trust its order and
60
+ its `blocked` set.
61
+ - **DON'T** start a `blocked` item or invent an order. Blocked → skip, it waits.
62
+
63
+ ### Loop / graders / closure (hard gate)
64
+ - **DO** drive every item through a loop **contract** via `drive-loop`:
65
+ mechanical stages = commands (exit-0), judgment stages = independent graders.
66
+ - **DO** enforce **grader model ≠ executor model** (cross-vendor independence).
67
+ If a distinct, available grader model cannot be obtained, **STOP the item
68
+ with `E_NO_DIVERSITY`** — do NOT grade with the executor's own model to keep
69
+ moving.
70
+ - **DON'T** self-approve a judgment stage, skip a grader, or proceed to closure
71
+ without a recorded `loop_grader_verdict`. A judgment stage with no verdict is
72
+ a **block**, never an auto-pass. No "grader timed out → assume GO."
73
+ - **DON'T** mark a WorkItem **Closed**. Factory owns lifecycle: advance booleans
74
+ via `factory_workitem_lifecycle_advance`; the factory closes.
75
+ - **DON'T** use `git stash` during an active loop — invalidates worktree fingerprints.
76
+
77
+ ### Branch / PR / CI (follow azdo-ci-strategy exactly)
78
+ - **DO** branch from `integration` (kebab-case). A **pass** may bundle several
79
+ related WorkItems into one branch/PR — combining is allowed.
80
+ - **DO** land via **PR to `integration`** with `--work-items <id...> --squash
81
+ --auto-complete --delete-source-branch`. **Squash is policy-required** — if
82
+ `pr create` rejects the strategy, set it on the PR: `az repos pr update --id
83
+ <pr> --squash true --auto-complete true --delete-source-branch true`. Let PR CI
84
+ gate the merge.
85
+ - **DON'T** branch from `main`, commit directly to `integration`/`main`, or
86
+ promote to `main` (that's the automation's integration→main PR + manual approval).
87
+
88
+ ### Serialize on GREEN integration (HARD GATE)
89
+ - **DO NOT start the next pass until `integration` is GREEN.** A pass counts as
90
+ done only when its PR is **merged AND `integration`'s latest build is
91
+ succeeded**. Verify integration's build status is green before picking the next
92
+ WorkItem(s).
93
+ - **One pass in flight at a time** — never a second open `integration` PR, and
94
+ never new work stacked on an unmerged or red integration.
95
+ - If `integration` goes **red** after a merge: STOP. Drive integration back to
96
+ green (fix-forward or revert) before any new pass. Never pile new work onto a
97
+ red integration.
98
+
99
+ ### Failures (fail loud)
100
+ - **DON'T** swallow failures. CI red, stalled agent, missing dependency, tool
101
+ error → surface it and STOP the item. No `|| true`, no silent retry-then-
102
+ pretend-pass. Retries are allowed only when explicit in the loop's policy and
103
+ visible in the log.
104
+
105
+ ### Dispatch discipline (Paseo)
106
+ - **DO** use `notifyOnFinish` and move on; respect `loopWatch` stalled/watchdog
107
+ signals.
108
+ - **DON'T** poll running agents, and **DON'T restart the Paseo daemon** (it
109
+ kills every running agent).
110
+
111
+ ### Stop conditions (never open-ended)
112
+ Stop and report when ANY of these is true:
113
+ 1. In-scope queue is empty (`total === 0` or no eligible items remain).
114
+ 2. `--max-items` or `--max-time` budget reached (if the human set one).
115
+ 3. A hard blocker that needs a human (CI cannot be made green, `E_NO_DIVERSITY`,
116
+ ambiguous scope, repeated stall).
117
+
118
+ ---
119
+
120
+ ## The drive loop
121
+
122
+ ### Step 0 — Read the queue (single source of truth for scope + order)
123
+
124
+ ```
125
+ GET http://<dashboard-host>:<port>/api/factory/queue
126
+ → { ok: true, queue: QueueEntry[], blocked: QueueEntry[], total: number }
127
+ ```
128
+
129
+ The dashboard the human is running serves this (port shown when the dashboard
130
+ starts; default factory config). It returns the **dependency-resolved,
131
+ project-scoped** queue — the same model the board renders. Each `QueueEntry`
132
+ has `{ id, title, kind, status, priority, area, projectSlug, topoRank,
133
+ eligible, blockedBy, reason, nextStage, updatedAt }`, already ordered
134
+ `topoRank → priority → updatedAt → id`.
135
+
136
+ - **This endpoint is the ONLY authority for what is in scope and in what order.**
137
+ - If the endpoint is unreachable → **STOP**. Do NOT fall back to
138
+ `factory_workitem_list` to guess scope — guessing scope risks working an
139
+ out-of-scope repo, which violates the hard boundary. Tell the human to start
140
+ the dashboard.
141
+ - Use `factory_workitem_get` only to enrich a chosen item's detail
142
+ (acceptance criteria, closure requirements) — never to bypass scope/order.
143
+
144
+ Pick the **first `eligible` item**. If none are eligible (all blocked or queue
145
+ empty) → go to STOP.
146
+
147
+ ### Step 1 — Classify + route the item
148
+
149
+ Classify by signals in priority order: explicit label/tag → `area` → relevant
150
+ file paths → `kind` → title keywords. When ambiguous, default to **Backend /
151
+ logic** and add a judgment grader. (Full tree:
152
+ `FACTORY_DRIVE_DECISION_TREE.md` in the enact-factory repo.)
153
+
154
+ | Type | Executor (surface) | Grader — default cheap | Escalate to strong grader when |
155
+ |---|---|---|---|
156
+ | Frontend / UI | `claude` / sonnet — UX, visual, copy | **minimax M3** / **kimi K2.7** | `advisor` (gpt-5.5) for a11y / visual / UX judgment |
157
+ | Backend / logic | `codex` / **gpt-5.4** — mechanical workhorse | **minimax M3** / **kimi K2.7** | `committee` (opus + gpt-5.5) if architecture unclear |
158
+ | Data-heavy | `codex` / **gpt-5.4** high-effort + data-safety stages | **minimax M3** / **kimi K2.7** | `committee` for risky or irreversible migrations |
159
+ | Infra / CI | `codex` / **gpt-5.4** + pipeline validation | **minimax M3** / **kimi K2.7** | `committee` before branch policy; `opus 4.8` for security/public-API changes |
160
+ | Docs | `claude` / sonnet (writing) | **minimax M3** / **kimi K2.7** | rarely |
161
+
162
+ The **executor ≠ grader** rule is a hard gate everywhere (see contract above).
163
+
164
+ #### Function × cost tiers
165
+
166
+ Two orthogonal axes route work: **TYPE** (frontend / backend / data / infra / docs) sets the
167
+ contract shape (gates + number of judgment stages); **FUNCTION × COST** decides which model runs
168
+ each role:
169
+
170
+ | Function tier | Models | Used for |
171
+ |---|---|---|
172
+ | Workers (execute) | **sonnet** (in-window) · **codex/gpt-5.4** | implementation, diffs, refactors, bugfixes |
173
+ | Planning / architecture | **opus 4.8** · **gpt-5.5** (reasoning: xhigh) | plans, interface/architecture design, hard root-cause, committee |
174
+ | Verify / review / grade (DEFAULT cheap) | **minimax M3** (opencode) · **kimi K2.7** | first-pass judgment on routine code-review / verify / docs (~80% of grading) |
175
+ | Explorers (map, read-only) | **haiku** · **cursor composer 2.5** | codebase sweeps, naming maps, brownfield discovery — never grade |
176
+
177
+ **Grading = cheap default + risk-based escalation.** minimax M3 / kimi K2.7 grade the routine
178
+ ~80%. Escalate to a strong cross-vendor grader for:
179
+ - Frontend / UI a11y or visual / UX judgment → **advisor** = **gpt-5.5** (or opus if executor was codex)
180
+ - Security, public API / barrel / contract changes → **opus 4.8**
181
+ - Architecture decisions / risky or irreversible migrations → **committee** (opus + gpt-5.5)
182
+
183
+ #### Contract shape per tier
184
+
185
+ The number and kind of judgment stages should match the deliverable's risk profile.
186
+ This matters: in a validated 3-wave run, independent graders caught FIVE real defects
187
+ (faked-AA contrast, missing focus indicator, consumer-prop a11y override, untested
188
+ variant, theme flash) that every mechanical gate passed — the two-judgment Frontend/UI
189
+ shape and cross-vendor model-distinct grading are what surfaced them.
190
+
191
+ | Tier | Judgment stages | Rationale |
192
+ |---|---|---|
193
+ | Frontend / UI | TWO — `code-review` + `verify` | Visual, a11y, and consumer-API surface require both implementation review and evidence the deliverable actually meets acceptance criteria |
194
+ | Backend / logic | ONE or TWO — `code-review` (+ `verify` for risky changes) | Logic gates benefit from impl review; add `verify` when the blast radius is large |
195
+ | Docs | ONE lighter `review` (e.g. `critic` for scope fidelity) | Correctness is mainly structural; a single lighter judgment is sufficient |
196
+ | Infra / CI | ONE or TWO — architecture fit + pipeline validation | |
197
+
198
+ #### Sonnet-executor grader caveat
199
+
200
+ When the executor is **`claude-sonnet-4-6`** (or any sonnet-tier model), the
201
+ `cursor` grader (`cursor/claude-sonnet-4-6`) is **NOT model-distinct** — it runs
202
+ the same underlying model and the independence rule is violated.
203
+
204
+ **Default cheap graders for sonnet work:** use **minimax M3** (opencode) or **kimi K2.7** — both
205
+ are vendor-distinct from sonnet and satisfy the independence rule cleanly. Use:
206
+
207
+ - **minimax M3** / **kimi K2.7** — default graders for sonnet-executor work (cheap, independent)
208
+ - **opus 4.8** / **gpt-5.5** — escalation graders for high-risk judgment (see escalation table above)
209
+ - `cursor` grader ONLY when the executor is opus-tier (cursor runs claude-sonnet, so it is distinct from opus)
210
+
211
+ #### Paseo permission-mode table
212
+
213
+ Non-default permission modes are REQUIRED — omitting them causes the grader to stall
214
+ or return an empty session:
215
+
216
+ | Grader provider | Paseo flag | Notes |
217
+ |---|---|---|
218
+ | `codex` | `--mode auto` | `--mode bypass` is rejected by codex |
219
+ | `cursor` | default / agent | `--mode bypass` is a claude mode, NOT cursor's — previously documented wrong; cursor uses default or agent mode |
220
+ | `kimi` | `--mode auto` | Same as codex |
221
+ | `opencode` (minimax M3) | default | No special mode flag needed |
222
+
223
+ **Verdict capture is STRUCTURED, not log-scraped.** Dispatch the grader with:
224
+ `paseo run --output-schema <verdict.json> --json --label continuation=<cid>`
225
+ — stdout is the validated `{verdict, evidence}` object. Recover the actual grader model and cost
226
+ via `paseo ls -a --label continuation=<cid> --json` then `paseo inspect <id> --json`. Watch live
227
+ with `paseo attach <id>` (recover the id by label first).
228
+ See design doc: `enact-loop/docs/design/2026-06-22-paseo-verdict-capture.md`.
229
+
230
+ ### Step 2 — Prepare the item
231
+
232
+ Invoke [`work-with-workitem`](../work-with-workitem/SKILL.md): `factory_workitem_get`
233
+ → confirm readiness → `EnterWorktree` to isolate. Branch off `integration` per
234
+ `azdo-ci-strategy`. Confirm there is **no other open integration PR** first; if
235
+ there is, wait for it (or STOP if `--max-time` would be exceeded).
236
+
237
+ ### Step 3 — Build the contract + drive it
238
+
239
+ Build the loop contract with stages tailored to the type (see per-type stage
240
+ lists in `FACTORY_DRIVE_DECISION_TREE.md` §4), then hand to
241
+ [`drive-loop`](../drive-loop/SKILL.md):
242
+
243
+ - `loop_start({ contract })` — the boulder activates; you cannot stop until
244
+ every required stage passes and every judgment stage has an independent GO.
245
+ - Mechanical stages → `loop_grade({ stageId })` — engine runs stage command in loop root.
246
+ - Judgment stages → `loop_grader_dispatch` → spawn grader on a **different model** →
247
+ driver relays `loop_grader_verdict` (`captureSource: "relayed"`) or grader calls directly.
248
+ - **No `git stash` during an active loop** — invalidates worktree fingerprints.
249
+ - On stall: escalate via `committee` (root-cause) or `advisor` (judgment call);
250
+ if still stuck, STOP the item and report. Never fake a verdict to escape.
251
+
252
+ ### Step 4 — Close + land
253
+
254
+ When the loop signals closure: first run `enact-loop summary write` so the
255
+ runtime stamps a new append-only
256
+ `~/.enact/loop/projects/<key>/state/<YYMMDDHH>-loop-summary.md` and updates
257
+ `summary-current.json`. Then `factory_workitem_lifecycle_advance({ workItemId,
258
+ fields: { <closure booleans> } })` advances lifecycle booleans (this also writes
259
+ the assignment record as a side-effect) — you do NOT set Closed. Then per
260
+ `azdo-ci-strategy`: open the PR to
261
+ `integration` with `--work-items <id> --auto-complete --delete-source-branch`,
262
+ let PR CI gate the merge.
263
+
264
+ - CI red → fix on the same branch; if it cannot be made green → STOP, report.
265
+ - CI green → auto-merge advances the board.
266
+
267
+ ### Step 5 — Next item
268
+
269
+ `ExitWorktree`. Re-read the queue (Step 0) — it reflects the just-merged item
270
+ and any newly-unblocked dependents. Repeat until a stop condition.
271
+
272
+ ---
273
+
274
+ ## Per-item output (report each)
275
+
276
+ For every item, report: chosen item (id + title) and why it was first; type +
277
+ route (executor/grader models, proving cross-vendor); contract stages and their
278
+ results; grader verdicts; closure summary; PR URL; CI outcome; lifecycle delta.
279
+ Then the next item. At STOP: a one-line summary of the run (items drained, items
280
+ blocked + why, follow-up WorkItems created, stop reason).
281
+
282
+ ---
283
+
284
+ ## Skill selection — what to use when, and what NEVER to use
285
+
286
+ The runner does **not** guess skills from keywords. It selects deterministically.
287
+ The hard rule: **a skill is runner-safe only if it runs to completion with NO
288
+ human input.** Anything that waits on a person is out — there is no human in an
289
+ autonomous drain.
290
+
291
+ **Spine (every item, in order):**
292
+ - `workitem-triage` (read-only) — confirm the item is ready before driving.
293
+ - `work-with-workitem` — isolate + deliver the item.
294
+ - `drive-loop` — run the contract (mechanical stages + judgment graders).
295
+ - `azdo-ci-strategy` — branch / PR / CI / merge.
296
+
297
+ **Invoke as loop stages or sub-steps when the item/type calls for it (all
298
+ autonomous-safe):**
299
+ - `plan` / `looplan` / `hyperplan` — when the item needs a reviewable plan first.
300
+ - `tdd`, `testing-strategy` — implementing behavior / writing tests (mechanical).
301
+ - `trace` — read-only blast-radius mapping before risky changes.
302
+ - `review` — pre-landing review (can back a judgment stage).
303
+ - `ultraqa` — QA cycling with hard-stop gates (a lane).
304
+ - `ai-slop-cleaner` — sweep the diff for TODO/placeholder/silent-catch before closure.
305
+ - `remove-deadcode` — LSP-verified deletion (only for cleanup items; gate carefully).
306
+ - `research` — evidence-first research when the approach is unknown.
307
+ - `security-research` — only for security items. **Side-effectful: it can
308
+ auto-create AzDO bugs** — use deliberately.
309
+
310
+ **Escalation (when stuck/uncertain — autonomous-safe):**
311
+ - `advisor` — one cross-vendor GO/CONCERNS judgment call.
312
+ - `committee` — two contrasting agents root-cause a stalled/looping item.
313
+ - `handoff` — delegate an independent item to a detached, board-tracked agent.
314
+
315
+ **NEVER invoke during an autonomous drain (human-in-the-loop):**
316
+ - `deep-interview` — an interactive clarification loop that REQUIRES a human to
317
+ answer. If an item is too vague/ambiguous to drive, do NOT deep-interview.
318
+ Instead: **file the open questions as a NEW AzDO WorkItem** (or mark the item
319
+ blocked-needs-human) and move on. Ambiguity is a STOP/escalate signal, never a
320
+ prompt-the-user signal.
321
+
322
+ ---
323
+
324
+ ## Anti-patterns (these are the failure modes this skill exists to prevent)
325
+
326
+ - **Toggling a repo to get more work.** Never. The human owns scope.
327
+ - **Grading with the executor's model** because a grader model was unavailable.
328
+ STOP with `E_NO_DIVERSITY` instead.
329
+ - **Auto-passing a judgment stage** because the grader was slow/failed. Block.
330
+ - **Quietly fixing out-of-scope things.** File a new WorkItem.
331
+ - **`|| true` / silent retries** to make a red step look green. Fail loud.
332
+ - **Restarting the Paseo daemon** to "unstick" an agent. It kills everything.
333
+ - **Marking a WorkItem Closed.** Factory owns lifecycle via `factory_workitem_lifecycle_advance`.
334
+ - **Branching from `main` or running two integration PRs at once.**
335
+
336
+ ---
337
+
338
+ ## Related
339
+
340
+ - [`work-with-workitem`](../work-with-workitem/SKILL.md) — per-item prep + handoff.
341
+ - [`drive-loop`](../drive-loop/SKILL.md) — the contract runner + grader dispatch.
342
+ - [`azdo-ci-strategy`](../azdo-ci-strategy/SKILL.md) — branch/PR/CI/release rules.
343
+ - [`advisor`](../advisor/SKILL.md) — single cross-vendor GO/CONCERNS judgment.
344
+ - [`committee`](../committee/SKILL.md) — root-cause a stuck/blocked item.
345
+ - [`handoff`](../handoff/SKILL.md) — delegate an item to a detached, board-tracked agent.
346
+ - `FACTORY_DRIVE_DECISION_TREE.md` (enact-factory repo) — full type→route tree
347
+ and per-type contract stages.
@@ -17,6 +17,11 @@ metadata:
17
17
 
18
18
  # Azure DevOps CI/CD Strategy — enact-os
19
19
 
20
+ > **Storage is GLOBAL — never write to a repo-local `.enact` dir.** Resolve the project's global dir:
21
+ > 1. `ROOT="$(git rev-parse --show-toplevel)"`
22
+ > 2. In `~/.enact/workspaces.json` → `workspaces`, find the entry whose `.root` == `$ROOT`; its object key is `<name>-<id>`.
23
+ > 3. Factory planning artifacts go under `~/.enact/factory/projects/<key>/…`; this skill itself does not define durable markdown artifacts.
24
+
20
25
  The enact-os branch / release strategy and pipeline conventions. The `az` CLI
21
26
  and REST command catalogs live in `references/` (see [Reference files](#reference-files))
22
27
  and load on demand — this file holds the strategy and the everyday workflow.
@@ -33,8 +38,8 @@ and load on demand — this file holds the strategy and the everyday workflow.
33
38
  ## Branch flow
34
39
 
35
40
  ```text
36
- feat/* PR to integration ── PR CI ──► auto-merge to integration
37
- fix/* PR to integration ── PR CI ──► auto-merge to integration
41
+ feat/* local CI ──► PR to integration ── PR CI ──► auto-merge to integration
42
+ fix/* local CI ──► PR to integration ── PR CI ──► auto-merge to integration
38
43
  integration ── automation creates or updates one PR to main ──► main
39
44
  main ── manual approval + CI ──► publish
40
45
  ```
@@ -120,13 +125,24 @@ az devops configure --defaults organization="$ORG_URL" project="$PROJECT"
120
125
  --source-branch feat/my-branch \
121
126
  --target-branch integration \
122
127
  --title "feat: description" \
128
+ --squash true \
123
129
  --auto-complete true \
124
130
  --delete-source-branch true \
125
131
  --detect
126
132
  ```
127
133
 
128
- 4. CI runs automatically on the PR. When CI passes the PR **auto-merges** into
129
- `integration`. No reviewer is required on integration.
134
+ **Merge strategy is policy-gated.** `integration` requires the **squash**
135
+ strategy without `--squash true`, completion fails with
136
+ `Merge strategy is not allowed by policy`. Note `pr create` may still create
137
+ the PR while rejecting the auto-complete settings; in that case set them on
138
+ the existing PR (idempotent):
139
+
140
+ ```bash
141
+ az repos pr update --id <pr-id> --squash true --auto-complete true --delete-source-branch true
142
+ ```
143
+
144
+ 4. CI runs automatically on the PR. When CI passes the PR **auto-merges** (squash)
145
+ into `integration`. No reviewer is required on integration.
130
146
  5. After each successful merge to `integration`, automation creates or updates
131
147
  one open `integration → main` PR.
132
148
  6. The `integration → main` PR stays **manual** — owner approval on it is the
@@ -136,10 +152,10 @@ az devops configure --defaults organization="$ORG_URL" project="$PROJECT"
136
152
 
137
153
  | Trigger | What runs |
138
154
  | ------------------------------------------- | ----------------------------------------------------------------------------------------------- |
139
- | Push to `feat/*` | Build + test + lint |
155
+ | Push to `feat/*` | **Nothing** local Docker CI is the gate |
140
156
  | Push to `fix/*` | **Nothing** — local Docker CI is the gate |
141
- | PR opened / updated targeting `integration` | Build + test + lint |
142
- | Push to `integration` (after PR merged) | Build + test + lint |
157
+ | PR opened / updated targeting `integration` | Build + test + lint (no version bump — see Version management) |
158
+ | Push to `integration` (after PR merged) | Build + test + lint + **patch version auto-bump** (pushed directly to `integration`, `***NO_CI***`) |
143
159
  | Push to `main` (after PR merged) | Build + test + lint + **Publish** for publishable packages; CI only for internal-only packages |
144
160
 
145
161
  > **⛔ NEVER use `az pipelines run` to manually trigger CI as a substitute for a
@@ -161,14 +177,26 @@ az devops configure --defaults organization="$ORG_URL" project="$PROJECT"
161
177
  - Internal-only packages can omit a publish stage while keeping the same
162
178
  `integration` / `main` CI trigger pattern.
163
179
  - Merging the `integration → main` PR IS the manual approval for publish.
164
- - Version bumps are done manually by the repo owner before approving that PR.
180
+ - Patch auto-bumps per PR (see Version management); the owner sets minor/major and
181
+ gates the `integration → main` merge that triggers publish.
165
182
 
166
183
  ## Version management
167
184
 
168
- - No automated changesets or version bots.
169
- - Repo owner bumps `package.json` / `Cargo.toml` version manually.
170
- - Automation opens or updates the `integration main` PR.
171
- - Repo owner merges that PR to trigger publish.
185
+ - **Patch auto-bumps on the `integration` build, AFTER each PR merges.** The
186
+ integration CI runs `version-bump.sh --integration` and pushes the bumped
187
+ `package.json` commit **directly to `integration`**, marked `***NO_CI***` so
188
+ Azure skips it (no re-trigger). This needs the Project Build Service to have
189
+ **"Bypass policies when pushing"** on the repo (set in the Git Repositories
190
+ security namespace). Previously this bump ran on the `feat/*`/`fix/*` source
191
+ branch pre-merge, but pushing the bump there updated the PR source and forced a
192
+ second PR validation build (a wasteful double-trigger) — moving it to the
193
+ post-merge integration build removes that. (The bump is one patch per merged PR.)
194
+ - Minor/major bumps are set manually by the repo owner; no changeset tooling.
195
+ - **`integration → main` promotion + publish are owner-gated**: automation
196
+ opens/updates the `integration → main` PR; the owner approves the merge, which
197
+ triggers the versioned publish on `main`.
198
+ - Exception: packages whose version lives in a non-npm file (e.g. Python —
199
+ enact-observe/gateway/voice) disable the auto-bump and bump manually.
172
200
 
173
201
  ## Pipeline trigger config (all packages)
174
202
 
@@ -177,7 +205,6 @@ trigger:
177
205
  branches:
178
206
  include:
179
207
  - integration
180
- - feat/*
181
208
  - main
182
209
 
183
210
  pr:
@@ -186,8 +213,8 @@ pr:
186
213
  - integration
187
214
  ```
188
215
 
189
- `feat/*` is included so pushes to feature branches run CI (per the table above);
190
- `fix/*` is intentionally excluded local Docker CI is its only gate.
216
+ `feat/*` and `fix/*` are intentionally excluded local Docker CI is the only
217
+ branch gate before opening a PR to `integration`.
191
218
 
192
219
  Publish stage condition:
193
220