ai-engineering-loop 1.0.11 → 1.0.13
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/.agents/devil-advocate.md +15 -4
- package/.agents/judge.md +11 -3
- package/.agents/workflows/ai-engineering-loop.md +4 -2
- package/.claude/agents/devil-advocate.md +15 -4
- package/.claude/agents/judge.md +11 -3
- package/.claude/commands/ai-engineering-loop.md +1 -1
- package/.claude/skills/ai-engineering-loop/SKILL.md +6 -5
- package/.gemini/skills/ai-engineering-loop/SKILL.md +59 -0
- package/.grok/agents/devil-advocate.md +15 -4
- package/.grok/agents/judge.md +11 -3
- package/.grok/commands/ai-engineering-loop.md +1 -1
- package/.grok/skills/ai-engineering-loop/SKILL.md +8 -6
- package/README.md +31 -3
- package/README.npm.md +5 -2
- package/adapters/dot/README.md +27 -3
- package/adapters/dot/coreview.md +30 -11
- package/adapters/dot/mattermost.md +31 -19
- package/adapters/dot/skills/dot-dev-skill-router/SKILL.md +55 -0
- package/adapters/dot/skills/dot-dev-workflow/SKILL.md +118 -0
- package/agents/devil-advocate.md +3 -1
- package/agents/maker.md +13 -11
- package/agents/shared/devil-advocate.body.md +15 -4
- package/agents/shared/judge.body.md +11 -3
- package/bin/ai-engineering-loop.js +131 -22
- package/core/context-impact-assessment.md +2 -0
- package/core/definition-of-done.md +2 -0
- package/core/goal-contract.md +23 -4
- package/core/grill-policy.md +94 -0
- package/core/handoff-policy.md +44 -0
- package/core/judge-policy.md +11 -5
- package/core/project-initialization.md +2 -1
- package/core/repo-config-schema.md +15 -1
- package/core/root-cause-analysis.md +30 -0
- package/core/verification-loop.md +3 -1
- package/examples/initialization/discovery-trace.md +1 -1
- package/examples/initialization/generated-context.md +1 -1
- package/lib/orchestration.js +20 -2
- package/lib/sync-hosts.js +195 -0
- package/package.json +2 -1
- package/policies/finding-policy.md +7 -1
- package/policies/review-budget.md +1 -0
- package/policies/tdd-policy.md +33 -0
- package/scripts/init.sh +21 -0
- package/templates/repo-config/adr-readme.md +33 -0
- package/templates/repo-config/glossary.md +18 -0
- package/tests/living-context.test.js +46 -0
- package/tests/orchestration.test.js +80 -0
- package/tests/skill-host-compat.test.js +110 -0
- package/tests/sync-hosts.test.js +119 -0
|
@@ -14,8 +14,14 @@ const fs = require('fs');
|
|
|
14
14
|
const path = require('path');
|
|
15
15
|
const crypto = require('crypto');
|
|
16
16
|
const { execSync } = require('child_process');
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
const {
|
|
18
|
+
homeDir,
|
|
19
|
+
applyHostSync,
|
|
20
|
+
planHostSync,
|
|
21
|
+
formatHostSyncReport
|
|
22
|
+
} = require('../lib/sync-hosts.js');
|
|
23
|
+
|
|
24
|
+
const VERSION = '1.0.13';
|
|
19
25
|
const CWD = process.cwd();
|
|
20
26
|
const CONTEXT_DIR = path.join(CWD, '.ai-engineering-loop');
|
|
21
27
|
|
|
@@ -26,9 +32,20 @@ const REQUIRED_FILES = [
|
|
|
26
32
|
'architecture.md',
|
|
27
33
|
'conventions.md',
|
|
28
34
|
'verification.md',
|
|
29
|
-
'adapter.md'
|
|
35
|
+
'adapter.md',
|
|
36
|
+
'glossary.md',
|
|
37
|
+
'adrs/README.md'
|
|
30
38
|
];
|
|
31
39
|
|
|
40
|
+
function writeContextFile(filePath, content, { overwrite = true } = {}) {
|
|
41
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
42
|
+
if (!overwrite && fs.existsSync(filePath) && fs.statSync(filePath).size > 0) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
fs.writeFileSync(filePath, content);
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
|
|
32
49
|
/**
|
|
33
50
|
* Colorized console helpers
|
|
34
51
|
*/
|
|
@@ -249,7 +266,8 @@ function analyzeRepository(rootDir) {
|
|
|
249
266
|
/**
|
|
250
267
|
* Generate Context Files (Including metadata.json Baseline)
|
|
251
268
|
*/
|
|
252
|
-
function generateContextFiles(rootDir, discovery, trigger = 'init', impact = 'INITIAL_BOOTSTRAP') {
|
|
269
|
+
function generateContextFiles(rootDir, discovery, trigger = 'init', impact = 'INITIAL_BOOTSTRAP', options = {}) {
|
|
270
|
+
const overwriteCore = options.overwriteCore !== false;
|
|
253
271
|
const targetDir = path.join(rootDir, '.ai-engineering-loop');
|
|
254
272
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
255
273
|
|
|
@@ -257,7 +275,7 @@ function generateContextFiles(rootDir, discovery, trigger = 'init', impact = 'IN
|
|
|
257
275
|
|
|
258
276
|
// 0. metadata.json (Baseline)
|
|
259
277
|
const metadataJson = {
|
|
260
|
-
contextVersion: '1.0.
|
|
278
|
+
contextVersion: '1.0.13',
|
|
261
279
|
generatedAt: new Date().toISOString(),
|
|
262
280
|
repositoryRevision: currentRevision,
|
|
263
281
|
projectProfile: discovery.profile,
|
|
@@ -268,7 +286,11 @@ function generateContextFiles(rootDir, discovery, trigger = 'init', impact = 'IN
|
|
|
268
286
|
impact
|
|
269
287
|
}
|
|
270
288
|
};
|
|
271
|
-
|
|
289
|
+
writeContextFile(
|
|
290
|
+
path.join(targetDir, 'metadata.json'),
|
|
291
|
+
JSON.stringify(metadataJson, null, 2) + '\n',
|
|
292
|
+
{ overwrite: overwriteCore }
|
|
293
|
+
);
|
|
272
294
|
|
|
273
295
|
// 1. config.md
|
|
274
296
|
const configMd = `# Project Configuration
|
|
@@ -286,7 +308,7 @@ ${discovery.frameworks.map((f) => ` - ${f}`).join('\n') || ' - Standard'}
|
|
|
286
308
|
## Observed Evidence
|
|
287
309
|
${discovery.evidence.map((e) => `- ${e}`).join('\n')}
|
|
288
310
|
`;
|
|
289
|
-
|
|
311
|
+
writeContextFile(path.join(targetDir, 'config.md'), configMd, { overwrite: overwriteCore });
|
|
290
312
|
|
|
291
313
|
// 2. architecture.md
|
|
292
314
|
const archMd = `# Project Architecture
|
|
@@ -306,7 +328,7 @@ ${discovery.topLevelDirs.map((d) => `- \`${d}/\``).join('\n') || '- Flat directo
|
|
|
306
328
|
- Observed from: Directory scan, package manifests
|
|
307
329
|
- Confidence: HIGH
|
|
308
330
|
`;
|
|
309
|
-
|
|
331
|
+
writeContextFile(path.join(targetDir, 'architecture.md'), archMd, { overwrite: overwriteCore });
|
|
310
332
|
|
|
311
333
|
// 3. conventions.md
|
|
312
334
|
const convMd = `# Project Conventions
|
|
@@ -321,7 +343,7 @@ ${discovery.topLevelDirs.map((d) => `- \`${d}/\``).join('\n') || '- Flat directo
|
|
|
321
343
|
- Never commit private secrets, passwords, or API keys.
|
|
322
344
|
- Do not make unsolicited renovations outside the active Goal Contract scope.
|
|
323
345
|
`;
|
|
324
|
-
|
|
346
|
+
writeContextFile(path.join(targetDir, 'conventions.md'), convMd, { overwrite: overwriteCore });
|
|
325
347
|
|
|
326
348
|
// 4. verification.md
|
|
327
349
|
const verifyMd = `# Project Verification Commands
|
|
@@ -337,7 +359,7 @@ ${discovery.scripts.e2e ? `- **e2e**: \`${discovery.scripts.e2e}\`` : ''}
|
|
|
337
359
|
- 100% deterministic checks must pass before Devil's Advocate review.
|
|
338
360
|
- Unit tests must cover boundary cases, null safety, and error paths.
|
|
339
361
|
`;
|
|
340
|
-
|
|
362
|
+
writeContextFile(path.join(targetDir, 'verification.md'), verifyMd, { overwrite: overwriteCore });
|
|
341
363
|
|
|
342
364
|
// 5. adapter.md
|
|
343
365
|
const adapterMd = `# Project Delivery Adapter Configuration
|
|
@@ -348,7 +370,48 @@ ${discovery.adapter.repoSlug ? `- **remote_repository**: "${discovery.adapter.re
|
|
|
348
370
|
- **default_target_branch**: "${discovery.adapter.defaultBranch}"
|
|
349
371
|
- **ci_provider**: "${discovery.adapter.ciProvider}"
|
|
350
372
|
`;
|
|
351
|
-
|
|
373
|
+
writeContextFile(path.join(targetDir, 'adapter.md'), adapterMd, { overwrite: overwriteCore });
|
|
374
|
+
|
|
375
|
+
const glossaryMd = `# Ubiquitous Language
|
|
376
|
+
|
|
377
|
+
One term per concept. Agents and humans use these words in Goal Contracts, tests, code names, and review.
|
|
378
|
+
|
|
379
|
+
## Terms
|
|
380
|
+
|
|
381
|
+
| Term | Meaning | Do not say |
|
|
382
|
+
|---|---|---|
|
|
383
|
+
| Goal Contract | Frozen Stage 1 acceptance document | "the prompt" |
|
|
384
|
+
| Seam | Public interface under test | "the internals" |
|
|
385
|
+
|
|
386
|
+
Update this file during Stage 1 grill when a term is coined or corrected.
|
|
387
|
+
`;
|
|
388
|
+
writeContextFile(path.join(targetDir, 'glossary.md'), glossaryMd, { overwrite: false });
|
|
389
|
+
|
|
390
|
+
const adrReadme = `# Architecture Decision Records
|
|
391
|
+
|
|
392
|
+
Hard decisions that would otherwise live only in chat. Write one ADR when Stage 1 grill settles a choice that future agents must not re-litigate.
|
|
393
|
+
|
|
394
|
+
File name: \`NNN-short-kebab-title.md\`
|
|
395
|
+
|
|
396
|
+
## Template
|
|
397
|
+
|
|
398
|
+
\`\`\`markdown
|
|
399
|
+
# ADR NNN: <title>
|
|
400
|
+
|
|
401
|
+
## Status
|
|
402
|
+
Accepted
|
|
403
|
+
|
|
404
|
+
## Context
|
|
405
|
+
What forced a choice.
|
|
406
|
+
|
|
407
|
+
## Decision
|
|
408
|
+
What we chose, in glossary terms.
|
|
409
|
+
|
|
410
|
+
## Consequences
|
|
411
|
+
What becomes easier, harder, or forbidden.
|
|
412
|
+
\`\`\`
|
|
413
|
+
`;
|
|
414
|
+
writeContextFile(path.join(targetDir, 'adrs', 'README.md'), adrReadme, { overwrite: false });
|
|
352
415
|
}
|
|
353
416
|
|
|
354
417
|
/**
|
|
@@ -460,6 +523,10 @@ function handleInit() {
|
|
|
460
523
|
log.info('AI Engineering Loop — Project Context Bootstrap (init)');
|
|
461
524
|
log.dim(`Target directory: ${CWD}`);
|
|
462
525
|
|
|
526
|
+
let overwriteCore = true;
|
|
527
|
+
let trigger = 'init';
|
|
528
|
+
let impact = 'INITIAL_BOOTSTRAP';
|
|
529
|
+
|
|
463
530
|
if (fs.existsSync(CONTEXT_DIR)) {
|
|
464
531
|
const validation = validateContext(CONTEXT_DIR);
|
|
465
532
|
if (validation.valid) {
|
|
@@ -470,6 +537,9 @@ function handleInit() {
|
|
|
470
537
|
process.exit(0);
|
|
471
538
|
} else {
|
|
472
539
|
log.warn(`! Existing .ai-engineering-loop/ found but incomplete: ${validation.reason}. Repairing...`);
|
|
540
|
+
overwriteCore = false;
|
|
541
|
+
trigger = 'repair';
|
|
542
|
+
impact = 'REPAIR_MISSING';
|
|
473
543
|
}
|
|
474
544
|
}
|
|
475
545
|
|
|
@@ -481,7 +551,7 @@ function handleInit() {
|
|
|
481
551
|
log.dim(`> Package Manager: ${discovery.packageManager}`);
|
|
482
552
|
log.dim(`> Unit Test Command: ${discovery.scripts.testUnit}`);
|
|
483
553
|
|
|
484
|
-
generateContextFiles(CWD, discovery,
|
|
554
|
+
generateContextFiles(CWD, discovery, trigger, impact, { overwriteCore });
|
|
485
555
|
|
|
486
556
|
const validation = validateContext(CONTEXT_DIR);
|
|
487
557
|
if (validation.valid) {
|
|
@@ -523,7 +593,17 @@ function handleStatus() {
|
|
|
523
593
|
console.log(`- Project Profile: ${metadata.projectProfile || 'unspecified'}`);
|
|
524
594
|
console.log(`- Context Baseline Git: ${metadata.repositoryRevision ? metadata.repositoryRevision.slice(0, 8) : 'unknown'}`);
|
|
525
595
|
console.log(`- Living Freshness: \x1b[32m${drift.status}\x1b[0m (${drift.reason})`);
|
|
526
|
-
console.log(
|
|
596
|
+
console.log(`- Context Files: ${REQUIRED_FILES.length}/${REQUIRED_FILES.length} verified (including metadata.json, glossary.md, adrs/)`);
|
|
597
|
+
|
|
598
|
+
const hostPlan = planHostSync({ home: homeDir() });
|
|
599
|
+
const hostCopy = hostPlan.filter((item) => item.action === 'copy').length;
|
|
600
|
+
if (hostCopy > 0) {
|
|
601
|
+
log.warn(`- Host skills: STALE (${hostCopy} file(s) behind package v${VERSION})`);
|
|
602
|
+
log.dim(' Run "npx ai-engineering-loop sync-hosts" then start a new session.');
|
|
603
|
+
} else {
|
|
604
|
+
const hostCurrent = hostPlan.filter((item) => item.action === 'current').length;
|
|
605
|
+
console.log(`- Host skills: CURRENT (${hostCurrent} managed file(s) match v${VERSION})`);
|
|
606
|
+
}
|
|
527
607
|
}
|
|
528
608
|
|
|
529
609
|
// Command: refresh
|
|
@@ -537,8 +617,15 @@ function handleRefresh() {
|
|
|
537
617
|
return;
|
|
538
618
|
}
|
|
539
619
|
|
|
620
|
+
const validation = validateContext(CONTEXT_DIR);
|
|
621
|
+
if (!validation.valid) {
|
|
622
|
+
log.info(`Incomplete context: ${validation.reason}. Filling missing files without overwriting filled ones...`);
|
|
623
|
+
const discovery = analyzeRepository(CWD);
|
|
624
|
+
generateContextFiles(CWD, discovery, 'refresh', 'REPAIR_MISSING', { overwriteCore: false });
|
|
625
|
+
}
|
|
626
|
+
|
|
540
627
|
const drift = evaluateDrift(CWD, CONTEXT_DIR);
|
|
541
|
-
if (drift.status === 'CURRENT') {
|
|
628
|
+
if (drift.status === 'CURRENT' && validateContext(CONTEXT_DIR).valid) {
|
|
542
629
|
log.success('✓ Context is already CURRENT. No changes required.');
|
|
543
630
|
log.dim(`Reason: ${drift.reason}`);
|
|
544
631
|
process.exit(0);
|
|
@@ -547,12 +634,26 @@ function handleRefresh() {
|
|
|
547
634
|
log.info(`Drift detected: ${drift.reason}. Reconciling context...`);
|
|
548
635
|
const discovery = analyzeRepository(CWD);
|
|
549
636
|
|
|
550
|
-
generateContextFiles(CWD, discovery, 'refresh', 'DRIFT_RECONCILIATION');
|
|
637
|
+
generateContextFiles(CWD, discovery, 'refresh', 'DRIFT_RECONCILIATION', { overwriteCore: true });
|
|
551
638
|
|
|
552
639
|
log.success('✓ Context reconciled non-destructively.');
|
|
553
640
|
handleStatus();
|
|
554
641
|
}
|
|
555
642
|
|
|
643
|
+
function syncHostsQuiet() {
|
|
644
|
+
const results = applyHostSync({ home: homeDir(), dryRun: false });
|
|
645
|
+
const copied = results.filter((item) => item.action === 'copy').length;
|
|
646
|
+
if (copied === 0) return;
|
|
647
|
+
console.log(formatHostSyncReport(results, { version: VERSION }));
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function handleSyncHosts() {
|
|
651
|
+
const dryRun = process.argv.includes('--dry-run');
|
|
652
|
+
log.info(`AI Engineering Loop — Sync host skills (sync-hosts)${dryRun ? ' [dry-run]' : ''}`);
|
|
653
|
+
const results = applyHostSync({ home: homeDir(), dryRun });
|
|
654
|
+
console.log(formatHostSyncReport(results, { version: VERSION, dryRun }));
|
|
655
|
+
}
|
|
656
|
+
|
|
556
657
|
function detectGrokHost() {
|
|
557
658
|
try {
|
|
558
659
|
const { detectGrokRuntime } = require('../lib/orchestration.js');
|
|
@@ -573,13 +674,15 @@ function handleRun() {
|
|
|
573
674
|
handleStatus();
|
|
574
675
|
}
|
|
575
676
|
|
|
677
|
+
syncHostsQuiet();
|
|
678
|
+
|
|
576
679
|
const grok = detectGrokHost();
|
|
577
680
|
|
|
578
681
|
console.log('\n------------------------------------------------------------');
|
|
579
682
|
log.bold('AI Agent Ready:');
|
|
580
|
-
console.log('1.
|
|
581
|
-
console.log('2.
|
|
582
|
-
console.log('3. Maker
|
|
683
|
+
console.log('1. Grill if needed, then freeze Goal Contract (core/grill-policy.md, core/goal-contract.md)');
|
|
684
|
+
console.log('2. Root Cause Analysis (core/root-cause-analysis.md) & Plan');
|
|
685
|
+
console.log('3. Maker TDD at named seams (policies/tdd-policy.md)');
|
|
583
686
|
console.log('4. Run Deterministic Verification');
|
|
584
687
|
console.log('5. Execute Devil\'s Advocate Adversarial Review');
|
|
585
688
|
console.log('6. Judge Agent evaluates DoD and issues PASS verdict');
|
|
@@ -636,10 +739,13 @@ Usage:
|
|
|
636
739
|
npx ai-engineering-loop <command>
|
|
637
740
|
|
|
638
741
|
Commands:
|
|
639
|
-
init
|
|
640
|
-
status
|
|
641
|
-
refresh
|
|
642
|
-
run
|
|
742
|
+
init Bootstrap .ai-engineering-loop/ context from repository discovery
|
|
743
|
+
status Check the validity, readiness, and baseline freshness of context
|
|
744
|
+
refresh Reconcile drifted context against repository non-destructively
|
|
745
|
+
run Verify context readiness, sync host skills, and instruct the agent
|
|
746
|
+
sync-hosts Copy package skills/agents/commands into ~/.claude ~/.grok ~/.gemini ~/.agents
|
|
747
|
+
(only hosts that already exist; DOT skills only if already installed)
|
|
748
|
+
--dry-run print the plan without writing
|
|
643
749
|
|
|
644
750
|
Options:
|
|
645
751
|
-h, --help Show this help menu
|
|
@@ -667,6 +773,9 @@ switch (command) {
|
|
|
667
773
|
case 'run':
|
|
668
774
|
handleRun();
|
|
669
775
|
break;
|
|
776
|
+
case 'sync-hosts':
|
|
777
|
+
handleSyncHosts();
|
|
778
|
+
break;
|
|
670
779
|
case '-v':
|
|
671
780
|
case '--version':
|
|
672
781
|
console.log(`ai-engineering-loop v${VERSION}`);
|
|
@@ -69,6 +69,8 @@ flowchart TD
|
|
|
69
69
|
| `package.json` / `go.mod` scripts modified | `verification.md`, `config.md` | Update test/build/lint command entries |
|
|
70
70
|
| New folder in `src/modules/` or `apps/` | `architecture.md` | Add module summary and boundary notes |
|
|
71
71
|
| New global error class or lint rule added | `conventions.md` | Document new pattern or forbidden rule |
|
|
72
|
+
| New or corrected domain term | `glossary.md` | Add or fix one glossary row |
|
|
73
|
+
| Load-bearing design choice settled | `adrs/NNN-*.md` | Write an ADR; do not bury it in chat |
|
|
72
74
|
| `.gitlab-ci.yml` / `.github/workflows` edited | `adapter.md` | Update CI/CD workflow references |
|
|
73
75
|
|
|
74
76
|
- **Action**: Reconcile *only* the affected markdown file(s) and update `metadata.json` baseline.
|
|
@@ -39,6 +39,8 @@ flowchart LR
|
|
|
39
39
|
### Pillar 3: Code & Diff Quality
|
|
40
40
|
- **Surgical Diff**: Smallest coherent diff that completely resolves the issue.
|
|
41
41
|
- **Architecture Preservation**: Adheres to existing repository patterns, naming conventions, and layer boundaries.
|
|
42
|
+
- **Seams & TDD**: Tests sit at Goal Contract seams; red then green (`policies/tdd-policy.md`).
|
|
43
|
+
- **Glossary**: New names match `.ai-engineering-loop/glossary.md`.
|
|
42
44
|
- **Zero Placeholders**: No stubbed functions, empty `catch` blocks, speculative `TODO` comments, or orphaned dead code.
|
|
43
45
|
- **Null & Boundary Safety**: Explicit handling of `null`, `undefined`, empty collections, and error paths.
|
|
44
46
|
|
package/core/goal-contract.md
CHANGED
|
@@ -11,6 +11,8 @@ The Goal Contract establishes:
|
|
|
11
11
|
- **Where** the boundaries are set (preventing scope creep).
|
|
12
12
|
- **When** the work is strictly considered complete.
|
|
13
13
|
|
|
14
|
+
Alignment before freeze follows [Grill Policy](file:///Users/egagofur/Development/work/ai-engineering-loop/core/grill-policy.md). Terms come from `.ai-engineering-loop/glossary.md`.
|
|
15
|
+
|
|
14
16
|
---
|
|
15
17
|
|
|
16
18
|
## 2. Mandatory Contract Schema
|
|
@@ -40,13 +42,22 @@ Every Goal Contract MUST adhere to the following schema in Markdown or structure
|
|
|
40
42
|
## 5. Out of Scope
|
|
41
43
|
- [Explicitly list what the agent MUST NOT touch or refactor during this task]
|
|
42
44
|
|
|
43
|
-
## 6.
|
|
45
|
+
## 6. Ubiquitous Language
|
|
46
|
+
- Terms used in this contract (must match `.ai-engineering-loop/glossary.md`): [term, ...]
|
|
47
|
+
- New terms coined in Stage 1 grill: [add to glossary before freeze]
|
|
48
|
+
|
|
49
|
+
## 7. Test Seams
|
|
50
|
+
- [Public interface under test. Prefer existing seams. No test at an unconfirmed seam.]
|
|
51
|
+
- [What a passing test at this seam proves for AC-1..N]
|
|
52
|
+
|
|
53
|
+
## 8. Verification Requirements
|
|
44
54
|
- **Unit Tests**: [Target files, boundary cases, and minimum expected coverage]
|
|
45
55
|
- **Static Analysis**: [Typecheck command, linter command, schema validation command]
|
|
46
56
|
- **Build / Packaging**: [Build command or bundling check]
|
|
47
57
|
- **Runtime / Integration**: [Manual smoke test steps or integration test command]
|
|
58
|
+
- **TDD**: Red then green at the seams above (`policies/tdd-policy.md`)
|
|
48
59
|
|
|
49
|
-
##
|
|
60
|
+
## 9. Definition of Done (DoD)
|
|
50
61
|
- [ ] All Acceptance Criteria (AC-1 through AC-N) verified with automated tests.
|
|
51
62
|
- [ ] 100% pass on all deterministic verification commands (0 errors, 0 warnings where enforced).
|
|
52
63
|
- [ ] Independent Devil's Advocate review completed with 0 unresolved blocking findings (SEV-1 / SEV-2).
|
|
@@ -60,11 +71,15 @@ Every Goal Contract MUST adhere to the following schema in Markdown or structure
|
|
|
60
71
|
|
|
61
72
|
1. **Pre-Implementation Freezing**:
|
|
62
73
|
- The Goal Contract is authored and frozen *before* any production code edits.
|
|
63
|
-
- If the task is ambiguous, the
|
|
74
|
+
- If the task is ambiguous and a human is present, run the [Grill Policy](file:///Users/egagofur/Development/work/ai-engineering-loop/core/grill-policy.md) until the design-tree frontier is empty, then freeze.
|
|
75
|
+
- If the task is unambiguous, waived, or headless with testable AC, skip grill and freeze immediately.
|
|
64
76
|
2. **Immutability During Iteration**:
|
|
65
77
|
- Neither the Maker Agent nor the Devil's Advocate Agent may alter Acceptance Criteria during an iteration loop to make tests pass or bypass critique.
|
|
66
78
|
3. **Contract Amendments**:
|
|
67
79
|
- If during implementation a fundamental contradiction or impossible requirement is discovered, the agent must trigger **Human Escalation**. Only a human user may amend the Goal Contract.
|
|
80
|
+
4. **Chat is not the contract**:
|
|
81
|
+
- Parent-transcript `setuju` does not freeze AC.
|
|
82
|
+
- Every user-visible grill decision (order of pages, enable flags, layout) MUST appear as AC-1..N in the contract file before Maker starts.
|
|
68
83
|
|
|
69
84
|
---
|
|
70
85
|
|
|
@@ -83,6 +98,10 @@ Every single item listed under `Acceptance Criteria` must map to at least one co
|
|
|
83
98
|
|
|
84
99
|
## 5. Anti-Patterns to Avoid
|
|
85
100
|
|
|
86
|
-
- **The Vague Contract**: "Make authentication work better." (Invalid: lacks testable acceptance criteria).
|
|
101
|
+
- **The Vague Contract**: "Make authentication work better." (Invalid: lacks testable acceptance criteria). Grill or refuse to freeze.
|
|
102
|
+
- **The Missing Seam**: Acceptance criteria with no public interface to test against.
|
|
103
|
+
- **The Parallel Glossary**: Using 20 words for a concept that already has a term in `glossary.md`.
|
|
87
104
|
- **The Missing Constraint**: Failing to declare out-of-scope files, leading to arbitrary refactoring of adjacent legacy modules.
|
|
88
105
|
- **The Self-Serving Goal**: Modifying acceptance criteria post-hoc when tests fail rather than fixing the underlying implementation.
|
|
106
|
+
- **The Chat Contract**: Treating "setuju" in the parent transcript as AC. The file is the contract.
|
|
107
|
+
- **The Wrong Artifact**: Tests pass on a `/tmp` build while the sample the user opens omits the feature.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Grill Policy (Stage 1 Alignment)
|
|
2
|
+
|
|
3
|
+
The Goal Contract is frozen only after alignment is real. When the task is ambiguous and a human can answer, the orchestrator **grills** before any production edit. This is Stage 1, not a separate product.
|
|
4
|
+
|
|
5
|
+
## When to grill
|
|
6
|
+
|
|
7
|
+
Grill when **all** of these are true:
|
|
8
|
+
|
|
9
|
+
1. No frozen Goal Contract exists for this task.
|
|
10
|
+
2. The request is ambiguous, multi-way, or missing acceptance criteria, seams, or out-of-scope.
|
|
11
|
+
3. A human is present in this session (interactive TUI / chat).
|
|
12
|
+
|
|
13
|
+
## When to skip
|
|
14
|
+
|
|
15
|
+
Skip grill (write the Goal Contract from what is already known) when any of these is true:
|
|
16
|
+
|
|
17
|
+
1. The user waived it ("just do it", "skip grill", contract already pasted).
|
|
18
|
+
2. A Goal Contract for this task is already frozen on disk.
|
|
19
|
+
3. The session is headless / autonomous and the prompt already has testable AC-1..N.
|
|
20
|
+
4. The change is a one-line mechanical fix with an obvious AC (typo, lint, version bump).
|
|
21
|
+
|
|
22
|
+
Do not interview the user for **facts** you can look up (files, scripts, types, git). Look them up. Grill only **decisions**.
|
|
23
|
+
|
|
24
|
+
## Idea and menu requests
|
|
25
|
+
|
|
26
|
+
If the user asks for ideas, a feature catalog, or "what should we add" without naming one task:
|
|
27
|
+
|
|
28
|
+
1. Do not implement.
|
|
29
|
+
2. Do not freeze a Goal Contract.
|
|
30
|
+
3. List at most five options. Mark one recommended. Wait for a pick.
|
|
31
|
+
4. After they pick, grill that one task, then freeze.
|
|
32
|
+
|
|
33
|
+
`/ai-engineering-loop` on an idea request still stays this loop: menu, then grill. Do not switch to a parallel brainstorm product.
|
|
34
|
+
|
|
35
|
+
## Freeze gate
|
|
36
|
+
|
|
37
|
+
Chat `setuju`, `lanjut`, `ok`, or "looks good" is **not** a freeze.
|
|
38
|
+
|
|
39
|
+
Before Maker starts:
|
|
40
|
+
|
|
41
|
+
1. Every accepted grill decision that changes user-visible output is a numbered AC in the Goal Contract **file** (page order, enable flags, layout, copy, numbering).
|
|
42
|
+
2. Each of those ACs names the artifact to inspect (sample path, command, seam).
|
|
43
|
+
3. Write `.ai-engineering-loop/tasks/goal-contract.md` (or the path this repo uses). Show the AC list.
|
|
44
|
+
4. Freeze only after that file exists and contains those ACs.
|
|
45
|
+
|
|
46
|
+
If a decision was agreed in chat and is missing from the file, the contract is not frozen. Do not start Maker.
|
|
47
|
+
|
|
48
|
+
## DOT adapter (`adapter_type: dot`)
|
|
49
|
+
|
|
50
|
+
On DOT repositories, grill is **one** session that includes the four-pillar blast radius from Antigravity skill `task-impact-inquiry` (`~/.gemini/config/skills/task-impact-inquiry/SKILL.md`). Do not run that skill as a second interview after grill.
|
|
51
|
+
|
|
52
|
+
The four pillars must appear in the grill (and then in the Goal Contract) whenever the change can touch:
|
|
53
|
+
|
|
54
|
+
1. State and condition permutations (status, overtime vs normal hours, locked vs open periods)
|
|
55
|
+
2. Sibling / historical isolation (other entities in the same parent, period, or cart)
|
|
56
|
+
3. Actor and approval authority (who edits, when an existing approval is void vs kept)
|
|
57
|
+
4. Downstream jobs and queues (BullMQ, cron, payroll/aggregates)
|
|
58
|
+
|
|
59
|
+
**Do not skip grill** for those four cases, even if AC look obvious or the user said "just do it". Typo, lint, and version-bump skips still apply.
|
|
60
|
+
|
|
61
|
+
If the skill file is missing on this host, still ask the four pillars from this section. Do not claim the Gemini skill ran.
|
|
62
|
+
|
|
63
|
+
Present the impact matrix and 2–3 probing questions in the same grill round as other Stage 1 decisions. Recommended answers required. After the frontier is empty, freeze the Goal Contract once.
|
|
64
|
+
|
|
65
|
+
## Design tree
|
|
66
|
+
|
|
67
|
+
Map the work as a design tree. The **frontier** is every undecided question whose prerequisites are settled.
|
|
68
|
+
|
|
69
|
+
Work in **rounds**. Each round asks the whole current frontier. Number the questions. Give a recommended answer for each. Wait for the user's answers before the next round.
|
|
70
|
+
|
|
71
|
+
```text
|
|
72
|
+
Q1 - <title>: <body, including choices>
|
|
73
|
+
Recommended: <your answer>
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A question that depends on an unanswered question in this round belongs to a later round.
|
|
77
|
+
|
|
78
|
+
The grill is done when the frontier is empty: every branch visited, nothing silently assumed. Confirm shared understanding, then freeze the Goal Contract (`core/goal-contract.md`).
|
|
79
|
+
|
|
80
|
+
## What the grill must settle
|
|
81
|
+
|
|
82
|
+
- Objective and business outcome
|
|
83
|
+
- Acceptance criteria that can fail a test
|
|
84
|
+
- Out of scope
|
|
85
|
+
- Test **seams** (public interfaces to observe; prefer existing seams; fewer is better)
|
|
86
|
+
- Glossary terms to use (read and update `.ai-engineering-loop/glossary.md`)
|
|
87
|
+
- Hard decisions that belong in an ADR under `.ai-engineering-loop/adrs/`
|
|
88
|
+
|
|
89
|
+
## Invariants
|
|
90
|
+
|
|
91
|
+
- No production code edits during grill.
|
|
92
|
+
- Neither Maker nor Devil's Advocate may amend AC after freeze. Only a human amends the contract (`core/goal-contract.md`).
|
|
93
|
+
- Use glossary terms in the contract, ticket, and later code names.
|
|
94
|
+
- Do not own the user's process outside this loop. Grill exists to freeze Stage 1, then the 8-stage OS continues.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Handoff Artifact
|
|
2
|
+
|
|
3
|
+
When a session stops mid-loop (context limit, user switch, detach), the orchestrator writes a handoff so the next agent continues the same 8-stage run. This is not a new stage.
|
|
4
|
+
|
|
5
|
+
## Path
|
|
6
|
+
|
|
7
|
+
`.ai-engineering-loop/tasks/handoff.md`
|
|
8
|
+
|
|
9
|
+
Overwrite the previous handoff for the active task. Do not commit unless the user asks.
|
|
10
|
+
|
|
11
|
+
## Required sections
|
|
12
|
+
|
|
13
|
+
```markdown
|
|
14
|
+
# Handoff: <short task title>
|
|
15
|
+
|
|
16
|
+
## Stage
|
|
17
|
+
<0-8 plus grill / iterate-N>
|
|
18
|
+
|
|
19
|
+
## Goal Contract
|
|
20
|
+
<path, frozen or not>
|
|
21
|
+
|
|
22
|
+
## Seams
|
|
23
|
+
- <public interface under test>
|
|
24
|
+
|
|
25
|
+
## Verification
|
|
26
|
+
- last command, exit code, log path (or NOT RUN)
|
|
27
|
+
|
|
28
|
+
## Review
|
|
29
|
+
- DA ledger path (or NOT RUN)
|
|
30
|
+
- Judge verdict (or NOT RUN)
|
|
31
|
+
- open VALID BLOCKER/HIGH ids
|
|
32
|
+
|
|
33
|
+
## Glossary / ADRs touched
|
|
34
|
+
- <paths>
|
|
35
|
+
|
|
36
|
+
## Next action
|
|
37
|
+
One sentence the next agent must do first. No recap of chat.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Rules
|
|
41
|
+
|
|
42
|
+
- Facts only: paths, commands, ids. No Maker optimism.
|
|
43
|
+
- The next session reads this file, the Goal Contract, and `.ai-engineering-loop/glossary.md` before grilling again.
|
|
44
|
+
- Do not restart Stage 1 if the contract is already frozen.
|
package/core/judge-policy.md
CHANGED
|
@@ -30,12 +30,13 @@ flowchart TD
|
|
|
30
30
|
|
|
31
31
|
## 2. Evidence-Based Decision Matrix
|
|
32
32
|
|
|
33
|
-
The Judge renders decisions based strictly on **Validity + Severity**. The reviewer's subjective disposition (`STRONG`, `ACCEPTABLE`, `WEAK`) **never overrides factual evidence
|
|
33
|
+
The Judge renders decisions based strictly on **Validity + Severity**, then **review axis**. The reviewer's subjective disposition (`STRONG`, `ACCEPTABLE`, `WEAK`) **never overrides factual evidence**. Do not merge Spec and Standards into one ranking:
|
|
34
34
|
|
|
35
35
|
| Finding Validity | Finding Severity | Disposition | Judge Action | Impact on Final Verdict |
|
|
36
36
|
|---|---|---|---|---|
|
|
37
|
-
| **`VALID`** | **`BLOCKER`** | Any | **UPHELD (Blocking)** | **`ITERATE`** — Maker must apply alternative diff & tests. |
|
|
38
|
-
| **`VALID`** | **`HIGH`** | Any | **UPHELD (Blocking)** | **`ITERATE`** — Maker must apply alternative diff & tests. |
|
|
37
|
+
| **`VALID`** | **`BLOCKER`** | Any | **UPHELD (Blocking)** if `axis` is `spec` (or omitted), or `standards` with `hardConvention: true` | **`ITERATE`** — Maker must apply alternative diff & tests. |
|
|
38
|
+
| **`VALID`** | **`HIGH`** | Any | **UPHELD (Blocking)** under the same axis rule | **`ITERATE`** — Maker must apply alternative diff & tests. |
|
|
39
|
+
| **`VALID`** | **`BLOCKER` / `HIGH`** | Any | **TRADEOFF** if `axis` is `standards` and `hardConvention` is not true | **`PASS`** (if ACs met) — smell/convention judgement, not an AC breach. |
|
|
39
40
|
| **`VALID`** | **`MEDIUM`** | `ACCEPTABLE` | **UPHELD (Tradeoff)** | **`PASS`** (if ACs met) — Logged as known tradeoff in MR. |
|
|
40
41
|
| **`VALID`** | **`LOW`** | `ACCEPTABLE` | **UPHELD (Tradeoff)** | **`PASS`** (if ACs met) — Logged as known tradeoff in MR. |
|
|
41
42
|
| **`INVALID`** | Any | `WEAK` | **DISMISSED (Hallucination)** | **`PASS`** (if ACs met) — Discarded with evidence proof. |
|
|
@@ -51,13 +52,18 @@ The Judge renders decisions based strictly on **Validity + Severity**. The revie
|
|
|
51
52
|
3. Zero open `VALID + BLOCKER` or `VALID + HIGH` findings.
|
|
52
53
|
4. Any `INVALID` findings are formally dismissed with counter-evidence.
|
|
53
54
|
5. Any `VALID + MEDIUM/LOW` findings are documented as tradeoffs.
|
|
55
|
+
6. AC source is **only** the Goal Contract file given to the Judge. Chat agreement is not an AC. `CONTEXT_ISOLATION_ONLY` does not relax this.
|
|
56
|
+
7. Evidence is for the artifact the AC names (sample path, seam, verification command). A `/tmp` build is not proof of a different user-facing file.
|
|
57
|
+
8. Source `grep` of implementation files is not AC proof (`policies/tdd-policy.md`).
|
|
54
58
|
|
|
55
59
|
---
|
|
56
60
|
|
|
57
61
|
### Verdict 2: `ITERATE`
|
|
58
62
|
- **Conditions**:
|
|
59
|
-
1. One or more `VALID + BLOCKER` or `VALID + HIGH` findings exist.
|
|
60
|
-
2. Active iteration count
|
|
63
|
+
1. One or more `VALID + BLOCKER` or `VALID + HIGH` findings exist (Spec, or Standards with `hardConvention: true`).
|
|
64
|
+
2. Active iteration count is below MAX_ITERATIONS (default 3).
|
|
65
|
+
3. Maker or verification cites chat agreement for behavior that is not an AC in the Goal Contract file.
|
|
66
|
+
4. Evidence is for the wrong artifact, is source-grep only, or does not map to written AC ids.
|
|
61
67
|
- **Maker Directive**: The Maker must adopt the concrete alternative diff or provide an equivalent verified architectural resolution, authoring regression unit tests.
|
|
62
68
|
|
|
63
69
|
---
|
|
@@ -81,7 +81,8 @@ Inspect Topology ──▶ Manifests/Commands ──▶ Inferred Profile ──
|
|
|
81
81
|
- Cross-checks existing docs (`README.md`, `CONTRIBUTING.md`, `CLAUDE.md`, `AGENTS.md`) without blindly trusting contradictions.
|
|
82
82
|
5. **Pass 5 (Safety Audit & File Generation)**:
|
|
83
83
|
- Strictly ignores private credentials (`.env`, `.env.local`, `.pem`, tokens, API keys).
|
|
84
|
-
- Generates `.ai-engineering-loop/` (`config.md`, `architecture.md`, `conventions.md`, `verification.md`, `adapter.md`).
|
|
84
|
+
- Generates `.ai-engineering-loop/` (`config.md`, `architecture.md`, `conventions.md`, `verification.md`, `adapter.md`, `glossary.md`, `adrs/README.md`).
|
|
85
|
+
- Repair of a valid-but-incomplete directory fills missing files only. Filled `glossary.md` and ADRs are never overwritten.
|
|
85
86
|
|
|
86
87
|
---
|
|
87
88
|
|
|
@@ -12,7 +12,11 @@ The `.ai-engineering-loop/` directory serves as the **Living Project Context** f
|
|
|
12
12
|
├── architecture.md # System architecture, layers, & boundaries
|
|
13
13
|
├── conventions.md # Code standards, patterns, & forbidden practices
|
|
14
14
|
├── verification.md # Exact CLI verification commands
|
|
15
|
-
|
|
15
|
+
├── adapter.md # Configured delivery pipeline & CI/CD tools
|
|
16
|
+
├── glossary.md # Ubiquitous language (one term per concept)
|
|
17
|
+
├── adrs/ # Architecture Decision Records from Stage 1 grill
|
|
18
|
+
│ └── README.md
|
|
19
|
+
└── tasks/ # Ephemeral: current.diff, handoff.md, verification logs
|
|
16
20
|
```
|
|
17
21
|
|
|
18
22
|
---
|
|
@@ -65,6 +69,16 @@ Maintains lightweight state for instant drift detection:
|
|
|
65
69
|
- `default_target_branch`: Base target branch.
|
|
66
70
|
- `ci_provider`: Detected CI engine (GitHub Actions, GitLab CI).
|
|
67
71
|
|
|
72
|
+
### 7. `glossary.md` — Ubiquitous Language
|
|
73
|
+
- One term per domain concept. Goal Contracts, tests, and code names must use these words.
|
|
74
|
+
- Updated during Stage 1 grill when a term is coined or corrected. Never overwritten by `refresh` if already filled.
|
|
75
|
+
|
|
76
|
+
### 8. `adrs/` — Architecture Decision Records
|
|
77
|
+
- Durable why for load-bearing choices settled in grill. `refresh` does not overwrite existing ADRs.
|
|
78
|
+
|
|
79
|
+
### 9. `tasks/` — Run artifacts (optional)
|
|
80
|
+
- `current.diff`, verification logs, `handoff.md`. Not required for `init` validity.
|
|
81
|
+
|
|
68
82
|
---
|
|
69
83
|
|
|
70
84
|
## 3. Version Control Recommendation
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Root Cause Analysis (Stage 2)
|
|
2
|
+
|
|
3
|
+
Stage 2 is diagnosis, not coding. The Maker must not start a production diff until the failure (or the missing capability) is named with evidence.
|
|
4
|
+
|
|
5
|
+
## Feature work
|
|
6
|
+
|
|
7
|
+
For a new capability with a frozen Goal Contract:
|
|
8
|
+
|
|
9
|
+
1. Trace the data path (ingress → domain → data → side effects).
|
|
10
|
+
2. Name the existing module and **seam** that will carry the change.
|
|
11
|
+
3. List edge cases the AC already require.
|
|
12
|
+
4. Stop. Stage 3 is the plan; Stage 4 is the diff.
|
|
13
|
+
|
|
14
|
+
## Bug and regression work
|
|
15
|
+
|
|
16
|
+
Use a gated diagnosis loop. Do not skip a gate.
|
|
17
|
+
|
|
18
|
+
1. **Red repro.** Build or run a feedback loop that fails on this bug (test, log, metric, or script). If you cannot turn it red, you do not understand it yet.
|
|
19
|
+
2. **Minimise.** Shrink input, surface, and time window until one causal slice remains.
|
|
20
|
+
3. **Hypothesise.** Write 1–3 falsifiable causes. Do not "try things".
|
|
21
|
+
4. **Instrument.** Add the smallest probe that distinguishes those causes. Remove the probe if it is not a product requirement.
|
|
22
|
+
5. **Fix.** Only after one hypothesis is confirmed. The fix is Stage 4, still test-first at the agreed seam (`policies/tdd-policy.md`).
|
|
23
|
+
6. **Regression test.** The red repro becomes a kept test mapped to an AC.
|
|
24
|
+
|
|
25
|
+
## Anti-patterns
|
|
26
|
+
|
|
27
|
+
- Guessing a fix from stack-trace vibe without a red repro
|
|
28
|
+
- Horizontal exploration of the whole repo "in case"
|
|
29
|
+
- Editing production code in Stage 2
|
|
30
|
+
- Asking the user for facts that exist in git, logs, or `.ai-engineering-loop/verification.md`
|
|
@@ -6,6 +6,8 @@ The Verification Loop is the deterministic machine gate of the AI Engineering Lo
|
|
|
6
6
|
|
|
7
7
|
> **"Code cannot enter Devil's Advocate review until it achieves 100% green machine verification backed by explicit, verifiable execution evidence."**
|
|
8
8
|
|
|
9
|
+
Maker reaches that green via [TDD Policy](file:///Users/egagofur/Development/work/ai-engineering-loop/policies/tdd-policy.md): red at a named seam, then green. "We did TDD" without logs is not a PASS.
|
|
10
|
+
|
|
9
11
|
---
|
|
10
12
|
|
|
11
13
|
## 2. Verification Evidence Contract
|
|
@@ -20,7 +22,7 @@ A verification `PASS` is **strictly invalid** without concrete execution evidenc
|
|
|
20
22
|
5. **`stdout` & `stderr`**: Raw machine logs captured from execution.
|
|
21
23
|
6. **`timeoutStatus`**: Must be `"COMPLETED"` (not timed out or backgrounded without completion).
|
|
22
24
|
7. **`testCounts`**: Explicit counts of passed, failed, and skipped tests.
|
|
23
|
-
8. **`assertionEvidence`**: Specific assertion proof matching the active Goal Contract's Acceptance Criteria.
|
|
25
|
+
8. **`assertionEvidence`**: Specific assertion proof matching the active Goal Contract's Acceptance Criteria, observed at a named test seam.
|
|
24
26
|
|
|
25
27
|
```json
|
|
26
28
|
{
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
## 3. Completion & Hand-off
|
|
58
58
|
|
|
59
59
|
```text
|
|
60
|
-
[ENGINE] Generated .ai-engineering-loop/ (config.md, architecture.md, conventions.md, verification.md, adapter.md)
|
|
60
|
+
[ENGINE] Generated .ai-engineering-loop/ (config.md, architecture.md, conventions.md, verification.md, adapter.md, glossary.md, adrs/README.md)
|
|
61
61
|
[ENGINE] Project Context successfully initialized!
|
|
62
62
|
[ENGINE] Proceeding to Goal Contract formulation...
|
|
63
63
|
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Generated Context Artifacts: `acme-platform`
|
|
2
2
|
|
|
3
|
-
Below are the
|
|
3
|
+
Below are the files generated automatically inside `/workspaces/acme-platform/.ai-engineering-loop/` (including `glossary.md` and `adrs/README.md`):
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|