@humain/humain-code-contracts 0.4.9 → 0.4.10
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/CHANGELOG.md +10 -0
- package/dist/flow-admission.d.ts +23 -0
- package/dist/flow-admission.d.ts.map +1 -1
- package/dist/flow-profile.d.ts +136 -58
- package/dist/flow-profile.d.ts.map +1 -1
- package/dist/flow-profile.js +54 -1
- package/dist/flow-profile.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.10] - 2026-10-13
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Added optional `FlowProfileV1.modelSelection` for Flow-only tier and capability primaries, ordered backups and capability effort, with exported schemas, types and supported tier and capability constants. Backup lists allow at most eight models and reject duplicate references; omitted backups inherit while `[]` explicitly disables fallbacks.
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Profiles and admissions containing `modelSelection` include it in their digest input. Existing documents without it retain their original digests. Older strict readers reject the new field; update profile and admission consumers before exchanging new-format documents.
|
|
12
|
+
|
|
3
13
|
## [0.4.9] - 2026-10-13
|
|
4
14
|
|
|
5
15
|
### Added
|
package/dist/flow-admission.d.ts
CHANGED
|
@@ -172,6 +172,29 @@ export declare const FlowRunAdmissionV1Schema: Type.TObject<{
|
|
|
172
172
|
readonly triage: Type.TOptional<Type.TInteger>;
|
|
173
173
|
}>>;
|
|
174
174
|
}>;
|
|
175
|
+
readonly modelSelection: Type.TOptional<Type.TObject<{
|
|
176
|
+
readonly tiers: Type.TOptional<Type.TObject<Record<"cheap" | "frontier" | "mid" | "premium", Type.TOptional<Type.TObject<{
|
|
177
|
+
readonly primary: Type.TOptional<Type.TObject<{
|
|
178
|
+
readonly provider: Type.TString;
|
|
179
|
+
readonly model: Type.TString;
|
|
180
|
+
}>>;
|
|
181
|
+
readonly backups: Type.TOptional<Type.TArray<Type.TObject<{
|
|
182
|
+
readonly provider: Type.TString;
|
|
183
|
+
readonly model: Type.TString;
|
|
184
|
+
}>>>;
|
|
185
|
+
}>>>>>;
|
|
186
|
+
readonly capabilities: Type.TOptional<Type.TObject<Record<"analysis_mid" | "analysis_strong" | "api_contract_review" | "architect" | "implementation_fast" | "implementation_strong" | "integration_review" | "lead" | "lead_large" | "lead_small" | "migration_review" | "performance_review" | "qa_agent" | "scope_scout" | "scout" | "security_review" | "technical_lead" | "technical_review" | "triage" | "worker", Type.TOptional<Type.TObject<{
|
|
187
|
+
readonly primary: Type.TOptional<Type.TObject<{
|
|
188
|
+
readonly provider: Type.TString;
|
|
189
|
+
readonly model: Type.TString;
|
|
190
|
+
}>>;
|
|
191
|
+
readonly backups: Type.TOptional<Type.TArray<Type.TObject<{
|
|
192
|
+
readonly provider: Type.TString;
|
|
193
|
+
readonly model: Type.TString;
|
|
194
|
+
}>>>;
|
|
195
|
+
readonly effort: Type.TOptional<Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">, Type.TLiteral<"max">]>>;
|
|
196
|
+
}>>>>>;
|
|
197
|
+
}>>;
|
|
175
198
|
readonly providers: Type.TOptional<Type.TObject<{
|
|
176
199
|
readonly preference: Type.TArray<Type.TString>;
|
|
177
200
|
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-admission.d.ts","sourceRoot":"","sources":["../src/flow-admission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAIN,KAAK,gBAAgB,EAUrB,MAAM,kBAAkB,CAAC;AAG1B,eAAO,MAAM,wBAAwB
|
|
1
|
+
{"version":3,"file":"flow-admission.d.ts","sourceRoot":"","sources":["../src/flow-admission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAIN,KAAK,gBAAgB,EAUrB,MAAM,kBAAkB,CAAC;AAG1B,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAuBnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAIzE,+GAA+G;AAC/G,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,kBAAkB,GAAG,MAAM,CAExE;AAYD;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAE/E;AAED,+HAA+H;AAC/H,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,GAAG,kBAAkB,CASpG"}
|
package/dist/flow-profile.d.ts
CHANGED
|
@@ -1,20 +1,75 @@
|
|
|
1
|
-
import { type Static, Type } from "typebox";
|
|
1
|
+
import { type Static, type TObject, type TOptional, Type } from "typebox";
|
|
2
2
|
import { type FlowDigestHasher } from "./flow-common.ts";
|
|
3
3
|
export { FlowProfileRefSchema, type FlowProfileRefV1 } from "./flow-common.ts";
|
|
4
4
|
export declare const FlowEffortSchema: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
5
|
-
export declare const FlowRoleBindingSchema:
|
|
6
|
-
readonly primary:
|
|
5
|
+
export declare const FlowRoleBindingSchema: TObject<{
|
|
6
|
+
readonly primary: TObject<{
|
|
7
7
|
readonly provider: Type.TString;
|
|
8
8
|
readonly model: Type.TString;
|
|
9
9
|
}>;
|
|
10
|
-
readonly backups: Type.TArray<
|
|
10
|
+
readonly backups: Type.TArray<TObject<{
|
|
11
11
|
readonly provider: Type.TString;
|
|
12
12
|
readonly model: Type.TString;
|
|
13
13
|
}>>;
|
|
14
14
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
15
15
|
}>;
|
|
16
16
|
export type FlowRoleBindingV1 = Static<typeof FlowRoleBindingSchema>;
|
|
17
|
-
|
|
17
|
+
/** Cost tiers a selection may declare (matches Flow's `Tier`). */
|
|
18
|
+
export declare const FLOW_MODEL_SELECTION_TIERS: readonly ["cheap", "mid", "premium", "frontier"];
|
|
19
|
+
export type FlowSelectionTier = (typeof FLOW_MODEL_SELECTION_TIERS)[number];
|
|
20
|
+
/** Flow's `ALL_CAPABILITIES` (method.json) plus the runtime `triage` capability; parity is pinned in the flow tests. */
|
|
21
|
+
export declare const FLOW_MODEL_SELECTION_CAPABILITIES: readonly ["scout", "scope_scout", "worker", "implementation_fast", "analysis_mid", "technical_lead", "lead_small", "lead", "lead_large", "implementation_strong", "technical_review", "integration_review", "migration_review", "performance_review", "api_contract_review", "qa_agent", "analysis_strong", "architect", "security_review", "triage"];
|
|
22
|
+
export type FlowSelectionCapability = (typeof FLOW_MODEL_SELECTION_CAPABILITIES)[number];
|
|
23
|
+
export declare const FlowSelectionEffortSchema: Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">, Type.TLiteral<"max">]>;
|
|
24
|
+
/** Omitted `backups` inherits; an explicit `[]` means no fallbacks. Both must survive round-trips. */
|
|
25
|
+
export declare const FlowTierSelectionSchema: TObject<{
|
|
26
|
+
readonly primary: TOptional<TObject<{
|
|
27
|
+
readonly provider: Type.TString;
|
|
28
|
+
readonly model: Type.TString;
|
|
29
|
+
}>>;
|
|
30
|
+
readonly backups: TOptional<Type.TArray<TObject<{
|
|
31
|
+
readonly provider: Type.TString;
|
|
32
|
+
readonly model: Type.TString;
|
|
33
|
+
}>>>;
|
|
34
|
+
}>;
|
|
35
|
+
export type FlowTierSelectionV1 = Static<typeof FlowTierSelectionSchema>;
|
|
36
|
+
export declare const FlowCapabilitySelectionSchema: TObject<{
|
|
37
|
+
readonly primary: TOptional<TObject<{
|
|
38
|
+
readonly provider: Type.TString;
|
|
39
|
+
readonly model: Type.TString;
|
|
40
|
+
}>>;
|
|
41
|
+
readonly backups: TOptional<Type.TArray<TObject<{
|
|
42
|
+
readonly provider: Type.TString;
|
|
43
|
+
readonly model: Type.TString;
|
|
44
|
+
}>>>;
|
|
45
|
+
readonly effort: TOptional<Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">, Type.TLiteral<"max">]>>;
|
|
46
|
+
}>;
|
|
47
|
+
export type FlowCapabilitySelectionV1 = Static<typeof FlowCapabilitySelectionSchema>;
|
|
48
|
+
export declare const FlowModelSelectionSchema: TObject<{
|
|
49
|
+
readonly tiers: TOptional<TObject<Record<"cheap" | "frontier" | "mid" | "premium", TOptional<TObject<{
|
|
50
|
+
readonly primary: TOptional<TObject<{
|
|
51
|
+
readonly provider: Type.TString;
|
|
52
|
+
readonly model: Type.TString;
|
|
53
|
+
}>>;
|
|
54
|
+
readonly backups: TOptional<Type.TArray<TObject<{
|
|
55
|
+
readonly provider: Type.TString;
|
|
56
|
+
readonly model: Type.TString;
|
|
57
|
+
}>>>;
|
|
58
|
+
}>>>>>;
|
|
59
|
+
readonly capabilities: TOptional<TObject<Record<"analysis_mid" | "analysis_strong" | "api_contract_review" | "architect" | "implementation_fast" | "implementation_strong" | "integration_review" | "lead" | "lead_large" | "lead_small" | "migration_review" | "performance_review" | "qa_agent" | "scope_scout" | "scout" | "security_review" | "technical_lead" | "technical_review" | "triage" | "worker", TOptional<TObject<{
|
|
60
|
+
readonly primary: TOptional<TObject<{
|
|
61
|
+
readonly provider: Type.TString;
|
|
62
|
+
readonly model: Type.TString;
|
|
63
|
+
}>>;
|
|
64
|
+
readonly backups: TOptional<Type.TArray<TObject<{
|
|
65
|
+
readonly provider: Type.TString;
|
|
66
|
+
readonly model: Type.TString;
|
|
67
|
+
}>>>;
|
|
68
|
+
readonly effort: TOptional<Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">, Type.TLiteral<"max">]>>;
|
|
69
|
+
}>>>>>;
|
|
70
|
+
}>;
|
|
71
|
+
export type FlowModelSelectionV1 = Static<typeof FlowModelSelectionSchema>;
|
|
72
|
+
export declare const FlowProfileV1Schema: TObject<{
|
|
18
73
|
readonly schema: Type.TLiteral<"humain-flow-profile">;
|
|
19
74
|
readonly schemaVersion: Type.TLiteral<1>;
|
|
20
75
|
readonly id: Type.TString;
|
|
@@ -22,139 +77,139 @@ export declare const FlowProfileV1Schema: Type.TObject<{
|
|
|
22
77
|
readonly digest: Type.TString;
|
|
23
78
|
readonly kind: Type.TUnion<[Type.TLiteral<"direct">, Type.TLiteral<"flow">]>;
|
|
24
79
|
readonly label: Type.TString;
|
|
25
|
-
readonly description:
|
|
26
|
-
readonly direct:
|
|
27
|
-
readonly model:
|
|
80
|
+
readonly description: TOptional<Type.TString>;
|
|
81
|
+
readonly direct: TOptional<TObject<{
|
|
82
|
+
readonly model: TObject<{
|
|
28
83
|
readonly provider: Type.TString;
|
|
29
84
|
readonly model: Type.TString;
|
|
30
85
|
}>;
|
|
31
|
-
readonly fallbacks: Type.TArray<
|
|
86
|
+
readonly fallbacks: Type.TArray<TObject<{
|
|
32
87
|
readonly provider: Type.TString;
|
|
33
88
|
readonly model: Type.TString;
|
|
34
89
|
}>>;
|
|
35
90
|
}>>;
|
|
36
|
-
readonly roles:
|
|
37
|
-
readonly scout:
|
|
38
|
-
readonly primary:
|
|
91
|
+
readonly roles: TOptional<TObject<{
|
|
92
|
+
readonly scout: TOptional<TObject<{
|
|
93
|
+
readonly primary: TObject<{
|
|
39
94
|
readonly provider: Type.TString;
|
|
40
95
|
readonly model: Type.TString;
|
|
41
96
|
}>;
|
|
42
|
-
readonly backups: Type.TArray<
|
|
97
|
+
readonly backups: Type.TArray<TObject<{
|
|
43
98
|
readonly provider: Type.TString;
|
|
44
99
|
readonly model: Type.TString;
|
|
45
100
|
}>>;
|
|
46
101
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
47
102
|
}>>;
|
|
48
|
-
readonly worker:
|
|
49
|
-
readonly primary:
|
|
103
|
+
readonly worker: TOptional<TObject<{
|
|
104
|
+
readonly primary: TObject<{
|
|
50
105
|
readonly provider: Type.TString;
|
|
51
106
|
readonly model: Type.TString;
|
|
52
107
|
}>;
|
|
53
|
-
readonly backups: Type.TArray<
|
|
108
|
+
readonly backups: Type.TArray<TObject<{
|
|
54
109
|
readonly provider: Type.TString;
|
|
55
110
|
readonly model: Type.TString;
|
|
56
111
|
}>>;
|
|
57
112
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
58
113
|
}>>;
|
|
59
|
-
readonly implementer:
|
|
60
|
-
readonly primary:
|
|
114
|
+
readonly implementer: TOptional<TObject<{
|
|
115
|
+
readonly primary: TObject<{
|
|
61
116
|
readonly provider: Type.TString;
|
|
62
117
|
readonly model: Type.TString;
|
|
63
118
|
}>;
|
|
64
|
-
readonly backups: Type.TArray<
|
|
119
|
+
readonly backups: Type.TArray<TObject<{
|
|
65
120
|
readonly provider: Type.TString;
|
|
66
121
|
readonly model: Type.TString;
|
|
67
122
|
}>>;
|
|
68
123
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
69
124
|
}>>;
|
|
70
|
-
readonly lead:
|
|
71
|
-
readonly primary:
|
|
125
|
+
readonly lead: TOptional<TObject<{
|
|
126
|
+
readonly primary: TObject<{
|
|
72
127
|
readonly provider: Type.TString;
|
|
73
128
|
readonly model: Type.TString;
|
|
74
129
|
}>;
|
|
75
|
-
readonly backups: Type.TArray<
|
|
130
|
+
readonly backups: Type.TArray<TObject<{
|
|
76
131
|
readonly provider: Type.TString;
|
|
77
132
|
readonly model: Type.TString;
|
|
78
133
|
}>>;
|
|
79
134
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
80
135
|
}>>;
|
|
81
|
-
readonly lead_large:
|
|
82
|
-
readonly primary:
|
|
136
|
+
readonly lead_large: TOptional<TObject<{
|
|
137
|
+
readonly primary: TObject<{
|
|
83
138
|
readonly provider: Type.TString;
|
|
84
139
|
readonly model: Type.TString;
|
|
85
140
|
}>;
|
|
86
|
-
readonly backups: Type.TArray<
|
|
141
|
+
readonly backups: Type.TArray<TObject<{
|
|
87
142
|
readonly provider: Type.TString;
|
|
88
143
|
readonly model: Type.TString;
|
|
89
144
|
}>>;
|
|
90
145
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
91
146
|
}>>;
|
|
92
|
-
readonly architect:
|
|
93
|
-
readonly primary:
|
|
147
|
+
readonly architect: TOptional<TObject<{
|
|
148
|
+
readonly primary: TObject<{
|
|
94
149
|
readonly provider: Type.TString;
|
|
95
150
|
readonly model: Type.TString;
|
|
96
151
|
}>;
|
|
97
|
-
readonly backups: Type.TArray<
|
|
152
|
+
readonly backups: Type.TArray<TObject<{
|
|
98
153
|
readonly provider: Type.TString;
|
|
99
154
|
readonly model: Type.TString;
|
|
100
155
|
}>>;
|
|
101
156
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
102
157
|
}>>;
|
|
103
|
-
readonly reviewer:
|
|
104
|
-
readonly primary:
|
|
158
|
+
readonly reviewer: TOptional<TObject<{
|
|
159
|
+
readonly primary: TObject<{
|
|
105
160
|
readonly provider: Type.TString;
|
|
106
161
|
readonly model: Type.TString;
|
|
107
162
|
}>;
|
|
108
|
-
readonly backups: Type.TArray<
|
|
163
|
+
readonly backups: Type.TArray<TObject<{
|
|
109
164
|
readonly provider: Type.TString;
|
|
110
165
|
readonly model: Type.TString;
|
|
111
166
|
}>>;
|
|
112
167
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
113
168
|
}>>;
|
|
114
|
-
readonly security_reviewer:
|
|
115
|
-
readonly primary:
|
|
169
|
+
readonly security_reviewer: TOptional<TObject<{
|
|
170
|
+
readonly primary: TObject<{
|
|
116
171
|
readonly provider: Type.TString;
|
|
117
172
|
readonly model: Type.TString;
|
|
118
173
|
}>;
|
|
119
|
-
readonly backups: Type.TArray<
|
|
174
|
+
readonly backups: Type.TArray<TObject<{
|
|
120
175
|
readonly provider: Type.TString;
|
|
121
176
|
readonly model: Type.TString;
|
|
122
177
|
}>>;
|
|
123
178
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
124
179
|
}>>;
|
|
125
|
-
readonly qa:
|
|
126
|
-
readonly primary:
|
|
180
|
+
readonly qa: TOptional<TObject<{
|
|
181
|
+
readonly primary: TObject<{
|
|
127
182
|
readonly provider: Type.TString;
|
|
128
183
|
readonly model: Type.TString;
|
|
129
184
|
}>;
|
|
130
|
-
readonly backups: Type.TArray<
|
|
185
|
+
readonly backups: Type.TArray<TObject<{
|
|
131
186
|
readonly provider: Type.TString;
|
|
132
187
|
readonly model: Type.TString;
|
|
133
188
|
}>>;
|
|
134
189
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
135
190
|
}>>;
|
|
136
|
-
readonly triage:
|
|
137
|
-
readonly primary:
|
|
191
|
+
readonly triage: TOptional<TObject<{
|
|
192
|
+
readonly primary: TObject<{
|
|
138
193
|
readonly provider: Type.TString;
|
|
139
194
|
readonly model: Type.TString;
|
|
140
195
|
}>;
|
|
141
|
-
readonly backups: Type.TArray<
|
|
196
|
+
readonly backups: Type.TArray<TObject<{
|
|
142
197
|
readonly provider: Type.TString;
|
|
143
198
|
readonly model: Type.TString;
|
|
144
199
|
}>>;
|
|
145
200
|
readonly effort: Type.TUnion<[Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">]>;
|
|
146
201
|
}>>;
|
|
147
202
|
}>>;
|
|
148
|
-
readonly sizing:
|
|
203
|
+
readonly sizing: TOptional<TObject<{
|
|
149
204
|
readonly classifierPolicyId: Type.TString;
|
|
150
|
-
readonly thresholds:
|
|
205
|
+
readonly thresholds: TObject<{
|
|
151
206
|
readonly mediumAt: Type.TNumber;
|
|
152
207
|
readonly largeAt: Type.TNumber;
|
|
153
208
|
}>;
|
|
154
209
|
readonly triageRole: Type.TLiteral<"triage">;
|
|
155
210
|
readonly maxEscalations: Type.TUnion<[Type.TLiteral<0>, Type.TLiteral<1>]>;
|
|
156
211
|
}>>;
|
|
157
|
-
readonly limits:
|
|
212
|
+
readonly limits: TObject<{
|
|
158
213
|
readonly maxAgents: Type.TInteger;
|
|
159
214
|
readonly maxConcurrent: Type.TInteger;
|
|
160
215
|
readonly maxDepth: Type.TInteger;
|
|
@@ -162,30 +217,53 @@ export declare const FlowProfileV1Schema: Type.TObject<{
|
|
|
162
217
|
readonly inactivityMs: Type.TInteger;
|
|
163
218
|
readonly ciWaitMs: Type.TInteger;
|
|
164
219
|
}>;
|
|
165
|
-
readonly spend:
|
|
220
|
+
readonly spend: TObject<{
|
|
166
221
|
readonly runCapMicrousd: Type.TInteger;
|
|
167
222
|
readonly warnAtPct: Type.TInteger;
|
|
168
|
-
readonly perRoleCapMicrousd:
|
|
169
|
-
readonly scout:
|
|
170
|
-
readonly worker:
|
|
171
|
-
readonly implementer:
|
|
172
|
-
readonly lead:
|
|
173
|
-
readonly lead_large:
|
|
174
|
-
readonly architect:
|
|
175
|
-
readonly reviewer:
|
|
176
|
-
readonly security_reviewer:
|
|
177
|
-
readonly qa:
|
|
178
|
-
readonly triage:
|
|
223
|
+
readonly perRoleCapMicrousd: TOptional<TObject<{
|
|
224
|
+
readonly scout: TOptional<Type.TInteger>;
|
|
225
|
+
readonly worker: TOptional<Type.TInteger>;
|
|
226
|
+
readonly implementer: TOptional<Type.TInteger>;
|
|
227
|
+
readonly lead: TOptional<Type.TInteger>;
|
|
228
|
+
readonly lead_large: TOptional<Type.TInteger>;
|
|
229
|
+
readonly architect: TOptional<Type.TInteger>;
|
|
230
|
+
readonly reviewer: TOptional<Type.TInteger>;
|
|
231
|
+
readonly security_reviewer: TOptional<Type.TInteger>;
|
|
232
|
+
readonly qa: TOptional<Type.TInteger>;
|
|
233
|
+
readonly triage: TOptional<Type.TInteger>;
|
|
179
234
|
}>>;
|
|
180
235
|
}>;
|
|
181
|
-
readonly
|
|
236
|
+
readonly modelSelection: TOptional<TObject<{
|
|
237
|
+
readonly tiers: TOptional<TObject<Record<"cheap" | "frontier" | "mid" | "premium", TOptional<TObject<{
|
|
238
|
+
readonly primary: TOptional<TObject<{
|
|
239
|
+
readonly provider: Type.TString;
|
|
240
|
+
readonly model: Type.TString;
|
|
241
|
+
}>>;
|
|
242
|
+
readonly backups: TOptional<Type.TArray<TObject<{
|
|
243
|
+
readonly provider: Type.TString;
|
|
244
|
+
readonly model: Type.TString;
|
|
245
|
+
}>>>;
|
|
246
|
+
}>>>>>;
|
|
247
|
+
readonly capabilities: TOptional<TObject<Record<"analysis_mid" | "analysis_strong" | "api_contract_review" | "architect" | "implementation_fast" | "implementation_strong" | "integration_review" | "lead" | "lead_large" | "lead_small" | "migration_review" | "performance_review" | "qa_agent" | "scope_scout" | "scout" | "security_review" | "technical_lead" | "technical_review" | "triage" | "worker", TOptional<TObject<{
|
|
248
|
+
readonly primary: TOptional<TObject<{
|
|
249
|
+
readonly provider: Type.TString;
|
|
250
|
+
readonly model: Type.TString;
|
|
251
|
+
}>>;
|
|
252
|
+
readonly backups: TOptional<Type.TArray<TObject<{
|
|
253
|
+
readonly provider: Type.TString;
|
|
254
|
+
readonly model: Type.TString;
|
|
255
|
+
}>>>;
|
|
256
|
+
readonly effort: TOptional<Type.TUnion<[Type.TLiteral<"off">, Type.TLiteral<"minimal">, Type.TLiteral<"low">, Type.TLiteral<"medium">, Type.TLiteral<"high">, Type.TLiteral<"xhigh">, Type.TLiteral<"max">]>>;
|
|
257
|
+
}>>>>>;
|
|
258
|
+
}>>;
|
|
259
|
+
readonly providers: TOptional<TObject<{
|
|
182
260
|
readonly preference: Type.TArray<Type.TString>;
|
|
183
261
|
}>>;
|
|
184
|
-
readonly approval:
|
|
262
|
+
readonly approval: TOptional<TObject<{
|
|
185
263
|
readonly approvedBy: Type.TString;
|
|
186
264
|
readonly approvedAt: Type.TRefine<Type.TString>;
|
|
187
265
|
}>>;
|
|
188
|
-
readonly builtIn:
|
|
266
|
+
readonly builtIn: TOptional<Type.TLiteral<true>>;
|
|
189
267
|
}>;
|
|
190
268
|
export type FlowProfileV1 = Static<typeof FlowProfileV1Schema>;
|
|
191
269
|
/** Canonical text hashed (sha256 hex) to produce `digest`: the document without `digest`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-profile.d.ts","sourceRoot":"","sources":["../src/flow-profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"flow-profile.d.ts","sourceRoot":"","sources":["../src/flow-profile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,OAAO,EAAE,KAAK,SAAS,EAAgB,IAAI,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAIN,KAAK,gBAAgB,EAcrB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,oBAAoB,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,eAAO,MAAM,gBAAgB,qFAAkF,CAAC;AAEhH,eAAO,MAAM,qBAAqB;;;;;;;;;;EAIhC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAErE,kEAAkE;AAClE,eAAO,MAAM,0BAA0B,YAAI,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC;AAC3F,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E,wHAAwH;AACxH,eAAO,MAAM,iCAAiC,YAC7C,OAAO,EACP,aAAa,EACb,QAAQ,EACR,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,QAAQ,CACC,CAAC;AACX,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,iCAAiC,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzF,eAAO,MAAM,yBAAyB,mLAAiE,CAAC;AAExG,sGAAsG;AACtG,eAAO,MAAM,uBAAuB;;;;;;;;;EAGlC,CAAC;AACH,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAEzE,eAAO,MAAM,6BAA6B;;;;;;;;;;EAIxC,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,MAAM,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAKrF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;EAWnC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE3E,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyC9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAK/D,6FAA6F;AAC7F,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAEjE;AAiCD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAErE;AAED,sHAAsH;AACtH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,GAAG,aAAa,CAM1F"}
|
package/dist/flow-profile.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
|
-
import { canonicalWithout, compileFlow, FlowContractError, FlowDigestSchema, FlowIdSchema, FlowMicrousdSchema, FlowModelRefSchema, FlowPositiveIntSchema, FlowTimestampSchema, hasDuplicateModels, parseFlowData, partialByRole, StrictObject, verifyFlowDigest, } from "./flow-common.js";
|
|
2
|
+
import { canonicalWithout, compileFlow, FlowContractError, FlowDigestSchema, FlowIdSchema, FlowMicrousdSchema, FlowModelRefSchema, FlowPositiveIntSchema, FlowTimestampSchema, hasDuplicateModels, lit, parseFlowData, partialByRole, StrictObject, verifyFlowDigest, } from "./flow-common.js";
|
|
3
3
|
export { FlowProfileRefSchema } from "./flow-common.js";
|
|
4
4
|
export const FlowEffortSchema = Type.Union([Type.Literal("low"), Type.Literal("medium"), Type.Literal("high")]);
|
|
5
5
|
export const FlowRoleBindingSchema = StrictObject({
|
|
@@ -7,6 +7,47 @@ export const FlowRoleBindingSchema = StrictObject({
|
|
|
7
7
|
backups: Type.Array(FlowModelRefSchema, { maxItems: 8 }),
|
|
8
8
|
effort: FlowEffortSchema,
|
|
9
9
|
});
|
|
10
|
+
/** Cost tiers a selection may declare (matches Flow's `Tier`). */
|
|
11
|
+
export const FLOW_MODEL_SELECTION_TIERS = ["cheap", "mid", "premium", "frontier"];
|
|
12
|
+
/** Flow's `ALL_CAPABILITIES` (method.json) plus the runtime `triage` capability; parity is pinned in the flow tests. */
|
|
13
|
+
export const FLOW_MODEL_SELECTION_CAPABILITIES = [
|
|
14
|
+
"scout",
|
|
15
|
+
"scope_scout",
|
|
16
|
+
"worker",
|
|
17
|
+
"implementation_fast",
|
|
18
|
+
"analysis_mid",
|
|
19
|
+
"technical_lead",
|
|
20
|
+
"lead_small",
|
|
21
|
+
"lead",
|
|
22
|
+
"lead_large",
|
|
23
|
+
"implementation_strong",
|
|
24
|
+
"technical_review",
|
|
25
|
+
"integration_review",
|
|
26
|
+
"migration_review",
|
|
27
|
+
"performance_review",
|
|
28
|
+
"api_contract_review",
|
|
29
|
+
"qa_agent",
|
|
30
|
+
"analysis_strong",
|
|
31
|
+
"architect",
|
|
32
|
+
"security_review",
|
|
33
|
+
"triage",
|
|
34
|
+
];
|
|
35
|
+
export const FlowSelectionEffortSchema = lit("off", "minimal", "low", "medium", "high", "xhigh", "max");
|
|
36
|
+
/** Omitted `backups` inherits; an explicit `[]` means no fallbacks. Both must survive round-trips. */
|
|
37
|
+
export const FlowTierSelectionSchema = StrictObject({
|
|
38
|
+
primary: Type.Optional(FlowModelRefSchema),
|
|
39
|
+
backups: Type.Optional(Type.Array(FlowModelRefSchema, { maxItems: 8 })),
|
|
40
|
+
});
|
|
41
|
+
export const FlowCapabilitySelectionSchema = StrictObject({
|
|
42
|
+
primary: Type.Optional(FlowModelRefSchema),
|
|
43
|
+
backups: Type.Optional(Type.Array(FlowModelRefSchema, { maxItems: 8 })),
|
|
44
|
+
effort: Type.Optional(FlowSelectionEffortSchema),
|
|
45
|
+
});
|
|
46
|
+
const optionalEach = (keys, schema) => StrictObject(Object.fromEntries(keys.map((key) => [key, Type.Optional(schema)])));
|
|
47
|
+
export const FlowModelSelectionSchema = StrictObject({
|
|
48
|
+
tiers: Type.Optional(optionalEach(FLOW_MODEL_SELECTION_TIERS, FlowTierSelectionSchema)),
|
|
49
|
+
capabilities: Type.Optional(optionalEach(FLOW_MODEL_SELECTION_CAPABILITIES, FlowCapabilitySelectionSchema)),
|
|
50
|
+
});
|
|
10
51
|
export const FlowProfileV1Schema = StrictObject({
|
|
11
52
|
schema: Type.Literal("humain-flow-profile"),
|
|
12
53
|
schemaVersion: Type.Literal(1),
|
|
@@ -40,6 +81,7 @@ export const FlowProfileV1Schema = StrictObject({
|
|
|
40
81
|
warnAtPct: Type.Integer({ minimum: 1, maximum: 99 }),
|
|
41
82
|
perRoleCapMicrousd: Type.Optional(partialByRole(FlowMicrousdSchema)),
|
|
42
83
|
}),
|
|
84
|
+
modelSelection: Type.Optional(FlowModelSelectionSchema),
|
|
43
85
|
providers: Type.Optional(StrictObject({ preference: Type.Array(FlowIdSchema, { maxItems: 16 }) })),
|
|
44
86
|
approval: Type.Optional(StrictObject({ approvedBy: FlowIdSchema, approvedAt: FlowTimestampSchema })),
|
|
45
87
|
builtIn: Type.Optional(Type.Literal(true)),
|
|
@@ -50,7 +92,18 @@ const REQUIRED_FLOW_ROLES = ["lead", "worker", "reviewer", "qa"];
|
|
|
50
92
|
export function flowProfileDigestInput(doc) {
|
|
51
93
|
return canonicalWithout(doc, "digest");
|
|
52
94
|
}
|
|
95
|
+
function selectionLayerValid(layer) {
|
|
96
|
+
const refs = [...(layer.primary === undefined ? [] : [layer.primary]), ...(layer.backups ?? [])];
|
|
97
|
+
return !hasDuplicateModels(refs);
|
|
98
|
+
}
|
|
99
|
+
function modelSelectionValid(selection) {
|
|
100
|
+
const layers = [...Object.values(selection.tiers ?? {}), ...Object.values(selection.capabilities ?? {})];
|
|
101
|
+
return layers.every(selectionLayerValid);
|
|
102
|
+
}
|
|
53
103
|
function crossFieldsValid(doc) {
|
|
104
|
+
if (doc.modelSelection !== undefined && (doc.kind === "direct" || !modelSelectionValid(doc.modelSelection))) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
54
107
|
if (doc.kind === "direct") {
|
|
55
108
|
if (doc.direct === undefined || doc.roles !== undefined || doc.sizing !== undefined)
|
|
56
109
|
return false;
|
package/dist/flow-profile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flow-profile.js","sourceRoot":"","sources":["../src/flow-profile.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport {\n\tcanonicalWithout,\n\tcompileFlow,\n\tFlowContractError,\n\ttype FlowDigestHasher,\n\tFlowDigestSchema,\n\tFlowIdSchema,\n\tFlowMicrousdSchema,\n\ttype FlowModelRef,\n\tFlowModelRefSchema,\n\tFlowPositiveIntSchema,\n\tFlowTimestampSchema,\n\thasDuplicateModels,\n\tparseFlowData,\n\tpartialByRole,\n\tStrictObject,\n\tverifyFlowDigest,\n} from \"./flow-common.ts\";\n\nexport { FlowProfileRefSchema, type FlowProfileRefV1 } from \"./flow-common.ts\";\n\nexport const FlowEffortSchema = Type.Union([Type.Literal(\"low\"), Type.Literal(\"medium\"), Type.Literal(\"high\")]);\n\nexport const FlowRoleBindingSchema = StrictObject({\n\tprimary: FlowModelRefSchema,\n\tbackups: Type.Array(FlowModelRefSchema, { maxItems: 8 }),\n\teffort: FlowEffortSchema,\n});\nexport type FlowRoleBindingV1 = Static<typeof FlowRoleBindingSchema>;\n\nexport const FlowProfileV1Schema = StrictObject({\n\tschema: Type.Literal(\"humain-flow-profile\"),\n\tschemaVersion: Type.Literal(1),\n\tid: FlowIdSchema,\n\tversion: FlowPositiveIntSchema,\n\tdigest: FlowDigestSchema,\n\tkind: Type.Union([Type.Literal(\"direct\"), Type.Literal(\"flow\")]),\n\tlabel: Type.String({ minLength: 1, maxLength: 80 }),\n\tdescription: Type.Optional(Type.String({ maxLength: 500 })),\n\tdirect: Type.Optional(\n\t\tStrictObject({ model: FlowModelRefSchema, fallbacks: Type.Array(FlowModelRefSchema, { maxItems: 8 }) }),\n\t),\n\troles: Type.Optional(partialByRole(FlowRoleBindingSchema)),\n\tsizing: Type.Optional(\n\t\tStrictObject({\n\t\t\tclassifierPolicyId: FlowIdSchema,\n\t\t\tthresholds: StrictObject({\n\t\t\t\tmediumAt: Type.Number({ minimum: 0, maximum: 1_000_000 }),\n\t\t\t\tlargeAt: Type.Number({ minimum: 0, maximum: 1_000_000 }),\n\t\t\t}),\n\t\t\ttriageRole: Type.Literal(\"triage\"),\n\t\t\tmaxEscalations: Type.Union([Type.Literal(0), Type.Literal(1)]),\n\t\t}),\n\t),\n\tlimits: StrictObject({\n\t\tmaxAgents: Type.Integer({ minimum: 1, maximum: 256 }),\n\t\tmaxConcurrent: Type.Integer({ minimum: 1, maximum: 64 }),\n\t\tmaxDepth: Type.Integer({ minimum: 0, maximum: 3 }),\n\t\tmaxRetries: Type.Integer({ minimum: 0, maximum: 16 }),\n\t\tinactivityMs: Type.Integer({ minimum: 1, maximum: 86_400_000 }),\n\t\tciWaitMs: Type.Integer({ minimum: 0, maximum: 86_400_000 }),\n\t}),\n\tspend: StrictObject({\n\t\trunCapMicrousd: FlowMicrousdSchema,\n\t\twarnAtPct: Type.Integer({ minimum: 1, maximum: 99 }),\n\t\tperRoleCapMicrousd: Type.Optional(partialByRole(FlowMicrousdSchema)),\n\t}),\n\tproviders: Type.Optional(StrictObject({ preference: Type.Array(FlowIdSchema, { maxItems: 16 }) })),\n\tapproval: Type.Optional(StrictObject({ approvedBy: FlowIdSchema, approvedAt: FlowTimestampSchema })),\n\tbuiltIn: Type.Optional(Type.Literal(true)),\n});\nexport type FlowProfileV1 = Static<typeof FlowProfileV1Schema>;\n\nconst Validator = compileFlow(FlowProfileV1Schema);\nconst REQUIRED_FLOW_ROLES = [\"lead\", \"worker\", \"reviewer\", \"qa\"] as const;\n\n/** Canonical text hashed (sha256 hex) to produce `digest`: the document without `digest`. */\nexport function flowProfileDigestInput(doc: FlowProfileV1): string {\n\treturn canonicalWithout(doc, \"digest\");\n}\n\nfunction crossFieldsValid(doc: FlowProfileV1): boolean {\n\tif (doc.kind === \"direct\") {\n\t\tif (doc.direct === undefined || doc.roles !== undefined || doc.sizing !== undefined) return false;\n\t\treturn !hasDuplicateModels([doc.direct.model, ...doc.direct.fallbacks]);\n\t}\n\tif (doc.direct !== undefined || doc.roles === undefined) return false;\n\tfor (const role of REQUIRED_FLOW_ROLES) if (doc.roles[role] === undefined) return false;\n\tfor (const binding of Object.values(doc.roles)) {\n\t\tconst refs: FlowModelRef[] = [binding.primary, ...binding.backups];\n\t\tif (hasDuplicateModels(refs)) return false;\n\t}\n\treturn doc.sizing === undefined || doc.sizing.thresholds.mediumAt <= doc.sizing.thresholds.largeAt;\n}\n\nfunction isProfile(value: unknown): value is FlowProfileV1 {\n\treturn Validator.Check(value) && crossFieldsValid(value);\n}\n\n/**\n * SHAPE ONLY: validates structure and cross-field rules but does NOT verify `digest`. Use only for documents whose\n * integrity is established elsewhere (e.g. authored drafts); prefer {@link parseFlowProfileV1}.\n */\nexport function parseFlowProfileV1Shape(input: unknown): FlowProfileV1 {\n\treturn parseFlowData(\"profile_invalid\", input, isProfile);\n}\n\n/** Shape validation plus digest verification with the injected hasher (digests are integrity, not authentication). */\nexport function parseFlowProfileV1(input: unknown, hasher: FlowDigestHasher): FlowProfileV1 {\n\tconst profile = parseFlowProfileV1Shape(input);\n\tif (!verifyFlowDigest(hasher, flowProfileDigestInput(profile), profile.digest)) {\n\t\tthrow new FlowContractError(\"digest_mismatch\");\n\t}\n\treturn profile;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"flow-profile.js","sourceRoot":"","sources":["../src/flow-profile.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, type TObject, type TOptional, type TSchema, Type } from \"typebox\";\nimport {\n\tcanonicalWithout,\n\tcompileFlow,\n\tFlowContractError,\n\ttype FlowDigestHasher,\n\tFlowDigestSchema,\n\tFlowIdSchema,\n\tFlowMicrousdSchema,\n\ttype FlowModelRef,\n\tFlowModelRefSchema,\n\tFlowPositiveIntSchema,\n\tFlowTimestampSchema,\n\thasDuplicateModels,\n\tlit,\n\tparseFlowData,\n\tpartialByRole,\n\tStrictObject,\n\tverifyFlowDigest,\n} from \"./flow-common.ts\";\n\nexport { FlowProfileRefSchema, type FlowProfileRefV1 } from \"./flow-common.ts\";\n\nexport const FlowEffortSchema = Type.Union([Type.Literal(\"low\"), Type.Literal(\"medium\"), Type.Literal(\"high\")]);\n\nexport const FlowRoleBindingSchema = StrictObject({\n\tprimary: FlowModelRefSchema,\n\tbackups: Type.Array(FlowModelRefSchema, { maxItems: 8 }),\n\teffort: FlowEffortSchema,\n});\nexport type FlowRoleBindingV1 = Static<typeof FlowRoleBindingSchema>;\n\n/** Cost tiers a selection may declare (matches Flow's `Tier`). */\nexport const FLOW_MODEL_SELECTION_TIERS = [\"cheap\", \"mid\", \"premium\", \"frontier\"] as const;\nexport type FlowSelectionTier = (typeof FLOW_MODEL_SELECTION_TIERS)[number];\n\n/** Flow's `ALL_CAPABILITIES` (method.json) plus the runtime `triage` capability; parity is pinned in the flow tests. */\nexport const FLOW_MODEL_SELECTION_CAPABILITIES = [\n\t\"scout\",\n\t\"scope_scout\",\n\t\"worker\",\n\t\"implementation_fast\",\n\t\"analysis_mid\",\n\t\"technical_lead\",\n\t\"lead_small\",\n\t\"lead\",\n\t\"lead_large\",\n\t\"implementation_strong\",\n\t\"technical_review\",\n\t\"integration_review\",\n\t\"migration_review\",\n\t\"performance_review\",\n\t\"api_contract_review\",\n\t\"qa_agent\",\n\t\"analysis_strong\",\n\t\"architect\",\n\t\"security_review\",\n\t\"triage\",\n] as const;\nexport type FlowSelectionCapability = (typeof FLOW_MODEL_SELECTION_CAPABILITIES)[number];\n\nexport const FlowSelectionEffortSchema = lit(\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\", \"max\");\n\n/** Omitted `backups` inherits; an explicit `[]` means no fallbacks. Both must survive round-trips. */\nexport const FlowTierSelectionSchema = StrictObject({\n\tprimary: Type.Optional(FlowModelRefSchema),\n\tbackups: Type.Optional(Type.Array(FlowModelRefSchema, { maxItems: 8 })),\n});\nexport type FlowTierSelectionV1 = Static<typeof FlowTierSelectionSchema>;\n\nexport const FlowCapabilitySelectionSchema = StrictObject({\n\tprimary: Type.Optional(FlowModelRefSchema),\n\tbackups: Type.Optional(Type.Array(FlowModelRefSchema, { maxItems: 8 })),\n\teffort: Type.Optional(FlowSelectionEffortSchema),\n});\nexport type FlowCapabilitySelectionV1 = Static<typeof FlowCapabilitySelectionSchema>;\n\nconst optionalEach = <T extends TSchema>(keys: readonly string[], schema: T) =>\n\tStrictObject(Object.fromEntries(keys.map((key) => [key, Type.Optional(schema)])));\n\nexport const FlowModelSelectionSchema = StrictObject({\n\ttiers: Type.Optional(\n\t\toptionalEach(FLOW_MODEL_SELECTION_TIERS, FlowTierSelectionSchema) as TObject<\n\t\t\tRecord<FlowSelectionTier, TOptional<typeof FlowTierSelectionSchema>>\n\t\t>,\n\t),\n\tcapabilities: Type.Optional(\n\t\toptionalEach(FLOW_MODEL_SELECTION_CAPABILITIES, FlowCapabilitySelectionSchema) as TObject<\n\t\t\tRecord<FlowSelectionCapability, TOptional<typeof FlowCapabilitySelectionSchema>>\n\t\t>,\n\t),\n});\nexport type FlowModelSelectionV1 = Static<typeof FlowModelSelectionSchema>;\n\nexport const FlowProfileV1Schema = StrictObject({\n\tschema: Type.Literal(\"humain-flow-profile\"),\n\tschemaVersion: Type.Literal(1),\n\tid: FlowIdSchema,\n\tversion: FlowPositiveIntSchema,\n\tdigest: FlowDigestSchema,\n\tkind: Type.Union([Type.Literal(\"direct\"), Type.Literal(\"flow\")]),\n\tlabel: Type.String({ minLength: 1, maxLength: 80 }),\n\tdescription: Type.Optional(Type.String({ maxLength: 500 })),\n\tdirect: Type.Optional(\n\t\tStrictObject({ model: FlowModelRefSchema, fallbacks: Type.Array(FlowModelRefSchema, { maxItems: 8 }) }),\n\t),\n\troles: Type.Optional(partialByRole(FlowRoleBindingSchema)),\n\tsizing: Type.Optional(\n\t\tStrictObject({\n\t\t\tclassifierPolicyId: FlowIdSchema,\n\t\t\tthresholds: StrictObject({\n\t\t\t\tmediumAt: Type.Number({ minimum: 0, maximum: 1_000_000 }),\n\t\t\t\tlargeAt: Type.Number({ minimum: 0, maximum: 1_000_000 }),\n\t\t\t}),\n\t\t\ttriageRole: Type.Literal(\"triage\"),\n\t\t\tmaxEscalations: Type.Union([Type.Literal(0), Type.Literal(1)]),\n\t\t}),\n\t),\n\tlimits: StrictObject({\n\t\tmaxAgents: Type.Integer({ minimum: 1, maximum: 256 }),\n\t\tmaxConcurrent: Type.Integer({ minimum: 1, maximum: 64 }),\n\t\tmaxDepth: Type.Integer({ minimum: 0, maximum: 3 }),\n\t\tmaxRetries: Type.Integer({ minimum: 0, maximum: 16 }),\n\t\tinactivityMs: Type.Integer({ minimum: 1, maximum: 86_400_000 }),\n\t\tciWaitMs: Type.Integer({ minimum: 0, maximum: 86_400_000 }),\n\t}),\n\tspend: StrictObject({\n\t\trunCapMicrousd: FlowMicrousdSchema,\n\t\twarnAtPct: Type.Integer({ minimum: 1, maximum: 99 }),\n\t\tperRoleCapMicrousd: Type.Optional(partialByRole(FlowMicrousdSchema)),\n\t}),\n\tmodelSelection: Type.Optional(FlowModelSelectionSchema),\n\tproviders: Type.Optional(StrictObject({ preference: Type.Array(FlowIdSchema, { maxItems: 16 }) })),\n\tapproval: Type.Optional(StrictObject({ approvedBy: FlowIdSchema, approvedAt: FlowTimestampSchema })),\n\tbuiltIn: Type.Optional(Type.Literal(true)),\n});\nexport type FlowProfileV1 = Static<typeof FlowProfileV1Schema>;\n\nconst Validator = compileFlow(FlowProfileV1Schema);\nconst REQUIRED_FLOW_ROLES = [\"lead\", \"worker\", \"reviewer\", \"qa\"] as const;\n\n/** Canonical text hashed (sha256 hex) to produce `digest`: the document without `digest`. */\nexport function flowProfileDigestInput(doc: FlowProfileV1): string {\n\treturn canonicalWithout(doc, \"digest\");\n}\n\nfunction selectionLayerValid(layer: FlowTierSelectionV1 | FlowCapabilitySelectionV1): boolean {\n\tconst refs = [...(layer.primary === undefined ? [] : [layer.primary]), ...(layer.backups ?? [])];\n\treturn !hasDuplicateModels(refs);\n}\n\nfunction modelSelectionValid(selection: FlowModelSelectionV1): boolean {\n\tconst layers = [...Object.values(selection.tiers ?? {}), ...Object.values(selection.capabilities ?? {})];\n\treturn layers.every(selectionLayerValid);\n}\n\nfunction crossFieldsValid(doc: FlowProfileV1): boolean {\n\tif (doc.modelSelection !== undefined && (doc.kind === \"direct\" || !modelSelectionValid(doc.modelSelection))) {\n\t\treturn false;\n\t}\n\tif (doc.kind === \"direct\") {\n\t\tif (doc.direct === undefined || doc.roles !== undefined || doc.sizing !== undefined) return false;\n\t\treturn !hasDuplicateModels([doc.direct.model, ...doc.direct.fallbacks]);\n\t}\n\tif (doc.direct !== undefined || doc.roles === undefined) return false;\n\tfor (const role of REQUIRED_FLOW_ROLES) if (doc.roles[role] === undefined) return false;\n\tfor (const binding of Object.values(doc.roles)) {\n\t\tconst refs: FlowModelRef[] = [binding.primary, ...binding.backups];\n\t\tif (hasDuplicateModels(refs)) return false;\n\t}\n\treturn doc.sizing === undefined || doc.sizing.thresholds.mediumAt <= doc.sizing.thresholds.largeAt;\n}\n\nfunction isProfile(value: unknown): value is FlowProfileV1 {\n\treturn Validator.Check(value) && crossFieldsValid(value);\n}\n\n/**\n * SHAPE ONLY: validates structure and cross-field rules but does NOT verify `digest`. Use only for documents whose\n * integrity is established elsewhere (e.g. authored drafts); prefer {@link parseFlowProfileV1}.\n */\nexport function parseFlowProfileV1Shape(input: unknown): FlowProfileV1 {\n\treturn parseFlowData(\"profile_invalid\", input, isProfile);\n}\n\n/** Shape validation plus digest verification with the injected hasher (digests are integrity, not authentication). */\nexport function parseFlowProfileV1(input: unknown, hasher: FlowDigestHasher): FlowProfileV1 {\n\tconst profile = parseFlowProfileV1Shape(input);\n\tif (!verifyFlowDigest(hasher, flowProfileDigestInput(profile), profile.digest)) {\n\t\tthrow new FlowContractError(\"digest_mismatch\");\n\t}\n\treturn profile;\n}\n"]}
|