agentic-orchestrator 0.1.4 → 0.1.6
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/.claude/settings.local.json +6 -1
- package/README.md +81 -54
- package/agentic/orchestrator/defaults/policy.defaults.yaml +212 -0
- package/agentic/orchestrator/schemas/adapters.schema.json +17 -4
- package/agentic/orchestrator/schemas/agents.schema.json +58 -13
- package/agentic/orchestrator/schemas/gates.schema.json +88 -17
- package/agentic/orchestrator/schemas/index.schema.json +172 -37
- package/agentic/orchestrator/schemas/multi-project.schema.json +85 -17
- package/agentic/orchestrator/schemas/plan.schema.json +135 -30
- package/agentic/orchestrator/schemas/policy.schema.json +198 -69
- package/agentic/orchestrator/schemas/policy.user.schema.json +165 -0
- package/agentic/orchestrator/schemas/qa_test_index.schema.json +71 -14
- package/agentic/orchestrator/schemas/state.schema.json +196 -39
- package/apps/control-plane/scripts/validate-architecture-rules.mjs +5 -3
- package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +0 -3
- package/apps/control-plane/scripts/validate-mcp-contracts.ts +2 -6
- package/apps/control-plane/src/application/services/policy-loader-service.ts +115 -0
- package/apps/control-plane/src/cli/aop.ts +35 -1
- package/apps/control-plane/src/cli/cli-argument-parser.ts +4 -0
- package/apps/control-plane/src/cli/help-command-handler.ts +2 -1
- package/apps/control-plane/src/cli/init-command-handler.ts +136 -27
- package/apps/control-plane/src/cli/retry-command-handler.ts +3 -6
- package/apps/control-plane/src/cli/types.ts +1 -0
- package/apps/control-plane/src/core/git.ts +1 -3
- package/apps/control-plane/src/core/kernel.ts +3 -6
- package/apps/control-plane/src/core/schemas.ts +36 -1
- package/apps/control-plane/src/interfaces/cli/bootstrap.ts +1 -1
- package/apps/control-plane/src/mcp/tool-registry-loader.ts +37 -1
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +1 -1
- package/apps/control-plane/test/aop.spec.ts +37 -0
- package/apps/control-plane/test/batch-operations.spec.ts +5 -3
- package/apps/control-plane/test/bootstrap-attach.spec.ts +28 -18
- package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +25 -15
- package/apps/control-plane/test/bootstrap.spec.ts +30 -22
- package/apps/control-plane/test/cli.unit.spec.ts +55 -10
- package/apps/control-plane/test/core-utils.spec.ts +12 -3
- package/apps/control-plane/test/feature-deletion-service.spec.ts +2 -1
- package/apps/control-plane/test/feature-lifecycle.spec.ts +1 -1
- package/apps/control-plane/test/helpers.ts +22 -2
- package/apps/control-plane/test/init-wizard.spec.ts +160 -7
- package/apps/control-plane/test/issue-tracker.spec.ts +3 -3
- package/apps/control-plane/test/kernel.spec.ts +62 -0
- package/apps/control-plane/test/lock-service.spec.ts +4 -4
- package/apps/control-plane/test/policy-loader-service.spec.ts +346 -0
- package/apps/control-plane/test/reactions.spec.ts +8 -6
- package/apps/control-plane/test/resume-command.spec.ts +31 -15
- package/apps/control-plane/test/supervisor.unit.spec.ts +2 -2
- package/apps/control-plane/test/tool-registry-loader.spec.ts +12 -0
- package/apps/control-plane/vitest.config.ts +1 -1
- package/dist/apps/control-plane/application/services/policy-loader-service.d.ts +24 -0
- package/dist/apps/control-plane/application/services/policy-loader-service.js +90 -0
- package/dist/apps/control-plane/application/services/policy-loader-service.js.map +1 -0
- package/dist/apps/control-plane/application/tools/tool-metadata.js +1 -0
- package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -1
- package/dist/apps/control-plane/cli/aop.js +33 -1
- package/dist/apps/control-plane/cli/aop.js.map +1 -1
- package/dist/apps/control-plane/cli/cli-argument-parser.js +4 -0
- package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
- package/dist/apps/control-plane/cli/dashboard-command-handler.js +11 -5
- package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/help-command-handler.js +5 -4
- package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/init-command-handler.d.ts +1 -0
- package/dist/apps/control-plane/cli/init-command-handler.js +110 -26
- package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/retry-command-handler.js +3 -6
- package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
- package/dist/apps/control-plane/cli/types.d.ts +1 -0
- package/dist/apps/control-plane/core/git.js +1 -3
- package/dist/apps/control-plane/core/git.js.map +1 -1
- package/dist/apps/control-plane/core/kernel.js +3 -5
- package/dist/apps/control-plane/core/kernel.js.map +1 -1
- package/dist/apps/control-plane/core/schemas.d.ts +2 -0
- package/dist/apps/control-plane/core/schemas.js +31 -1
- package/dist/apps/control-plane/core/schemas.js.map +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js +1 -1
- package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.d.ts +2 -0
- package/dist/apps/control-plane/mcp/tool-registry-loader.js +31 -1
- package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/package.json +18 -17
- package/packages/web-dashboard/package.json +1 -1
- package/packages/web-dashboard/src/app/api/actions/route.ts +2 -2
- package/packages/web-dashboard/src/app/api/events/route.ts +1 -1
- package/packages/web-dashboard/src/app/api/features/[id]/checkout/route.ts +1 -1
- package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +1 -1
- package/packages/web-dashboard/src/app/api/features/[id]/evidence/[artifact]/route.ts +1 -1
- package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +2 -2
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +1 -1
- package/packages/web-dashboard/src/app/api/projects/route.ts +2 -2
- package/packages/web-dashboard/src/app/api/status/route.ts +1 -1
- package/packages/web-dashboard/src/app/page.tsx +1 -1
- package/packages/web-dashboard/src/lib/aop-client.ts +1 -1
- package/packages/web-dashboard/src/lib/orchestrator-tools.ts +1 -1
- package/packages/web-dashboard/tsconfig.json +1 -0
- package/spec-files/completed/agentic_orchestrator_init_policy_ux_simplification_spec.md +481 -0
- package/spec-files/outstanding/agentic_orchestrator_artifact_database_publishing_spec.md +500 -0
- package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +500 -195
- package/spec-files/outstanding/agentic_orchestrator_performance_improvements_spec.md +471 -162
- package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +532 -268
- package/spec-files/outstanding/agentic_orchestrator_productization_commercial_spec.md +645 -0
- package/spec-files/progress.md +99 -2
- package/tsconfig.base.json +4 -0
- /package/spec-files/{outstanding → completed}/agentic_orchestrator_validator_hardening_spec.md +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-orchestrator",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"workspaces": [
|
|
6
6
|
"packages/*"
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"validate:all": "npm run validate:mcp-contracts && npm run validate:docker-mcp && npm run validate:architecture",
|
|
20
20
|
"lint": "eslint . --max-warnings 0",
|
|
21
21
|
"lint:fix": "npm run lint -- --fix",
|
|
22
|
+
"publish:npm": "npm run typecheck && npm run validate:all && npm run test && npm run build && npm publish",
|
|
22
23
|
"dashboard:dev": "npm run --workspace @aop/web-dashboard dev",
|
|
23
24
|
"dashboard:build": "npm run --workspace @aop/web-dashboard build",
|
|
24
25
|
"dashboard:start": "npm run --workspace @aop/web-dashboard start"
|
|
@@ -27,23 +28,23 @@
|
|
|
27
28
|
"aop": "dist/apps/control-plane/cli/aop.js"
|
|
28
29
|
},
|
|
29
30
|
"devDependencies": {
|
|
30
|
-
"@testing-library/react": "^
|
|
31
|
-
"@eslint/js": "^
|
|
32
|
-
"@types/node": "^
|
|
33
|
-
"@vitest/coverage-v8": "^
|
|
34
|
-
"eslint": "^
|
|
35
|
-
"globals": "^
|
|
36
|
-
"nx": "^
|
|
37
|
-
"tsx": "^4.
|
|
38
|
-
"typescript-eslint": "^8.
|
|
39
|
-
"typescript": "^5.
|
|
40
|
-
"msw": "^2.
|
|
41
|
-
"vitest": "^
|
|
31
|
+
"@testing-library/react": "^16.3.2",
|
|
32
|
+
"@eslint/js": "^10.0.1",
|
|
33
|
+
"@types/node": "^25.3.3",
|
|
34
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
35
|
+
"eslint": "^10.0.2",
|
|
36
|
+
"globals": "^17.4.0",
|
|
37
|
+
"nx": "^22.5.3",
|
|
38
|
+
"tsx": "^4.21.0",
|
|
39
|
+
"typescript-eslint": "^8.56.1",
|
|
40
|
+
"typescript": "^5.9.3",
|
|
41
|
+
"msw": "^2.12.10",
|
|
42
|
+
"vitest": "^4.0.18"
|
|
42
43
|
},
|
|
43
44
|
"dependencies": {
|
|
44
|
-
"ajv": "^8.
|
|
45
|
-
"chalk": "^5.
|
|
46
|
-
"minimatch": "^10.
|
|
47
|
-
"yaml": "^2.
|
|
45
|
+
"ajv": "^8.18.0",
|
|
46
|
+
"chalk": "^5.6.2",
|
|
47
|
+
"minimatch": "^10.2.4",
|
|
48
|
+
"yaml": "^2.8.2"
|
|
48
49
|
}
|
|
49
50
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { approveFeatureReview, denyFeatureReview, requestFeatureChanges } from '@/lib/orchestrator-tools';
|
|
2
|
-
import { resolveProjectRoot } from '@/lib/aop-client';
|
|
1
|
+
import { approveFeatureReview, denyFeatureReview, requestFeatureChanges } from '@/lib/orchestrator-tools.js';
|
|
2
|
+
import { resolveProjectRoot } from '@/lib/aop-client.js';
|
|
3
3
|
|
|
4
4
|
export const dynamic = 'force-dynamic';
|
|
5
5
|
|
|
@@ -2,7 +2,7 @@ import { execFile } from 'node:child_process';
|
|
|
2
2
|
import { access, mkdir, readFile, unlink, writeFile } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { promisify } from 'node:util';
|
|
5
|
-
import { readFeatureState, resolveProjectRoot } from '@/lib/aop-client';
|
|
5
|
+
import { readFeatureState, resolveProjectRoot } from '@/lib/aop-client.js';
|
|
6
6
|
|
|
7
7
|
const execFileAsync = promisify(execFile);
|
|
8
8
|
|
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
approveFeatureReview,
|
|
3
3
|
denyFeatureReview,
|
|
4
4
|
requestFeatureChanges
|
|
5
|
-
} from '@/lib/orchestrator-tools';
|
|
6
|
-
import { resolveProjectRoot } from '@/lib/aop-client';
|
|
5
|
+
} from '@/lib/orchestrator-tools.js';
|
|
6
|
+
import { resolveProjectRoot } from '@/lib/aop-client.js';
|
|
7
7
|
|
|
8
8
|
export const dynamic = 'force-dynamic';
|
|
9
9
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { getAopRoot } from '@/lib/aop-client';
|
|
2
|
-
import { readMultiProjectConfig } from '@/lib/multi-project-config';
|
|
1
|
+
import { getAopRoot } from '@/lib/aop-client.js';
|
|
2
|
+
import { readMultiProjectConfig } from '@/lib/multi-project-config.js';
|
|
3
3
|
|
|
4
4
|
export const dynamic = 'force-dynamic';
|
|
5
5
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
4
|
-
import type { DashboardStatusPayload, FeatureDetail, FeatureSummary, SSEEvent } from '@/lib/types';
|
|
4
|
+
import type { DashboardStatusPayload, FeatureDetail, FeatureSummary, SSEEvent } from '@/lib/types.js';
|
|
5
5
|
|
|
6
6
|
type ReviewAction = 'review.approve' | 'review.deny' | 'review.request_changes';
|
|
7
7
|
type ProjectEntry = { name: string; path: string };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import YAML from 'yaml';
|
|
4
|
-
import { getProjectByName, readMultiProjectConfig } from './multi-project-config';
|
|
4
|
+
import { getProjectByName, readMultiProjectConfig } from './multi-project-config.js';
|
|
5
5
|
import type {
|
|
6
6
|
DashboardStatusPayload,
|
|
7
7
|
EvidenceArtifact,
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
# Feature Spec: Init UX + Policy Defaults Simplification (AOP)
|
|
2
|
+
|
|
3
|
+
> **Purpose of this document**: Define implementation-ready changes that make `aop init` simpler for default users while preserving full control for superusers and maintaining deterministic runtime behavior.
|
|
4
|
+
|
|
5
|
+
**Version:** 1.1
|
|
6
|
+
**Date:** 2026-03-03
|
|
7
|
+
**Status:** Draft (Expanded Implementation Detail)
|
|
8
|
+
**Roadmap Mapping:** M39
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 0. Standards and Dependencies
|
|
13
|
+
|
|
14
|
+
### 0.1 Required Standards
|
|
15
|
+
|
|
16
|
+
All implementation MUST preserve:
|
|
17
|
+
- deterministic runtime behavior and MCP contract semantics
|
|
18
|
+
- existing CLI command names (`aop init`, `aop run`, etc.)
|
|
19
|
+
- schema validation as a hard gate for loaded policy
|
|
20
|
+
- full backward compatibility for existing full `policy.yaml` files
|
|
21
|
+
- test naming style (`GIVEN_..._WHEN_..._THEN_...`) and Vitest usage
|
|
22
|
+
|
|
23
|
+
### 0.2 Upstream Inputs
|
|
24
|
+
|
|
25
|
+
Implementing agents MUST read:
|
|
26
|
+
- `apps/control-plane/src/cli/init-command-handler.ts`
|
|
27
|
+
- `apps/control-plane/src/cli/cli-argument-parser.ts`
|
|
28
|
+
- `apps/control-plane/src/cli/types.ts`
|
|
29
|
+
- `apps/control-plane/src/cli/help-command-handler.ts`
|
|
30
|
+
- `apps/control-plane/src/interfaces/cli/bootstrap.ts`
|
|
31
|
+
- `apps/control-plane/src/core/kernel.ts`
|
|
32
|
+
- `apps/control-plane/src/core/schemas.ts`
|
|
33
|
+
- `agentic/orchestrator/policy.yaml`
|
|
34
|
+
- `agentic/orchestrator/schemas/policy.schema.json`
|
|
35
|
+
- `apps/control-plane/test/init-wizard.spec.ts`
|
|
36
|
+
- `apps/control-plane/test/kernel.spec.ts`
|
|
37
|
+
|
|
38
|
+
### 0.3 Current Baseline (Already Implemented in M39 Pre-Work)
|
|
39
|
+
|
|
40
|
+
As of 2026-03-03, these pieces are already done:
|
|
41
|
+
- `aop init` no longer copies schema files into target repos.
|
|
42
|
+
- schema loading can fall back to bundled AOP schemas when repo-local schemas are absent.
|
|
43
|
+
- `aop init` captures provider/model/SCM defaults.
|
|
44
|
+
- `activity-detector` in `adapters.yaml` is derived from provider.
|
|
45
|
+
|
|
46
|
+
This spec defines the next step: policy simplification and runtime composition.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## 1. Problem Analysis
|
|
51
|
+
|
|
52
|
+
### 1.1 Primary UX Gap
|
|
53
|
+
|
|
54
|
+
`aop init` currently emits a verbose `policy.yaml` with many low-frequency controls (locks, RBAC internals, retry internals, path rules, hard constraints). Most teams do not need to edit these fields, but still must parse and own them.
|
|
55
|
+
|
|
56
|
+
### 1.2 Resulting Risks
|
|
57
|
+
|
|
58
|
+
- Setup friction: first-time users face a large policy surface area.
|
|
59
|
+
- Misconfiguration risk: accidental edits to advanced controls.
|
|
60
|
+
- Upgrade friction: defaults cannot evolve cleanly when every repo stores a fully expanded copy.
|
|
61
|
+
|
|
62
|
+
### 1.3 Desired UX Direction
|
|
63
|
+
|
|
64
|
+
Default users should configure only common controls; advanced users can opt into full explicit policy authoring.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 2. Objectives
|
|
69
|
+
|
|
70
|
+
### 2.1 Must-Have Outcomes
|
|
71
|
+
|
|
72
|
+
1. Default `aop init` emits a lean, user-editable policy file.
|
|
73
|
+
2. Runtime composes lean policy over bundled defaults into one canonical full snapshot.
|
|
74
|
+
3. Superusers can still generate and maintain a full explicit policy.
|
|
75
|
+
4. Existing full policies continue to work without migration.
|
|
76
|
+
5. Validation errors remain clear and actionable.
|
|
77
|
+
|
|
78
|
+
### 2.2 Non-Goals
|
|
79
|
+
|
|
80
|
+
- No redesign of locking, RBAC, or gate semantics.
|
|
81
|
+
- No changes to tool names or tool schemas.
|
|
82
|
+
- No removal of full policy support.
|
|
83
|
+
- No behavioral weakening of schema validation.
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## 3. Architecture Decisions
|
|
88
|
+
|
|
89
|
+
### ADP-1: Defaults-First Policy Composition
|
|
90
|
+
|
|
91
|
+
Runtime will always build a canonical full policy by:
|
|
92
|
+
1. loading bundled `policy.defaults.yaml`,
|
|
93
|
+
2. loading user `agentic/orchestrator/policy.yaml`,
|
|
94
|
+
3. deep-merging user overrides over defaults,
|
|
95
|
+
4. validating merged result against full `policy.schema.json`.
|
|
96
|
+
|
|
97
|
+
This removes the need for brittle full-vs-lean mode detection and keeps backward compatibility.
|
|
98
|
+
|
|
99
|
+
### ADP-2: Explicit Advanced Init Mode
|
|
100
|
+
|
|
101
|
+
Add `aop init --advanced-policy` to generate the full explicit policy template (current behavior).
|
|
102
|
+
|
|
103
|
+
Default `aop init` generates lean policy.
|
|
104
|
+
|
|
105
|
+
### ADP-3: Deterministic Merge Semantics
|
|
106
|
+
|
|
107
|
+
Policy merge must use deterministic rules:
|
|
108
|
+
- scalar values: override defaults
|
|
109
|
+
- objects: recursive merge
|
|
110
|
+
- arrays: replace when key exists in user policy
|
|
111
|
+
- absent keys: inherit defaults
|
|
112
|
+
- `null` values: rejected by schema unless explicitly allowed
|
|
113
|
+
|
|
114
|
+
### ADP-4: Validation of User Shape + Canonical Shape
|
|
115
|
+
|
|
116
|
+
Two validations are required:
|
|
117
|
+
1. optional user-shape validation (`policy.user.schema.json`) for clearer authoring errors
|
|
118
|
+
2. mandatory canonical full validation (`policy.schema.json`) after merge
|
|
119
|
+
|
|
120
|
+
If user-shape validation is omitted for MVP, canonical full validation remains mandatory.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 4. UX and Configuration Model
|
|
125
|
+
|
|
126
|
+
### 4.1 Default `aop init` Output (Lean Policy)
|
|
127
|
+
|
|
128
|
+
Lean policy should include only common knobs:
|
|
129
|
+
- `version`
|
|
130
|
+
- `worktree.base_branch`
|
|
131
|
+
- `supervisor.max_parallel_gate_runs`
|
|
132
|
+
- `dashboard.enabled`
|
|
133
|
+
- `dashboard.port`
|
|
134
|
+
- `notifications`
|
|
135
|
+
- `merge_policy.require_user_approval`
|
|
136
|
+
- optional `recovery.orchestrator_session_reattach_timeout_ms`
|
|
137
|
+
|
|
138
|
+
Example shape:
|
|
139
|
+
|
|
140
|
+
```yaml
|
|
141
|
+
version: 1
|
|
142
|
+
worktree:
|
|
143
|
+
base_branch: main
|
|
144
|
+
supervisor:
|
|
145
|
+
max_parallel_gate_runs: 3
|
|
146
|
+
dashboard:
|
|
147
|
+
enabled: true
|
|
148
|
+
port: 3000
|
|
149
|
+
merge_policy:
|
|
150
|
+
require_user_approval: true
|
|
151
|
+
notifications:
|
|
152
|
+
enabled: false
|
|
153
|
+
channels:
|
|
154
|
+
desktop:
|
|
155
|
+
enabled: false
|
|
156
|
+
slack:
|
|
157
|
+
enabled: false
|
|
158
|
+
webhook: ""
|
|
159
|
+
channel: "#aop-alerts"
|
|
160
|
+
webhook:
|
|
161
|
+
enabled: false
|
|
162
|
+
url: ""
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 4.2 Advanced `aop init --advanced-policy` Output
|
|
166
|
+
|
|
167
|
+
Generates current fully expanded `policy.yaml` template with all advanced fields.
|
|
168
|
+
|
|
169
|
+
### 4.3 Init Prompt Surface
|
|
170
|
+
|
|
171
|
+
Interactive wizard continues to collect:
|
|
172
|
+
- default provider
|
|
173
|
+
- default model
|
|
174
|
+
- SCM provider
|
|
175
|
+
- base branch
|
|
176
|
+
- max parallel gates
|
|
177
|
+
- dashboard port
|
|
178
|
+
- notification channels + webhook values
|
|
179
|
+
- framework for gates
|
|
180
|
+
|
|
181
|
+
`adapters.yaml` activity-detector mapping:
|
|
182
|
+
- `claude` -> `claude-jsonl`
|
|
183
|
+
- `codex` -> `codex-rpc`
|
|
184
|
+
- everything else -> `process-heuristic`
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 5. Implementation Plan
|
|
189
|
+
|
|
190
|
+
### M39-M1: CLI and Init Generation
|
|
191
|
+
|
|
192
|
+
### INIT-T-001: Add Advanced Policy CLI Flag
|
|
193
|
+
|
|
194
|
+
**Files:**
|
|
195
|
+
- `apps/control-plane/src/cli/types.ts`
|
|
196
|
+
- `apps/control-plane/src/cli/cli-argument-parser.ts`
|
|
197
|
+
- `apps/control-plane/src/cli/help-command-handler.ts`
|
|
198
|
+
- `apps/control-plane/src/interfaces/cli/bootstrap.ts`
|
|
199
|
+
|
|
200
|
+
**Changes:**
|
|
201
|
+
- add `advanced_policy?: boolean` to `CliOptions`
|
|
202
|
+
- parse `--advanced-policy`
|
|
203
|
+
- pass through to `InitCommandHandler.execute({ auto, force, advanced_policy })`
|
|
204
|
+
- document flag in `aop help init`
|
|
205
|
+
|
|
206
|
+
### INIT-T-002: Extend Init Options Contract
|
|
207
|
+
|
|
208
|
+
**File:** `apps/control-plane/src/cli/init-command-handler.ts`
|
|
209
|
+
|
|
210
|
+
**Changes:**
|
|
211
|
+
- add `advanced_policy?: boolean` to `InitOptions`
|
|
212
|
+
- branch policy template generation:
|
|
213
|
+
- `advanced_policy === true` -> full template
|
|
214
|
+
- else -> lean template
|
|
215
|
+
|
|
216
|
+
### INIT-T-003: Split Policy Template Generation
|
|
217
|
+
|
|
218
|
+
**File:** `apps/control-plane/src/cli/init-command-handler.ts`
|
|
219
|
+
|
|
220
|
+
**Changes:**
|
|
221
|
+
- keep existing full generator as `generateFullPolicyYaml(...)`
|
|
222
|
+
- add `generateLeanPolicyYaml(...)`
|
|
223
|
+
- keep `gates.yaml`, `agents.yaml`, `adapters.yaml`, prompts generation unchanged
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
### M39-M2: Runtime Policy Composition
|
|
228
|
+
|
|
229
|
+
### INIT-T-004: Add Bundled Defaults Artifact
|
|
230
|
+
|
|
231
|
+
**New file:**
|
|
232
|
+
- `agentic/orchestrator/defaults/policy.defaults.yaml`
|
|
233
|
+
|
|
234
|
+
**Requirements:**
|
|
235
|
+
- this file represents canonical defaults equivalent to current full template semantics
|
|
236
|
+
- should be versioned and reviewed like other bundled contracts
|
|
237
|
+
|
|
238
|
+
### INIT-T-005: Implement Policy Composition Loader
|
|
239
|
+
|
|
240
|
+
**New file (recommended):**
|
|
241
|
+
- `apps/control-plane/src/application/services/policy-loader-service.ts`
|
|
242
|
+
|
|
243
|
+
**Interface (suggested):**
|
|
244
|
+
|
|
245
|
+
```ts
|
|
246
|
+
interface LoadPolicyResult {
|
|
247
|
+
userPolicy: Record<string, unknown>;
|
|
248
|
+
mergedPolicy: Record<string, unknown>;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function loadComposedPolicy(repoRoot: string, policyPath: string, schemaRegistry: SchemaRegistry): Promise<LoadPolicyResult>;
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**Behavior:**
|
|
255
|
+
- read defaults YAML (bundled path, not repo path)
|
|
256
|
+
- read user policy YAML (repo path)
|
|
257
|
+
- deep merge according to ADP-3 semantics
|
|
258
|
+
- validate merged policy against `policy.schema.json`
|
|
259
|
+
- return merged result
|
|
260
|
+
|
|
261
|
+
**Implementation details (normative):**
|
|
262
|
+
|
|
263
|
+
1. Defaults path resolution:
|
|
264
|
+
- resolve from module location first (`import.meta.url` + upward walk), not from user repo.
|
|
265
|
+
- fail with explicit error if defaults artifact cannot be located.
|
|
266
|
+
|
|
267
|
+
2. Merge algorithm:
|
|
268
|
+
- perform pure-function merge (do not mutate defaults or user objects).
|
|
269
|
+
- object + object -> recursive merge.
|
|
270
|
+
- array in user value -> replace defaults array wholesale.
|
|
271
|
+
- primitive in user value -> replace defaults primitive.
|
|
272
|
+
- `undefined` user fields -> ignored.
|
|
273
|
+
|
|
274
|
+
3. Validation order:
|
|
275
|
+
- optional: validate user file against `policy.user.schema.json`.
|
|
276
|
+
- mandatory: validate merged output against `policy.schema.json`.
|
|
277
|
+
|
|
278
|
+
4. Error contract:
|
|
279
|
+
- user-shape errors must point to user `policy.yaml`.
|
|
280
|
+
- canonical-shape errors must include merged key path and mention defaults composition.
|
|
281
|
+
|
|
282
|
+
**Reference merge pseudocode:**
|
|
283
|
+
|
|
284
|
+
```ts
|
|
285
|
+
function mergePolicy(defaults: unknown, user: unknown): unknown {
|
|
286
|
+
if (Array.isArray(user)) return user.slice();
|
|
287
|
+
if (isObject(defaults) && isObject(user)) {
|
|
288
|
+
const out: Record<string, unknown> = { ...defaults };
|
|
289
|
+
for (const key of Object.keys(user)) {
|
|
290
|
+
const userVal = (user as Record<string, unknown>)[key];
|
|
291
|
+
if (userVal === undefined) continue;
|
|
292
|
+
out[key] = key in out ? mergePolicy(out[key], userVal) : clone(userVal);
|
|
293
|
+
}
|
|
294
|
+
return out;
|
|
295
|
+
}
|
|
296
|
+
return clone(user);
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### INIT-T-006: Wire Kernel to Composed Policy
|
|
301
|
+
|
|
302
|
+
**File:** `apps/control-plane/src/core/kernel.ts`
|
|
303
|
+
|
|
304
|
+
**Current behavior:** direct `loadAndValidateYaml(... 'policy.schema.json', policyPath)`
|
|
305
|
+
|
|
306
|
+
**Target behavior:** load policy via composition loader from INIT-T-005, then assign merged policy to `this.policy`.
|
|
307
|
+
|
|
308
|
+
### INIT-T-007: Optional User-Shape Schema
|
|
309
|
+
|
|
310
|
+
**New file (optional but recommended):**
|
|
311
|
+
- `agentic/orchestrator/schemas/policy.user.schema.json`
|
|
312
|
+
|
|
313
|
+
**Purpose:**
|
|
314
|
+
- validate lean authoring keys for better error messages before merge
|
|
315
|
+
- canonical enforcement still happens via full schema on merged result
|
|
316
|
+
|
|
317
|
+
**Schema policy:**
|
|
318
|
+
- `additionalProperties: false` at top level for lean mode.
|
|
319
|
+
- explicitly allow only intended user-editable sections.
|
|
320
|
+
- do not include internal sections (`locks`, `rbac`, `config_precedence`, etc.) in lean schema.
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### M39-M3: Docs and Migration Clarity
|
|
325
|
+
|
|
326
|
+
### INIT-T-008: Documentation Updates
|
|
327
|
+
|
|
328
|
+
**Files:**
|
|
329
|
+
- `README.md`
|
|
330
|
+
- `agentic/orchestrator/tools.md` (if references policy generation behavior)
|
|
331
|
+
- any init command docs/examples
|
|
332
|
+
|
|
333
|
+
**Documentation requirements:**
|
|
334
|
+
- clearly separate “common config” vs “advanced policy config”
|
|
335
|
+
- add `--advanced-policy` usage examples
|
|
336
|
+
- document merge semantics and where defaults live
|
|
337
|
+
|
|
338
|
+
### INIT-T-009: Init Output Messaging
|
|
339
|
+
|
|
340
|
+
**File:** `apps/control-plane/src/cli/init-command-handler.ts`
|
|
341
|
+
|
|
342
|
+
**Changes:**
|
|
343
|
+
- `next_steps` output should state whether lean or advanced policy was generated
|
|
344
|
+
- mention `--advanced-policy` as escape hatch when lean mode is used
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## 6. File-Level Delta Matrix
|
|
349
|
+
|
|
350
|
+
| File | Change Type | Scope |
|
|
351
|
+
|---|---|---|
|
|
352
|
+
| `apps/control-plane/src/cli/types.ts` | modify | add `advanced_policy` option |
|
|
353
|
+
| `apps/control-plane/src/cli/cli-argument-parser.ts` | modify | parse `--advanced-policy` |
|
|
354
|
+
| `apps/control-plane/src/cli/help-command-handler.ts` | modify | help text for new flag |
|
|
355
|
+
| `apps/control-plane/src/interfaces/cli/bootstrap.ts` | modify | pass flag into init handler |
|
|
356
|
+
| `apps/control-plane/src/cli/init-command-handler.ts` | modify | lean/full policy generation |
|
|
357
|
+
| `apps/control-plane/src/core/kernel.ts` | modify | use composed policy loader |
|
|
358
|
+
| `apps/control-plane/src/application/services/policy-loader-service.ts` | add | defaults + user merge + validate |
|
|
359
|
+
| `agentic/orchestrator/defaults/policy.defaults.yaml` | add | bundled canonical defaults |
|
|
360
|
+
| `agentic/orchestrator/schemas/policy.user.schema.json` | add (optional) | lean user policy shape |
|
|
361
|
+
| `README.md` | modify | init UX and policy authoring docs |
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## 7. Acceptance Criteria
|
|
366
|
+
|
|
367
|
+
### 7.1 Init UX
|
|
368
|
+
|
|
369
|
+
- [ ] `aop init` writes lean `policy.yaml` by default.
|
|
370
|
+
- [ ] `aop init --advanced-policy` writes full explicit `policy.yaml`.
|
|
371
|
+
- [ ] `aop init --auto` works in both lean and advanced modes.
|
|
372
|
+
- [ ] `aop help init` documents `--advanced-policy`.
|
|
373
|
+
|
|
374
|
+
### 7.2 Runtime Composition
|
|
375
|
+
|
|
376
|
+
- [ ] Kernel boots correctly with lean policy.
|
|
377
|
+
- [ ] Kernel boots correctly with existing full legacy policy.
|
|
378
|
+
- [ ] Merged policy always passes full schema validation.
|
|
379
|
+
- [ ] Policy merge behavior is deterministic and documented.
|
|
380
|
+
|
|
381
|
+
### 7.3 Compatibility
|
|
382
|
+
|
|
383
|
+
- [ ] Existing repositories with full policy require no changes.
|
|
384
|
+
- [ ] Existing tests for non-init commands remain green.
|
|
385
|
+
- [ ] No tool contract or transport behavior regressions.
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 8. Test Plan
|
|
390
|
+
|
|
391
|
+
### 8.1 Init Tests
|
|
392
|
+
|
|
393
|
+
**File:** `apps/control-plane/test/init-wizard.spec.ts`
|
|
394
|
+
|
|
395
|
+
Add:
|
|
396
|
+
- `GIVEN_default_init_WHEN_policy_generated_THEN_policy_is_lean_shape`
|
|
397
|
+
- `GIVEN_advanced_policy_flag_WHEN_policy_generated_THEN_policy_is_full_shape`
|
|
398
|
+
- `GIVEN_advanced_policy_flag_WHEN_help_rendered_THEN_flag_is_documented`
|
|
399
|
+
|
|
400
|
+
### 8.2 Policy Composition Tests
|
|
401
|
+
|
|
402
|
+
**New file:** `apps/control-plane/test/policy-loader-service.spec.ts`
|
|
403
|
+
|
|
404
|
+
Add:
|
|
405
|
+
- `GIVEN_defaults_and_lean_user_policy_WHEN_composed_THEN_merged_policy_is_valid`
|
|
406
|
+
- `GIVEN_full_user_policy_WHEN_composed_THEN_user_values_override_defaults`
|
|
407
|
+
- `GIVEN_array_override_WHEN_composed_THEN_array_replaces_default_array`
|
|
408
|
+
- `GIVEN_invalid_user_policy_WHEN_loaded_THEN_validation_error_is_actionable`
|
|
409
|
+
|
|
410
|
+
### 8.3 Kernel Integration Tests
|
|
411
|
+
|
|
412
|
+
**File:** `apps/control-plane/test/kernel.spec.ts`
|
|
413
|
+
|
|
414
|
+
Add:
|
|
415
|
+
- `GIVEN_lean_policy_repo_WHEN_kernel_loads_THEN_runtime_boots_successfully`
|
|
416
|
+
- `GIVEN_full_policy_repo_WHEN_kernel_loads_THEN_runtime_boots_successfully`
|
|
417
|
+
|
|
418
|
+
### 8.4 Regression Test Runs
|
|
419
|
+
|
|
420
|
+
Required run list:
|
|
421
|
+
- `npm run lint`
|
|
422
|
+
- `npm run typecheck`
|
|
423
|
+
- `npm test`
|
|
424
|
+
- `npm run validate:mcp-contracts`
|
|
425
|
+
- `npm run validate:architecture`
|
|
426
|
+
|
|
427
|
+
### 8.5 Determinism and Edge Cases (Required)
|
|
428
|
+
|
|
429
|
+
Add explicit tests for:
|
|
430
|
+
- merge determinism with object key order differences (same result hash)
|
|
431
|
+
- array replacement semantics for `required_modes` and `protected_areas`
|
|
432
|
+
- missing defaults artifact error path (clear actionable message)
|
|
433
|
+
- behavior when user policy is empty `{}` (defaults-only canonical policy)
|
|
434
|
+
- behavior when user policy file is absent (hard failure or auto-init guidance; choose one and test)
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## 9. Rollout Strategy
|
|
439
|
+
|
|
440
|
+
### Phase A (Safe Introduction)
|
|
441
|
+
|
|
442
|
+
Ship runtime composition first while keeping full-policy init generation as default.
|
|
443
|
+
|
|
444
|
+
### Phase B (UX Flip)
|
|
445
|
+
|
|
446
|
+
Flip `aop init` default to lean policy once composition is stable and tested.
|
|
447
|
+
|
|
448
|
+
### Phase C (Docs and Adoption)
|
|
449
|
+
|
|
450
|
+
Document lean default and advanced mode; include migration note for teams that prefer explicit full policy.
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## 10. Risks and Mitigations
|
|
455
|
+
|
|
456
|
+
- Risk: ambiguity around merge semantics.
|
|
457
|
+
- Mitigation: explicit deterministic rules + unit tests for scalars/objects/arrays.
|
|
458
|
+
- Risk: defaults drift from real runtime assumptions.
|
|
459
|
+
- Mitigation: keep defaults artifact under version control and validate merged output with full schema.
|
|
460
|
+
- Risk: advanced users lose discoverability of lower-level knobs.
|
|
461
|
+
- Mitigation: `--advanced-policy` and dedicated docs section with full template.
|
|
462
|
+
- Risk: error messages become less actionable due to merge layer.
|
|
463
|
+
- Mitigation: preserve source-path context (`policy.yaml` field path) in validation errors.
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## 11. Definition of Done
|
|
468
|
+
|
|
469
|
+
This spec is complete when:
|
|
470
|
+
1. INIT-T-001 through INIT-T-009 are implemented.
|
|
471
|
+
2. acceptance criteria in Section 7 are all checked.
|
|
472
|
+
3. test plan in Section 8 passes in CI.
|
|
473
|
+
4. `spec-files/progress.md` is updated with delivered tasks and residual follow-ups.
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## 12. Open Questions
|
|
478
|
+
|
|
479
|
+
1. Should missing `agentic/orchestrator/policy.yaml` trigger hard failure or auto-bootstrap from defaults?
|
|
480
|
+
2. Do we want `aop init --advanced-policy` as a one-time generator only, or also a conversion command from lean to full?
|
|
481
|
+
3. Should lean mode permit `cleanup.*` (frequently edited in some teams) or keep it advanced-only?
|