agentic-orchestrator 0.1.25 → 0.1.26
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/agentic/orchestrator/defaults/policy.defaults.yaml +1 -0
- package/agentic/orchestrator/policy.yaml +1 -0
- package/agentic/orchestrator/schemas/policy.schema.json +4 -0
- package/agentic/orchestrator/schemas/policy.user.schema.json +4 -0
- package/apps/control-plane/src/application/services/activity-monitor-service.ts +42 -0
- package/apps/control-plane/src/application/services/collision-queue-service.ts +48 -0
- package/apps/control-plane/src/application/services/cost-tracking-service.ts +80 -0
- package/apps/control-plane/src/application/services/feature-deletion-service.ts +57 -0
- package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +65 -0
- package/apps/control-plane/src/application/services/feature-state-service.ts +87 -0
- package/apps/control-plane/src/application/services/gate-selection-service.ts +28 -0
- package/apps/control-plane/src/application/services/gate-service.ts +148 -0
- package/apps/control-plane/src/application/services/issue-tracker-service.ts +28 -0
- package/apps/control-plane/src/application/services/lock-service.ts +88 -0
- package/apps/control-plane/src/application/services/merge-service.ts +63 -0
- package/apps/control-plane/src/application/services/notifier-service.ts +70 -0
- package/apps/control-plane/src/application/services/patch-service.ts +95 -0
- package/apps/control-plane/src/application/services/performance-analytics-service.ts +90 -0
- package/apps/control-plane/src/application/services/plan-service.ts +184 -0
- package/apps/control-plane/src/application/services/pr-monitor-service.ts +58 -0
- package/apps/control-plane/src/application/services/qa-index-service.ts +68 -0
- package/apps/control-plane/src/application/services/reactions-service.ts +77 -0
- package/apps/control-plane/src/application/services/reporting-service.ts +79 -0
- package/apps/control-plane/src/application/services/run-lease-service.ts +79 -0
- package/apps/control-plane/src/application/tools/tool-router.ts +76 -0
- package/apps/control-plane/src/mcp/tool-runtime.ts +4 -0
- package/apps/control-plane/src/providers/providers.ts +96 -0
- package/apps/control-plane/src/providers/worker-provider-factory.ts +4 -0
- package/apps/control-plane/src/supervisor/build-wave-executor.ts +4 -0
- package/apps/control-plane/src/supervisor/planning-wave-executor.ts +4 -0
- package/apps/control-plane/src/supervisor/qa-wave-executor.ts +4 -0
- package/apps/control-plane/src/supervisor/run-coordinator.ts +4 -0
- package/apps/control-plane/src/supervisor/runtime.ts +4 -0
- package/apps/control-plane/src/supervisor/session-orchestrator.ts +4 -0
- package/apps/control-plane/test/dashboard-api.integration.spec.ts +310 -1
- package/apps/control-plane/test/dashboard-client.spec.ts +136 -1
- package/apps/control-plane/test/dashboard-live-feed.spec.ts +153 -0
- package/apps/control-plane/test/dashboard-ui-utils.spec.ts +132 -0
- package/apps/control-plane/test/mcp.spec.ts +96 -0
- package/apps/control-plane/test/tool-runtime.spec.ts +68 -0
- package/config/agentic/orchestrator/policy.yaml +1 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.d.ts +42 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.js +42 -0
- package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +48 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js +48 -0
- package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +79 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js +76 -0
- package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +57 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js +57 -0
- package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +64 -0
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +61 -0
- package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/feature-state-service.d.ts +86 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js +83 -0
- package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-selection-service.d.ts +28 -0
- package/dist/apps/control-plane/application/services/gate-selection-service.js +28 -0
- package/dist/apps/control-plane/application/services/gate-selection-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/gate-service.d.ts +148 -0
- package/dist/apps/control-plane/application/services/gate-service.js +120 -0
- package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/issue-tracker-service.d.ts +28 -0
- package/dist/apps/control-plane/application/services/issue-tracker-service.js +28 -0
- package/dist/apps/control-plane/application/services/issue-tracker-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/lock-service.d.ts +88 -0
- package/dist/apps/control-plane/application/services/lock-service.js +64 -0
- package/dist/apps/control-plane/application/services/lock-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/merge-service.d.ts +62 -0
- package/dist/apps/control-plane/application/services/merge-service.js +59 -0
- package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/notifier-service.d.ts +70 -0
- package/dist/apps/control-plane/application/services/notifier-service.js +70 -0
- package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/patch-service.d.ts +94 -0
- package/dist/apps/control-plane/application/services/patch-service.js +91 -0
- package/dist/apps/control-plane/application/services/patch-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +89 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js +86 -0
- package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/plan-service.d.ts +287 -0
- package/dist/apps/control-plane/application/services/plan-service.js +207 -0
- package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/pr-monitor-service.d.ts +58 -0
- package/dist/apps/control-plane/application/services/pr-monitor-service.js +58 -0
- package/dist/apps/control-plane/application/services/pr-monitor-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/qa-index-service.d.ts +67 -0
- package/dist/apps/control-plane/application/services/qa-index-service.js +64 -0
- package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reactions-service.d.ts +76 -0
- package/dist/apps/control-plane/application/services/reactions-service.js +73 -0
- package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/reporting-service.d.ts +78 -0
- package/dist/apps/control-plane/application/services/reporting-service.js +75 -0
- package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
- package/dist/apps/control-plane/application/services/run-lease-service.d.ts +79 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js +79 -0
- package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
- package/dist/apps/control-plane/application/tools/tool-router.d.ts +76 -0
- package/dist/apps/control-plane/application/tools/tool-router.js +62 -0
- package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -1
- package/dist/apps/control-plane/mcp/tool-runtime.d.ts +3 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js +3 -0
- package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
- package/dist/apps/control-plane/providers/providers.d.ts +88 -0
- package/dist/apps/control-plane/providers/providers.js.map +1 -1
- package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +3 -0
- package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
- package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js +3 -0
- package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js +3 -0
- package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js +3 -0
- package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
- package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.js +3 -0
- package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
- package/dist/apps/control-plane/supervisor/runtime.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/runtime.js +3 -0
- package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
- package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +3 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js +3 -0
- package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
- package/package.json +1 -1
- package/packages/web-dashboard/src/app/analytics/page.tsx +451 -0
- package/packages/web-dashboard/src/app/api/analytics/route.ts +62 -0
- package/packages/web-dashboard/src/app/api/collisions/route.ts +63 -0
- package/packages/web-dashboard/src/app/api/features/[id]/cost/route.ts +29 -0
- package/packages/web-dashboard/src/app/api/features/[id]/review-brief/route.ts +31 -0
- package/packages/web-dashboard/src/app/api/features/[id]/route.ts +5 -8
- package/packages/web-dashboard/src/app/api/features/[id]/test-index/route.ts +31 -0
- package/packages/web-dashboard/src/app/api/flaky/route.ts +20 -0
- package/packages/web-dashboard/src/app/api/policy/budget/route.ts +31 -0
- package/packages/web-dashboard/src/app/api/run/route.ts +162 -0
- package/packages/web-dashboard/src/app/api/status/route.ts +2 -5
- package/packages/web-dashboard/src/app/feature/[id]/page.tsx +112 -0
- package/packages/web-dashboard/src/app/page.tsx +379 -77
- package/packages/web-dashboard/src/components/agent-pipeline-stepper.tsx +100 -0
- package/packages/web-dashboard/src/components/dependency-chains.tsx +58 -0
- package/packages/web-dashboard/src/components/detail-panel.tsx +215 -5
- package/packages/web-dashboard/src/components/feature-card.tsx +5 -0
- package/packages/web-dashboard/src/components/feature-cost-panel.tsx +66 -0
- package/packages/web-dashboard/src/components/feature-list-view.tsx +336 -0
- package/packages/web-dashboard/src/components/gate-step-drilldown.tsx +92 -0
- package/packages/web-dashboard/src/components/kanban-board.tsx +3 -0
- package/packages/web-dashboard/src/components/live-event-feed.tsx +60 -0
- package/packages/web-dashboard/src/components/lock-resource-map.tsx +73 -0
- package/packages/web-dashboard/src/components/plan-revision-timeline.tsx +55 -0
- package/packages/web-dashboard/src/components/plan-risk-annotations.tsx +63 -0
- package/packages/web-dashboard/src/components/plan-scope-tree.tsx +285 -0
- package/packages/web-dashboard/src/components/qa-coverage-map.tsx +174 -0
- package/packages/web-dashboard/src/components/quick-launch-panel.tsx +70 -0
- package/packages/web-dashboard/src/components/review-brief-panel.tsx +75 -0
- package/packages/web-dashboard/src/components/run-health-panel.tsx +85 -0
- package/packages/web-dashboard/src/components/summary-bar.tsx +59 -2
- package/packages/web-dashboard/src/components/verification-signals.tsx +167 -0
- package/packages/web-dashboard/src/lib/analytics-utils.ts +3 -0
- package/packages/web-dashboard/src/lib/aop-client.ts +510 -11
- package/packages/web-dashboard/src/lib/api-envelope.ts +48 -0
- package/packages/web-dashboard/src/lib/authz-adapter.ts +33 -0
- package/packages/web-dashboard/src/lib/dashboard-utils.ts +304 -0
- package/packages/web-dashboard/src/lib/live-feed.ts +218 -0
- package/packages/web-dashboard/src/lib/policy-reader.ts +22 -0
- package/packages/web-dashboard/src/lib/types.ts +114 -0
- package/packages/web-dashboard/src/styles/dashboard.module.css +341 -1
- package/spec-files/{outstanding → completed}/agentic_orchestrator_dashboard_advanced_ux_spec.md +1 -1
- package/spec-files/outstanding/agentic_orchestrator_evidence_integrity_doctor_spec.md +561 -0
- package/spec-files/outstanding/agentic_orchestrator_kernel_simplification_spec.md +834 -0
- package/spec-files/outstanding/agentic_orchestrator_observability_integrity_diagnostics_spec.md +12 -5
- package/spec-files/outstanding/agentic_orchestrator_observability_replay_spec.md +442 -0
- package/spec-files/progress.md +174 -1
|
@@ -34,11 +34,73 @@ function computeAggregates(outcomes) {
|
|
|
34
34
|
}
|
|
35
35
|
return aggregates;
|
|
36
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Manages performance analytics and outcome tracking.
|
|
39
|
+
*
|
|
40
|
+
* ## Responsibilities
|
|
41
|
+
* - Record feature outcomes (status, retries, duration, cost)
|
|
42
|
+
* - Aggregate metrics by provider/model
|
|
43
|
+
* - Calculate success rates and averages
|
|
44
|
+
* - Provide analytics for dashboard
|
|
45
|
+
*
|
|
46
|
+
* ## Dependencies
|
|
47
|
+
* Depends on {@link PerformanceAnalyticsServicePort} for:
|
|
48
|
+
* - Analytics file path resolution
|
|
49
|
+
* - Timestamp utilities
|
|
50
|
+
*
|
|
51
|
+
* ## Key Methods
|
|
52
|
+
* - `recordOutcome()` - record feature outcome
|
|
53
|
+
* - `getAnalytics()` - retrieve aggregated metrics
|
|
54
|
+
* - `getProviderStats()` - get metrics by provider/model
|
|
55
|
+
*
|
|
56
|
+
* ## Error Conditions
|
|
57
|
+
* - FILE_NOT_FOUND - analytics file does not exist
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const perfService = new PerformanceAnalyticsService(port);
|
|
62
|
+
* await perfService.recordOutcome({
|
|
63
|
+
* feature_id: 'my_feature',
|
|
64
|
+
* status: 'merged',
|
|
65
|
+
* provider: 'claude',
|
|
66
|
+
* model: 'claude-3-5-sonnet-20241022',
|
|
67
|
+
* retries: 2,
|
|
68
|
+
* duration_ms: 300000,
|
|
69
|
+
* cost_usd: 1.50
|
|
70
|
+
* });
|
|
71
|
+
* const analytics = await perfService.getAnalytics();
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* ## Metrics Tracked
|
|
75
|
+
* - Success rate by provider/model
|
|
76
|
+
* - Average cost per feature
|
|
77
|
+
* - Average duration per phase
|
|
78
|
+
* - Retry counts and reasons
|
|
79
|
+
*/
|
|
37
80
|
export class PerformanceAnalyticsService {
|
|
38
81
|
port;
|
|
39
82
|
constructor(port) {
|
|
40
83
|
this.port = port;
|
|
41
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Records feature outcome for analytics.
|
|
87
|
+
*
|
|
88
|
+
* @param outcome - outcome data (status, retries, duration, cost, provider, model)
|
|
89
|
+
* @returns Updated analytics snapshot
|
|
90
|
+
*
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* await perfService.recordOutcome({
|
|
94
|
+
* feature_id: 'my_feature',
|
|
95
|
+
* status: 'merged',
|
|
96
|
+
* provider: 'claude',
|
|
97
|
+
* model: 'claude-3-5-sonnet-20241022',
|
|
98
|
+
* retries: 2,
|
|
99
|
+
* duration_ms: 300000,
|
|
100
|
+
* cost_usd: 1.50
|
|
101
|
+
* });
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
42
104
|
async recordOutcome(outcome) {
|
|
43
105
|
const filePath = this.port.analyticsPath();
|
|
44
106
|
await ensureDir(path.dirname(filePath));
|
|
@@ -49,9 +111,33 @@ export class PerformanceAnalyticsService {
|
|
|
49
111
|
await atomicWriteJson(filePath, current);
|
|
50
112
|
return current;
|
|
51
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Retrieves aggregated performance analytics.
|
|
116
|
+
*
|
|
117
|
+
* @returns Analytics snapshot with provider/model metrics
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const analytics = await perfService.getAnalytics();
|
|
122
|
+
* console.log(analytics.by_provider);
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
52
125
|
async getAnalytics() {
|
|
53
126
|
return await this.readSnapshot();
|
|
54
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Retrieves provider/model statistics with optional filtering.
|
|
130
|
+
*
|
|
131
|
+
* @param provider - optional provider filter
|
|
132
|
+
* @param model - optional model filter
|
|
133
|
+
* @returns Array of provider/model stats
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* const stats = await perfService.getProviderStats('claude');
|
|
138
|
+
* console.log(stats[0].success_rate);
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
55
141
|
async getProviderStats(provider, model) {
|
|
56
142
|
const snapshot = await this.readSnapshot();
|
|
57
143
|
let stats = snapshot.aggregates;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performance-analytics-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/performance-analytics-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"performance-analytics-service.js","sourceRoot":"","sources":["../../../../../apps/control-plane/src/application/services/performance-analytics-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,IAAI,MAAM,WAAW,CAAC;AAyC7B,SAAS,iBAAiB,CAAC,QAA0B;IACnD,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAyB,EAAE,CAAC;IAC5C,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;QAC3B,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC;QAC7D,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAE1D,UAAU,CAAC,IAAI,CAAC;YACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,YAAY;YAC3B,YAAY,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAClD,eAAe,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACjD,eAAe,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACpD,YAAY,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7C,YAAY,EAAE,MAAM,EAAE;SACvB,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,OAAO,2BAA2B;IACrB,IAAI,CAAkC;IAEvD,YAAY,IAAqC;QAC/C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,aAAa,CAAC,OAAuB;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3C,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAExC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1C,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/B,OAAO,CAAC,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACzD,OAAO,CAAC,YAAY,GAAG,MAAM,EAAE,CAAC;QAEhC,MAAM,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,YAAY;QAChB,OAAO,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IACnC,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,gBAAgB,CAAC,QAAiB,EAAE,KAAc;QACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC3C,IAAI,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC;QAEhC,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,KAAK,EAAE,CAAC;YACV,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;QACjD,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAoB,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,CAAC;QACpF,OAAO,CACL,QAAQ,IAAI;YACV,QAAQ,EAAE,EAAE;YACZ,UAAU,EAAE,EAAE;YACd,YAAY,EAAE,MAAM,EAAE;SACvB,CACF,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -6,10 +6,44 @@ type StateUpdater = (frontMatter: AnyRecord, body: string) => Promise<{
|
|
|
6
6
|
frontMatter?: AnyRecord;
|
|
7
7
|
body?: string;
|
|
8
8
|
}>;
|
|
9
|
+
/**
|
|
10
|
+
* Port interface for plan operations.
|
|
11
|
+
*
|
|
12
|
+
* ## Contract
|
|
13
|
+
* Implementations must ensure:
|
|
14
|
+
* - Thread-safe access to plan files via feature locks
|
|
15
|
+
* - Atomic read-modify-write operations for state updates
|
|
16
|
+
* - Schema validation before persistence
|
|
17
|
+
* - Version guard enforcement for optimistic concurrency
|
|
18
|
+
*
|
|
19
|
+
* ## Error Handling
|
|
20
|
+
* All methods throw normalized errors with:
|
|
21
|
+
* - `code` - stable error code from ERROR_CODES
|
|
22
|
+
* - `message` - human-readable description
|
|
23
|
+
* - `details` - { retryable, requires_human, suggestions }
|
|
24
|
+
*/
|
|
9
25
|
export interface PlanServicePort {
|
|
26
|
+
/**
|
|
27
|
+
* Returns the current policy snapshot.
|
|
28
|
+
* Must not return null; policy is loaded during kernel initialization.
|
|
29
|
+
*/
|
|
10
30
|
getPolicySnapshot(): AnyRecord;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the current gates configuration.
|
|
33
|
+
*/
|
|
11
34
|
getGatesConfig(): AnyRecord;
|
|
35
|
+
/**
|
|
36
|
+
* Returns the absolute path to a feature's plan.json file.
|
|
37
|
+
* Does not check if file exists.
|
|
38
|
+
*
|
|
39
|
+
* @param featureId - feature identifier
|
|
40
|
+
*/
|
|
12
41
|
planPath(featureId: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Discovers all canonical feature specs under .aop/features/.
|
|
44
|
+
*
|
|
45
|
+
* @returns List of feature IDs with canonical specs
|
|
46
|
+
*/
|
|
13
47
|
featureDiscoverSpecs(): Promise<{
|
|
14
48
|
data: {
|
|
15
49
|
specs: Array<{
|
|
@@ -17,34 +51,265 @@ export interface PlanServicePort {
|
|
|
17
51
|
}>;
|
|
18
52
|
};
|
|
19
53
|
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Reads feature state (front matter + body).
|
|
56
|
+
*
|
|
57
|
+
* @param featureId - feature identifier
|
|
58
|
+
* @throws FEATURE_NOT_FOUND - if state.md doesn't exist
|
|
59
|
+
*/
|
|
20
60
|
readState(featureId: string): Promise<StateReadResult>;
|
|
61
|
+
/**
|
|
62
|
+
* Validates a value against a named schema.
|
|
63
|
+
*
|
|
64
|
+
* @param schemaName - schema identifier (e.g., 'plan', 'state')
|
|
65
|
+
* @param value - value to validate
|
|
66
|
+
* @returns Validation result with errors if invalid
|
|
67
|
+
* @throws SCHEMA_NOT_FOUND - if schema doesn't exist
|
|
68
|
+
*/
|
|
21
69
|
validateSchema(schemaName: string, value: unknown): Promise<{
|
|
22
70
|
valid: boolean;
|
|
23
71
|
errors?: unknown;
|
|
24
72
|
}>;
|
|
73
|
+
/**
|
|
74
|
+
* Executes an operation with feature-level lock held.
|
|
75
|
+
* Serializes concurrent access to feature state.
|
|
76
|
+
*
|
|
77
|
+
* @param featureId - feature identifier
|
|
78
|
+
* @param operation - async operation to execute
|
|
79
|
+
*/
|
|
25
80
|
withFeatureLock<T>(featureId: string, operation: () => Promise<T>): Promise<T>;
|
|
81
|
+
/**
|
|
82
|
+
* Executes an operation with index-level lock held.
|
|
83
|
+
* Serializes concurrent access to global index.
|
|
84
|
+
*
|
|
85
|
+
* @param operation - async operation to execute
|
|
86
|
+
*/
|
|
26
87
|
withIndexLock<T>(operation: () => Promise<T>): Promise<T>;
|
|
88
|
+
/**
|
|
89
|
+
* Reads the global feature index.
|
|
90
|
+
*
|
|
91
|
+
* @returns Index object with active/blocked/merged features, locks, sessions
|
|
92
|
+
*/
|
|
27
93
|
readIndex(): Promise<AnyRecord>;
|
|
94
|
+
/**
|
|
95
|
+
* Writes the global feature index atomically.
|
|
96
|
+
*
|
|
97
|
+
* @param index - index object to persist
|
|
98
|
+
*/
|
|
28
99
|
writeIndex(index: AnyRecord): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Updates feature state with optimistic concurrency control.
|
|
102
|
+
*
|
|
103
|
+
* @param featureId - feature identifier
|
|
104
|
+
* @param expectedVersion - expected version for concurrency check (null = no check)
|
|
105
|
+
* @param updater - function that returns updated front matter and/or body
|
|
106
|
+
* @returns Updated front matter
|
|
107
|
+
* @throws VERSION_MISMATCH - if expectedVersion doesn't match current version
|
|
108
|
+
*/
|
|
29
109
|
updateState(featureId: string, expectedVersion: number | null, updater: StateUpdater): Promise<AnyRecord>;
|
|
30
110
|
}
|
|
111
|
+
/**
|
|
112
|
+
* Manages plan submission, validation, and collision detection.
|
|
113
|
+
*
|
|
114
|
+
* ## Responsibilities
|
|
115
|
+
* - Validate plan schema and policy compliance
|
|
116
|
+
* - Detect file/area/contract collisions with other features
|
|
117
|
+
* - Enforce lock requirements for protected resources
|
|
118
|
+
* - Manage plan versioning with optimistic concurrency
|
|
119
|
+
* - Select appropriate gate profiles based on plan intent
|
|
120
|
+
*
|
|
121
|
+
* ## Dependencies
|
|
122
|
+
* Depends on {@link PlanServicePort} for:
|
|
123
|
+
* - Policy and schema access
|
|
124
|
+
* - State and index operations
|
|
125
|
+
* - File locking primitives
|
|
126
|
+
*
|
|
127
|
+
* ## Key Methods
|
|
128
|
+
* - `planSubmit()` - submit initial plan with full validation
|
|
129
|
+
* - `planUpdate()` - submit versioned plan revision
|
|
130
|
+
* - `planGet()` - retrieve accepted plan
|
|
131
|
+
* - `checkPlanCollision()` - detect collisions with other features
|
|
132
|
+
* - `assertPlanLocksHeld()` - verify required locks are held
|
|
133
|
+
*
|
|
134
|
+
* ## Error Conditions
|
|
135
|
+
* - SCHEMA_VALIDATION_FAILED - plan fails JSON schema validation
|
|
136
|
+
* - PLAN_COLLISION - file/area/contract conflicts with another feature
|
|
137
|
+
* - LOCK_NOT_HELD - required resource locks not acquired
|
|
138
|
+
* - VERSION_CONFLICT - plan version mismatch (concurrent update)
|
|
139
|
+
* - DEPENDENCY_CYCLE - circular feature dependencies detected
|
|
140
|
+
*
|
|
141
|
+
* ## Thread Safety
|
|
142
|
+
* All mutations are protected by feature-level or index-level locks.
|
|
143
|
+
* Concurrent reads are safe. Concurrent writes are serialized.
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ```typescript
|
|
147
|
+
* const planService = new PlanService(port);
|
|
148
|
+
*
|
|
149
|
+
* // Submit initial plan
|
|
150
|
+
* await planService.planSubmit('my_feature', planData, null);
|
|
151
|
+
*
|
|
152
|
+
* // Update plan with version guard
|
|
153
|
+
* await planService.planUpdate('my_feature', updatedPlan, 1);
|
|
154
|
+
*
|
|
155
|
+
* // Check for collisions
|
|
156
|
+
* const result = await planService.checkPlanCollision('my_feature', planData);
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* @see CollisionDetector - for collision detection algorithm
|
|
160
|
+
* @see GateSelectionService - for gate profile selection
|
|
161
|
+
*/
|
|
31
162
|
export declare class PlanService {
|
|
32
163
|
private readonly port;
|
|
33
164
|
private readonly gateSelectionService;
|
|
34
165
|
constructor(port: PlanServicePort);
|
|
166
|
+
/**
|
|
167
|
+
* Retrieves the accepted plan for a feature.
|
|
168
|
+
*
|
|
169
|
+
* @param featureId - feature identifier
|
|
170
|
+
* @returns Plan data wrapped in success response
|
|
171
|
+
* @throws FILE_NOT_FOUND - plan file does not exist
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const result = await planService.planGet('my_feature');
|
|
176
|
+
* console.log(result.data.plan);
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
35
179
|
planGet(featureId: string): Promise<{
|
|
36
180
|
data: {
|
|
37
181
|
feature_id: string;
|
|
38
182
|
plan: unknown;
|
|
39
183
|
};
|
|
40
184
|
}>;
|
|
185
|
+
/**
|
|
186
|
+
* Collects all accepted plans from discovered features.
|
|
187
|
+
*
|
|
188
|
+
* Used for collision detection and dependency analysis.
|
|
189
|
+
*
|
|
190
|
+
* @param excludeFeatureId - optional feature to exclude from collection
|
|
191
|
+
* @returns Array of plan objects
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* // Get all plans except current feature
|
|
196
|
+
* const plans = await planService.collectAcceptedPlans('my_feature');
|
|
197
|
+
* ```
|
|
198
|
+
*/
|
|
41
199
|
collectAcceptedPlans(excludeFeatureId?: string | null): Promise<AnyRecord[]>;
|
|
200
|
+
/**
|
|
201
|
+
* Determines required resource locks based on plan contracts.
|
|
202
|
+
*
|
|
203
|
+
* Maps contract modifications to resource identifiers per policy.
|
|
204
|
+
*
|
|
205
|
+
* @param plan - plan object with contracts section
|
|
206
|
+
* @returns Sorted array of required resource identifiers
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* ```typescript
|
|
210
|
+
* const resources = planService.requiredResourcesForPlan(plan);
|
|
211
|
+
* // ['openapi', 'db_migrations']
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
42
214
|
requiredResourcesForPlan(plan: AnyRecord): string[];
|
|
215
|
+
/**
|
|
216
|
+
* Verifies that all required resource locks are held by the feature.
|
|
217
|
+
*
|
|
218
|
+
* @param featureId - feature identifier
|
|
219
|
+
* @param plan - plan object requiring locks
|
|
220
|
+
* @throws LOCK_NOT_HELD - required locks are not held
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* await planService.assertPlanLocksHeld('my_feature', plan);
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
43
227
|
assertPlanLocksHeld(featureId: string, plan: AnyRecord): Promise<void>;
|
|
228
|
+
/**
|
|
229
|
+
* Validates plan revision rules for versioning and optimistic concurrency.
|
|
230
|
+
*
|
|
231
|
+
* Enforces:
|
|
232
|
+
* - Initial plans must be version 1 without revision_of
|
|
233
|
+
* - Updates must increment version and reference previous version
|
|
234
|
+
* - Version guard must match current plan version
|
|
235
|
+
*
|
|
236
|
+
* @param existingPlan - current plan or null for initial submission
|
|
237
|
+
* @param plan - new plan to validate
|
|
238
|
+
* @param expectedPlanVersion - expected current version for concurrency guard
|
|
239
|
+
* @throws PLAN_VALIDATION_FAILED - revision rules violated
|
|
240
|
+
* @throws VERSION_CONFLICT - version mismatch (concurrent update)
|
|
241
|
+
*/
|
|
44
242
|
validatePlanRevisionRules(existingPlan: AnyRecord | null, plan: AnyRecord, expectedPlanVersion?: number | null): void;
|
|
243
|
+
/**
|
|
244
|
+
* Validates plan against JSON schema.
|
|
245
|
+
*
|
|
246
|
+
* @param plan - plan object to validate
|
|
247
|
+
* @throws SCHEMA_VALIDATION_FAILED - plan does not conform to schema
|
|
248
|
+
*
|
|
249
|
+
* @example
|
|
250
|
+
* ```typescript
|
|
251
|
+
* await planService.validatePlanSchema(planData);
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
45
254
|
validatePlanSchema(plan: AnyRecord): Promise<void>;
|
|
255
|
+
/**
|
|
256
|
+
* Detects file, area, and contract collisions with other features.
|
|
257
|
+
*
|
|
258
|
+
* Compares plan against all accepted plans to find conflicts.
|
|
259
|
+
*
|
|
260
|
+
* @param featureId - feature identifier
|
|
261
|
+
* @param plan - plan to check for collisions
|
|
262
|
+
* @returns Collision matrix with conflicts by feature
|
|
263
|
+
* @throws PLAN_COLLISION - collisions detected (per policy)
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* ```typescript
|
|
267
|
+
* const result = await planService.checkPlanCollision('my_feature', plan);
|
|
268
|
+
* if (result.data.has_collisions) {
|
|
269
|
+
* console.log(result.data.collisions);
|
|
270
|
+
* }
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
46
273
|
checkPlanCollision(featureId: string, plan: AnyRecord): Promise<unknown>;
|
|
274
|
+
/**
|
|
275
|
+
* Validates feature dependencies and detects circular references.
|
|
276
|
+
*
|
|
277
|
+
* @param featureId - feature to check (null checks all features)
|
|
278
|
+
* @throws DEPENDENCY_CYCLE - circular dependency detected
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* ```typescript
|
|
282
|
+
* await planService.checkDependencies('my_feature');
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
47
285
|
checkDependencies(featureId: string | null): Promise<void>;
|
|
286
|
+
/**
|
|
287
|
+
* Submits initial plan with full validation pipeline.
|
|
288
|
+
*
|
|
289
|
+
* Validation steps:
|
|
290
|
+
* 1. Schema validation
|
|
291
|
+
* 2. Revision rules check
|
|
292
|
+
* 3. Lock requirement verification
|
|
293
|
+
* 4. Collision detection
|
|
294
|
+
* 5. Dependency cycle check
|
|
295
|
+
* 6. Gate profile selection
|
|
296
|
+
*
|
|
297
|
+
* @param featureId - feature identifier
|
|
298
|
+
* @param plan - plan object to submit
|
|
299
|
+
* @param expectedVersion - expected state version for concurrency guard
|
|
300
|
+
* @returns Acceptance result with plan version
|
|
301
|
+
* @throws INVALID_ARGUMENT - missing or invalid plan
|
|
302
|
+
* @throws SCHEMA_VALIDATION_FAILED - plan schema invalid
|
|
303
|
+
* @throws LOCK_NOT_HELD - required locks not held
|
|
304
|
+
* @throws PLAN_COLLISION - collisions detected
|
|
305
|
+
* @throws DEPENDENCY_CYCLE - circular dependencies
|
|
306
|
+
*
|
|
307
|
+
* @example
|
|
308
|
+
* ```typescript
|
|
309
|
+
* const result = await planService.planSubmit('my_feature', planData, null);
|
|
310
|
+
* console.log(`Plan accepted: version ${result.data.plan_version}`);
|
|
311
|
+
* ```
|
|
312
|
+
*/
|
|
48
313
|
planSubmit(featureId: string | null, plan: AnyRecord | null, expectedVersion?: number | null): Promise<{
|
|
49
314
|
data: {
|
|
50
315
|
feature_id: string | null;
|
|
@@ -52,6 +317,28 @@ export declare class PlanService {
|
|
|
52
317
|
plan_version: number;
|
|
53
318
|
};
|
|
54
319
|
}>;
|
|
320
|
+
/**
|
|
321
|
+
* Submits versioned plan revision with full revalidation.
|
|
322
|
+
*
|
|
323
|
+
* Requires plan_version to be current_version + 1 and revision_of
|
|
324
|
+
* to reference current version. Runs full validation pipeline.
|
|
325
|
+
*
|
|
326
|
+
* @param featureId - feature identifier
|
|
327
|
+
* @param plan - updated plan object
|
|
328
|
+
* @param expectedPlanVersion - expected current plan version
|
|
329
|
+
* @returns Acceptance result with new plan version
|
|
330
|
+
* @throws VERSION_CONFLICT - plan version mismatch
|
|
331
|
+
* @throws PLAN_VALIDATION_FAILED - revision rules violated
|
|
332
|
+
* @throws SCHEMA_VALIDATION_FAILED - plan schema invalid
|
|
333
|
+
* @throws LOCK_NOT_HELD - required locks not held
|
|
334
|
+
* @throws PLAN_COLLISION - collisions detected
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* ```typescript
|
|
338
|
+
* // Update plan from version 1 to version 2
|
|
339
|
+
* const result = await planService.planUpdate('my_feature', updatedPlan, 1);
|
|
340
|
+
* ```
|
|
341
|
+
*/
|
|
55
342
|
planUpdate(featureId: string | null, expectedPlanVersion: number | null, plan: AnyRecord | null): Promise<{
|
|
56
343
|
data: {
|
|
57
344
|
feature_id: string | null;
|