@williambeto/ai-workflow 2.9.2 โ 2.9.4
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/CHANGELOG.md +41 -0
- package/README.md +36 -19
- package/bin/ai-workflow.js +79 -1
- package/bin/ai-workflow.js.map +1 -1
- package/dist-assets/AGENTS.md +1 -1
- package/dist-assets/agents/astra.md +5 -0
- package/dist-assets/agents/atlas.md +4 -3
- package/dist-assets/agents/nexus.md +5 -0
- package/dist-assets/agents/orion.md +5 -0
- package/dist-assets/agents/phoenix.md +5 -0
- package/dist-assets/agents/sage.md +5 -0
- package/dist-assets/docs/policies/SKILLS_COMMON_GOVERNANCE.md +9 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
## [unreleased]
|
|
2
2
|
|
|
3
|
+
## [2.9.4] - 2026-07-16
|
|
4
|
+
|
|
5
|
+
### ๐ก๏ธ Hardening
|
|
6
|
+
|
|
7
|
+
- Add an opt-in repository-local pre-push hook that rejects direct updates to
|
|
8
|
+
`main` and `master` without changing the published consumer payload
|
|
9
|
+
- Refresh development-only lockfile dependencies to remove known production,
|
|
10
|
+
moderate, high, and critical audit findings
|
|
11
|
+
|
|
12
|
+
### ๐งช Testing
|
|
13
|
+
|
|
14
|
+
- Add stable contract coverage for documentation integrity, protected-branch
|
|
15
|
+
pushes, finalizer change detection, and validation-result precedence
|
|
16
|
+
- Verify that the public tarball excludes contributor hooks, internal
|
|
17
|
+
validators, tests, and generated evidence
|
|
18
|
+
|
|
19
|
+
### ๐ Documentation
|
|
20
|
+
|
|
21
|
+
- Align the README with the canonical AI Workflow Kit product promise,
|
|
22
|
+
installed paths, agent roles, and the actual CLI enforcement boundary
|
|
23
|
+
|
|
24
|
+
## [2.9.3] - 2026-07-16
|
|
25
|
+
|
|
26
|
+
### ๐ Bug Fixes
|
|
27
|
+
|
|
28
|
+
- Restore scoped specialist delegation for every core AIWK agent without
|
|
29
|
+
reintroducing `bash` or `edit` approval prompts
|
|
30
|
+
- Allow Atlas to reach both workflow agents and all registered specialists
|
|
31
|
+
while preventing specialists from delegating recursively
|
|
32
|
+
- Set OpenCode's bounded subagent depth to two so workflow agents delegated by
|
|
33
|
+
Atlas can still consult one specialist
|
|
34
|
+
- Detect stale or incomplete specialist routing through `ai-workflow doctor`
|
|
35
|
+
|
|
36
|
+
### ๐งช Testing
|
|
37
|
+
|
|
38
|
+
- Cover the complete six-caller by twenty-specialist routing matrix
|
|
39
|
+
- Verify upgrades from permission-free `2.9.2` configurations and reject
|
|
40
|
+
recursive specialist delegation
|
|
41
|
+
- Exercise Atlas to workflow-agent to specialist routing in a real OpenCode
|
|
42
|
+
runtime smoke test
|
|
43
|
+
|
|
3
44
|
## [2.9.2] - 2026-07-16
|
|
4
45
|
|
|
5
46
|
### ๐ Bug Fixes
|
package/README.md
CHANGED
|
@@ -15,20 +15,22 @@
|
|
|
15
15
|
|
|
16
16
|
## What is AI Workflow Kit?
|
|
17
17
|
|
|
18
|
-
AI Workflow
|
|
18
|
+
AI Workflow is an npm CLI that installs agents, commands, skills, policies and templates into your repository. It guides coding agents from request to implementation, validation and evidence.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
AI Workflow Kit preserves workflow integrity so coding agents cannot skip from request to code to success without an explicit implementation path, proportional validation, and final evidence.
|
|
21
|
+
|
|
22
|
+
It works with [OpenCode](https://opencode.ai) to turn a natural language request into a proportionate delivery โ with branch isolation, optional specialist analysis, observed validation, and evidence appropriate to the task risk.
|
|
21
23
|
|
|
22
24
|
**Without AIWK**, a coding agent receives a request, writes code, and reports success. There is no proof, no branch isolation, and no guarantee that tests passed.
|
|
23
25
|
|
|
24
26
|
**With AIWK**, the same request travels through a mandatory workflow:
|
|
25
27
|
|
|
26
28
|
```
|
|
27
|
-
Your request โ Classification โ Branch Gate โ
|
|
28
|
-
โ
|
|
29
|
+
Your request โ Classification โ Branch Gate โ Workflow Owner
|
|
30
|
+
โ Observed Validation โ Evidence โ Handoff
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
Within the `ai-workflow execute` control plane, every stage is evaluated and a successful final state requires observed validation. Direct model chat remains subject to runtime capabilities; see the [runtime compatibility matrix](dist-assets/docs/compatibility/runtime-matrix.md).
|
|
32
34
|
|
|
33
35
|
---
|
|
34
36
|
|
|
@@ -47,7 +49,7 @@ AI Workflow Kit enforces a contract: **the agent must earn the right to deliver.
|
|
|
47
49
|
|
|
48
50
|
## How it works
|
|
49
51
|
|
|
50
|
-
AIWK installs a structured team of 6
|
|
52
|
+
AIWK installs a structured team of 6 core workflow agents into your repository. Each agent has a defined role and ownership boundary. Any core agent may request bounded analysis from a registered specialist when that improves the result, while retaining ownership of its workflow stage.
|
|
51
53
|
|
|
52
54
|
When you run `npx aw execute "your task"`, Atlas (the coordinator) takes over:
|
|
53
55
|
|
|
@@ -59,7 +61,7 @@ When you run `npx aw execute "your task"`, Atlas (the coordinator) takes over:
|
|
|
59
61
|
| **4. Implement** | Astra | Implements the change on the feature branch |
|
|
60
62
|
| **5. Validate** | Sage | Runs tests, accessibility checks, visual regression โ writes evidence |
|
|
61
63
|
| **6. Remediate** | Phoenix | If validation fails, Phoenix heals within a bounded attempt limit |
|
|
62
|
-
| **7. Evidence** | Atlas | Saves `EVIDENCE.json`
|
|
64
|
+
| **7. Evidence** | Atlas | Saves the handoff and ledger; persists `EVIDENCE.json` when the evidence policy requires it |
|
|
63
65
|
|
|
64
66
|
> **Proportional by design.** A typo fix in a README gets 1 remediation attempt and no spec. A payment integration gets 3 attempts, a required SDD, and mandatory persisted evidence. The kit calibrates automatically.
|
|
65
67
|
|
|
@@ -100,7 +102,7 @@ This creates the `.ai-workflow/` directory and installs 6 agents, 25 skills, and
|
|
|
100
102
|
npx aw execute "Add a health check endpoint returning HTTP 200"
|
|
101
103
|
```
|
|
102
104
|
|
|
103
|
-
Atlas classifies the request,
|
|
105
|
+
Atlas classifies the request, the branch gate establishes a safe branch, Astra owns requested changes, and validation and evidence run proportionally.
|
|
104
106
|
|
|
105
107
|
### 4. Check the evidence
|
|
106
108
|
|
|
@@ -134,7 +136,7 @@ Each agent has a fixed role and cannot exceed its operational boundary.
|
|
|
134
136
|
| ๐งช **Sage** | Validator | Audits changes, runs quality gates, writes verifiable evidence |
|
|
135
137
|
| ๐ง **Phoenix** | Recovery | Heals broken states within a bounded remediation limit |
|
|
136
138
|
|
|
137
|
-
Agents are installed as prompts in your `.ai-workflow/agents/` directory. You can read, audit, or customise them.
|
|
139
|
+
Agents are installed as prompts in your `.ai-workflow/opencode/agents/` directory. You can read, audit, or customise them.
|
|
138
140
|
|
|
139
141
|
---
|
|
140
142
|
|
|
@@ -170,15 +172,22 @@ You don't configure this. The kit reads your request and calibrates automaticall
|
|
|
170
172
|
|
|
171
173
|
Running `npx aw init` writes the following into your repository:
|
|
172
174
|
|
|
175
|
+
The canonical OpenCode runtime paths are `.ai-workflow/opencode/agents/`, `.ai-workflow/opencode/commands/`, `.ai-workflow/opencode/skills/`, and `.ai-workflow/opencode/docs/`.
|
|
176
|
+
|
|
173
177
|
```
|
|
174
178
|
.ai-workflow/
|
|
175
|
-
โโโ
|
|
176
|
-
โโโ
|
|
177
|
-
โโโ
|
|
179
|
+
โโโ opencode/
|
|
180
|
+
โ โโโ agents/ # Atlas, Nexus, Orion, Astra, Sage, Phoenix prompts
|
|
181
|
+
โ โโโ commands/ # Slash commands for OpenCode
|
|
182
|
+
โ โโโ skills/ # Domain skills (architecture, security, database, ...)
|
|
183
|
+
โ โโโ docs/ # Runtime policies, profiles, references, and guides
|
|
184
|
+
โโโ harness/ # Workflow and handoff harness
|
|
185
|
+
โโโ schemas/ # Evidence and workflow schemas
|
|
178
186
|
โโโ templates/ # Specification and handoff templates
|
|
179
|
-
โโโ
|
|
180
|
-
|
|
181
|
-
|
|
187
|
+
โโโ history/ # Runtime-generated workflow ledgers
|
|
188
|
+
โโโ handoffs/ # Runtime-generated delivery handoffs
|
|
189
|
+
AGENTS.md # Project-local contributor contract
|
|
190
|
+
QUICKSTART.md # Installed quickstart
|
|
182
191
|
opencode.jsonc # OpenCode runtime configuration
|
|
183
192
|
```
|
|
184
193
|
|
|
@@ -188,8 +197,8 @@ Everything is plain text โ readable, auditable, and version-controlled.
|
|
|
188
197
|
|
|
189
198
|
## Safety Guarantees
|
|
190
199
|
|
|
191
|
-
- **Branch
|
|
192
|
-
- **Read-only confinement**: tasks classified as read-only
|
|
200
|
+
- **Branch gate**: write-mode execution is blocked on `main`/`master`. A feature branch is created automatically when the worktree is clean.
|
|
201
|
+
- **Read-only confinement**: tasks classified as read-only compare SHA-256 workspace snapshots before and after execution; any observed mutation blocks completion.
|
|
193
202
|
- **Bounded remediation**: Phoenix is limited to N attempts. The kit never loops indefinitely.
|
|
194
203
|
- **Mandatory handoff**: every write-mode execution produces a `HANDOFF-<task>.md` with evidence, diff, and status โ regardless of risk level.
|
|
195
204
|
- **Schema-validated evidence**: `EVIDENCE.json` is validated against a strict Ajv schema. Path traversal and shell injection are blocked.
|
|
@@ -231,12 +240,12 @@ Beyond the 6 core agents, AIWK ships 25 domain skills that agents activate as co
|
|
|
231
240
|
|
|
232
241
|
## Contributing
|
|
233
242
|
|
|
234
|
-
AIWK
|
|
243
|
+
This development repository follows the AIWK contributor contract directly without installing consumer runtime assets into itself. To contribute:
|
|
235
244
|
|
|
236
245
|
```
|
|
237
246
|
src/ TypeScript source (CLI + Core)
|
|
238
247
|
dist-assets/ Templates, agents, skills, schemas installed into consumer repos
|
|
239
|
-
tests/ Unit
|
|
248
|
+
tests/ Unit, contract, linting, and E2E suites
|
|
240
249
|
internal/ Validation pipelines and release scripts
|
|
241
250
|
docs/ Guides, ADRs, specs, and release notes
|
|
242
251
|
```
|
|
@@ -249,6 +258,14 @@ npm run validate
|
|
|
249
258
|
|
|
250
259
|
All 23 quality gates must pass.
|
|
251
260
|
|
|
261
|
+
Contributors without server-side branch protection can enable the repository's local push safeguard explicitly:
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
npm run setup:hooks
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
The hook blocks pushes targeting `main` or `master` and allows maintenance or feature branches. It prevents accidents but is not a server-side security boundary and can be bypassed with Git's `--no-verify` option.
|
|
268
|
+
|
|
252
269
|
---
|
|
253
270
|
|
|
254
271
|
## License
|
package/bin/ai-workflow.js
CHANGED
|
@@ -761,6 +761,58 @@ var SUBAGENTS = {
|
|
|
761
761
|
"Technical-Leader": { description: "Capability only: analyze technical decisions, architecture, and trade-offs", skill: "technical-leadership" },
|
|
762
762
|
"UI-UX-Engineer": { description: "Capability only: review usability and interface clarity", skill: "ui-ux-design" }
|
|
763
763
|
};
|
|
764
|
+
var CORE_AGENT_NAMES = Object.freeze(Object.keys(AGENTS));
|
|
765
|
+
var SPECIALIST_AGENT_NAMES = Object.freeze(Object.keys(SUBAGENTS));
|
|
766
|
+
var MIN_SUBAGENT_DEPTH = 2;
|
|
767
|
+
function inspectSpecialistRoutingConfig(opencodeConfig) {
|
|
768
|
+
const errors = [];
|
|
769
|
+
const warnings = [];
|
|
770
|
+
const agents = opencodeConfig?.agent ?? {};
|
|
771
|
+
if (typeof opencodeConfig?.subagent_depth !== "number" || opencodeConfig.subagent_depth < MIN_SUBAGENT_DEPTH) {
|
|
772
|
+
errors.push(`OpenCode subagent_depth must be at least ${MIN_SUBAGENT_DEPTH} for workflow-agent to specialist routing`);
|
|
773
|
+
}
|
|
774
|
+
for (const specialist of SPECIALIST_AGENT_NAMES) {
|
|
775
|
+
if (agents[specialist]?.mode !== "subagent") {
|
|
776
|
+
errors.push(`specialist missing or not configured as subagent: ${specialist}`);
|
|
777
|
+
}
|
|
778
|
+
if (agents[specialist]?.permission?.task !== void 0) {
|
|
779
|
+
errors.push(`specialist must not delegate recursively: ${specialist}`);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
for (const caller of CORE_AGENT_NAMES) {
|
|
783
|
+
const taskPermissions = agents[caller]?.permission?.task;
|
|
784
|
+
if (!taskPermissions || typeof taskPermissions !== "object" || Array.isArray(taskPermissions)) {
|
|
785
|
+
errors.push(`core agent lacks explicit specialist task routing: ${caller}`);
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
if (taskPermissions["*"] !== "deny") {
|
|
789
|
+
errors.push(`core agent task routing must deny unspecified targets: ${caller}`);
|
|
790
|
+
}
|
|
791
|
+
if (Object.values(taskPermissions).includes("ask")) {
|
|
792
|
+
errors.push(`core agent task routing must not request approval: ${caller}`);
|
|
793
|
+
}
|
|
794
|
+
const blockedSpecialists = SPECIALIST_AGENT_NAMES.filter((specialist) => taskPermissions[specialist] !== "allow");
|
|
795
|
+
if (blockedSpecialists.length > 0) {
|
|
796
|
+
errors.push(`core agent cannot reach all specialists: ${caller} (${blockedSpecialists.join(", ")})`);
|
|
797
|
+
}
|
|
798
|
+
const otherCoreAgents = CORE_AGENT_NAMES.filter((name) => name !== caller);
|
|
799
|
+
if (caller === "Atlas") {
|
|
800
|
+
const blockedCoreAgents = otherCoreAgents.filter((name) => taskPermissions[name] !== "allow");
|
|
801
|
+
if (blockedCoreAgents.length > 0) {
|
|
802
|
+
errors.push(`Atlas cannot reach all workflow agents: ${blockedCoreAgents.join(", ")}`);
|
|
803
|
+
}
|
|
804
|
+
} else {
|
|
805
|
+
const recursiveCoreAgents = otherCoreAgents.filter((name) => taskPermissions[name] === "allow");
|
|
806
|
+
if (recursiveCoreAgents.length > 0) {
|
|
807
|
+
errors.push(`non-Atlas core agent can recursively delegate workflow ownership: ${caller} (${recursiveCoreAgents.join(", ")})`);
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
if (opencodeConfig?.permission?.task !== void 0) {
|
|
812
|
+
warnings.push("consumer-level permission.task may override AIWK specialist routing or enable recursive delegation");
|
|
813
|
+
}
|
|
814
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
815
|
+
}
|
|
764
816
|
var COMMANDS = {
|
|
765
817
|
atlas: { description: "Decide safest next step and delegate to the appropriate workflow or agent", agent: "Atlas" },
|
|
766
818
|
run: { description: "Execute the master orchestration pipeline (Gates, SDD, Implementation, Validation, Healing)", agent: "Atlas" },
|
|
@@ -779,11 +831,23 @@ var COMMANDS = {
|
|
|
779
831
|
};
|
|
780
832
|
function buildManagedConfig() {
|
|
781
833
|
const agent = {};
|
|
834
|
+
const specialistTaskPermissions = Object.fromEntries([
|
|
835
|
+
["*", "deny"],
|
|
836
|
+
...SPECIALIST_AGENT_NAMES.map((name) => [name, "allow"])
|
|
837
|
+
]);
|
|
838
|
+
const atlasTaskPermissions = Object.fromEntries([
|
|
839
|
+
["*", "deny"],
|
|
840
|
+
...CORE_AGENT_NAMES.filter((name) => name !== "Atlas").map((name) => [name, "allow"]),
|
|
841
|
+
...SPECIALIST_AGENT_NAMES.map((name) => [name, "allow"])
|
|
842
|
+
]);
|
|
782
843
|
for (const [name, def] of Object.entries(AGENTS)) {
|
|
783
844
|
agent[name] = {
|
|
784
845
|
mode: def.mode,
|
|
785
846
|
description: def.description,
|
|
786
|
-
prompt: `{file:./.ai-workflow/opencode/agents/${name.toLowerCase()}.md}
|
|
847
|
+
prompt: `{file:./.ai-workflow/opencode/agents/${name.toLowerCase()}.md}`,
|
|
848
|
+
permission: {
|
|
849
|
+
task: name === "Atlas" ? atlasTaskPermissions : specialistTaskPermissions
|
|
850
|
+
}
|
|
787
851
|
};
|
|
788
852
|
}
|
|
789
853
|
for (const [name, def] of Object.entries(SUBAGENTS)) {
|
|
@@ -804,6 +868,7 @@ function buildManagedConfig() {
|
|
|
804
868
|
return {
|
|
805
869
|
$schema: "https://opencode.ai/config.json",
|
|
806
870
|
default_agent: "Atlas",
|
|
871
|
+
subagent_depth: MIN_SUBAGENT_DEPTH,
|
|
807
872
|
agent,
|
|
808
873
|
skills: {
|
|
809
874
|
paths: ["./.ai-workflow/opencode/skills"]
|
|
@@ -839,6 +904,7 @@ async function mergeOpencodeConfig(cwd, { force = false, backupRoot = ".ai-workf
|
|
|
839
904
|
const next = {
|
|
840
905
|
...currentWithoutLegacy,
|
|
841
906
|
$schema: current.$schema ?? managed.$schema,
|
|
907
|
+
subagent_depth: typeof current.subagent_depth === "number" ? Math.max(current.subagent_depth, managed.subagent_depth) : managed.subagent_depth,
|
|
842
908
|
...managed.mcp ? {
|
|
843
909
|
mcp: {
|
|
844
910
|
...current.mcp ?? {},
|
|
@@ -1988,6 +2054,18 @@ async function checkOpencodeJson(cwd, state) {
|
|
|
1988
2054
|
console.log(`FAIL opencode agent entries missing: ${missingAgents.join(", ")}`);
|
|
1989
2055
|
}
|
|
1990
2056
|
}
|
|
2057
|
+
const specialistRouting = inspectSpecialistRoutingConfig(opencodeConfig);
|
|
2058
|
+
if (specialistRouting.valid) {
|
|
2059
|
+
console.log(`PASS OpenCode specialist routing available (${CORE_AGENT_NAMES.length} callers, ${SPECIALIST_AGENT_NAMES.length} specialists)`);
|
|
2060
|
+
} else {
|
|
2061
|
+
state.hasWarning = true;
|
|
2062
|
+
for (const error of specialistRouting.errors) console.log(`WARN ${error}`);
|
|
2063
|
+
console.log("WARN specialist routing is stale or incomplete; rerun `ai-workflow init --yes --no-install`");
|
|
2064
|
+
}
|
|
2065
|
+
for (const warning of specialistRouting.warnings) {
|
|
2066
|
+
state.hasWarning = true;
|
|
2067
|
+
console.log(`WARN ${warning}`);
|
|
2068
|
+
}
|
|
1991
2069
|
} catch {
|
|
1992
2070
|
state.hasFailure = true;
|
|
1993
2071
|
console.log("FAIL opencode.jsonc is not valid JSONC");
|