@company-semantics/contracts 9.0.0 → 9.2.0
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/package.json +6 -3
- package/src/__tests__/resource-keys.test.ts +30 -23
- package/src/admin/authz-simulate.ts +4 -4
- package/src/admin/direct-grants.ts +2 -2
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +97 -0
- package/src/api/http/routes/ai-chat.ts +3 -3
- package/src/api/http/utils/resource-response.ts +5 -2
- package/src/api/index.ts +4 -4
- package/src/api/primitives.ts +6 -2
- package/src/auth/README.md +1 -0
- package/src/auth/index.ts +12 -5
- package/src/autotune.ts +5 -1
- package/src/billing/index.ts +1 -1
- package/src/billing/types.ts +1 -1
- package/src/chat/README.md +3 -0
- package/src/chat/__tests__/runtime-profile.test.ts +68 -48
- package/src/chat/index.ts +10 -4
- package/src/chat/runtime-profile.ts +25 -10
- package/src/chat/schemas.ts +49 -41
- package/src/chat/types.ts +48 -42
- package/src/ci-envelope/README.md +2 -0
- package/src/ci-envelope/__tests__/transitions.test.ts +56 -56
- package/src/ci-envelope/index.ts +2 -2
- package/src/ci-envelope/types.ts +20 -20
- package/src/ci-results/index.ts +2 -2
- package/src/ci-results/repo-ci-result.ts +15 -12
- package/src/compatibility.ts +6 -6
- package/src/content/index.ts +10 -4
- package/src/content/schemas.ts +42 -24
- package/src/dispatch/index.ts +18 -15
- package/src/email/__tests__/registry.test.ts +81 -77
- package/src/email/index.ts +3 -3
- package/src/email/registry.ts +25 -25
- package/src/email/types.ts +43 -43
- package/src/errors/index.ts +8 -8
- package/src/execution/__tests__/events.test.ts +42 -42
- package/src/execution/__tests__/lifecycle.test.ts +192 -190
- package/src/execution/__tests__/registry.test.ts +114 -114
- package/src/execution/audit-export.ts +4 -4
- package/src/execution/errors.ts +7 -7
- package/src/execution/event-metadata.ts +4 -4
- package/src/execution/events.ts +23 -21
- package/src/execution/expiry.ts +5 -5
- package/src/execution/hash-chain.ts +2 -2
- package/src/execution/index.ts +19 -28
- package/src/execution/kinds.ts +7 -7
- package/src/execution/lifecycle.ts +33 -33
- package/src/execution/registry.ts +63 -63
- package/src/execution/schemas.ts +31 -23
- package/src/execution/status.ts +45 -26
- package/src/execution/summary.ts +16 -17
- package/src/execution/timeline-ui.ts +9 -9
- package/src/execution/types.ts +31 -25
- package/src/generated/openapi-routes.ts +2 -0
- package/src/guards/config.ts +22 -18
- package/src/guards/index.ts +4 -4
- package/src/guards/types.ts +32 -24
- package/src/identity/__tests__/avatar.test.ts +68 -59
- package/src/identity/avatar.ts +8 -8
- package/src/identity/display-name.ts +3 -3
- package/src/identity/index.ts +8 -8
- package/src/identity/people-org-chart.ts +8 -4
- package/src/identity/schemas.ts +28 -18
- package/src/identity/types.ts +5 -5
- package/src/impersonation/index.ts +5 -5
- package/src/impersonation/schemas.ts +15 -9
- package/src/impersonation-events.ts +21 -21
- package/src/impersonation.ts +25 -24
- package/src/index.ts +118 -90
- package/src/interfaces/mcp/tools/help.ts +19 -19
- package/src/internal-admin.ts +6 -6
- package/src/mcp/README.md +2 -0
- package/src/mcp/__tests__/capability-graph.test.ts +290 -290
- package/src/mcp/capability-graph.ts +42 -40
- package/src/mcp/failure-context.ts +1 -3
- package/src/mcp/index.ts +69 -56
- package/src/mcp/resources.ts +9 -9
- package/src/meetings/index.ts +2 -2
- package/src/meetings/schemas.ts +51 -34
- package/src/message-parts/README.md +2 -0
- package/src/message-parts/__tests__/builder.test.ts +142 -142
- package/src/message-parts/__tests__/confirmation.test.ts +100 -86
- package/src/message-parts/__tests__/preview.test.ts +63 -63
- package/src/message-parts/__tests__/wire.test.ts +130 -124
- package/src/message-parts/builder.ts +23 -23
- package/src/message-parts/confirmation.ts +17 -14
- package/src/message-parts/execution.ts +7 -7
- package/src/message-parts/index.ts +10 -10
- package/src/message-parts/lifecycle.ts +25 -25
- package/src/message-parts/preview.ts +30 -30
- package/src/message-parts/types.ts +27 -27
- package/src/message-parts/wire.ts +24 -24
- package/src/mutations.ts +2 -2
- package/src/observability.ts +23 -11
- package/src/org/__tests__/org-units.test.ts +131 -96
- package/src/org/__tests__/tree-ordering.test.ts +57 -37
- package/src/org/__tests__/view-scopes.test.ts +40 -40
- package/src/org/domain.ts +9 -9
- package/src/org/index.ts +31 -21
- package/src/org/org-units.ts +34 -20
- package/src/org/schemas.ts +261 -124
- package/src/org/sharing.ts +17 -13
- package/src/org/tree-ordering.ts +3 -1
- package/src/org/types.ts +54 -47
- package/src/org/view-scopes.ts +9 -9
- package/src/permissions/access-levels.ts +7 -2
- package/src/permissions/access-source.ts +6 -6
- package/src/permissions/index.ts +5 -5
- package/src/permissions/orgchart-roles.ts +7 -7
- package/src/permissions/permission-introspection.ts +7 -5
- package/src/permissions/share-api.ts +19 -9
- package/src/pressure.ts +4 -4
- package/src/queryIntent.ts +21 -21
- package/src/ralph/__tests__/prd-groups.test.ts +159 -159
- package/src/ralph/__tests__/prd.test.ts +30 -30
- package/src/ralph/index.ts +3 -8
- package/src/ralph/prd.ts +33 -33
- package/src/ralph/progress.ts +1 -1
- package/src/rate-limit/README.md +4 -4
- package/src/rate-limit/index.ts +3 -3
- package/src/requests.ts +36 -8
- package/src/resource-keys.ts +207 -124
- package/src/resource-registry.ts +5 -5
- package/src/route-builder.ts +3 -3
- package/src/safe-mode.ts +2 -2
- package/src/security/index.ts +4 -4
- package/src/security/org-secrets.ts +13 -9
- package/src/security/secret.ts +3 -3
- package/src/sse.ts +3 -1
- package/src/system/README.md +3 -0
- package/src/system/capabilities.ts +22 -23
- package/src/system/diagram.ts +45 -45
- package/src/system/index.ts +14 -14
- package/src/tiers.ts +1 -1
- package/src/timeouts.ts +1 -1
- package/src/tracing.ts +30 -30
- package/src/types/analytics.ts +2 -2
- package/src/usage/README.md +3 -0
- package/src/usage/execution-types.ts +69 -69
- package/src/usage/types.ts +7 -3
|
@@ -1,249 +1,249 @@
|
|
|
1
|
-
import { describe, it, expect } from
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
2
|
import type {
|
|
3
3
|
RalphPRD,
|
|
4
4
|
RalphFeatureGroup,
|
|
5
5
|
RalphExecutionPolicy,
|
|
6
|
-
} from
|
|
6
|
+
} from "../index.js";
|
|
7
7
|
|
|
8
|
-
describe(
|
|
9
|
-
describe(
|
|
10
|
-
it(
|
|
8
|
+
describe("RalphFeatureGroup and RalphExecutionPolicy types", () => {
|
|
9
|
+
describe("RalphPRD with groups field", () => {
|
|
10
|
+
it("typechecks with groups containing RalphFeatureGroup entries", () => {
|
|
11
11
|
const prd = {
|
|
12
|
-
version:
|
|
13
|
-
repo:
|
|
12
|
+
version: "2.1",
|
|
13
|
+
repo: "company-semantics-backend",
|
|
14
14
|
features: [],
|
|
15
|
-
stopCondition:
|
|
15
|
+
stopCondition: "All features pass",
|
|
16
16
|
groups: [
|
|
17
17
|
{
|
|
18
|
-
id:
|
|
19
|
-
description:
|
|
20
|
-
features: [
|
|
18
|
+
id: "auth-group",
|
|
19
|
+
description: "Authentication features",
|
|
20
|
+
features: ["auth/login", "auth/logout"],
|
|
21
21
|
},
|
|
22
22
|
],
|
|
23
|
-
} satisfies RalphPRD
|
|
23
|
+
} satisfies RalphPRD;
|
|
24
24
|
|
|
25
|
-
expect(prd.groups).toHaveLength(1)
|
|
26
|
-
expect(prd.groups![0].id).toBe(
|
|
27
|
-
expect(prd.groups![0].features).toEqual([
|
|
28
|
-
})
|
|
25
|
+
expect(prd.groups).toHaveLength(1);
|
|
26
|
+
expect(prd.groups![0].id).toBe("auth-group");
|
|
27
|
+
expect(prd.groups![0].features).toEqual(["auth/login", "auth/logout"]);
|
|
28
|
+
});
|
|
29
29
|
|
|
30
|
-
it(
|
|
30
|
+
it("typechecks with multiple groups", () => {
|
|
31
31
|
const prd = {
|
|
32
|
-
version:
|
|
33
|
-
repo:
|
|
32
|
+
version: "2.1",
|
|
33
|
+
repo: "company-semantics-backend",
|
|
34
34
|
features: [],
|
|
35
|
-
stopCondition:
|
|
35
|
+
stopCondition: "All features pass",
|
|
36
36
|
groups: [
|
|
37
37
|
{
|
|
38
|
-
id:
|
|
39
|
-
description:
|
|
40
|
-
features: [
|
|
38
|
+
id: "group-a",
|
|
39
|
+
description: "First group",
|
|
40
|
+
features: ["feat-1"],
|
|
41
41
|
},
|
|
42
42
|
{
|
|
43
|
-
id:
|
|
44
|
-
description:
|
|
45
|
-
features: [
|
|
46
|
-
sharedContext:
|
|
43
|
+
id: "group-b",
|
|
44
|
+
description: "Second group",
|
|
45
|
+
features: ["feat-2", "feat-3"],
|
|
46
|
+
sharedContext: "Shared context for group B",
|
|
47
47
|
},
|
|
48
48
|
],
|
|
49
|
-
} satisfies RalphPRD
|
|
49
|
+
} satisfies RalphPRD;
|
|
50
50
|
|
|
51
|
-
expect(prd.groups).toHaveLength(2)
|
|
52
|
-
})
|
|
53
|
-
})
|
|
51
|
+
expect(prd.groups).toHaveLength(2);
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
54
|
|
|
55
|
-
describe(
|
|
56
|
-
it(
|
|
55
|
+
describe("backward compatibility — PRD without groups field", () => {
|
|
56
|
+
it("typechecks without groups field (existing PRD shape)", () => {
|
|
57
57
|
const prd = {
|
|
58
|
-
version:
|
|
59
|
-
repo:
|
|
58
|
+
version: "2.0",
|
|
59
|
+
repo: "company-semantics-contracts",
|
|
60
60
|
features: [
|
|
61
61
|
{
|
|
62
|
-
id:
|
|
63
|
-
category:
|
|
64
|
-
description:
|
|
65
|
-
steps: [
|
|
62
|
+
id: "test/feature",
|
|
63
|
+
category: "functional" as const,
|
|
64
|
+
description: "A test feature",
|
|
65
|
+
steps: ["Step 1"],
|
|
66
66
|
passes: false,
|
|
67
|
-
priority:
|
|
67
|
+
priority: "high" as const,
|
|
68
68
|
},
|
|
69
69
|
],
|
|
70
|
-
stopCondition:
|
|
71
|
-
} satisfies RalphPRD
|
|
70
|
+
stopCondition: "All features pass",
|
|
71
|
+
} satisfies RalphPRD;
|
|
72
72
|
|
|
73
|
-
expect(prd.groups).toBeUndefined()
|
|
74
|
-
expect(prd.features).toHaveLength(1)
|
|
75
|
-
})
|
|
73
|
+
expect(prd.groups).toBeUndefined();
|
|
74
|
+
expect(prd.features).toHaveLength(1);
|
|
75
|
+
});
|
|
76
76
|
|
|
77
|
-
it(
|
|
77
|
+
it("typechecks with all v2.0 optional fields but no groups", () => {
|
|
78
78
|
const prd = {
|
|
79
|
-
version:
|
|
80
|
-
repo:
|
|
79
|
+
version: "2.0",
|
|
80
|
+
repo: "company-semantics-backend",
|
|
81
81
|
features: [],
|
|
82
|
-
stopCondition:
|
|
82
|
+
stopCondition: "Done",
|
|
83
83
|
agentContract: {
|
|
84
|
-
mode:
|
|
85
|
-
allowedActions: [
|
|
84
|
+
mode: "afk" as const,
|
|
85
|
+
allowedActions: ["Edit"],
|
|
86
86
|
forbiddenActions: [],
|
|
87
|
-
autonomyLevel:
|
|
87
|
+
autonomyLevel: "bounded" as const,
|
|
88
88
|
},
|
|
89
89
|
failurePolicy: {
|
|
90
90
|
maxRetries: 2,
|
|
91
|
-
onRepeatedFailure:
|
|
92
|
-
retryScope:
|
|
91
|
+
onRepeatedFailure: "halt_and_report" as const,
|
|
92
|
+
retryScope: "current_feature_only" as const,
|
|
93
93
|
},
|
|
94
94
|
scope: {
|
|
95
|
-
allowedPaths: [
|
|
96
|
-
forbiddenPaths: [
|
|
95
|
+
allowedPaths: ["src/**"],
|
|
96
|
+
forbiddenPaths: ["node_modules/**"],
|
|
97
97
|
refactoringAllowed: true,
|
|
98
98
|
},
|
|
99
99
|
commitPolicy: {
|
|
100
|
-
strategy:
|
|
101
|
-
commitOn:
|
|
102
|
-
rollbackOnFailure:
|
|
103
|
-
onHalt:
|
|
100
|
+
strategy: "per_feature" as const,
|
|
101
|
+
commitOn: "acceptance_pass" as const,
|
|
102
|
+
rollbackOnFailure: "uncommitted_only" as const,
|
|
103
|
+
onHalt: "leave_committed" as const,
|
|
104
104
|
logRollback: true,
|
|
105
105
|
},
|
|
106
|
-
} satisfies RalphPRD
|
|
106
|
+
} satisfies RalphPRD;
|
|
107
107
|
|
|
108
|
-
expect(prd.groups).toBeUndefined()
|
|
109
|
-
expect(prd.agentContract).toBeDefined()
|
|
110
|
-
})
|
|
111
|
-
})
|
|
108
|
+
expect(prd.groups).toBeUndefined();
|
|
109
|
+
expect(prd.agentContract).toBeDefined();
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
112
|
|
|
113
|
-
describe(
|
|
114
|
-
it(
|
|
113
|
+
describe("RalphExecutionPolicy defaults", () => {
|
|
114
|
+
it("accepts all required fields", () => {
|
|
115
115
|
const policy = {
|
|
116
116
|
parallelism: 1,
|
|
117
|
-
preferredExecutor:
|
|
117
|
+
preferredExecutor: "same",
|
|
118
118
|
serializeFiles: [],
|
|
119
|
-
} satisfies RalphExecutionPolicy
|
|
119
|
+
} satisfies RalphExecutionPolicy;
|
|
120
120
|
|
|
121
|
-
expect(policy.parallelism).toBe(1)
|
|
122
|
-
expect(policy.preferredExecutor).toBe(
|
|
123
|
-
expect(policy.serializeFiles).toEqual([])
|
|
124
|
-
})
|
|
121
|
+
expect(policy.parallelism).toBe(1);
|
|
122
|
+
expect(policy.preferredExecutor).toBe("same");
|
|
123
|
+
expect(policy.serializeFiles).toEqual([]);
|
|
124
|
+
});
|
|
125
125
|
|
|
126
|
-
it(
|
|
126
|
+
it("accepts preferredExecutor: any", () => {
|
|
127
127
|
const policy = {
|
|
128
128
|
parallelism: 4,
|
|
129
|
-
preferredExecutor:
|
|
130
|
-
serializeFiles: [
|
|
131
|
-
} satisfies RalphExecutionPolicy
|
|
129
|
+
preferredExecutor: "any",
|
|
130
|
+
serializeFiles: ["src/config.ts"],
|
|
131
|
+
} satisfies RalphExecutionPolicy;
|
|
132
132
|
|
|
133
|
-
expect(policy.preferredExecutor).toBe(
|
|
134
|
-
expect(policy.serializeFiles).toEqual([
|
|
135
|
-
})
|
|
133
|
+
expect(policy.preferredExecutor).toBe("any");
|
|
134
|
+
expect(policy.serializeFiles).toEqual(["src/config.ts"]);
|
|
135
|
+
});
|
|
136
136
|
|
|
137
|
-
it(
|
|
137
|
+
it("accepts high parallelism with multiple serialized files", () => {
|
|
138
138
|
const policy = {
|
|
139
139
|
parallelism: 10,
|
|
140
|
-
preferredExecutor:
|
|
141
|
-
serializeFiles: [
|
|
142
|
-
} satisfies RalphExecutionPolicy
|
|
140
|
+
preferredExecutor: "any",
|
|
141
|
+
serializeFiles: ["package.json", "pnpm-lock.yaml", "src/index.ts"],
|
|
142
|
+
} satisfies RalphExecutionPolicy;
|
|
143
143
|
|
|
144
|
-
expect(policy.parallelism).toBe(10)
|
|
145
|
-
expect(policy.serializeFiles).toHaveLength(3)
|
|
146
|
-
})
|
|
147
|
-
})
|
|
144
|
+
expect(policy.parallelism).toBe(10);
|
|
145
|
+
expect(policy.serializeFiles).toHaveLength(3);
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
148
|
|
|
149
|
-
describe(
|
|
150
|
-
it(
|
|
149
|
+
describe("RalphFeatureGroup optional fields", () => {
|
|
150
|
+
it("typechecks with no optional fields", () => {
|
|
151
151
|
const group = {
|
|
152
|
-
id:
|
|
153
|
-
description:
|
|
154
|
-
features: [
|
|
155
|
-
} satisfies RalphFeatureGroup
|
|
156
|
-
|
|
157
|
-
expect(group.id).toBe(
|
|
158
|
-
expect(group.sharedContext).toBeUndefined()
|
|
159
|
-
expect(group.completionCriteria).toBeUndefined()
|
|
160
|
-
expect(group.executionPolicy).toBeUndefined()
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
it(
|
|
152
|
+
id: "minimal-group",
|
|
153
|
+
description: "Minimal group with required fields only",
|
|
154
|
+
features: ["feat/one"],
|
|
155
|
+
} satisfies RalphFeatureGroup;
|
|
156
|
+
|
|
157
|
+
expect(group.id).toBe("minimal-group");
|
|
158
|
+
expect(group.sharedContext).toBeUndefined();
|
|
159
|
+
expect(group.completionCriteria).toBeUndefined();
|
|
160
|
+
expect(group.executionPolicy).toBeUndefined();
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it("typechecks with sharedContext only", () => {
|
|
164
164
|
const group = {
|
|
165
|
-
id:
|
|
166
|
-
description:
|
|
167
|
-
features: [
|
|
168
|
-
sharedContext:
|
|
169
|
-
} satisfies RalphFeatureGroup
|
|
165
|
+
id: "shared-ctx-group",
|
|
166
|
+
description: "Group with shared context",
|
|
167
|
+
features: ["feat/a", "feat/b"],
|
|
168
|
+
sharedContext: "All features share the auth domain",
|
|
169
|
+
} satisfies RalphFeatureGroup;
|
|
170
170
|
|
|
171
|
-
expect(group.sharedContext).toBe(
|
|
172
|
-
})
|
|
171
|
+
expect(group.sharedContext).toBe("All features share the auth domain");
|
|
172
|
+
});
|
|
173
173
|
|
|
174
|
-
it(
|
|
174
|
+
it("typechecks with completionCriteria only", () => {
|
|
175
175
|
const group = {
|
|
176
|
-
id:
|
|
177
|
-
description:
|
|
178
|
-
features: [
|
|
179
|
-
completionCriteria:
|
|
180
|
-
} satisfies RalphFeatureGroup
|
|
176
|
+
id: "completion-group",
|
|
177
|
+
description: "Group with completion criteria",
|
|
178
|
+
features: ["feat/x"],
|
|
179
|
+
completionCriteria: "Integration test suite passes end-to-end",
|
|
180
|
+
} satisfies RalphFeatureGroup;
|
|
181
181
|
|
|
182
182
|
expect(group.completionCriteria).toBe(
|
|
183
|
-
|
|
184
|
-
)
|
|
185
|
-
})
|
|
183
|
+
"Integration test suite passes end-to-end",
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
186
|
|
|
187
|
-
it(
|
|
187
|
+
it("typechecks with executionPolicy only", () => {
|
|
188
188
|
const group = {
|
|
189
|
-
id:
|
|
190
|
-
description:
|
|
191
|
-
features: [
|
|
189
|
+
id: "policy-group",
|
|
190
|
+
description: "Group with execution policy",
|
|
191
|
+
features: ["feat/p", "feat/q"],
|
|
192
192
|
executionPolicy: {
|
|
193
193
|
parallelism: 2,
|
|
194
|
-
preferredExecutor:
|
|
195
|
-
serializeFiles: [
|
|
194
|
+
preferredExecutor: "any",
|
|
195
|
+
serializeFiles: ["shared.ts"],
|
|
196
196
|
},
|
|
197
|
-
} satisfies RalphFeatureGroup
|
|
197
|
+
} satisfies RalphFeatureGroup;
|
|
198
198
|
|
|
199
|
-
expect(group.executionPolicy).toBeDefined()
|
|
200
|
-
expect(group.executionPolicy!.parallelism).toBe(2)
|
|
201
|
-
})
|
|
199
|
+
expect(group.executionPolicy).toBeDefined();
|
|
200
|
+
expect(group.executionPolicy!.parallelism).toBe(2);
|
|
201
|
+
});
|
|
202
202
|
|
|
203
|
-
it(
|
|
203
|
+
it("typechecks with all optional fields present", () => {
|
|
204
204
|
const group = {
|
|
205
|
-
id:
|
|
206
|
-
description:
|
|
207
|
-
features: [
|
|
208
|
-
sharedContext:
|
|
209
|
-
completionCriteria:
|
|
205
|
+
id: "full-group",
|
|
206
|
+
description: "Group with all optional fields",
|
|
207
|
+
features: ["feat/1", "feat/2", "feat/3"],
|
|
208
|
+
sharedContext: "All features modify the database schema",
|
|
209
|
+
completionCriteria: "Migration runs cleanly and all tests pass",
|
|
210
210
|
executionPolicy: {
|
|
211
211
|
parallelism: 1,
|
|
212
|
-
preferredExecutor:
|
|
213
|
-
serializeFiles: [
|
|
212
|
+
preferredExecutor: "same",
|
|
213
|
+
serializeFiles: ["drizzle/schema.ts"],
|
|
214
214
|
},
|
|
215
|
-
} satisfies RalphFeatureGroup
|
|
215
|
+
} satisfies RalphFeatureGroup;
|
|
216
216
|
|
|
217
|
-
expect(group.sharedContext).toBeDefined()
|
|
218
|
-
expect(group.completionCriteria).toBeDefined()
|
|
219
|
-
expect(group.executionPolicy).toBeDefined()
|
|
220
|
-
expect(group.executionPolicy!.preferredExecutor).toBe(
|
|
221
|
-
})
|
|
222
|
-
})
|
|
217
|
+
expect(group.sharedContext).toBeDefined();
|
|
218
|
+
expect(group.completionCriteria).toBeDefined();
|
|
219
|
+
expect(group.executionPolicy).toBeDefined();
|
|
220
|
+
expect(group.executionPolicy!.preferredExecutor).toBe("same");
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
223
|
|
|
224
|
-
describe(
|
|
225
|
-
it(
|
|
224
|
+
describe("RalphPRD groups integration", () => {
|
|
225
|
+
it("groups field references RalphFeatureGroup type correctly", () => {
|
|
226
226
|
const group: RalphFeatureGroup = {
|
|
227
|
-
id:
|
|
228
|
-
description:
|
|
229
|
-
features: [
|
|
227
|
+
id: "test-group",
|
|
228
|
+
description: "Test group",
|
|
229
|
+
features: ["a", "b"],
|
|
230
230
|
executionPolicy: {
|
|
231
231
|
parallelism: 3,
|
|
232
|
-
preferredExecutor:
|
|
232
|
+
preferredExecutor: "any",
|
|
233
233
|
serializeFiles: [],
|
|
234
234
|
},
|
|
235
|
-
}
|
|
235
|
+
};
|
|
236
236
|
|
|
237
237
|
const prd: RalphPRD = {
|
|
238
|
-
version:
|
|
239
|
-
repo:
|
|
238
|
+
version: "2.1",
|
|
239
|
+
repo: "company-semantics-app",
|
|
240
240
|
features: [],
|
|
241
|
-
stopCondition:
|
|
241
|
+
stopCondition: "Done",
|
|
242
242
|
groups: [group],
|
|
243
|
-
}
|
|
243
|
+
};
|
|
244
244
|
|
|
245
|
-
expect(prd.groups).toHaveLength(1)
|
|
246
|
-
expect(prd.groups![0]).toBe(group)
|
|
247
|
-
})
|
|
248
|
-
})
|
|
249
|
-
})
|
|
245
|
+
expect(prd.groups).toHaveLength(1);
|
|
246
|
+
expect(prd.groups![0]).toBe(group);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
});
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
import { describe, it, expect } from
|
|
2
|
-
import { REPO_PRECEDENCE } from
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { REPO_PRECEDENCE } from "../prd.js";
|
|
3
3
|
|
|
4
|
-
describe(
|
|
5
|
-
it(
|
|
6
|
-
expect(REPO_PRECEDENCE[0]).toBe(
|
|
7
|
-
})
|
|
4
|
+
describe("REPO_PRECEDENCE", () => {
|
|
5
|
+
it("has contracts first (dependency source)", () => {
|
|
6
|
+
expect(REPO_PRECEDENCE[0]).toBe("company-semantics-contracts");
|
|
7
|
+
});
|
|
8
8
|
|
|
9
|
-
it(
|
|
9
|
+
it("exact values and order are frozen (golden snapshot)", () => {
|
|
10
10
|
expect(REPO_PRECEDENCE).toStrictEqual([
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
])
|
|
19
|
-
})
|
|
11
|
+
"company-semantics-contracts",
|
|
12
|
+
"company-semantics-control",
|
|
13
|
+
"company-semantics-ci",
|
|
14
|
+
"company-semantics-backend",
|
|
15
|
+
"company-semantics-edge",
|
|
16
|
+
"company-semantics-app",
|
|
17
|
+
"company-semantics-site",
|
|
18
|
+
]);
|
|
19
|
+
});
|
|
20
20
|
|
|
21
|
-
it(
|
|
22
|
-
expect(REPO_PRECEDENCE).toHaveLength(7)
|
|
23
|
-
})
|
|
21
|
+
it("has exactly 7 entries (all known repos)", () => {
|
|
22
|
+
expect(REPO_PRECEDENCE).toHaveLength(7);
|
|
23
|
+
});
|
|
24
24
|
|
|
25
|
-
it(
|
|
26
|
-
expect(new Set(REPO_PRECEDENCE).size).toBe(REPO_PRECEDENCE.length)
|
|
27
|
-
})
|
|
25
|
+
it("has no duplicates", () => {
|
|
26
|
+
expect(new Set(REPO_PRECEDENCE).size).toBe(REPO_PRECEDENCE.length);
|
|
27
|
+
});
|
|
28
28
|
|
|
29
|
-
it(
|
|
29
|
+
it("all entries start with company-semantics- prefix", () => {
|
|
30
30
|
for (const repo of REPO_PRECEDENCE) {
|
|
31
|
-
expect(repo).toMatch(/^company-semantics-/)
|
|
31
|
+
expect(repo).toMatch(/^company-semantics-/);
|
|
32
32
|
}
|
|
33
|
-
})
|
|
33
|
+
});
|
|
34
34
|
|
|
35
|
-
it(
|
|
35
|
+
it("all entries are non-empty strings", () => {
|
|
36
36
|
for (const repo of REPO_PRECEDENCE) {
|
|
37
|
-
expect(typeof repo).toBe(
|
|
38
|
-
expect(repo.length).toBeGreaterThan(0)
|
|
37
|
+
expect(typeof repo).toBe("string");
|
|
38
|
+
expect(repo.length).toBeGreaterThan(0);
|
|
39
39
|
}
|
|
40
|
-
})
|
|
41
|
-
})
|
|
40
|
+
});
|
|
41
|
+
});
|
package/src/ralph/index.ts
CHANGED
|
@@ -31,15 +31,10 @@ export type {
|
|
|
31
31
|
// PRD v2.1 schema extensions
|
|
32
32
|
RalphExecutionPolicy,
|
|
33
33
|
RalphFeatureGroup,
|
|
34
|
-
} from
|
|
34
|
+
} from "./prd";
|
|
35
35
|
|
|
36
36
|
// PRD constants (cross-repo support)
|
|
37
|
-
export { REPO_PRECEDENCE } from
|
|
37
|
+
export { REPO_PRECEDENCE } from "./prd";
|
|
38
38
|
|
|
39
39
|
// Progress types
|
|
40
|
-
export type {
|
|
41
|
-
RalphIteration,
|
|
42
|
-
RalphMode,
|
|
43
|
-
RalphProgress,
|
|
44
|
-
} from './progress';
|
|
45
|
-
|
|
40
|
+
export type { RalphIteration, RalphMode, RalphProgress } from "./progress";
|
package/src/ralph/prd.ts
CHANGED
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
* - Validation of repo graph (no cycles)
|
|
25
25
|
*/
|
|
26
26
|
export const REPO_PRECEDENCE = [
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
"company-semantics-contracts",
|
|
28
|
+
"company-semantics-control",
|
|
29
|
+
"company-semantics-ci",
|
|
30
|
+
"company-semantics-backend",
|
|
31
|
+
"company-semantics-edge",
|
|
32
|
+
"company-semantics-app",
|
|
33
|
+
"company-semantics-site",
|
|
34
34
|
] as const;
|
|
35
35
|
|
|
36
36
|
/**
|
|
@@ -48,16 +48,16 @@ export type AllowedRepo = (typeof REPO_PRECEDENCE)[number];
|
|
|
48
48
|
* Used for prioritization and verification strategy selection.
|
|
49
49
|
*/
|
|
50
50
|
export type RalphPRDCategory =
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
55
|
-
|
|
|
51
|
+
| "functional"
|
|
52
|
+
| "architectural"
|
|
53
|
+
| "integration"
|
|
54
|
+
| "polish"
|
|
55
|
+
| "validation";
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
58
|
* Priority level for feature ordering.
|
|
59
59
|
*/
|
|
60
|
-
export type RalphPRDPriority =
|
|
60
|
+
export type RalphPRDPriority = "high" | "medium" | "low";
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* A single feature item in a Ralph PRD.
|
|
@@ -107,15 +107,15 @@ export type RalphPRDItem = {
|
|
|
107
107
|
*/
|
|
108
108
|
export type RalphAgentContract = {
|
|
109
109
|
/** Execution mode (inferred from invocation if omitted) */
|
|
110
|
-
mode:
|
|
110
|
+
mode: "afk" | "hitl";
|
|
111
111
|
/** Actions explicitly allowed (empty = all allowed per trust level) */
|
|
112
112
|
allowedActions: string[];
|
|
113
113
|
/** Actions explicitly forbidden */
|
|
114
114
|
forbiddenActions: string[];
|
|
115
115
|
/** Autonomy level: bounded = conservative, full = aggressive */
|
|
116
|
-
autonomyLevel:
|
|
116
|
+
autonomyLevel: "bounded" | "full";
|
|
117
117
|
/** Enforcement: hard = block on violation, soft = warn + log */
|
|
118
|
-
enforcement?:
|
|
118
|
+
enforcement?: "hard" | "soft";
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
/**
|
|
@@ -128,11 +128,11 @@ export type RalphFailurePolicy = {
|
|
|
128
128
|
/** Number of retries before triggering onRepeatedFailure (0 = no retries) */
|
|
129
129
|
maxRetries: number;
|
|
130
130
|
/** Action on repeated failure */
|
|
131
|
-
onRepeatedFailure:
|
|
131
|
+
onRepeatedFailure: "halt_and_report" | "continue_next_feature" | "escalate";
|
|
132
132
|
/** Scope for retry attempts */
|
|
133
|
-
retryScope:
|
|
133
|
+
retryScope: "current_feature_only" | "full_prd";
|
|
134
134
|
/** Target for escalation (for future HITL workflows) */
|
|
135
|
-
escalationTarget?:
|
|
135
|
+
escalationTarget?: "human" | "issue" | "log_only";
|
|
136
136
|
};
|
|
137
137
|
|
|
138
138
|
/**
|
|
@@ -173,19 +173,19 @@ export type RalphMeta = {
|
|
|
173
173
|
* All criteria must pass for feature to be marked passes: true.
|
|
174
174
|
*/
|
|
175
175
|
export type RalphAcceptanceCriteria =
|
|
176
|
-
| { type:
|
|
176
|
+
| { type: "file_contains"; path: string; pattern: string }
|
|
177
177
|
| {
|
|
178
|
-
type:
|
|
178
|
+
type: "command_exit";
|
|
179
179
|
command: string;
|
|
180
180
|
expectedExitCode: number;
|
|
181
181
|
}
|
|
182
182
|
| {
|
|
183
|
-
type:
|
|
183
|
+
type: "ci_status";
|
|
184
184
|
workflow?: string;
|
|
185
|
-
status:
|
|
186
|
-
scope?:
|
|
185
|
+
status: "success" | "failure";
|
|
186
|
+
scope?: "current_sha" | "branch";
|
|
187
187
|
}
|
|
188
|
-
| { type:
|
|
188
|
+
| { type: "test_passes"; pattern?: string };
|
|
189
189
|
|
|
190
190
|
/**
|
|
191
191
|
* Code shape guidance for feature implementation.
|
|
@@ -194,15 +194,15 @@ export type RalphAcceptanceCriteria =
|
|
|
194
194
|
*/
|
|
195
195
|
export type RalphReferenceImplementation = {
|
|
196
196
|
/** How authoritative is this reference */
|
|
197
|
-
status:
|
|
197
|
+
status: "authoritative" | "guidance" | "partial" | "anti-pattern";
|
|
198
198
|
/** Programming language */
|
|
199
199
|
language: string;
|
|
200
200
|
/** Location: 'inline' for embedded code, or file path */
|
|
201
|
-
location:
|
|
201
|
+
location: "inline" | string;
|
|
202
202
|
/** Inline code (when location is 'inline') */
|
|
203
203
|
code?: string;
|
|
204
204
|
/** Policy for deviations from reference */
|
|
205
|
-
deviationPolicy?:
|
|
205
|
+
deviationPolicy?: "must_log" | "allowed";
|
|
206
206
|
/** Scoping for where this reference applies */
|
|
207
207
|
appliesTo?: {
|
|
208
208
|
/** File paths where this applies */
|
|
@@ -277,13 +277,13 @@ export type RalphSuccessCriteria = {
|
|
|
277
277
|
*/
|
|
278
278
|
export type RalphCommitPolicy = {
|
|
279
279
|
/** When commits are created */
|
|
280
|
-
strategy:
|
|
280
|
+
strategy: "per_feature" | "manual";
|
|
281
281
|
/** Gate for allowing commits */
|
|
282
|
-
commitOn:
|
|
282
|
+
commitOn: "acceptance_pass" | "manual";
|
|
283
283
|
/** What to do with code on failure */
|
|
284
|
-
rollbackOnFailure:
|
|
284
|
+
rollbackOnFailure: "none" | "uncommitted_only" | "current_feature";
|
|
285
285
|
/** What to do with completed work on halt/escalation */
|
|
286
|
-
onHalt:
|
|
286
|
+
onHalt: "leave_committed" | "rollback_uncommitted";
|
|
287
287
|
/** Whether to log all rollback actions (must be true if rollbackOnFailure !== 'none') */
|
|
288
288
|
logRollback: boolean;
|
|
289
289
|
};
|
|
@@ -301,7 +301,7 @@ export type RalphExecutionPolicy = {
|
|
|
301
301
|
/** Max concurrent executors for this group (default 1) */
|
|
302
302
|
parallelism: number;
|
|
303
303
|
/** 'same' prefers all features on one executor, 'any' allows distribution */
|
|
304
|
-
preferredExecutor:
|
|
304
|
+
preferredExecutor: "same" | "any";
|
|
305
305
|
/** Files that must not be modified concurrently (hard constraint) */
|
|
306
306
|
serializeFiles: string[];
|
|
307
307
|
};
|