@cat-factory/server 0.294.0 → 0.296.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.
Files changed (75) hide show
  1. package/dist/agents/promptOverrides.d.ts +3 -4
  2. package/dist/agents/promptOverrides.d.ts.map +1 -1
  3. package/dist/agents/promptOverrides.js +5 -9
  4. package/dist/agents/promptOverrides.js.map +1 -1
  5. package/dist/agents/toolServers.d.ts.map +1 -1
  6. package/dist/agents/toolServers.js +15 -1
  7. package/dist/agents/toolServers.js.map +1 -1
  8. package/dist/app.d.ts.map +1 -1
  9. package/dist/app.js +10 -0
  10. package/dist/app.js.map +1 -1
  11. package/dist/github/FetchGitHubClient.d.ts +2 -0
  12. package/dist/github/FetchGitHubClient.d.ts.map +1 -1
  13. package/dist/github/FetchGitHubClient.js +17 -91
  14. package/dist/github/FetchGitHubClient.js.map +1 -1
  15. package/dist/github/githubHttpHelpers.d.ts +59 -3
  16. package/dist/github/githubHttpHelpers.d.ts.map +1 -1
  17. package/dist/github/githubHttpHelpers.js +59 -4
  18. package/dist/github/githubHttpHelpers.js.map +1 -1
  19. package/dist/github/repoContents.d.ts +31 -0
  20. package/dist/github/repoContents.d.ts.map +1 -0
  21. package/dist/github/repoContents.js +121 -0
  22. package/dist/github/repoContents.js.map +1 -0
  23. package/dist/http/env.d.ts +10 -1
  24. package/dist/http/env.d.ts.map +1 -1
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +1 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/modules/agentKinds/AgentKindsController.d.ts +46 -0
  30. package/dist/modules/agentKinds/AgentKindsController.d.ts.map +1 -0
  31. package/dist/modules/agentKinds/AgentKindsController.js +56 -0
  32. package/dist/modules/agentKinds/AgentKindsController.js.map +1 -0
  33. package/dist/modules/persistence/PersistenceController.d.ts.map +1 -1
  34. package/dist/modules/persistence/PersistenceController.js +6 -161
  35. package/dist/modules/persistence/PersistenceController.js.map +1 -1
  36. package/dist/modules/persistence/dispatchScope.d.ts +16 -0
  37. package/dist/modules/persistence/dispatchScope.d.ts.map +1 -0
  38. package/dist/modules/persistence/dispatchScope.js +307 -0
  39. package/dist/modules/persistence/dispatchScope.js.map +1 -0
  40. package/dist/modules/publicApi/PublicProvisioningController.d.ts +57 -1
  41. package/dist/modules/publicApi/PublicProvisioningController.d.ts.map +1 -1
  42. package/dist/modules/publicApi/PublicProvisioningController.js +204 -8
  43. package/dist/modules/publicApi/PublicProvisioningController.js.map +1 -1
  44. package/dist/modules/publicApi/boardProjection.d.ts +9 -3
  45. package/dist/modules/publicApi/boardProjection.d.ts.map +1 -1
  46. package/dist/modules/publicApi/boardProjection.js +41 -8
  47. package/dist/modules/publicApi/boardProjection.js.map +1 -1
  48. package/dist/modules/publicApi/openapiDocument.generated.d.ts +1 -1
  49. package/dist/modules/publicApi/openapiDocument.generated.d.ts.map +1 -1
  50. package/dist/modules/publicApi/openapiDocument.generated.js +1 -1
  51. package/dist/modules/publicApi/openapiDocument.generated.js.map +1 -1
  52. package/dist/persistence/agentKinds.d.ts +43 -0
  53. package/dist/persistence/agentKinds.d.ts.map +1 -0
  54. package/dist/persistence/agentKinds.js +99 -0
  55. package/dist/persistence/agentKinds.js.map +1 -0
  56. package/dist/persistence/rpc-allowlist-libraries.d.ts +4 -0
  57. package/dist/persistence/rpc-allowlist-libraries.d.ts.map +1 -0
  58. package/dist/persistence/rpc-allowlist-libraries.js +209 -0
  59. package/dist/persistence/rpc-allowlist-libraries.js.map +1 -0
  60. package/dist/persistence/rpc-allowlist-vcs.d.ts +24 -0
  61. package/dist/persistence/rpc-allowlist-vcs.d.ts.map +1 -0
  62. package/dist/persistence/rpc-allowlist-vcs.js +119 -0
  63. package/dist/persistence/rpc-allowlist-vcs.js.map +1 -0
  64. package/dist/persistence/rpc-allowlist.d.ts.map +1 -1
  65. package/dist/persistence/rpc-allowlist.js +66 -249
  66. package/dist/persistence/rpc-allowlist.js.map +1 -1
  67. package/dist/persistence/rpc-scope.logic.d.ts +46 -0
  68. package/dist/persistence/rpc-scope.logic.d.ts.map +1 -1
  69. package/dist/persistence/rpc-scope.logic.js +109 -0
  70. package/dist/persistence/rpc-scope.logic.js.map +1 -1
  71. package/dist/persistence/rpc.d.ts +111 -0
  72. package/dist/persistence/rpc.d.ts.map +1 -1
  73. package/dist/persistence/rpc.js +42 -44
  74. package/dist/persistence/rpc.js.map +1 -1
  75. package/package.json +8 -8
@@ -0,0 +1,307 @@
1
+ /**
2
+ * The per-request READ MEMO, plus the one registry substitution it earns.
3
+ *
4
+ * Every entity-keyed scope rule resolves a row to bind the call, and for a handful of methods that
5
+ * row IS what the call then dispatches. Memoising each read per request keeps those to one query,
6
+ * and the `memoOverrides` table points the dispatched method at the same memo. Extracted from
7
+ * {@link buildDispatchScope} when the batched resolvers pushed it past its function-size budget:
8
+ * this half is about READING ONCE, the other about what a read MEANS for scope.
9
+ */
10
+ function buildRequestReaders(registry, request) {
11
+ const workspaceRepository = registry.workspaceRepository;
12
+ const blockRepository = registry.blockRepository;
13
+ const serviceRepository = registry.serviceRepository;
14
+ const skillSourceRepository = registry.skillSourceRepository;
15
+ // The owner-pair content-library source tables, keyed by the `LibrarySourceEntity` the rule
16
+ // names, so one resolver answers for both (and a new library is one row here). Keyed by the
17
+ // UNION rather than by `string`: a member added to `LibrarySourceEntity` must fail to compile
18
+ // here rather than resolve to nothing, which the stored-half check would otherwise be entitled
19
+ // to read as "no such row" and admit.
20
+ const librarySourceRepos = {
21
+ fragmentSource: registry.fragmentSourceRepository,
22
+ foundationalServiceSource: registry.foundationalServiceSourceRepository,
23
+ };
24
+ const resolveAccountId = (workspaceId) => workspaceRepository?.accountOf?.(workspaceId) ??
25
+ Promise.resolve(undefined);
26
+ // The BATCHED account read every list-shaped rule binds through. A registry that does not wire
27
+ // it answers an empty map, which fails every id closed rather than admitting one: the same
28
+ // disposition an unresolvable `accountOf` already has.
29
+ const readAccountIds = async (workspaceIds) => (await workspaceRepository?.accountIdsOf?.(workspaceIds)) ?? {};
30
+ // The `block`/`serviceList`/`service` scope checks resolve the owning account by reading the
31
+ // entity (`blockRepository.findById` / `serviceRepository.listByIds`). When the request ALSO
32
+ // dispatches that same read, memoise it per request so the resolver's read is reused instead
33
+ // of issuing a second identical query. `serviceRepository.get(id)` is the single-service form:
34
+ // its `service` scope resolves via `listByIds([id])`, so the dispatched `get` is routed through
35
+ // the same memo (a single-id `listByIds` yields the same row) rather than a second point read.
36
+ // (For every other `serviceList` method the dispatched method differs from the resolver's read,
37
+ // so there is nothing to dedupe.)
38
+ const memoizeRead = (fn) => {
39
+ const cache = new Map();
40
+ return (...args) => {
41
+ const key = JSON.stringify(args);
42
+ const hit = cache.get(key);
43
+ if (hit)
44
+ return hit;
45
+ const pending = Promise.resolve(fn(...args));
46
+ cache.set(key, pending);
47
+ return pending;
48
+ };
49
+ };
50
+ const installationRepository = registry.githubInstallationRepository;
51
+ const blockFindById = memoizeRead((blockId) => blockRepository?.findById?.(blockId));
52
+ // One memo per installation id, shared by the resolver and (via the override below) the
53
+ // dispatched point read, exactly as the source tables do. Built only when the repository is
54
+ // wired, so an unwired one answers `unreadable` rather than the absence an id-keyed upsert
55
+ // would be entitled to read as a create.
56
+ const installationGet = typeof installationRepository?.getByInstallationId === 'function'
57
+ ? memoizeRead((id) => installationRepository.getByInstallationId(id))
58
+ : undefined;
59
+ const blockFindByIds = memoizeRead((ids) => blockRepository?.findByIds?.(ids));
60
+ // One memo per requested SET of workspace ids, shared by the resolver and (via the override
61
+ // below) the dispatched `accountIdsOf`, exactly as the other self-keyed reads do.
62
+ const accountIdsOf = memoizeRead((ids) => readAccountIds(ids));
63
+ const installationListByIds = memoizeRead((ids) => installationRepository?.listByInstallationIds?.(ids));
64
+ const serviceListByIds = memoizeRead((ids) => serviceRepository?.listByIds?.(ids));
65
+ const skillSourceGet = memoizeRead((id) => skillSourceRepository?.get?.(id));
66
+ // One memo per source TABLE, keyed by entity: the resolver and the dispatched `get` of the same
67
+ // library then share a read, exactly as `skillSourceGet` does for skills. A table whose `get`
68
+ // this deployment does not wire gets NO reader rather than one answering `undefined`, so the
69
+ // resolver below can report `unreadable` instead of the absence that would admit an upsert.
70
+ const librarySourceReader = (entity) => {
71
+ const repo = librarySourceRepos[entity];
72
+ if (typeof repo?.get !== 'function')
73
+ return undefined;
74
+ // Called through the repository so a class-implemented `get` keeps its receiver.
75
+ return memoizeRead((id) => repo.get(id));
76
+ };
77
+ const librarySourceGets = {
78
+ fragmentSource: librarySourceReader('fragmentSource'),
79
+ foundationalServiceSource: librarySourceReader('foundationalServiceSource'),
80
+ };
81
+ // For the self-keyed reads, point the dispatcher's own call at the memo so it hits the
82
+ // resolver's already-resolved result. Only the one dispatched method is overridden; the rest
83
+ // of the registry is untouched. Keyed `repo.method` so a new self-keyed read is one row here
84
+ // rather than another rung on a ternary chain.
85
+ const serviceGetViaMemo = async (id) => (await serviceListByIds([id]))?.[0] ?? null;
86
+ const memoOverrides = {
87
+ 'blockRepository.findById': { blockRepository: { findById: blockFindById } },
88
+ 'blockRepository.findByIds': { blockRepository: { findByIds: blockFindByIds } },
89
+ 'serviceRepository.listByIds': { serviceRepository: { listByIds: serviceListByIds } },
90
+ 'serviceRepository.get': { serviceRepository: { get: serviceGetViaMemo } },
91
+ // The two batched self-keyed reads: the `workspaceList` rule resolves the accounts of exactly
92
+ // the ids `accountIdsOf` is being asked for, and `installationList` resolves the owners of
93
+ // exactly the ids `listByInstallationIds` is being asked for.
94
+ 'workspaceRepository.accountIdsOf': { workspaceRepository: { accountIdsOf } },
95
+ 'githubInstallationRepository.listByInstallationIds': {
96
+ githubInstallationRepository: { listByInstallationIds: installationListByIds },
97
+ },
98
+ // The `skillSource` scope resolves a source's account by reading the source; when the
99
+ // dispatched call IS that read (the sync service's `get`), reuse the resolver's result.
100
+ 'skillSourceRepository.get': { skillSourceRepository: { get: skillSourceGet } },
101
+ // The same self-keyed read for an installation: the `installation` rule resolves the row to
102
+ // scope the call, and the dispatched `getByInstallationId` IS that row.
103
+ ...(installationGet
104
+ ? {
105
+ 'githubInstallationRepository.getByInstallationId': {
106
+ githubInstallationRepository: { getByInstallationId: installationGet },
107
+ },
108
+ }
109
+ : {}),
110
+ // The same self-keyed read for the two owner-pair libraries' source tables. Contributed only
111
+ // where a reader exists: a table whose `get` is unwired has nothing to memoise, and the
112
+ // dispatcher's own wiring check answers that call with `... is not wired` regardless.
113
+ ...(librarySourceGets.fragmentSource
114
+ ? {
115
+ 'fragmentSourceRepository.get': {
116
+ fragmentSourceRepository: { get: librarySourceGets.fragmentSource },
117
+ },
118
+ }
119
+ : {}),
120
+ ...(librarySourceGets.foundationalServiceSource
121
+ ? {
122
+ 'foundationalServiceSourceRepository.get': {
123
+ foundationalServiceSourceRepository: {
124
+ get: librarySourceGets.foundationalServiceSource,
125
+ },
126
+ },
127
+ }
128
+ : {}),
129
+ };
130
+ // Substitute ONLY for a method the real registry actually wires. `memoizeRead` returns a
131
+ // function unconditionally — it closes over an optional-chained call — so overriding an ABSENT
132
+ // repository would satisfy the dispatcher's `typeof fn !== 'function'` wiring check and answer a
133
+ // misconfigured deployment with a scope 404 (or a bare null) instead of the `... is not wired`
134
+ // that names what to fix. The key is only ever consulted after `Object.hasOwn`, so an
135
+ // attacker-controlled `request.repo` cannot reach an inherited member through the lookup below.
136
+ const memoKey = `${request.repo}.${request.method}`;
137
+ const override = Object.hasOwn(memoOverrides, memoKey)
138
+ ? typeof registry[request.repo]?.[request.method] === 'function'
139
+ ? memoOverrides[memoKey]
140
+ : undefined
141
+ : undefined;
142
+ const registryForDispatch = override ? { ...registry, ...override } : registry;
143
+ return {
144
+ registryForDispatch,
145
+ blockRepository,
146
+ installationRepository,
147
+ resolveAccountId,
148
+ accountIdsOf,
149
+ blockFindById,
150
+ blockFindByIds,
151
+ serviceListByIds,
152
+ skillSourceGet,
153
+ librarySourceGets,
154
+ installationGet,
155
+ installationListByIds,
156
+ };
157
+ }
158
+ /**
159
+ * The per-request SCOPE RESOLUTION half of `POST /internal/persistence`: the entity readers the
160
+ * dispatcher binds a call through (block → workspace → account, service → account, a library
161
+ * source's owner pair, an installation's owner, an account's roster), over the per-request memo
162
+ * {@link buildRequestReaders} builds.
163
+ *
164
+ * Split out of `PersistenceController` when the surface completion pushed the handler past its
165
+ * function-size budget. It is the half that grows: every new entity-keyed scope rule adds a
166
+ * resolver here, while the controller's own job (gate, parse, dispatch, relay) does not change.
167
+ */
168
+ export function buildDispatchScope(registry, request, scope) {
169
+ const { registryForDispatch, blockRepository, installationRepository, resolveAccountId, accountIdsOf, blockFindById, blockFindByIds, serviceListByIds, skillSourceGet, librarySourceGets, installationGet, installationListByIds, } = buildRequestReaders(registry, request);
170
+ return {
171
+ registry: registryForDispatch,
172
+ scope,
173
+ resolveAccountId,
174
+ resolveAccountIds: async (workspaceIds) => {
175
+ const accounts = (await accountIdsOf(workspaceIds));
176
+ return new Map(Object.entries(accounts));
177
+ },
178
+ // A block is keyed only by its id; resolve its home workspace, then that workspace's account.
179
+ resolveBlockAccountId: async (blockId) => {
180
+ const found = (await blockFindById(blockId));
181
+ const workspaceId = found?.workspaceId;
182
+ return typeof workspaceId === 'string' ? resolveAccountId(workspaceId) : undefined;
183
+ },
184
+ // The batched form, in exactly two reads however long the list: one `findByIds` resolves every
185
+ // block's home workspace, then ONE `accountIdsOf` over the deduped workspaces. A block absent
186
+ // from either read is absent from the map.
187
+ resolveBlockAccountIds: async (blockIds) => {
188
+ const found = (await blockFindByIds(blockIds));
189
+ const entries = found ?? [];
190
+ const accounts = (await accountIdsOf([
191
+ ...new Set(entries.map((entry) => entry.workspaceId)),
192
+ ]));
193
+ const map = new Map();
194
+ for (const entry of entries) {
195
+ map.set(entry.block.id, Object.hasOwn(accounts, entry.workspaceId) ? accounts[entry.workspaceId] : undefined);
196
+ }
197
+ return map;
198
+ },
199
+ // Services are account-owned; resolve each requested id's `accountId` for the scope check.
200
+ resolveServiceAccountIds: async (serviceIds) => {
201
+ const services = (await serviceListByIds(serviceIds));
202
+ const map = new Map();
203
+ for (const service of services ?? [])
204
+ map.set(service.id, service.accountId);
205
+ return map;
206
+ },
207
+ // Skill sources are account-owned; the sync surface's methods carry only a source id, so
208
+ // resolve the row and project its `accountId` for the scope check. A source that does not
209
+ // exist resolves to undefined, which fails closed (404) exactly like a missing block/service.
210
+ resolveSkillSourceAccountId: async (sourceId) => {
211
+ const source = (await skillSourceGet(sourceId));
212
+ return source?.accountId;
213
+ },
214
+ // The owner-PAIR libraries' equivalent: a fragment / foundational-service source is owned by
215
+ // an `(ownerKind, ownerId)` tier rather than an account, so project the pair and let the rule
216
+ // resolve it the way it resolves a positional owner. A source that does not exist answers
217
+ // `absent`, which the sourceId-keyed rules fail closed on (404) exactly like a missing
218
+ // block/service, and which `ownerFieldUpsert` alone reads as a create.
219
+ resolveLibrarySourceOwner: async (entity, sourceId) => {
220
+ const read = librarySourceGets[entity];
221
+ // No reader for that table: nothing is known about the id, so say so. Answering `absent`
222
+ // here would let an id-keyed upsert through on its DECLARED owner alone.
223
+ if (!read)
224
+ return { status: 'unreadable' };
225
+ const source = (await read(sourceId));
226
+ return source
227
+ ? { status: 'found', owner: { ownerKind: source.ownerKind, ownerId: source.ownerId } }
228
+ : { status: 'absent' };
229
+ },
230
+ // A VCS installation binds either an ACCOUNT (a GitHub App installation, shared with every
231
+ // board of that account) or just its connector WORKSPACE (a per-workspace PAT, which stores
232
+ // no account). Resolve the effective owner so both bind the same way, and keep "no such
233
+ // binding" apart from "this deployment cannot read the table": the batched annotation read
234
+ // admits the first and must refuse the second.
235
+ resolveInstallationOwner: async (installationId) => {
236
+ if (!installationGet)
237
+ return { status: 'unreadable' };
238
+ const row = (await installationGet(installationId));
239
+ if (!row)
240
+ return { status: 'absent' };
241
+ if (typeof row.accountId === 'string')
242
+ return { status: 'found', accountId: row.accountId };
243
+ const workspaceId = row.workspaceId;
244
+ return {
245
+ status: 'found',
246
+ accountId: typeof workspaceId === 'string' ? await resolveAccountId(workspaceId) : null,
247
+ };
248
+ },
249
+ // The batched form: one `listByInstallationIds` plus one `accountIdsOf` over the connector
250
+ // workspaces of the PAT bindings that store no account. Ids with no binding are absent from
251
+ // the read, so the rule sees them as `absent` (the admission the annotation read needs) while
252
+ // an UNWIRED repository yields no map at all, which the rule fails closed on.
253
+ resolveInstallationOwners: async (installationIds) => {
254
+ const owners = new Map();
255
+ if (typeof installationRepository?.listByInstallationIds !== 'function') {
256
+ for (const id of installationIds)
257
+ owners.set(id, { status: 'unreadable' });
258
+ return owners;
259
+ }
260
+ const rows = ((await installationListByIds(installationIds)) ?? []);
261
+ const patWorkspaces = rows
262
+ .filter((row) => typeof row.accountId !== 'string' && typeof row.workspaceId === 'string')
263
+ .map((row) => row.workspaceId);
264
+ const accounts = (await accountIdsOf([...new Set(patWorkspaces)]));
265
+ for (const row of rows) {
266
+ if (typeof row.accountId === 'string') {
267
+ owners.set(row.installationId, { status: 'found', accountId: row.accountId });
268
+ continue;
269
+ }
270
+ const workspaceId = row.workspaceId;
271
+ owners.set(row.installationId, {
272
+ status: 'found',
273
+ accountId: typeof workspaceId === 'string' && Object.hasOwn(accounts, workspaceId)
274
+ ? accounts[workspaceId]
275
+ : null,
276
+ });
277
+ }
278
+ for (const id of installationIds) {
279
+ if (!owners.has(id))
280
+ owners.set(id, { status: 'absent' });
281
+ }
282
+ return owners;
283
+ },
284
+ // A service's frame block, as the three states `serviceInsert` needs: the row is written
285
+ // BEFORE its block, so `absent` is the ordinary create and only `found` binds.
286
+ resolveFrameBlockOwner: async (frameBlockId) => {
287
+ if (typeof blockRepository?.findById !== 'function')
288
+ return { status: 'unreadable' };
289
+ const found = (await blockFindById(frameBlockId));
290
+ if (!found)
291
+ return { status: 'absent' };
292
+ const workspaceId = found.workspaceId;
293
+ return {
294
+ status: 'found',
295
+ accountId: typeof workspaceId === 'string' ? await resolveAccountId(workspaceId) : null,
296
+ };
297
+ },
298
+ // The member-display scope (`user`/`userList`): a userId is in scope iff a co-member of an
299
+ // in-scope account, so resolve each in-scope account's roster to userIds. Bounded by the
300
+ // token's account scope, not the requested user list.
301
+ resolveAccountMemberIds: async (accountId) => {
302
+ const memberships = (await registry.membershipRepository?.listByAccount?.(accountId));
303
+ return (memberships ?? []).map((m) => m.userId);
304
+ },
305
+ };
306
+ }
307
+ //# sourceMappingURL=dispatchScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatchScope.js","sourceRoot":"","sources":["../../../src/modules/persistence/dispatchScope.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
- import { type BootstrapJob, type GitHubAvailableRepo, type GitHubConnection, type KubernetesManifestSource, type PublicAvailableRepo, type PublicBootstrapJob, type PublicKubernetesManifestSource, type ServiceProvisioning, type UpdatePublicServiceInput } from '@cat-factory/contracts';
1
+ import { type BootstrapJob, type EnvironmentHandlerView, type GitHubAvailableRepo, type GitHubConnection, type KubernetesManifestSource, type PublicAvailableRepo, type PublicBootstrapJob, type PublicEnvironmentHandler, type PublicKubernetesManifestSource, type ServiceProvisioning, type UpdatePublicServiceInput } from '@cat-factory/contracts';
2
2
  import type { RepoUseByRepoId } from '@cat-factory/orchestration';
3
+ import { type RepoFileContent, type RunRepoContext } from '@cat-factory/kernel';
3
4
  import { Hono } from 'hono';
4
5
  import type { AppEnv, ServerContainer } from '../../http/env.js';
5
6
  /**
@@ -64,11 +65,66 @@ export declare function toPublicAvailableRepo(repo: GitHubAvailableRepo, use: Re
64
65
  * prevent, on the deployment least able to tell that is what happened.
65
66
  */
66
67
  export declare function asVcsRefusal(error: unknown): unknown;
68
+ /**
69
+ * Read one file, turning the two answers only this layer can name into the refusals it documents.
70
+ *
71
+ * **A blob past the PROVIDER's own contents ceiling is the same refusal as one past ours.** GitHub
72
+ * reports it as a `403`, which {@link asVcsRefusal} would otherwise read as a rejected credential,
73
+ * so an operator whose lockfile is 1.4 MB would be told to re-mint a token that works. The adapter
74
+ * names the fact (`VcsBlobTooLargeError`) and this maps it onto `file_too_large` with the provider's
75
+ * limit and NO size, because nothing here measured one.
76
+ *
77
+ * **Bytes that are not UTF-8 are refused rather than answered.** The decode is lossy for a PNG, a
78
+ * tarball or a Latin-1 source file, and handing back replacement characters under a field documented
79
+ * as the file's content is the same lie the truncation above refuses to tell: a caller comparing
80
+ * against its own copy sees a mismatch it cannot attribute. The `sha` rides the refusal, so the
81
+ * byte-exact join a grader wanted is still available.
82
+ *
83
+ * Anything else is a fact about the provider and goes through {@link asVcsRefusal} unchanged.
84
+ */
85
+ export declare function readGradableFile(repo: RunRepoContext['repo'], at: string, path: string, ref: string | undefined): Promise<RepoFileContent | null>;
67
86
  /**
68
87
  * Lower a public manifest source onto the internal one, for the same reason and with the same
69
88
  * exhaustiveness as the URL source above.
70
89
  */
71
90
  export declare function toKubernetesManifestSource(source: PublicKubernetesManifestSource): KubernetesManifestSource;
91
+ /**
92
+ * Project a handler for the LIST, whatever engine services it.
93
+ *
94
+ * `engine` and `backendKind` are open strings here rather than the connect view's literal, because
95
+ * this read reports handlers the deployment SEEDED from its composition root, and a deployment may
96
+ * register an environment backend of its own: the whole point of the registry. Reporting one as
97
+ * `kubernetes` would be the coercion the board projection refuses next door, and omitting it would
98
+ * make a seeded handler indistinguishable from an absent one, which is the state this read exists to
99
+ * make checkable.
100
+ *
101
+ * `endpoint` and not `apiServerUrl`: the Kubernetes noun is false of every other engine, and stating
102
+ * it anyway is what sends an operator whose environment is a VM looking for an apiserver.
103
+ *
104
+ * BOTH manifest-id fields are reported, because the engine's own resolution
105
+ * (`resolveInfraHandler` → `matchesCustom`) matches a service's pinned `manifestId` against EITHER,
106
+ * and the two ways of registering a handler each set only one: a deployment SEEDING one keys it with
107
+ * `manifestId`, while a `remote-custom` connection declares `acceptsManifestId`. Publishing only the
108
+ * second made the commonest seed shape read as a handler serving nothing, so a setup script checking
109
+ * that its own seed landed found no entry naming it while a run against it resolved fine.
110
+ *
111
+ * No `config`, though `EnvironmentHandlerView` carries one for the app's connect-form prefill: it is
112
+ * the internal per-engine bag, deliberately open, and this surface may not freeze it (ADR 0034).
113
+ */
114
+ export declare function toPublicHandler(view: EnvironmentHandlerView): PublicEnvironmentHandler;
115
+ /**
116
+ * Order handlers by what IDENTIFIES one, comparing code units rather than collating.
117
+ *
118
+ * `localeCompare` is ICU- and locale-dependent, so the same set of handlers can serialise in one
119
+ * order from a workerd isolate and in another from a Node build with a different ICU: precisely the
120
+ * spurious diff the ordering was added to prevent. A code-unit comparison answers the same everywhere,
121
+ * which is what a wire ordering needs.
122
+ *
123
+ * Both manifest ids join the key, since two `custom` handlers keyed to different manifests are
124
+ * otherwise equal here. A handler that ties on all four keys keeps its position from the repository
125
+ * read (the sort is stable), which is the honest fallback: nothing published distinguishes them.
126
+ */
127
+ export declare function byHandlerIdentity(left: PublicEnvironmentHandler, right: PublicEnvironmentHandler): number;
72
128
  /**
73
129
  * Lower a public service patch onto the board patch.
74
130
  *
@@ -1 +1 @@
1
- {"version":3,"file":"PublicProvisioningController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicProvisioningController.ts"],"names":[],"mappings":"AAAA,OAAO,EAaL,KAAK,YAAY,EAEjB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAErB,KAAK,wBAAwB,EAI7B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAGvB,KAAK,8BAA8B,EAQnC,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAKV,eAAe,EAEhB,MAAM,4BAA4B,CAAA;AAWnC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAgEhE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,eAAe,EAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAQlC;AA6FD,wBAAgB,4BAA4B,IAAI,IAAI,CAAC,MAAM,CAAC,CAQ3D;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,kBAAkB,CAgB1E;AAiDD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,eAAe,GACnB,mBAAmB,CAsBrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoBpD;AAyID;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,8BAA8B,GACrC,wBAAwB,CAW1B;AAmFD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,EAC/B,MAAM,EAAE,mBAAmB,GAAG,SAAS,GACtC;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,mBAAmB,CAAA;CACnC,CAQA"}
1
+ {"version":3,"file":"PublicProvisioningController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicProvisioningController.ts"],"names":[],"mappings":"AAAA,OAAO,EAgBL,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EAErB,KAAK,wBAAwB,EAI7B,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EAGvB,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,EAQnC,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC9B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAKV,eAAe,EAEhB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EASL,KAAK,eAAe,EACpB,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAgEhE;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,eAAe,EAC1B,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAQlC;AA6FD,wBAAgB,4BAA4B,IAAI,IAAI,CAAC,MAAM,CAAC,CAQ3D;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,YAAY,GAAG,kBAAkB,CAgB1E;AAiDD;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,eAAe,GACnB,mBAAmB,CAsBrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAoBpD;AAoJD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAC5B,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAsBjC;AA6DD;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,8BAA8B,GACrC,wBAAwB,CAW1B;AA8BD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,sBAAsB,GAAG,wBAAwB,CAYtF;AA8CD;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,wBAAwB,EAC9B,KAAK,EAAE,wBAAwB,GAC9B,MAAM,CAOR;AAiCD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,wBAAwB,EAC/B,MAAM,EAAE,mBAAmB,GAAG,SAAS,GACtC;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,mBAAmB,CAAA;CACnC,CAQA"}