@cat-factory/server 0.262.0 → 0.263.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/dist/modules/publicApi/PublicSpecController.d.ts.map +1 -1
- package/dist/modules/publicApi/PublicSpecController.js +90 -8
- package/dist/modules/publicApi/PublicSpecController.js.map +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.d.ts +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.d.ts.map +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.js +1 -1
- package/dist/modules/publicApi/openapiDocument.generated.js.map +1 -1
- package/dist/modules/publicApi/specProjection.d.ts +17 -1
- package/dist/modules/publicApi/specProjection.d.ts.map +1 -1
- package/dist/modules/publicApi/specProjection.js +39 -9
- package/dist/modules/publicApi/specProjection.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicSpecController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicSpecController.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PublicSpecController.d.ts","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicSpecController.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAsK/C,wBAAgB,oBAAoB,IAAI,IAAI,CAAC,MAAM,CAAC,CAoDnD"}
|
|
@@ -1,19 +1,32 @@
|
|
|
1
|
-
import { getPublicServiceSpecContract, } from '@cat-factory/contracts';
|
|
1
|
+
import { getPublicRunSpecContract, getPublicServiceSpecContract, } from '@cat-factory/contracts';
|
|
2
2
|
import { readServiceSpec } from '@cat-factory/agents';
|
|
3
3
|
import { NotFoundError, UnavailableError } from '@cat-factory/kernel';
|
|
4
4
|
import { buildHonoRoute } from '@toad-contracts/hono';
|
|
5
5
|
import { Hono } from 'hono';
|
|
6
|
+
import { requireScopedRun, runNotFound } from './decisions/scope.js';
|
|
6
7
|
import { authorizeOrThrow } from './publicApiAuth.js';
|
|
7
|
-
import { toPublicServiceSpec } from './specProjection.js';
|
|
8
|
-
// The public SPEC
|
|
9
|
-
//
|
|
10
|
-
//
|
|
8
|
+
import { toPublicRunSpec, toPublicServiceSpec } from './specProjection.js';
|
|
9
|
+
// The public SPEC reads: the in-repo prescriptive specification (the structured requirement tree
|
|
10
|
+
// and the Gherkin rendered from it) for a consumer holding only an API key, at the two refs that
|
|
11
|
+
// answer two different questions.
|
|
11
12
|
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
13
|
+
// - `GET /api/v1/services/:serviceId/spec` reads the repository's DEFAULT branch: what the service
|
|
14
|
+
// is committed to honouring.
|
|
15
|
+
// - `GET /api/v1/runs/:runId/spec` reads the branch ONE RUN pushed its work to: what that run was
|
|
16
|
+
// judged against. A different tree for as long as its pull request is open, and the one a caller
|
|
17
|
+
// joining that run's verdicts needs, since every requirement the run itself added is absent from
|
|
18
|
+
// the default branch.
|
|
19
|
+
//
|
|
20
|
+
// They exist because the requirement ids on `GET /api/v1/runs/:runId/report` and `…/outcome` were a
|
|
21
|
+
// join key onto a document no headless caller could fetch. With these, reviewing a run's outcome
|
|
14
22
|
// against the criteria it was scored on is two GETs and a map lookup, with no repository clone and
|
|
15
23
|
// no VCS credential.
|
|
16
24
|
//
|
|
25
|
+
// Both read through the ONE spec reader, and the run read through the engine's own evidence loader,
|
|
26
|
+
// so the tree a caller joins against is the tree the platform joined against. A second reader with
|
|
27
|
+
// its own branch rule is how the app's outcome card and the outcome endpoint once came to describe
|
|
28
|
+
// one run differently.
|
|
29
|
+
//
|
|
17
30
|
// Everything below is one idea applied repeatedly: **a spec read has several outcomes and this
|
|
18
31
|
// controller refuses to fold them**, because the fold is silent and always in the same direction.
|
|
19
32
|
// The internal view the app's requirements window consumes reports `present: false` for both "this
|
|
@@ -30,7 +43,10 @@ import { toPublicServiceSpec } from './specProjection.js';
|
|
|
30
43
|
// outcome rather than a shade of the last one, because it is the case the provider REFUSES to
|
|
31
44
|
// distinguish: a renamed, transferred or deleted repository, a stale default branch and a lost
|
|
32
45
|
// installation all answer 404 exactly as an absent file does. Distinct because the fix is
|
|
33
|
-
// distinct: the deployment's repo link is wrong, and no amount of retrying repairs it.
|
|
46
|
+
// distinct: the deployment's repo link is wrong, and no amount of retrying repairs it. On the
|
|
47
|
+
// RUN read, a deleted pull-request head branch is deliberately not one of these: the loader
|
|
48
|
+
// reads the default branch instead and says so in `provenance.ref`, because a merged run whose
|
|
49
|
+
// branch was cleaned up is the ordinary end state rather than a misconfiguration.
|
|
34
50
|
// 4. **No spec on the default branch** → `200`, `anchor: "absent"`. A real, common, final answer,
|
|
35
51
|
// and one only reached with the ref resolved, so it is a statement about the branch rather
|
|
36
52
|
// than about our luck reaching it.
|
|
@@ -164,6 +180,72 @@ export function publicSpecController() {
|
|
|
164
180
|
const anchor = requireReadableAnchor(view, commit);
|
|
165
181
|
return c.json(toPublicServiceSpec(serviceId, anchor, view, provenanceOf(ctx, commit)), 200);
|
|
166
182
|
});
|
|
183
|
+
// The RUN's spec, at the branch that run pushed to. Everything the read decides is decided by the
|
|
184
|
+
// engine's evidence loader (the branch rule, the tester gate, the per-run memo, the reader), the
|
|
185
|
+
// same three the verification report and `…/outcome` read through; this route only maps WHERE the
|
|
186
|
+
// read stopped onto the surface's vocabulary. Composing a second read here is what would let this
|
|
187
|
+
// endpoint hand a caller a tree the run's own outcome summary was never joined against.
|
|
188
|
+
buildHonoRoute(app, getPublicRunSpecContract, async (c) => {
|
|
189
|
+
const auth = await authorizeOrThrow(c, getPublicRunSpecContract.minScope);
|
|
190
|
+
const { workspaceId } = auth;
|
|
191
|
+
const { runId } = c.req.valid('param');
|
|
192
|
+
// The same resolution every route under `/api/v1/runs/:runId/*` uses, so one prefix carries one
|
|
193
|
+
// access semantic: a run this key could already reach through `GET /jobs/:id` or
|
|
194
|
+
// `GET /tasks/:taskId/run`, and a 404 for anything else.
|
|
195
|
+
await requireScopedRun(c, workspaceId, runId);
|
|
196
|
+
const read = await c.get('container').executionService.readRunSpecOutcome(workspaceId, runId);
|
|
197
|
+
if (!read)
|
|
198
|
+
throw runNotFound(runId);
|
|
199
|
+
return c.json(toPublicRunSpec(runId, runSpecAnchor(runId, read)), 200);
|
|
200
|
+
});
|
|
167
201
|
return app;
|
|
168
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* The run read's anchor, or the refusal that says why there is no tree.
|
|
205
|
+
*
|
|
206
|
+
* The run's counterpart to {@link requireReadableAnchor}, and it defers to it for the half the two
|
|
207
|
+
* share: an `absent` with no resolved commit is unproven on the run's branch for exactly the reason
|
|
208
|
+
* it is on the default one. What it adds is the run-only pair at the top. `not_read` is a `200`
|
|
209
|
+
* because it is an ANSWER (the platform has consulted no tree for this run, which is what the same
|
|
210
|
+
* run's outcome summary already reports), while an unwired integration and an unreadable repository
|
|
211
|
+
* are outages that must never reach a body: served as an empty spec they would tell an integrator
|
|
212
|
+
* that a run was judged against no requirements at all.
|
|
213
|
+
*
|
|
214
|
+
* Which of them a run gets is the LOADER's ordering, not this switch's, and the two wiring states
|
|
215
|
+
* arrive only once a read is actually due: before the tester reports, every run answers `not_read`
|
|
216
|
+
* whatever the deployment wired. That is what keeps one unchanged deployment from answering `200`
|
|
217
|
+
* and `503` at different points of one run.
|
|
218
|
+
*
|
|
219
|
+
* Exhaustive over `RunSpecRead` through a `never`, so a state added to the loader fails the build
|
|
220
|
+
* here rather than surfacing as an unmapped value on `/api/v1`.
|
|
221
|
+
*/
|
|
222
|
+
function runSpecAnchor(runId, read) {
|
|
223
|
+
switch (read.status) {
|
|
224
|
+
case 'not_read':
|
|
225
|
+
return { anchor: 'not_read' };
|
|
226
|
+
case 'read':
|
|
227
|
+
return {
|
|
228
|
+
anchor: requireReadableAnchor(read.view, read.provenance.commit),
|
|
229
|
+
view: read.view,
|
|
230
|
+
provenance: read.provenance,
|
|
231
|
+
};
|
|
232
|
+
case 'vcs_unwired':
|
|
233
|
+
throw new UnavailableError('No version-control integration is configured for this deployment', 'vcs_not_configured');
|
|
234
|
+
case 'no_connection':
|
|
235
|
+
throw new UnavailableError('No version-control integration is connected for this workspace', 'vcs_not_configured');
|
|
236
|
+
case 'read_failed':
|
|
237
|
+
// Also where a service that lost its repository link lands, which is the one place this
|
|
238
|
+
// route is less precise than its service-scoped sibling (a `422` there). It stays folded
|
|
239
|
+
// here on purpose: a run resolved a repository to push to, so on this path an unlinked
|
|
240
|
+
// service is not a state a caller can reach, and a branch nothing reaches is a branch that
|
|
241
|
+
// costs four published SDKs an error code they can never see.
|
|
242
|
+
throw new UnavailableError("The run's repository could not be read; the spec may exist but could not be fetched", 'spec_read_failed');
|
|
243
|
+
case 'no_block':
|
|
244
|
+
// The same 404 the report and outcome reads answer when composition comes back empty: from
|
|
245
|
+
// outside, "no such run this key may read" and "the run's task is gone" are one fact.
|
|
246
|
+
throw runNotFound(runId);
|
|
247
|
+
default:
|
|
248
|
+
return assertNever(read);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
169
251
|
//# sourceMappingURL=PublicSpecController.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicSpecController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicSpecController.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,4BAA4B,GAI7B,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"PublicSpecController.js","sourceRoot":"","sources":["../../../src/modules/publicApi/PublicSpecController.ts"],"names":[],"mappings":"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"}
|