feat: add dynamic workflow team orchestration surface

Adds dynamic workflow/team orchestration skills, the content pack, and control-pane work-item/Kanban state DB support. Includes reviewer hardening for state-db CLI validation, optional state DB failure handling, and mergeStateStatus projection.
This commit is contained in:
Affaan Mustafa
2026-06-04 21:45:13 +08:00
committed by GitHub
parent 0f84c0e279
commit bc8e12bb80
19 changed files with 872 additions and 17 deletions

View File

@@ -0,0 +1,104 @@
#!/usr/bin/env node
/**
* Validate the dynamic workflow and team-orchestration public surface.
*/
'use strict';
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const REPO_ROOT = path.join(__dirname, '..', '..');
const SURFACES = [
{
path: 'skills/dynamic-workflow-mode/SKILL.md',
required: [
'dynamic workflow mode',
'task-local harness',
'shared skill',
'eval',
'control pane',
'handoff'
],
},
{
path: 'skills/team-agent-orchestration/SKILL.md',
required: [
'team-based orchestration',
'agent kanban',
'work item',
'ownership',
'merge gate',
'control pane'
],
},
{
path: 'docs/business/team-agent-orchestration-content-pack.md',
required: [
'Video Concepts',
'Article Angles',
'agent kanban',
'team orchestration',
'dynamic workflows',
'distribution'
],
forbidden: [
'https://x.com/',
'http://x.com/',
'twitter.com/'
],
},
];
function readSurface(relativePath) {
const absolutePath = path.join(REPO_ROOT, relativePath);
assert.ok(fs.existsSync(absolutePath), `${relativePath} is missing`);
return fs.readFileSync(absolutePath, 'utf8');
}
function test(name, fn) {
try {
fn();
console.log(` PASS ${name}`);
return true;
} catch (error) {
console.log(` FAIL ${name}`);
console.log(` Error: ${error.message}`);
return false;
}
}
function runTests() {
console.log('\n=== Testing dynamic workflow team surface ===\n');
let passed = 0;
let failed = 0;
for (const surface of SURFACES) {
if (test(`${surface.path} exists and carries required concepts`, () => {
const content = readSurface(surface.path);
const normalized = content.toLowerCase();
for (const term of surface.required) {
assert.ok(
normalized.includes(term.toLowerCase()),
`${surface.path} is missing required concept: ${term}`
);
}
for (const forbidden of surface.forbidden || []) {
assert.ok(
!normalized.includes(forbidden.toLowerCase()),
`${surface.path} must not expose private bookmark source URLs: ${forbidden}`
);
}
})) passed++; else failed++;
}
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
process.exit(failed > 0 ? 1 : 0);
}
runTests();

View File

@@ -227,6 +227,96 @@ async function writeSampleEcc2Database(dbPath) {
db.close();
}
async function writeSampleWorkItemsDatabase(dbPath) {
const SQL = await initSqlJs();
const db = new SQL.Database();
db.run(`
CREATE TABLE work_items (
id TEXT PRIMARY KEY,
source TEXT NOT NULL,
source_id TEXT,
title TEXT NOT NULL,
status TEXT NOT NULL,
priority TEXT,
url TEXT,
owner TEXT,
repo_root TEXT,
session_id TEXT,
metadata TEXT NOT NULL CHECK (json_valid(metadata)),
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
`);
const insertWorkItem = db.prepare(`
INSERT INTO work_items (
id, source, source_id, title, status, priority, url, owner,
repo_root, session_id, metadata, created_at, updated_at
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
insertWorkItem.run([
'agent-card-001',
'manual',
'agent-card-001',
'Build dynamic workflow skill',
'running',
'high',
null,
'codex',
'/repo/ecc',
'lead-hermes',
JSON.stringify({
branch: 'product/dynamic-workflow-team-orchestration',
mergeGate: 'focused tests and catalog check pass',
acceptance: ['skill exists', 'content pack exists'],
}),
'2026-06-04T09:00:00Z',
'2026-06-04T09:05:00Z',
]);
insertWorkItem.run([
'agent-card-002',
'github-pr',
'2131',
'Merge ECC control pane',
'done',
'normal',
'https://github.com/affaan-m/ECC/pull/2131',
'affaan',
'/repo/ecc',
null,
JSON.stringify({
branch: 'product/ecc2-knowledge-control-pane',
mergeStateStatus: 'CLEAN',
}),
'2026-06-03T13:00:00Z',
'2026-06-03T13:55:00Z',
]);
insertWorkItem.run([
'agent-card-003',
'manual',
'blocked-content',
'Record content pipeline',
'blocked',
'high',
null,
'operator',
'/repo/ecc',
null,
JSON.stringify({
blocker: 'needs publish approval',
mergeGate: 'approval packet accepted',
}),
'2026-06-04T09:10:00Z',
'2026-06-04T09:12:00Z',
]);
insertWorkItem.free();
fs.writeFileSync(dbPath, Buffer.from(db.export()));
db.close();
}
async function mutateSqlDatabase(dbPath, mutator) {
const SQL = await initSqlJs();
const buffer = fs.readFileSync(dbPath);
@@ -290,6 +380,64 @@ async function runTests() {
}
})) passed++; else failed++;
if (await test('projects state-store work items into agent Kanban summary', async () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-control-pane-work-items-'));
const dbPath = path.join(tempDir, 'ecc2.db');
const stateDbPath = path.join(tempDir, 'state.db');
try {
await writeSampleEcc2Database(dbPath);
await writeSampleWorkItemsDatabase(stateDbPath);
const snapshot = await buildControlPaneSnapshot({
dbPath,
stateDbPath,
repoRoot: path.join(__dirname, '..', '..'),
query: 'workflow',
});
assert.strictEqual(snapshot.workItems.totalCount, 3);
assert.strictEqual(snapshot.workItems.openCount, 2);
assert.strictEqual(snapshot.workItems.blockedCount, 1);
assert.strictEqual(snapshot.workItems.doneCount, 1);
assert.strictEqual(snapshot.workItems.kanban.running, 1);
assert.strictEqual(snapshot.workItems.kanban.blocked, 1);
assert.strictEqual(snapshot.workItems.items[0].id, 'agent-card-003');
assert.strictEqual(snapshot.workItems.items[0].mergeGate, 'approval packet accepted');
assert.strictEqual(snapshot.workItems.items[1].branch, 'product/dynamic-workflow-team-orchestration');
assert.strictEqual(
snapshot.workItems.items.find(item => item.id === 'agent-card-002').mergeGate,
'CLEAN'
);
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
})) passed++; else failed++;
if (await test('treats an unreadable optional state-store database as empty work items', async () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-control-pane-corrupt-work-items-'));
const dbPath = path.join(tempDir, 'ecc2.db');
const stateDbPath = path.join(tempDir, 'corrupt-state.db');
try {
await writeSampleEcc2Database(dbPath);
fs.writeFileSync(stateDbPath, 'not a sqlite database', 'utf8');
const snapshot = await buildControlPaneSnapshot({
dbPath,
stateDbPath,
repoRoot: path.join(__dirname, '..', '..'),
query: 'workflow',
});
assert.strictEqual(snapshot.stateDatabase.exists, true);
assert.strictEqual(snapshot.workItems.totalCount, 0);
assert.strictEqual(snapshot.summary.totalSessions, 2);
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
})) passed++; else failed++;
if (await test('resolves config from explicit db path and TOML connector file', async () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-control-pane-config-'));
const dbPath = path.join(tempDir, 'state.db');

View File

@@ -148,6 +148,8 @@ async function runTests() {
'8788',
'--db',
'/tmp/ecc2.db',
'--state-db',
'/tmp/ecc-state.db',
'--query',
'Hermes memory',
'--no-open',
@@ -156,6 +158,7 @@ async function runTests() {
assert.strictEqual(parsed.host, '127.0.0.1');
assert.strictEqual(parsed.port, 8788);
assert.strictEqual(parsed.dbPath, '/tmp/ecc2.db');
assert.strictEqual(parsed.stateDbPath, '/tmp/ecc-state.db');
assert.strictEqual(parsed.query, 'Hermes memory');
assert.strictEqual(parsed.openBrowser, false);
})) passed++; else failed++;
@@ -171,6 +174,17 @@ async function runTests() {
);
})) passed++; else failed++;
if (await test('rejects missing state database path values', async () => {
assert.throws(
() => parseArgs(['node', 'scripts/control-pane.js', '--state-db']),
/Invalid --state-db value/
);
assert.throws(
() => parseArgs(['node', 'scripts/control-pane.js', '--state-db', '--query', 'Hermes']),
/Invalid --state-db value/
);
})) passed++; else failed++;
if (await test('serves HTML and snapshot JSON from a temp ECC2 database', async () => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ecc-control-pane-server-'));
const dbPath = path.join(tempDir, 'ecc2.db');
@@ -191,12 +205,15 @@ async function runTests() {
const html = await fetchLocal(`${app.url}/`).then(response => response.text());
assert.ok(html.includes('ECC Control Pane'));
assert.ok(html.includes('id="app"'));
assert.ok(html.includes('id="work-items"'));
assert.ok(html.includes('function renderWorkItems'));
assert.ok(html.includes('function showError'));
assert.ok(html.includes('response.ok'));
const snapshot = await fetchLocal(`${app.url}/api/snapshot?query=control`).then(response => response.json());
assert.strictEqual(snapshot.schemaVersion, 'ecc.control-pane.snapshot.v1');
assert.strictEqual(snapshot.summary.totalSessions, 1);
assert.strictEqual(snapshot.workItems.totalCount, 0);
assert.strictEqual(snapshot.sessions[0].id, 'session-a');
} finally {
await app.close();