@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.
- package/README.md +11 -12
- package/dist/create/enact.js +1 -1
- package/dist/create/enact.js.map +1 -1
- package/dist/create/index.d.ts +4 -3
- package/dist/create/index.d.ts.map +1 -1
- package/dist/create/index.js +9 -2
- package/dist/create/index.js.map +1 -1
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/install.d.ts +5 -0
- package/dist/install.d.ts.map +1 -1
- package/dist/install.js +10 -3
- package/dist/install.js.map +1 -1
- package/dist/internal/agents.d.ts +6 -1
- package/dist/internal/agents.d.ts.map +1 -1
- package/dist/internal/agents.js +8 -4
- package/dist/internal/agents.js.map +1 -1
- package/dist/internal/claude.d.ts +24 -0
- package/dist/internal/claude.d.ts.map +1 -1
- package/dist/internal/claude.js +99 -0
- package/dist/internal/claude.js.map +1 -1
- package/dist/internal/platform.d.ts +3 -1
- package/dist/internal/platform.d.ts.map +1 -1
- package/dist/internal/platform.js +7 -1
- package/dist/internal/platform.js.map +1 -1
- package/dist/internal/types.d.ts +2 -1
- package/dist/internal/types.d.ts.map +1 -1
- package/dist/principles.d.ts +28 -0
- package/dist/principles.d.ts.map +1 -0
- package/dist/principles.js +159 -0
- package/dist/principles.js.map +1 -0
- package/extensions/dev-state/.agents/plugin.json +2 -1
- package/extensions/enact-context/.agents/plugin.json +2 -1
- package/extensions/enact-context/hooks/hooks.json +0 -10
- package/extensions/enact-context/skills/enact-context/SKILL.md +14 -12
- package/extensions/enact-context/skills/enact-context/scripts/install.sh +7 -7
- package/extensions/enact-core/.agents/plugin.json +2 -1
- package/extensions/enact-core/OPERATING-PRINCIPLES.md +7 -0
- package/extensions/enact-core/hooks/hooks.json +12 -0
- package/extensions/enact-evolve/.agents/plugin.json +47 -0
- package/extensions/enact-evolve/agents/evolve-session-analyst.toml +37 -0
- package/extensions/enact-evolve/skills/session-analysis/SKILL.md +98 -0
- package/extensions/enact-evolve/skills/session-analysis/scripts/run-evolve-analysis.sh +343 -0
- package/extensions/enact-factory/.agents/plugin.json +2 -2
- package/extensions/enact-factory/agents/architect.toml +9 -5
- package/extensions/enact-factory/agents/code-reviewer.toml +9 -5
- package/extensions/enact-factory/agents/critic.toml +9 -5
- package/extensions/enact-factory/agents/executor.toml +4 -1
- package/extensions/enact-factory/agents/explore.toml +4 -1
- package/extensions/enact-factory/agents/planner.toml +4 -1
- package/extensions/enact-factory/agents/verifier.toml +9 -5
- package/extensions/enact-factory/skills/advisor/SKILL.md +82 -0
- package/extensions/enact-factory/skills/ai-slop-cleaner/SKILL.md +6 -1
- package/extensions/enact-factory/skills/autonomous-runner/SKILL.md +347 -0
- package/extensions/enact-factory/skills/azdo-ci-strategy/SKILL.md +42 -15
- package/extensions/enact-factory/skills/committee/SKILL.md +80 -0
- package/extensions/enact-factory/skills/deep-interview/SKILL.md +9 -13
- package/extensions/enact-factory/skills/drive-loop/SKILL.md +161 -31
- package/extensions/enact-factory/skills/drive-loop/references/contract-schema.md +26 -6
- package/extensions/enact-factory/skills/handoff/SKILL.md +72 -0
- package/extensions/enact-factory/skills/hyperplan/SKILL.md +11 -3
- package/extensions/enact-factory/skills/looplan/SKILL.md +34 -17
- package/extensions/enact-factory/skills/plan/SKILL.md +40 -8
- package/extensions/enact-factory/skills/remove-deadcode/SKILL.md +6 -1
- package/extensions/enact-factory/skills/research/SKILL.md +14 -4
- package/extensions/enact-factory/skills/review/SKILL.md +21 -2
- package/extensions/enact-factory/skills/security-research/SKILL.md +5 -2
- package/extensions/enact-factory/skills/tdd/SKILL.md +7 -1
- package/extensions/enact-factory/skills/testing-strategy/SKILL.md +5 -0
- package/extensions/enact-factory/skills/trace/SKILL.md +5 -0
- package/extensions/enact-factory/skills/ultraqa/SKILL.md +21 -15
- package/extensions/enact-factory/skills/work-with-workitem/SKILL.md +5 -0
- package/extensions/enact-factory/skills/workitem-triage/SKILL.md +5 -0
- package/extensions/enact-loop/.agents/plugin.json +5 -4
- package/extensions/enact-loop/scripts/validate.mjs +123 -0
- package/extensions/enact-loop/skills/enact-loop/SKILL.md +189 -30
- package/extensions/enact-wiki/.agents/plugin.json +2 -1
- package/extensions/net-revenue-management/.agents/plugin.json +2 -1
- package/extensions/plugin-dev/.agents/plugin.json +2 -1
- package/extensions/plugin-dev/skills/start/SKILL.md +3 -3
- package/package.json +1 -1
- package/scripts/check-hooks.mjs +5 -5
- package/scripts/check-principles.mjs +19 -4
- package/scripts/enact-extensions.mjs +237 -90
- package/scripts/lib/hooks.mjs +61 -217
- package/scripts/lib/migrate-artifacts.mjs +144 -0
- package/scripts/lib/principles.mjs +109 -0
- package/scripts/lib/provision-mcp.mjs +1 -1
- package/scripts/lib/run-install.mjs +72 -2
- package/scripts/lib/run-prune.mjs +23 -2
- package/scripts/lib/run-sync.mjs +4 -1
- package/scripts/postinstall.mjs +6 -6
- package/scripts/setup-enact-context.sh +20 -15
- package/scripts/version-bump.sh +22 -1
- package/spec/codex.json +5 -0
- package/spec/enact.json +3 -3
- package/spec/enact.md +1 -4
- package/spec/index.json +1 -1
- package/extensions/enact-factory/hooks/hooks.json +0 -14
- package/extensions/enact-operator/.agents/plugin.json +0 -56
- package/extensions/enact-operator/.app.json +0 -3
- package/extensions/enact-operator/.mcp.json +0 -10
- package/extensions/enact-operator/_taxonomy.md +0 -86
- package/extensions/enact-operator/agents/README.md +0 -5
- package/extensions/enact-operator/agents/architect.toml +0 -25
- package/extensions/enact-operator/agents/code-reviewer.toml +0 -24
- package/extensions/enact-operator/agents/critic.toml +0 -30
- package/extensions/enact-operator/agents/executor.toml +0 -24
- package/extensions/enact-operator/agents/explore.toml +0 -23
- package/extensions/enact-operator/agents/planner.toml +0 -24
- package/extensions/enact-operator/agents/verifier.toml +0 -24
- package/extensions/enact-operator/docs/skill-variants.md +0 -44
- package/extensions/enact-operator/hooks/hooks.json +0 -91
- package/extensions/enact-operator/skills/ai-slop-cleaner/SKILL.md +0 -50
- package/extensions/enact-operator/skills/analyze/SKILL.md +0 -91
- package/extensions/enact-operator/skills/ask/SKILL.md +0 -47
- package/extensions/enact-operator/skills/autopilot/SKILL.md +0 -170
- package/extensions/enact-operator/skills/autoresearch-goal/SKILL.md +0 -79
- package/extensions/enact-operator/skills/cancel/SKILL.md +0 -99
- package/extensions/enact-operator/skills/configure-notifications/SKILL.md +0 -77
- package/extensions/enact-operator/skills/deep-interview/SKILL.md +0 -80
- package/extensions/enact-operator/skills/doctor/SKILL.md +0 -48
- package/extensions/enact-operator/skills/hud/SKILL.md +0 -49
- package/extensions/enact-operator/skills/hyperplan/SKILL.md +0 -47
- package/extensions/enact-operator/skills/plan/SKILL.md +0 -78
- package/extensions/enact-operator/skills/ralph/SKILL.md +0 -201
- package/extensions/enact-operator/skills/ralph/gemini.md +0 -18
- package/extensions/enact-operator/skills/ralplan/SKILL.md +0 -151
- package/extensions/enact-operator/skills/remove-deadcode/SKILL.md +0 -45
- package/extensions/enact-operator/skills/research/SKILL.md +0 -74
- package/extensions/enact-operator/skills/review/SKILL.md +0 -58
- package/extensions/enact-operator/skills/security-research/SKILL.md +0 -54
- package/extensions/enact-operator/skills/setup/SKILL.md +0 -91
- package/extensions/enact-operator/skills/setup/scripts/install.sh +0 -50
- package/extensions/enact-operator/skills/skill/SKILL.md +0 -82
- package/extensions/enact-operator/skills/tdd/SKILL.md +0 -59
- package/extensions/enact-operator/skills/team/SKILL.md +0 -199
- package/extensions/enact-operator/skills/trace/SKILL.md +0 -41
- package/extensions/enact-operator/skills/ultragoal/SKILL.md +0 -99
- package/extensions/enact-operator/skills/ultraqa/SKILL.md +0 -113
- package/extensions/enact-operator/skills/ultrawork/SKILL.md +0 -145
- package/extensions/enact-operator/skills/ultrawork/planner.md +0 -28
- package/extensions/enact-operator/skills/wiki/SKILL.md +0 -41
- package/extensions/enact-operator/skills/work-with-workitem/SKILL.md +0 -51
- /package/extensions/{enact-operator → enact-evolve}/assets/icon.png +0 -0
- /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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
10
|
-
independently — do not defer to the executor's self-assessment.
|
|
11
|
-
`loop_grader_verdict`
|
|
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
|
-
-
|
|
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
|
|
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
|
-
|
|
129
|
-
|
|
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/*` |
|
|
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
|
-
-
|
|
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
|
-
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
-
|
|
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/*`
|
|
190
|
-
|
|
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
|
|