@company-semantics/contracts 91.1.0 → 92.0.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 +3 -2
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +4 -10
- package/src/source-sync/README.md +2 -1
- package/src/source-sync/__tests__/approval-schemas.test.ts +2 -13
- package/src/source-sync/__tests__/current-synthesis.test.ts +1 -0
- package/src/source-sync/__tests__/schemas.test.ts +5 -32
- package/src/source-sync/schemas.ts +6 -15
- package/src/workflows/deferred-route.ts +2 -0
- package/src/workflows/outcome-reasons.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@company-semantics/contracts",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "92.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -179,6 +179,7 @@
|
|
|
179
179
|
"esbuild@<0.28.1": ">=0.28.1",
|
|
180
180
|
"linkify-it@<5.0.2": ">=5.0.2",
|
|
181
181
|
"postcss@<8.5.23": ">=8.5.23",
|
|
182
|
+
"source-map-js@<1.2.2": ">=1.2.2",
|
|
182
183
|
"markdown-it@<14.2.0": ">=14.2.0",
|
|
183
184
|
"@humanfs/node@<0.16.8": ">=0.16.8 <0.17.0"
|
|
184
185
|
}
|
|
@@ -188,5 +189,5 @@
|
|
|
188
189
|
"*.md": "markdownlint-cli2",
|
|
189
190
|
"package.json": "node -e \"JSON.parse(require('fs').readFileSync('package.json'))\""
|
|
190
191
|
},
|
|
191
|
-
"securityRequirementsVersion": "
|
|
192
|
+
"securityRequirementsVersion": "4b88755e9a43a82b2f5eb55b953581526f1982de362da77bc579888d1f6a1bb0"
|
|
192
193
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
|
|
2
|
-
export const SPEC_HASH = '
|
|
3
|
-
export const SPEC_HASH_FULL = '
|
|
2
|
+
export const SPEC_HASH = '9937d3953931' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = '9937d39539319f5173df9f15191c8dc5af40aca8c8cd62a9995f7221436909d2' as const;
|
package/src/api/generated.ts
CHANGED
|
@@ -4936,7 +4936,7 @@ export interface paths {
|
|
|
4936
4936
|
put?: never;
|
|
4937
4937
|
/**
|
|
4938
4938
|
* Approve the draft candidate set as reviewed, per scope
|
|
4939
|
-
* @description Approves the named scopes (or every scope still open) at the revision the person reviewed. Per scope, the items freeze, a hash binds
|
|
4939
|
+
* @description Approves the named scopes (or every scope still open) at the revision the person reviewed. Per scope, the items freeze, a hash binds the approval to exactly those files and treatments, and a landing job is scheduled on one landing-and-synthesis workflow. Approval authorizes the revision only; it carries no spend.
|
|
4940
4940
|
*/
|
|
4941
4941
|
post: operations["approveSourceCandidateSet"];
|
|
4942
4942
|
delete?: never;
|
|
@@ -7169,7 +7169,7 @@ export interface components {
|
|
|
7169
7169
|
/** @enum {string} */
|
|
7170
7170
|
kind: "produced" | "empty" | "partial" | "stopped" | "failed" | "abandoned" | "unknown";
|
|
7171
7171
|
/** @enum {string} */
|
|
7172
|
-
reason: "updates_ready" | "updates_applied" | "stopped_by_user" | "paused_billing" | "synthesis_incomplete" | "approval_mismatch" | "landing_refused" | "standing_order_refused" | "no_connection" | "source_sync_off" | "internal_error" | "abandoned" | "unrecognized_terminal_state";
|
|
7172
|
+
reason: "updates_ready" | "updates_applied" | "stopped_by_user" | "paused_billing" | "run_ceiling_reached" | "pricing_unconfigured" | "synthesis_incomplete" | "approval_mismatch" | "landing_refused" | "standing_order_refused" | "no_connection" | "source_sync_off" | "internal_error" | "abandoned" | "unrecognized_terminal_state";
|
|
7173
7173
|
facts: {
|
|
7174
7174
|
scopeCount: number;
|
|
7175
7175
|
violationCount: number;
|
|
@@ -9829,11 +9829,6 @@ export interface components {
|
|
|
9829
9829
|
} | null;
|
|
9830
9830
|
approvedAt: string | null;
|
|
9831
9831
|
}[];
|
|
9832
|
-
estimate: {
|
|
9833
|
-
lowMicroUsd: string;
|
|
9834
|
-
highMicroUsd: string;
|
|
9835
|
-
capMicroUsd: string;
|
|
9836
|
-
} | null;
|
|
9837
9832
|
discovery: {
|
|
9838
9833
|
foundThisRun: number;
|
|
9839
9834
|
retainedDecisions: number;
|
|
@@ -9909,7 +9904,7 @@ export interface components {
|
|
|
9909
9904
|
workflowId: string;
|
|
9910
9905
|
batchId: string | null;
|
|
9911
9906
|
/** @enum {string} */
|
|
9912
|
-
phase: "landing" | "drafting" | "waiting_for_review" | "paused_billing" | "applied" | "applied_partial" | "failed" | "closed";
|
|
9907
|
+
phase: "landing" | "drafting" | "waiting_for_review" | "paused_billing" | "paused_ceiling" | "applied" | "applied_partial" | "failed" | "closed";
|
|
9913
9908
|
fileCount: number | null;
|
|
9914
9909
|
proposedDocumentCount: number;
|
|
9915
9910
|
appliedAt: string | null;
|
|
@@ -19984,7 +19979,6 @@ export interface operations {
|
|
|
19984
19979
|
content: {
|
|
19985
19980
|
"application/json": {
|
|
19986
19981
|
revision: number;
|
|
19987
|
-
spendCapMicroUsd: string;
|
|
19988
19982
|
scopeKeys?: string[];
|
|
19989
19983
|
};
|
|
19990
19984
|
};
|
|
@@ -19999,7 +19993,7 @@ export interface operations {
|
|
|
19999
19993
|
"application/json": components["schemas"]["SourceSyncApproveResponse"];
|
|
20000
19994
|
};
|
|
20001
19995
|
};
|
|
20002
|
-
/** @description Invalid request
|
|
19996
|
+
/** @description Invalid request (an unknown field such as a spend cap is refused by the schema), or a scope with no files (SOURCE_SYNC_SCOPE_UNKNOWN) */
|
|
20003
19997
|
400: {
|
|
20004
19998
|
headers: {
|
|
20005
19999
|
[name: string]: unknown;
|
|
@@ -305,7 +305,8 @@ in `attention-evidence.ts`.
|
|
|
305
305
|
`attentionEvidence` (null before index-first discovery).
|
|
306
306
|
- `SourceSyncCandidateSetResponseSchema` / `SourceSyncCandidateSetResponse` —
|
|
307
307
|
the draft set under review: its revision, items, presented questions,
|
|
308
|
-
distinct-file `totals
|
|
308
|
+
distinct-file `totals`. No cost estimate: approval authorizes the files,
|
|
309
|
+
never a spend.
|
|
309
310
|
- `SourceSyncCandidateTotalsSchema` / `SourceSyncCandidateTotals` and
|
|
310
311
|
`candidateTotalsOf(items)` — THE file count: distinct `sourceId`, never lines
|
|
311
312
|
(ADR-CONTRACTS-195).
|
|
@@ -48,7 +48,6 @@ function addCandidate(overrides: Record<string, unknown> = {}) {
|
|
|
48
48
|
function approveRequest(overrides: Record<string, unknown> = {}) {
|
|
49
49
|
return {
|
|
50
50
|
revision: 7,
|
|
51
|
-
spendCapMicroUsd: "2500000",
|
|
52
51
|
...overrides,
|
|
53
52
|
};
|
|
54
53
|
}
|
|
@@ -112,20 +111,10 @@ describe("SourceSyncApproveRequestSchema", () => {
|
|
|
112
111
|
expect(refused.error?.issues[0]?.path).toEqual(["revision"]);
|
|
113
112
|
});
|
|
114
113
|
|
|
115
|
-
it("refuses an approval
|
|
116
|
-
const { spendCapMicroUsd: _cap, ...withoutCap } = approveRequest();
|
|
117
|
-
const refused = SourceSyncApproveRequestSchema.safeParse(withoutCap);
|
|
118
|
-
expect(refused.success).toBe(false);
|
|
119
|
-
expect(refused.error?.issues[0]?.path).toEqual(["spendCapMicroUsd"]);
|
|
120
|
-
|
|
121
|
-
expect(
|
|
122
|
-
SourceSyncApproveRequestSchema.safeParse(
|
|
123
|
-
approveRequest({ spendCapMicroUsd: "2.50" }),
|
|
124
|
-
).success,
|
|
125
|
-
).toBe(false);
|
|
114
|
+
it("refuses a spend cap: an approval authorizes files, never a spend", () => {
|
|
126
115
|
expect(
|
|
127
116
|
SourceSyncApproveRequestSchema.safeParse(
|
|
128
|
-
approveRequest({ spendCapMicroUsd: 2500000 }),
|
|
117
|
+
approveRequest({ spendCapMicroUsd: "2500000" }),
|
|
129
118
|
).success,
|
|
130
119
|
).toBe(false);
|
|
131
120
|
});
|
|
@@ -140,11 +140,6 @@ function candidateSet(overrides: Record<string, unknown> = {}) {
|
|
|
140
140
|
filesPendingClassification: 0,
|
|
141
141
|
},
|
|
142
142
|
scopes: [],
|
|
143
|
-
estimate: {
|
|
144
|
-
lowMicroUsd: "250000",
|
|
145
|
-
highMicroUsd: "1250000",
|
|
146
|
-
capMicroUsd: "2000000",
|
|
147
|
-
},
|
|
148
143
|
discovery: {
|
|
149
144
|
foundThisRun: 12,
|
|
150
145
|
retainedDecisions: 3,
|
|
@@ -264,38 +259,16 @@ describe("SourceSyncCandidateItemSchema", () => {
|
|
|
264
259
|
});
|
|
265
260
|
|
|
266
261
|
describe("SourceSyncCandidateSetResponseSchema", () => {
|
|
267
|
-
it("accepts
|
|
262
|
+
it("accepts the draft set", () => {
|
|
268
263
|
expect(
|
|
269
264
|
SourceSyncCandidateSetResponseSchema.safeParse(candidateSet()).success,
|
|
270
265
|
).toBe(true);
|
|
271
|
-
const decimal = candidateSet({
|
|
272
|
-
estimate: {
|
|
273
|
-
lowMicroUsd: "0.25",
|
|
274
|
-
highMicroUsd: "1250000",
|
|
275
|
-
capMicroUsd: "2000000",
|
|
276
|
-
},
|
|
277
|
-
});
|
|
278
|
-
expect(
|
|
279
|
-
SourceSyncCandidateSetResponseSchema.safeParse(decimal).success,
|
|
280
|
-
).toBe(false);
|
|
281
|
-
const jsonNumber = candidateSet({
|
|
282
|
-
estimate: {
|
|
283
|
-
lowMicroUsd: "250000",
|
|
284
|
-
highMicroUsd: "1250000",
|
|
285
|
-
capMicroUsd: 2000000,
|
|
286
|
-
},
|
|
287
|
-
});
|
|
288
|
-
expect(
|
|
289
|
-
SourceSyncCandidateSetResponseSchema.safeParse(jsonNumber).success,
|
|
290
|
-
).toBe(false);
|
|
291
266
|
});
|
|
292
267
|
|
|
293
|
-
it("
|
|
294
|
-
expect(
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
).success,
|
|
298
|
-
).toBe(true);
|
|
268
|
+
it("carries no cost estimate: the review authorizes files, never a spend", () => {
|
|
269
|
+
expect(SourceSyncCandidateSetResponseSchema.shape).not.toHaveProperty(
|
|
270
|
+
"estimate",
|
|
271
|
+
);
|
|
299
272
|
});
|
|
300
273
|
|
|
301
274
|
it("refuses an unknown set state", () => {
|
|
@@ -30,9 +30,6 @@ import {
|
|
|
30
30
|
import { CandidateDiscoverySummarySchema } from "./relevance";
|
|
31
31
|
import { SourceSyncCandidateItemSchema } from "./candidate-item";
|
|
32
32
|
|
|
33
|
-
/** Integer micro-USD as a string — the billing domain's money convention on the wire. */
|
|
34
|
-
const MicroUsd = z.string().regex(/^[0-9]+$/);
|
|
35
|
-
|
|
36
33
|
/** A person as the review names them: a display label, never an id or an address. */
|
|
37
34
|
const PersonLabel = z.string().min(1).max(255);
|
|
38
35
|
|
|
@@ -109,14 +106,6 @@ export const SourceSyncCandidateSetResponseSchema = z.object({
|
|
|
109
106
|
totals: SourceSyncCandidateTotalsSchema,
|
|
110
107
|
/** Every scope of the set the caller may see, and where its approval stands. */
|
|
111
108
|
scopes: z.array(SourceSyncScopeApprovalProjectionSchema).max(500),
|
|
112
|
-
/** A RANGE, and the cap that is the promise. Null until the estimator has run. */
|
|
113
|
-
estimate: z
|
|
114
|
-
.object({
|
|
115
|
-
lowMicroUsd: MicroUsd,
|
|
116
|
-
highMicroUsd: MicroUsd,
|
|
117
|
-
capMicroUsd: MicroUsd,
|
|
118
|
-
})
|
|
119
|
-
.nullable(),
|
|
120
109
|
/** The last completed discovery run's counts; null before any run completed. */
|
|
121
110
|
discovery: z.nullable(CandidateDiscoverySummarySchema),
|
|
122
111
|
});
|
|
@@ -134,13 +123,14 @@ export const SourceSyncAddCandidateRequestSchema = z
|
|
|
134
123
|
|
|
135
124
|
/**
|
|
136
125
|
* Approve the set AS REVIEWED. `revision` is the revision the person was looking at; the server
|
|
137
|
-
* refuses a stale one, freezes the items, and hashes them PER SCOPE
|
|
126
|
+
* refuses a stale one, freezes the items, and hashes them PER SCOPE.
|
|
127
|
+
*
|
|
128
|
+
* An approval authorizes the files, never a spend: there is no cap and no estimate here. Spend is
|
|
129
|
+
* bounded by the org's standing spending controls and a server-derived run ceiling.
|
|
138
130
|
*/
|
|
139
131
|
export const SourceSyncApproveRequestSchema = z
|
|
140
132
|
.object({
|
|
141
133
|
revision: z.number().int().min(0),
|
|
142
|
-
/** The promise: synthesis stops at this. Integer micro-USD. */
|
|
143
|
-
spendCapMicroUsd: MicroUsd,
|
|
144
134
|
/** Absent: every scope the caller may approve (all of them for the single v1 approver). */
|
|
145
135
|
scopeKeys: z.array(z.string().min(1).max(64)).min(1).max(500).optional(),
|
|
146
136
|
})
|
|
@@ -151,7 +141,7 @@ export const SourceSyncScopeApprovalSchema = z.object({
|
|
|
151
141
|
/** 'company' or 'unit:<uuid>'. */
|
|
152
142
|
scopeKey: z.string().min(1).max(64),
|
|
153
143
|
approvalId: z.string().uuid(),
|
|
154
|
-
/** Hash over THIS scope's ordered (source, target, use, observation) tuples
|
|
144
|
+
/** Hash over THIS scope's ordered (source, target, use, observation) tuples. */
|
|
155
145
|
candidateSetHash: z.string().regex(/^[0-9a-f]{64}$/),
|
|
156
146
|
});
|
|
157
147
|
|
|
@@ -285,6 +275,7 @@ export const SOURCE_SYNC_SYNTHESIS_PHASES = [
|
|
|
285
275
|
"drafting",
|
|
286
276
|
"waiting_for_review",
|
|
287
277
|
"paused_billing",
|
|
278
|
+
"paused_ceiling",
|
|
288
279
|
"applied",
|
|
289
280
|
"applied_partial",
|
|
290
281
|
"failed",
|
|
@@ -150,6 +150,8 @@ export const SYNTHESIZE_DEFERRED_ROUTE_OF_REASON = {
|
|
|
150
150
|
updates_applied: { route: "covered", by: "sourceSync.docs_updated", fallback: "notice", audience: "creator" },
|
|
151
151
|
stopped_by_user: STOPPED,
|
|
152
152
|
paused_billing: EXPLAINED,
|
|
153
|
+
run_ceiling_reached: NOTICE_ADMINS,
|
|
154
|
+
pricing_unconfigured: NOTICE_ADMINS,
|
|
153
155
|
synthesis_incomplete: NOTICE_ADMINS,
|
|
154
156
|
approval_mismatch: NOTICE_ADMINS,
|
|
155
157
|
landing_refused: NOTICE_ADMINS,
|
|
@@ -123,6 +123,8 @@ export const SYNTHESIZE_OUTCOME_KIND_OF_REASON = {
|
|
|
123
123
|
updates_applied: "produced",
|
|
124
124
|
stopped_by_user: "stopped",
|
|
125
125
|
paused_billing: "failed",
|
|
126
|
+
run_ceiling_reached: "failed",
|
|
127
|
+
pricing_unconfigured: "failed",
|
|
126
128
|
synthesis_incomplete: "failed",
|
|
127
129
|
approval_mismatch: "failed",
|
|
128
130
|
landing_refused: "failed",
|
|
@@ -143,6 +145,8 @@ export const SYNTHESIZE_AFFORDANCES_OF_REASON = {
|
|
|
143
145
|
updates_applied: [],
|
|
144
146
|
stopped_by_user: [],
|
|
145
147
|
paused_billing: [OPEN_BILLING],
|
|
148
|
+
run_ceiling_reached: [],
|
|
149
|
+
pricing_unconfigured: [],
|
|
146
150
|
synthesis_incomplete: [],
|
|
147
151
|
approval_mismatch: [],
|
|
148
152
|
landing_refused: [],
|