agent-dealer 1.2.6 → 1.2.8
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/bundle/server/dist/adapters/agent-deck-bind.js +16 -6
- package/bundle/server/dist/adapters/agent-deck-bind.test.js +74 -0
- package/bundle/server/dist/adapters/agent-health.js +14 -3
- package/bundle/server/dist/adapters/github.js +4 -1
- package/bundle/server/dist/adapters/muse-capability.js +443 -24
- package/bundle/server/dist/adapters/muse-capability.test.js +469 -25
- package/bundle/server/dist/adapters/muse-visual-qa.js +114 -0
- package/bundle/server/dist/adapters/muse-visual-qa.test.js +68 -0
- package/bundle/server/dist/capacity/muse-probe.js +56 -9
- package/bundle/server/dist/capacity/muse-probe.test.js +188 -1
- package/bundle/server/dist/coordinator/admission.js +14 -1
- package/bundle/server/dist/coordinator/admission.test.js +197 -4
- package/bundle/server/dist/coordinator/auto-merge.integration.test.js +276 -0
- package/bundle/server/dist/coordinator/auto-merge.js +39 -3
- package/bundle/server/dist/coordinator/commands.js +90 -5
- package/bundle/server/dist/coordinator/deck-outage.integration.test.js +4 -2
- package/bundle/server/dist/coordinator/developer-effect.js +79 -1
- package/bundle/server/dist/coordinator/execution-report.js +6 -0
- package/bundle/server/dist/coordinator/execution-report.test.js +7 -0
- package/bundle/server/dist/coordinator/failure-cause.js +64 -1
- package/bundle/server/dist/coordinator/failure-cause.test.js +92 -1
- package/bundle/server/dist/coordinator/failure-reason.js +7 -0
- package/bundle/server/dist/coordinator/failure-reason.test.js +14 -0
- package/bundle/server/dist/coordinator/human-resolution.js +17 -1
- package/bundle/server/dist/coordinator/merge-conflict-sync.js +647 -0
- package/bundle/server/dist/coordinator/merge-conflict-sync.test.js +121 -0
- package/bundle/server/dist/coordinator/muse-developer.integration.test.js +9 -4
- package/bundle/server/dist/coordinator/muse-spawn.js +122 -29
- package/bundle/server/dist/coordinator/muse-spawn.test.js +210 -0
- package/bundle/server/dist/coordinator/playbook-feedback.js +690 -0
- package/bundle/server/dist/coordinator/playbook-feedback.test.js +702 -0
- package/bundle/server/dist/coordinator/prompts-execution-contract.test.js +107 -0
- package/bundle/server/dist/coordinator/prompts.js +78 -2
- package/bundle/server/dist/coordinator/prompts.test.js +83 -0
- package/bundle/server/dist/coordinator/reflect-trigger.js +33 -169
- package/bundle/server/dist/coordinator/reflect-trigger.test.js +149 -200
- package/bundle/server/dist/coordinator/reviewer-effect.js +10 -1
- package/bundle/server/dist/coordinator/reviewer-result.js +6 -0
- package/bundle/server/dist/coordinator/routing.test.js +14 -0
- package/bundle/server/dist/coordinator/session-timeouts.js +30 -0
- package/bundle/server/dist/coordinator/usage-cap.integration.test.js +1 -1
- package/bundle/server/dist/coordinator/worker-loop.js +18 -4
- package/bundle/server/dist/db/index.js +5 -0
- package/bundle/server/dist/db/schema.sql +3 -0
- package/bundle/server/dist/docs-execution-analysis.test.js +1 -0
- package/bundle/server/dist/repository/artifacts-for-issue.js +3 -3
- package/bundle/server/dist/repository/human-actions.js +14 -0
- package/bundle/server/dist/repository/issues.js +29 -4
- package/bundle/server/dist/repository/worker-sessions.js +51 -2
- package/bundle/server/dist/routes/human-actions.js +10 -8
- package/bundle/server/dist/routes/issues-execution-contract.test.js +321 -0
- package/bundle/server/dist/routes/issues.js +19 -2
- package/bundle/server/dist/runners/muse-code-jsonl.js +106 -11
- package/bundle/server/dist/runners/muse-config-core.js +18 -1
- package/bundle/server/dist/runners/muse-config.test.js +37 -0
- package/bundle/server/dist/runners/muse-serve-session.js +5 -0
- package/bundle/server/dist/runners/spawn-cli.js +116 -0
- package/bundle/server/dist/runners/spawn-cli.test.js +124 -0
- package/bundle/server/package.json +2 -2
- package/bundle/server/static-ui/assets/index-B6SVCzMR.js +64 -0
- package/bundle/server/static-ui/assets/index-K_YcYkQU.css +1 -0
- package/bundle/server/static-ui/index.html +2 -2
- package/bundle/shared/dist/action-presentation.d.ts +51 -0
- package/bundle/shared/dist/action-presentation.js +280 -0
- package/bundle/shared/dist/action-presentation.test.d.ts +1 -0
- package/bundle/shared/dist/action-presentation.test.js +180 -0
- package/bundle/shared/dist/attempt-waste.d.ts +2 -2
- package/bundle/shared/dist/execution-analysis.d.ts +22 -22
- package/bundle/shared/dist/execution-contract.d.ts +117 -0
- package/bundle/shared/dist/execution-contract.js +307 -0
- package/bundle/shared/dist/execution-contract.test.d.ts +2 -0
- package/bundle/shared/dist/execution-contract.test.js +499 -0
- package/bundle/shared/dist/execution-report.d.ts +11 -11
- package/bundle/shared/dist/execution-report.js +2 -0
- package/bundle/shared/dist/failure-cause.d.ts +4 -4
- package/bundle/shared/dist/failure-cause.js +2 -0
- package/bundle/shared/dist/human-actions.d.ts +14 -14
- package/bundle/shared/dist/human-actions.js +9 -0
- package/bundle/shared/dist/index.d.ts +126 -124
- package/bundle/shared/dist/index.js +4 -0
- package/bundle/shared/dist/issues.d.ts +158 -28
- package/bundle/shared/dist/issues.js +8 -0
- package/bundle/shared/dist/issues.test.js +1 -0
- package/bundle/shared/dist/outbound-draft.d.ts +18 -18
- package/bundle/shared/dist/profile-snapshot.d.ts +2 -2
- package/bundle/shared/dist/usage-events.d.ts +2 -2
- package/bundle/shared/dist/worker-sessions.d.ts +16 -6
- package/bundle/shared/dist/worker-sessions.js +8 -0
- package/bundle/shared/dist/worker-sessions.test.js +1 -0
- package/bundle/shared/dist/workflow.d.ts +6 -6
- package/bundle/shared/dist/workflow.js +10 -0
- package/bundle/shared/dist/workflow.test.js +2 -0
- package/bundle/shared/package.json +1 -1
- package/package.json +1 -1
- package/bundle/server/static-ui/assets/index-BII-LgB8.css +0 -1
- package/bundle/server/static-ui/assets/index-CoDzZcsz.js +0 -60
|
@@ -286,7 +286,7 @@ export declare const AttemptAnalysis: z.ZodObject<{
|
|
|
286
286
|
spawnEnvelopeQuality: z.ZodEnum<["exact", "inferred", "unavailable"]>;
|
|
287
287
|
spawnEnvelopeReasons: z.ZodArray<z.ZodString, "many">;
|
|
288
288
|
failureCauses: z.ZodArray<z.ZodObject<{
|
|
289
|
-
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
289
|
+
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "muse_no_progress", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
290
290
|
domain: z.ZodEnum<["task", "infrastructure", "unknown"]>;
|
|
291
291
|
primary: z.ZodBoolean;
|
|
292
292
|
confidence: z.ZodEnum<["high", "medium", "low"]>;
|
|
@@ -300,7 +300,7 @@ export declare const AttemptAnalysis: z.ZodObject<{
|
|
|
300
300
|
eventType: z.ZodNullable<z.ZodString>;
|
|
301
301
|
quality: z.ZodEnum<["exact", "inferred"]>;
|
|
302
302
|
}, "strip", z.ZodTypeAny, {
|
|
303
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
303
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
304
304
|
logPath: string | null;
|
|
305
305
|
domain: "unknown" | "task" | "infrastructure";
|
|
306
306
|
primary: boolean;
|
|
@@ -314,7 +314,7 @@ export declare const AttemptAnalysis: z.ZodObject<{
|
|
|
314
314
|
eventType: string | null;
|
|
315
315
|
quality: "exact" | "inferred";
|
|
316
316
|
}, {
|
|
317
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
317
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
318
318
|
logPath: string | null;
|
|
319
319
|
domain: "unknown" | "task" | "infrastructure";
|
|
320
320
|
primary: boolean;
|
|
@@ -419,7 +419,7 @@ export declare const AttemptAnalysis: z.ZodObject<{
|
|
|
419
419
|
spawnEnvelopeQuality: "exact" | "inferred" | "unavailable";
|
|
420
420
|
spawnEnvelopeReasons: string[];
|
|
421
421
|
failureCauses: {
|
|
422
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
422
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
423
423
|
logPath: string | null;
|
|
424
424
|
domain: "unknown" | "task" | "infrastructure";
|
|
425
425
|
primary: boolean;
|
|
@@ -497,7 +497,7 @@ export declare const AttemptAnalysis: z.ZodObject<{
|
|
|
497
497
|
spawnEnvelopeQuality: "exact" | "inferred" | "unavailable";
|
|
498
498
|
spawnEnvelopeReasons: string[];
|
|
499
499
|
failureCauses: {
|
|
500
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
500
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
501
501
|
logPath: string | null;
|
|
502
502
|
domain: "unknown" | "task" | "infrastructure";
|
|
503
503
|
primary: boolean;
|
|
@@ -876,7 +876,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
876
876
|
spawnEnvelopeQuality: z.ZodEnum<["exact", "inferred", "unavailable"]>;
|
|
877
877
|
spawnEnvelopeReasons: z.ZodArray<z.ZodString, "many">;
|
|
878
878
|
failureCauses: z.ZodArray<z.ZodObject<{
|
|
879
|
-
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
879
|
+
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "muse_no_progress", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
880
880
|
domain: z.ZodEnum<["task", "infrastructure", "unknown"]>;
|
|
881
881
|
primary: z.ZodBoolean;
|
|
882
882
|
confidence: z.ZodEnum<["high", "medium", "low"]>;
|
|
@@ -890,7 +890,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
890
890
|
eventType: z.ZodNullable<z.ZodString>;
|
|
891
891
|
quality: z.ZodEnum<["exact", "inferred"]>;
|
|
892
892
|
}, "strip", z.ZodTypeAny, {
|
|
893
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
893
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
894
894
|
logPath: string | null;
|
|
895
895
|
domain: "unknown" | "task" | "infrastructure";
|
|
896
896
|
primary: boolean;
|
|
@@ -904,7 +904,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
904
904
|
eventType: string | null;
|
|
905
905
|
quality: "exact" | "inferred";
|
|
906
906
|
}, {
|
|
907
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
907
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
908
908
|
logPath: string | null;
|
|
909
909
|
domain: "unknown" | "task" | "infrastructure";
|
|
910
910
|
primary: boolean;
|
|
@@ -1009,7 +1009,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1009
1009
|
spawnEnvelopeQuality: "exact" | "inferred" | "unavailable";
|
|
1010
1010
|
spawnEnvelopeReasons: string[];
|
|
1011
1011
|
failureCauses: {
|
|
1012
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1012
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1013
1013
|
logPath: string | null;
|
|
1014
1014
|
domain: "unknown" | "task" | "infrastructure";
|
|
1015
1015
|
primary: boolean;
|
|
@@ -1087,7 +1087,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1087
1087
|
spawnEnvelopeQuality: "exact" | "inferred" | "unavailable";
|
|
1088
1088
|
spawnEnvelopeReasons: string[];
|
|
1089
1089
|
failureCauses: {
|
|
1090
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1090
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1091
1091
|
logPath: string | null;
|
|
1092
1092
|
domain: "unknown" | "task" | "infrastructure";
|
|
1093
1093
|
primary: boolean;
|
|
@@ -1124,7 +1124,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1124
1124
|
/** The single primary cause across the issue (first chronological actionable
|
|
1125
1125
|
* cause), or null when no failure is recorded. */
|
|
1126
1126
|
primaryFailure: z.ZodNullable<z.ZodObject<{
|
|
1127
|
-
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
1127
|
+
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "muse_no_progress", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
1128
1128
|
domain: z.ZodEnum<["task", "infrastructure", "unknown"]>;
|
|
1129
1129
|
primary: z.ZodBoolean;
|
|
1130
1130
|
confidence: z.ZodEnum<["high", "medium", "low"]>;
|
|
@@ -1138,7 +1138,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1138
1138
|
eventType: z.ZodNullable<z.ZodString>;
|
|
1139
1139
|
quality: z.ZodEnum<["exact", "inferred"]>;
|
|
1140
1140
|
}, "strip", z.ZodTypeAny, {
|
|
1141
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1141
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1142
1142
|
logPath: string | null;
|
|
1143
1143
|
domain: "unknown" | "task" | "infrastructure";
|
|
1144
1144
|
primary: boolean;
|
|
@@ -1152,7 +1152,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1152
1152
|
eventType: string | null;
|
|
1153
1153
|
quality: "exact" | "inferred";
|
|
1154
1154
|
}, {
|
|
1155
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1155
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1156
1156
|
logPath: string | null;
|
|
1157
1157
|
domain: "unknown" | "task" | "infrastructure";
|
|
1158
1158
|
primary: boolean;
|
|
@@ -1169,7 +1169,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1169
1169
|
primaryFailureQuality: z.ZodEnum<["exact", "inferred", "unavailable"]>;
|
|
1170
1170
|
primaryFailureReasons: z.ZodArray<z.ZodString, "many">;
|
|
1171
1171
|
consequenceCauses: z.ZodArray<z.ZodObject<{
|
|
1172
|
-
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
1172
|
+
code: z.ZodEnum<["authentication_configuration", "provider_capacity_rate_limit", "agent_cli_crash", "tool_test_timeout", "muse_no_progress", "coordinator_crash", "validation_failure", "publish_git_failure", "agent_deck_unavailable", "host_sleep_liveness", "unknown"]>;
|
|
1173
1173
|
domain: z.ZodEnum<["task", "infrastructure", "unknown"]>;
|
|
1174
1174
|
primary: z.ZodBoolean;
|
|
1175
1175
|
confidence: z.ZodEnum<["high", "medium", "low"]>;
|
|
@@ -1183,7 +1183,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1183
1183
|
eventType: z.ZodNullable<z.ZodString>;
|
|
1184
1184
|
quality: z.ZodEnum<["exact", "inferred"]>;
|
|
1185
1185
|
}, "strip", z.ZodTypeAny, {
|
|
1186
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1186
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1187
1187
|
logPath: string | null;
|
|
1188
1188
|
domain: "unknown" | "task" | "infrastructure";
|
|
1189
1189
|
primary: boolean;
|
|
@@ -1197,7 +1197,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1197
1197
|
eventType: string | null;
|
|
1198
1198
|
quality: "exact" | "inferred";
|
|
1199
1199
|
}, {
|
|
1200
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1200
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1201
1201
|
logPath: string | null;
|
|
1202
1202
|
domain: "unknown" | "task" | "infrastructure";
|
|
1203
1203
|
primary: boolean;
|
|
@@ -1607,7 +1607,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1607
1607
|
spawnEnvelopeQuality: "exact" | "inferred" | "unavailable";
|
|
1608
1608
|
spawnEnvelopeReasons: string[];
|
|
1609
1609
|
failureCauses: {
|
|
1610
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1610
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1611
1611
|
logPath: string | null;
|
|
1612
1612
|
domain: "unknown" | "task" | "infrastructure";
|
|
1613
1613
|
primary: boolean;
|
|
@@ -1686,7 +1686,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1686
1686
|
category: string | null;
|
|
1687
1687
|
}[];
|
|
1688
1688
|
primaryFailure: {
|
|
1689
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1689
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1690
1690
|
logPath: string | null;
|
|
1691
1691
|
domain: "unknown" | "task" | "infrastructure";
|
|
1692
1692
|
primary: boolean;
|
|
@@ -1703,7 +1703,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1703
1703
|
primaryFailureQuality: "exact" | "inferred" | "unavailable";
|
|
1704
1704
|
primaryFailureReasons: string[];
|
|
1705
1705
|
consequenceCauses: {
|
|
1706
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1706
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1707
1707
|
logPath: string | null;
|
|
1708
1708
|
domain: "unknown" | "task" | "infrastructure";
|
|
1709
1709
|
primary: boolean;
|
|
@@ -1850,7 +1850,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1850
1850
|
spawnEnvelopeQuality: "exact" | "inferred" | "unavailable";
|
|
1851
1851
|
spawnEnvelopeReasons: string[];
|
|
1852
1852
|
failureCauses: {
|
|
1853
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1853
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1854
1854
|
logPath: string | null;
|
|
1855
1855
|
domain: "unknown" | "task" | "infrastructure";
|
|
1856
1856
|
primary: boolean;
|
|
@@ -1929,7 +1929,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1929
1929
|
category: string | null;
|
|
1930
1930
|
}[];
|
|
1931
1931
|
primaryFailure: {
|
|
1932
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1932
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1933
1933
|
logPath: string | null;
|
|
1934
1934
|
domain: "unknown" | "task" | "infrastructure";
|
|
1935
1935
|
primary: boolean;
|
|
@@ -1946,7 +1946,7 @@ export declare const IssueExecutionAnalysis: z.ZodObject<{
|
|
|
1946
1946
|
primaryFailureQuality: "exact" | "inferred" | "unavailable";
|
|
1947
1947
|
primaryFailureReasons: string[];
|
|
1948
1948
|
consequenceCauses: {
|
|
1949
|
-
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1949
|
+
code: "unknown" | "authentication_configuration" | "provider_capacity_rate_limit" | "agent_cli_crash" | "tool_test_timeout" | "muse_no_progress" | "coordinator_crash" | "validation_failure" | "publish_git_failure" | "agent_deck_unavailable" | "host_sleep_liveness";
|
|
1950
1950
|
logPath: string | null;
|
|
1951
1951
|
domain: "unknown" | "task" | "infrastructure";
|
|
1952
1952
|
primary: boolean;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* NOT-306: frozen Dealer execution contracts compiled from Planner-authored
|
|
4
|
+
* Linear tickets.
|
|
5
|
+
*
|
|
6
|
+
* A Planner brief carries its execution semantics as canonical Markdown
|
|
7
|
+
* headings in the ticket description. This module is the ONE implementation
|
|
8
|
+
* that parses, validates, and structures those headings — shared by the web
|
|
9
|
+
* intake, the API routes, and (through the API) the CLI, so no intake path
|
|
10
|
+
* keeps its own regex or drifts from the others.
|
|
11
|
+
*
|
|
12
|
+
* The ticket description stays the untouched source of truth; the contract is
|
|
13
|
+
* derived data. A description with none of the canonical headings is a
|
|
14
|
+
* compatible legacy issue (contract `null`) and existing/manual issues are
|
|
15
|
+
* never blocked.
|
|
16
|
+
*/
|
|
17
|
+
export declare const EXECUTION_CONTRACT_VERSION: "v1";
|
|
18
|
+
export declare const ExecutionMode: z.ZodEnum<["feature", "bug fix", "refactor", "investigation", "split child"]>;
|
|
19
|
+
export type ExecutionMode = z.infer<typeof ExecutionMode>;
|
|
20
|
+
export declare const ExecutionContractCriterion: z.ZodObject<{
|
|
21
|
+
text: z.ZodString;
|
|
22
|
+
/** Raw `Evidence:` line body (where to look, action/command, expected result). */
|
|
23
|
+
evidence: z.ZodNullable<z.ZodString>;
|
|
24
|
+
}, "strip", z.ZodTypeAny, {
|
|
25
|
+
text: string;
|
|
26
|
+
evidence: string | null;
|
|
27
|
+
}, {
|
|
28
|
+
text: string;
|
|
29
|
+
evidence: string | null;
|
|
30
|
+
}>;
|
|
31
|
+
export type ExecutionContractCriterion = z.infer<typeof ExecutionContractCriterion>;
|
|
32
|
+
export declare const ExecutionContractV1: z.ZodObject<{
|
|
33
|
+
version: z.ZodLiteral<"v1">;
|
|
34
|
+
executionMode: z.ZodEnum<["feature", "bug fix", "refactor", "investigation", "split child"]>;
|
|
35
|
+
nonGoals: z.ZodArray<z.ZodString, "many">;
|
|
36
|
+
exitPredicate: z.ZodString;
|
|
37
|
+
onePrStoppingPoint: z.ZodString;
|
|
38
|
+
acceptanceCriteria: z.ZodArray<z.ZodObject<{
|
|
39
|
+
text: z.ZodString;
|
|
40
|
+
/** Raw `Evidence:` line body (where to look, action/command, expected result). */
|
|
41
|
+
evidence: z.ZodNullable<z.ZodString>;
|
|
42
|
+
}, "strip", z.ZodTypeAny, {
|
|
43
|
+
text: string;
|
|
44
|
+
evidence: string | null;
|
|
45
|
+
}, {
|
|
46
|
+
text: string;
|
|
47
|
+
evidence: string | null;
|
|
48
|
+
}>, "many">;
|
|
49
|
+
}, "strip", z.ZodTypeAny, {
|
|
50
|
+
version: "v1";
|
|
51
|
+
executionMode: "feature" | "bug fix" | "refactor" | "investigation" | "split child";
|
|
52
|
+
nonGoals: string[];
|
|
53
|
+
exitPredicate: string;
|
|
54
|
+
onePrStoppingPoint: string;
|
|
55
|
+
acceptanceCriteria: {
|
|
56
|
+
text: string;
|
|
57
|
+
evidence: string | null;
|
|
58
|
+
}[];
|
|
59
|
+
}, {
|
|
60
|
+
version: "v1";
|
|
61
|
+
executionMode: "feature" | "bug fix" | "refactor" | "investigation" | "split child";
|
|
62
|
+
nonGoals: string[];
|
|
63
|
+
exitPredicate: string;
|
|
64
|
+
onePrStoppingPoint: string;
|
|
65
|
+
acceptanceCriteria: {
|
|
66
|
+
text: string;
|
|
67
|
+
evidence: string | null;
|
|
68
|
+
}[];
|
|
69
|
+
}>;
|
|
70
|
+
export type ExecutionContractV1 = z.infer<typeof ExecutionContractV1>;
|
|
71
|
+
/** Display names of the canonical `##` headings, in ticket order. */
|
|
72
|
+
export declare const EXECUTION_CONTRACT_HEADINGS: {
|
|
73
|
+
readonly executionMode: "Builder execution mode";
|
|
74
|
+
readonly nonGoals: "Non-goals";
|
|
75
|
+
readonly exitPredicate: "Exit predicate";
|
|
76
|
+
readonly onePrStoppingPoint: "One-PR stopping point";
|
|
77
|
+
readonly acceptanceCriteria: "Acceptance criteria";
|
|
78
|
+
};
|
|
79
|
+
/** Actionable validation failure — callers map this to a 400, never a silent drop. */
|
|
80
|
+
export declare class ExecutionContractError extends Error {
|
|
81
|
+
constructor(message: string);
|
|
82
|
+
}
|
|
83
|
+
/** Re-serialize contract criteria as the legacy acceptance-criteria text column. */
|
|
84
|
+
export declare function renderContractAcceptanceCriteria(contract: ExecutionContractV1): string;
|
|
85
|
+
export interface CompiledContract {
|
|
86
|
+
/** Non-null only when a Planner-signal heading makes this a contract ticket. */
|
|
87
|
+
contract: ExecutionContractV1 | null;
|
|
88
|
+
/**
|
|
89
|
+
* Acceptance-criteria text derived from the description: the raw section for
|
|
90
|
+
* an AC-only (legacy) ticket, the rendered criteria for a contract ticket,
|
|
91
|
+
* null when the description carries no criteria at all.
|
|
92
|
+
*/
|
|
93
|
+
acceptanceCriteria: string | null;
|
|
94
|
+
/** True when any canonical contract heading was found (contract or legacy AC). */
|
|
95
|
+
hasContractHeadings: boolean;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Compile a ticket description into its execution contract. Throws
|
|
99
|
+
* {@link ExecutionContractError} with an actionable message once any
|
|
100
|
+
* contract-signal heading is present and the brief is ambiguous or malformed.
|
|
101
|
+
* Never throws for a completely contract-free (legacy) description.
|
|
102
|
+
*/
|
|
103
|
+
export declare function compileExecutionContract(description: string | null | undefined): CompiledContract;
|
|
104
|
+
/** True when the description carries any Planner-signal heading (a contract ticket). */
|
|
105
|
+
export declare function hasExecutionContractSignal(description: string | null | undefined): boolean;
|
|
106
|
+
/**
|
|
107
|
+
* Resolve the issue-row fields derived from a ticket description: validate the
|
|
108
|
+
* contract when signal headings are present (throws) and fill a missing
|
|
109
|
+
* legacy acceptance-criteria value from the description. An explicitly
|
|
110
|
+
* provided non-empty value always wins — the contract never silently drops it.
|
|
111
|
+
*/
|
|
112
|
+
export declare function resolveIssueContractFields(description: string | null | undefined, explicitAcceptanceCriteria: string | null | undefined): {
|
|
113
|
+
executionContract: ExecutionContractV1 | null;
|
|
114
|
+
acceptanceCriteria: string | null;
|
|
115
|
+
};
|
|
116
|
+
/** Best-effort contract for read paths — legacy/unparseable descriptions read as null. */
|
|
117
|
+
export declare function tryCompileContract(description: string | null | undefined): ExecutionContractV1 | null;
|
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* NOT-306: frozen Dealer execution contracts compiled from Planner-authored
|
|
4
|
+
* Linear tickets.
|
|
5
|
+
*
|
|
6
|
+
* A Planner brief carries its execution semantics as canonical Markdown
|
|
7
|
+
* headings in the ticket description. This module is the ONE implementation
|
|
8
|
+
* that parses, validates, and structures those headings — shared by the web
|
|
9
|
+
* intake, the API routes, and (through the API) the CLI, so no intake path
|
|
10
|
+
* keeps its own regex or drifts from the others.
|
|
11
|
+
*
|
|
12
|
+
* The ticket description stays the untouched source of truth; the contract is
|
|
13
|
+
* derived data. A description with none of the canonical headings is a
|
|
14
|
+
* compatible legacy issue (contract `null`) and existing/manual issues are
|
|
15
|
+
* never blocked.
|
|
16
|
+
*/
|
|
17
|
+
export const EXECUTION_CONTRACT_VERSION = "v1";
|
|
18
|
+
export const ExecutionMode = z.enum(["feature", "bug fix", "refactor", "investigation", "split child"]);
|
|
19
|
+
const EXECUTION_MODES = ExecutionMode.options;
|
|
20
|
+
export const ExecutionContractCriterion = z.object({
|
|
21
|
+
text: z.string(),
|
|
22
|
+
/** Raw `Evidence:` line body (where to look, action/command, expected result). */
|
|
23
|
+
evidence: z.string().nullable(),
|
|
24
|
+
});
|
|
25
|
+
export const ExecutionContractV1 = z.object({
|
|
26
|
+
version: z.literal(EXECUTION_CONTRACT_VERSION),
|
|
27
|
+
executionMode: ExecutionMode,
|
|
28
|
+
nonGoals: z.array(z.string()),
|
|
29
|
+
exitPredicate: z.string(),
|
|
30
|
+
onePrStoppingPoint: z.string(),
|
|
31
|
+
acceptanceCriteria: z.array(ExecutionContractCriterion),
|
|
32
|
+
});
|
|
33
|
+
/** Display names of the canonical `##` headings, in ticket order. */
|
|
34
|
+
export const EXECUTION_CONTRACT_HEADINGS = {
|
|
35
|
+
executionMode: "Builder execution mode",
|
|
36
|
+
nonGoals: "Non-goals",
|
|
37
|
+
exitPredicate: "Exit predicate",
|
|
38
|
+
onePrStoppingPoint: "One-PR stopping point",
|
|
39
|
+
acceptanceCriteria: "Acceptance criteria",
|
|
40
|
+
};
|
|
41
|
+
/** Actionable validation failure — callers map this to a 400, never a silent drop. */
|
|
42
|
+
export class ExecutionContractError extends Error {
|
|
43
|
+
constructor(message) {
|
|
44
|
+
super(`Execution contract: ${message}`);
|
|
45
|
+
this.name = "ExecutionContractError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const SECTION_KEYS = Object.keys(EXECUTION_CONTRACT_HEADINGS);
|
|
49
|
+
/** Canonical key for a raw `##` heading: lowercase, hyphens→spaces, collapsed. */
|
|
50
|
+
function normalizeHeadingName(raw) {
|
|
51
|
+
return raw.trim().toLowerCase().replace(/[-_]+/g, " ").replace(/\s+/g, " ").trim();
|
|
52
|
+
}
|
|
53
|
+
const CANONICAL_BY_NORMALIZED = Object.fromEntries(SECTION_KEYS.map((key) => [
|
|
54
|
+
normalizeHeadingName(EXECUTION_CONTRACT_HEADINGS[key]),
|
|
55
|
+
key,
|
|
56
|
+
]));
|
|
57
|
+
/** The four Planner-signal headings. `Acceptance criteria` alone stays legacy. */
|
|
58
|
+
const SIGNAL_KEYS = [
|
|
59
|
+
"executionMode",
|
|
60
|
+
"nonGoals",
|
|
61
|
+
"exitPredicate",
|
|
62
|
+
"onePrStoppingPoint",
|
|
63
|
+
];
|
|
64
|
+
/** Split Markdown into `##`-level sections (only `##`, never `#` or `###`). */
|
|
65
|
+
function splitSections(description) {
|
|
66
|
+
const lines = description.split("\n");
|
|
67
|
+
const sections = [];
|
|
68
|
+
let current = null;
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
const heading = line.match(/^##\s+(.+?)\s*$/);
|
|
71
|
+
if (heading?.[1] !== undefined) {
|
|
72
|
+
if (current)
|
|
73
|
+
sections.push({ name: current.name, body: current.body.join("\n") });
|
|
74
|
+
current = { name: heading[1].trim(), body: [] };
|
|
75
|
+
}
|
|
76
|
+
else if (current) {
|
|
77
|
+
current.body.push(line);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (current)
|
|
81
|
+
sections.push({ name: current.name, body: current.body.join("\n") });
|
|
82
|
+
return sections;
|
|
83
|
+
}
|
|
84
|
+
/** Normalize an execution-mode value (`Bug-Fix` → `bug fix`); null when unknown. */
|
|
85
|
+
function normalizeExecutionMode(raw) {
|
|
86
|
+
const collapsed = raw
|
|
87
|
+
.trim()
|
|
88
|
+
.toLowerCase()
|
|
89
|
+
.replace(/[-_]+/g, " ")
|
|
90
|
+
.replace(/\s+/g, " ")
|
|
91
|
+
.trim()
|
|
92
|
+
// Planner tickets punctuate the value as prose (`Feature.`); trailing
|
|
93
|
+
// sentence punctuation is not part of the mode.
|
|
94
|
+
.replace(/[.\u3002!?;:,'"\)\]]+$/g, "")
|
|
95
|
+
.trim();
|
|
96
|
+
if (collapsed === "bugfix")
|
|
97
|
+
return "bug fix";
|
|
98
|
+
const found = EXECUTION_MODES.find((m) => m === collapsed);
|
|
99
|
+
return (found ?? null);
|
|
100
|
+
}
|
|
101
|
+
function requireSection(sections, key) {
|
|
102
|
+
const section = sections.get(key);
|
|
103
|
+
if (!section) {
|
|
104
|
+
throw new ExecutionContractError(`missing \`## ${EXECUTION_CONTRACT_HEADINGS[key]}\` — a ticket with any execution-contract heading must carry all five contract sections`);
|
|
105
|
+
}
|
|
106
|
+
return section;
|
|
107
|
+
}
|
|
108
|
+
function parseNonGoals(body) {
|
|
109
|
+
const items = [];
|
|
110
|
+
for (const line of body.split("\n")) {
|
|
111
|
+
if (!line.trim())
|
|
112
|
+
continue;
|
|
113
|
+
const item = line.match(/^\s*(?:[-*+]|\d+[.)])\s+(.+?)\s*$/);
|
|
114
|
+
if (!item?.[1]) {
|
|
115
|
+
throw new ExecutionContractError(`\`## Non-goals\` must be a Markdown list — got a non-list line: "${line.trim()}"`);
|
|
116
|
+
}
|
|
117
|
+
items.push(item[1]);
|
|
118
|
+
}
|
|
119
|
+
if (items.length === 0) {
|
|
120
|
+
throw new ExecutionContractError("`## Non-goals` must list at least one non-goal");
|
|
121
|
+
}
|
|
122
|
+
return items;
|
|
123
|
+
}
|
|
124
|
+
function parseExitPredicate(body) {
|
|
125
|
+
const text = body.trim();
|
|
126
|
+
if (!text) {
|
|
127
|
+
throw new ExecutionContractError("`## Exit predicate` must be one observable completion statement (got empty)");
|
|
128
|
+
}
|
|
129
|
+
if (/\n\s*\n/.test(text)) {
|
|
130
|
+
throw new ExecutionContractError("`## Exit predicate` must be one observable completion statement (a single paragraph)");
|
|
131
|
+
}
|
|
132
|
+
return text;
|
|
133
|
+
}
|
|
134
|
+
function parseOnePrStoppingPoint(body) {
|
|
135
|
+
const text = body.trim();
|
|
136
|
+
if (!text) {
|
|
137
|
+
throw new ExecutionContractError("`## One-PR stopping point` must state the boundary where this worker must stop (got empty)");
|
|
138
|
+
}
|
|
139
|
+
return text;
|
|
140
|
+
}
|
|
141
|
+
const CHECKBOX_RE = /^\s*[-*]\s+\[([ xX])\]\s+(.*)$/;
|
|
142
|
+
// Planner/Linear evidence lines carry the ticket's nested bullet (` * Evidence: ...`);
|
|
143
|
+
// accept an optional bullet marker so that canonical shape parses as evidence.
|
|
144
|
+
const EVIDENCE_RE = /^\s*(?:[-*+]\s+)?Evidence\s*:\s*(.*)$/i;
|
|
145
|
+
const BULLET_RE = /^\s*(?:[-*+]|\d+[.)])\s+/;
|
|
146
|
+
function normalizeCriterionText(raw) {
|
|
147
|
+
return raw.trim().replace(/\s+/g, " ").toLowerCase();
|
|
148
|
+
}
|
|
149
|
+
function parseAcceptanceCriteria(body) {
|
|
150
|
+
const criteria = [];
|
|
151
|
+
const seen = new Map();
|
|
152
|
+
let current = null;
|
|
153
|
+
let hasEvidence = false;
|
|
154
|
+
const flush = () => {
|
|
155
|
+
if (current)
|
|
156
|
+
criteria.push(current);
|
|
157
|
+
current = null;
|
|
158
|
+
hasEvidence = false;
|
|
159
|
+
};
|
|
160
|
+
for (const line of body.split("\n")) {
|
|
161
|
+
if (!line.trim())
|
|
162
|
+
continue;
|
|
163
|
+
const checkbox = line.match(CHECKBOX_RE);
|
|
164
|
+
if (checkbox) {
|
|
165
|
+
flush();
|
|
166
|
+
const text = (checkbox[2] ?? "").trim();
|
|
167
|
+
if (!text) {
|
|
168
|
+
throw new ExecutionContractError("`## Acceptance criteria` has a checkbox item with no text");
|
|
169
|
+
}
|
|
170
|
+
const key = normalizeCriterionText(text);
|
|
171
|
+
const first = seen.get(key);
|
|
172
|
+
if (first !== undefined) {
|
|
173
|
+
throw new ExecutionContractError(`\`## Acceptance criteria\` has a duplicate criterion: "${first}" — keep each criterion exactly once`);
|
|
174
|
+
}
|
|
175
|
+
seen.set(key, text);
|
|
176
|
+
current = { text, evidence: null };
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const evidence = line.match(EVIDENCE_RE);
|
|
180
|
+
if (evidence) {
|
|
181
|
+
if (!current) {
|
|
182
|
+
throw new ExecutionContractError("`## Acceptance criteria` has an `Evidence:` line before any criterion — indent it under the criterion it belongs to");
|
|
183
|
+
}
|
|
184
|
+
if (hasEvidence) {
|
|
185
|
+
throw new ExecutionContractError(`\`## Acceptance criteria\` has two \`Evidence:\` lines for one criterion ("${current.text}") — keep exactly one`);
|
|
186
|
+
}
|
|
187
|
+
const value = (evidence[1] ?? "").trim();
|
|
188
|
+
if (!value) {
|
|
189
|
+
throw new ExecutionContractError(`\`## Acceptance criteria\` has an empty \`Evidence:\` line for "${current.text}" — state where to look, the action/command, and the expected result`);
|
|
190
|
+
}
|
|
191
|
+
current.evidence = value;
|
|
192
|
+
hasEvidence = true;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
if (BULLET_RE.test(line)) {
|
|
196
|
+
throw new ExecutionContractError(`\`## Acceptance criteria\` items must be checkboxes (\`- [ ] text\`) with an optional indented \`Evidence:\` line — got a plain bullet: "${line.trim()}"`);
|
|
197
|
+
}
|
|
198
|
+
throw new ExecutionContractError(`\`## Acceptance criteria\` lines must be \`- [ ]\` checkbox items or indented \`Evidence:\` lines — got: "${line.trim()}"`);
|
|
199
|
+
}
|
|
200
|
+
flush();
|
|
201
|
+
if (criteria.length === 0) {
|
|
202
|
+
throw new ExecutionContractError("`## Acceptance criteria` must contain at least one `- [ ]` checkbox item");
|
|
203
|
+
}
|
|
204
|
+
return criteria;
|
|
205
|
+
}
|
|
206
|
+
/** Re-serialize contract criteria as the legacy acceptance-criteria text column. */
|
|
207
|
+
export function renderContractAcceptanceCriteria(contract) {
|
|
208
|
+
const lines = [];
|
|
209
|
+
for (const criterion of contract.acceptanceCriteria) {
|
|
210
|
+
lines.push(`- [ ] ${criterion.text}`);
|
|
211
|
+
if (criterion.evidence)
|
|
212
|
+
lines.push(` Evidence: ${criterion.evidence}`);
|
|
213
|
+
}
|
|
214
|
+
return lines.join("\n");
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Compile a ticket description into its execution contract. Throws
|
|
218
|
+
* {@link ExecutionContractError} with an actionable message once any
|
|
219
|
+
* contract-signal heading is present and the brief is ambiguous or malformed.
|
|
220
|
+
* Never throws for a completely contract-free (legacy) description.
|
|
221
|
+
*/
|
|
222
|
+
export function compileExecutionContract(description) {
|
|
223
|
+
if (!description?.trim()) {
|
|
224
|
+
return { contract: null, acceptanceCriteria: null, hasContractHeadings: false };
|
|
225
|
+
}
|
|
226
|
+
const found = new Map();
|
|
227
|
+
for (const section of splitSections(description)) {
|
|
228
|
+
const key = CANONICAL_BY_NORMALIZED[normalizeHeadingName(section.name)];
|
|
229
|
+
if (!key)
|
|
230
|
+
continue;
|
|
231
|
+
const prev = found.get(key);
|
|
232
|
+
if (prev) {
|
|
233
|
+
throw new ExecutionContractError(`duplicate \`## ${EXECUTION_CONTRACT_HEADINGS[key]}\` section — keep exactly one and move the extra content into it`);
|
|
234
|
+
}
|
|
235
|
+
found.set(key, { name: section.name, key, body: section.body });
|
|
236
|
+
}
|
|
237
|
+
if (found.size === 0) {
|
|
238
|
+
return { contract: null, acceptanceCriteria: null, hasContractHeadings: false };
|
|
239
|
+
}
|
|
240
|
+
const hasSignal = SIGNAL_KEYS.some((key) => found.has(key));
|
|
241
|
+
if (!hasSignal) {
|
|
242
|
+
// `## Acceptance criteria` alone is the pre-contract Linear intake shape:
|
|
243
|
+
// keep extracting its raw text exactly as before, without validation.
|
|
244
|
+
const raw = found.get("acceptanceCriteria").body.trim();
|
|
245
|
+
return { contract: null, acceptanceCriteria: raw || null, hasContractHeadings: true };
|
|
246
|
+
}
|
|
247
|
+
const modeSection = requireSection(found, "executionMode");
|
|
248
|
+
const modeLines = modeSection.body.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
249
|
+
if (modeLines.length !== 1) {
|
|
250
|
+
throw new ExecutionContractError(`\`## Builder execution mode\` must state exactly one execution mode (got ${modeLines.length} non-empty lines)`);
|
|
251
|
+
}
|
|
252
|
+
const executionMode = normalizeExecutionMode(modeLines[0]);
|
|
253
|
+
if (!executionMode) {
|
|
254
|
+
throw new ExecutionContractError(`unknown execution mode "${modeLines[0]}" — use exactly one of: ${EXECUTION_MODES.join(" | ")}`);
|
|
255
|
+
}
|
|
256
|
+
const nonGoals = parseNonGoals(requireSection(found, "nonGoals").body);
|
|
257
|
+
const exitPredicate = parseExitPredicate(requireSection(found, "exitPredicate").body);
|
|
258
|
+
const onePrStoppingPoint = parseOnePrStoppingPoint(requireSection(found, "onePrStoppingPoint").body);
|
|
259
|
+
const acceptanceCriteria = parseAcceptanceCriteria(requireSection(found, "acceptanceCriteria").body);
|
|
260
|
+
const contract = {
|
|
261
|
+
version: EXECUTION_CONTRACT_VERSION,
|
|
262
|
+
executionMode,
|
|
263
|
+
nonGoals,
|
|
264
|
+
exitPredicate,
|
|
265
|
+
onePrStoppingPoint,
|
|
266
|
+
acceptanceCriteria,
|
|
267
|
+
};
|
|
268
|
+
return {
|
|
269
|
+
contract,
|
|
270
|
+
acceptanceCriteria: renderContractAcceptanceCriteria(contract),
|
|
271
|
+
hasContractHeadings: true,
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/** True when the description carries any Planner-signal heading (a contract ticket). */
|
|
275
|
+
export function hasExecutionContractSignal(description) {
|
|
276
|
+
if (!description?.trim())
|
|
277
|
+
return false;
|
|
278
|
+
for (const section of splitSections(description)) {
|
|
279
|
+
const key = CANONICAL_BY_NORMALIZED[normalizeHeadingName(section.name)];
|
|
280
|
+
if (key && SIGNAL_KEYS.includes(key))
|
|
281
|
+
return true;
|
|
282
|
+
}
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Resolve the issue-row fields derived from a ticket description: validate the
|
|
287
|
+
* contract when signal headings are present (throws) and fill a missing
|
|
288
|
+
* legacy acceptance-criteria value from the description. An explicitly
|
|
289
|
+
* provided non-empty value always wins — the contract never silently drops it.
|
|
290
|
+
*/
|
|
291
|
+
export function resolveIssueContractFields(description, explicitAcceptanceCriteria) {
|
|
292
|
+
const compiled = compileExecutionContract(description ?? null);
|
|
293
|
+
const explicit = explicitAcceptanceCriteria?.trim() ? explicitAcceptanceCriteria : null;
|
|
294
|
+
return {
|
|
295
|
+
executionContract: compiled.contract,
|
|
296
|
+
acceptanceCriteria: explicit ?? compiled.acceptanceCriteria ?? null,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/** Best-effort contract for read paths — legacy/unparseable descriptions read as null. */
|
|
300
|
+
export function tryCompileContract(description) {
|
|
301
|
+
try {
|
|
302
|
+
return compileExecutionContract(description).contract;
|
|
303
|
+
}
|
|
304
|
+
catch {
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** Planner-authored Linear ticket carrying every contract-v1 heading. */
|
|
2
|
+
export declare const FULL_CONTRACT_DESCRIPTION = "Ship the frozen execution contract for Planner tickets.\n\n## Builder execution mode\nfeature\n\n## Non-goals\n- Selecting a playbook or reasoning about implementation architecture\n- Adding a generic workflow/schema editor\n\n## Exit predicate\nImporting a Planner-authored Linear ticket yields a versioned frozen execution contract visible in Dealer and both worker prompts.\n\n## One-PR stopping point\nStop after the contract compiles from ticket Markdown, persists/freezes with the Issue workflow, appears read-only in Issue Detail, and renders in developer/reviewer prompts.\n\n## Acceptance criteria\n- [ ] Full ticket imports into the exact structured schema\n Evidence: shared compiler fixtures | run the compiler test | every field asserted\n- [ ] Legacy issues without headings still start\n Evidence: migration tests | run the legacy suite | green\n";
|