@generacy-ai/cockpit 0.6.0 → 0.7.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/README.md +148 -0
- package/dist/gates/clarification-hash.d.ts +33 -0
- package/dist/gates/clarification-hash.d.ts.map +1 -0
- package/dist/gates/clarification-hash.js +27 -0
- package/dist/gates/clarification-hash.js.map +1 -0
- package/dist/gates/fixtures.d.ts +15 -0
- package/dist/gates/fixtures.d.ts.map +1 -0
- package/dist/gates/fixtures.js +227 -0
- package/dist/gates/fixtures.js.map +1 -0
- package/dist/gates/gate-id.d.ts +11 -0
- package/dist/gates/gate-id.d.ts.map +1 -0
- package/dist/gates/gate-id.js +11 -0
- package/dist/gates/gate-id.js.map +1 -0
- package/dist/gates/generation.d.ts +39 -0
- package/dist/gates/generation.d.ts.map +1 -0
- package/dist/gates/generation.js +31 -0
- package/dist/gates/generation.js.map +1 -0
- package/dist/gates/index.d.ts +10 -0
- package/dist/gates/index.d.ts.map +1 -0
- package/dist/gates/index.js +19 -0
- package/dist/gates/index.js.map +1 -0
- package/dist/gates/schema.d.ts +192 -0
- package/dist/gates/schema.d.ts.map +1 -0
- package/dist/gates/schema.js +136 -0
- package/dist/gates/schema.js.map +1 -0
- package/dist/gates/schemas.d.ts +28 -0
- package/dist/gates/schemas.d.ts.map +1 -0
- package/dist/gates/schemas.js +21 -0
- package/dist/gates/schemas.js.map +1 -0
- package/dist/gates/types.d.ts +15 -0
- package/dist/gates/types.d.ts.map +1 -0
- package/dist/gates/types.js +19 -0
- package/dist/gates/types.js.map +1 -0
- package/dist/gates/wire-fixtures.d.ts +84 -0
- package/dist/gates/wire-fixtures.d.ts.map +1 -0
- package/dist/gates/wire-fixtures.js +107 -0
- package/dist/gates/wire-fixtures.js.map +1 -0
- package/dist/gh/wrapper.d.ts +22 -0
- package/dist/gh/wrapper.d.ts.map +1 -1
- package/dist/gh/wrapper.js +47 -6
- package/dist/gh/wrapper.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/resolver/parse-epic-body.d.ts +9 -3
- package/dist/resolver/parse-epic-body.d.ts.map +1 -1
- package/dist/resolver/parse-epic-body.js +59 -5
- package/dist/resolver/parse-epic-body.js.map +1 -1
- package/dist/resolver/resolve.d.ts.map +1 -1
- package/dist/resolver/resolve.js +3 -1
- package/dist/resolver/resolve.js.map +1 -1
- package/dist/resolver/types.d.ts +19 -0
- package/dist/resolver/types.d.ts.map +1 -1
- package/dist/state/precedence.d.ts.map +1 -1
- package/dist/state/precedence.js +16 -0
- package/dist/state/precedence.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -78,6 +78,154 @@ cockpit:
|
|
|
78
78
|
owner: alice # optional; defaults to `gh auth status` login
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
+
## Gates protocol (Cockpit Remote Gates epic, P2 mirror-doc)
|
|
82
|
+
|
|
83
|
+
**Audience**: engineers implementing the P2 cloud-side fake-cluster tests in
|
|
84
|
+
`generacy-ai/generacy-cloud`. This section pins the wire shapes exchanged
|
|
85
|
+
between the cluster-side integration harness (`packages/orchestrator/src/__tests__/cockpit-gates-integration.integration.test.ts`)
|
|
86
|
+
and the fake relay peer, so the cloud side can emit and expect the exact
|
|
87
|
+
same bytes without cross-repo copy-paste.
|
|
88
|
+
|
|
89
|
+
**Single-source the shapes**: build every wire body through the fixture
|
|
90
|
+
builders exported from `@generacy-ai/cockpit` so cluster and cloud stay
|
|
91
|
+
byte-identical — never hand-inline a literal:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import {
|
|
95
|
+
gateOpenFixture, // POST /cockpit/gates body → GateOpenSchema
|
|
96
|
+
gateAckFixture, // POST /cockpit/gates/:id/ack body → GateAckSchema
|
|
97
|
+
answerLineFixture, // POST /cockpit/answers body + tail → GateAnswerEnvelopeSchema (+ scope)
|
|
98
|
+
DEFAULT_WIRE_SCOPE, // { owner, repo, number }
|
|
99
|
+
DEFAULT_WIRE_EPIC_REF // "owner/repo#number"
|
|
100
|
+
} from '@generacy-ai/cockpit';
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Wire framing
|
|
104
|
+
|
|
105
|
+
All messages are JSON-encoded WebSocket text frames matching
|
|
106
|
+
`RelayMessageSchema` from `@generacy-ai/cluster-relay`. No custom framing,
|
|
107
|
+
no compression, no TLS in tests (fake peer is `ws://127.0.0.1:<port>`).
|
|
108
|
+
|
|
109
|
+
### Cluster → Cloud
|
|
110
|
+
|
|
111
|
+
**Gate-open event** (emitted when a `POST /cockpit/gates` succeeds). The
|
|
112
|
+
route echoes the validated `GateOpen` envelope as `data` verbatim — the
|
|
113
|
+
`kind` discriminator lives at the top of `data`, not nested under a `gate`
|
|
114
|
+
key:
|
|
115
|
+
|
|
116
|
+
```jsonc
|
|
117
|
+
{
|
|
118
|
+
"type": "event",
|
|
119
|
+
"event": "cluster.cockpit",
|
|
120
|
+
"timestamp": "2026-07-21T12:34:56.789Z",
|
|
121
|
+
"data": {
|
|
122
|
+
"kind": "gate-open",
|
|
123
|
+
"gateId": "g_…",
|
|
124
|
+
"generation": 0,
|
|
125
|
+
"scope": { "owner": "generacy-ai", "repo": "generacy", "number": 1024 },
|
|
126
|
+
"openedAt": "2026-07-21T12:00:00.000Z"
|
|
127
|
+
// …plus any passthrough keys (e.g. `payload`) — GateOpenSchema is .passthrough()
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**Gate-ack event** (emitted when a `POST /cockpit/gates/:id/ack` succeeds).
|
|
133
|
+
`data` is the validated `GateAck` envelope; the route injects the path `:id`
|
|
134
|
+
as `gateId`:
|
|
135
|
+
|
|
136
|
+
```jsonc
|
|
137
|
+
{
|
|
138
|
+
"type": "event",
|
|
139
|
+
"event": "cluster.cockpit",
|
|
140
|
+
"timestamp": "…",
|
|
141
|
+
"data": {
|
|
142
|
+
"kind": "gate-ack",
|
|
143
|
+
"gateId": "g_…",
|
|
144
|
+
"generation": 0,
|
|
145
|
+
"outcome": "answered",
|
|
146
|
+
"ackedAt": "2026-07-21T12:05:01.000Z"
|
|
147
|
+
// …plus any passthrough keys (e.g. `answer`)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Both events use `data.kind` (`"gate-open"` | `"gate-ack"`) as the
|
|
153
|
+
discriminator on the `cluster.cockpit` channel.
|
|
154
|
+
|
|
155
|
+
### Cloud → Cluster
|
|
156
|
+
|
|
157
|
+
**Answer down-path** — the cloud injects operator-authored answers into the
|
|
158
|
+
cluster via an `api_request` frame that the orchestrator proxies to its
|
|
159
|
+
`POST /cockpit/answers` route:
|
|
160
|
+
|
|
161
|
+
```jsonc
|
|
162
|
+
{
|
|
163
|
+
"type": "api_request",
|
|
164
|
+
"correlationId": "<uuid v4>",
|
|
165
|
+
"method": "POST",
|
|
166
|
+
"path": "/cockpit/answers",
|
|
167
|
+
"headers": { "content-type": "application/json" },
|
|
168
|
+
"body": {
|
|
169
|
+
"kind": "gate-answer",
|
|
170
|
+
"deliveryId": "dlv_…", // dedup key — the writer keeps one file line per deliveryId
|
|
171
|
+
"gateId": "g_…",
|
|
172
|
+
"generation": 0,
|
|
173
|
+
"answeredAt": "2026-07-21T12:05:00.000Z",
|
|
174
|
+
"answer": { /* operator's choice */ },
|
|
175
|
+
"scope": { "owner": "generacy-ai", "repo": "generacy", "number": 1024 }
|
|
176
|
+
// `answeredBy` optional
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
> **Seam pinned by the harness**: the answers route validates
|
|
182
|
+
> `GateAnswerEnvelopeSchema` (which does not require `scope`), but the doorbell
|
|
183
|
+
> tailer validates `GateAnswerLineSchema` (which does). A body **without**
|
|
184
|
+
> `scope` is written to the answers file yet silently dropped by the doorbell.
|
|
185
|
+
> `answerLineFixture()` carries `scope` so the single wire shape satisfies both
|
|
186
|
+
> ends — mirror it exactly.
|
|
187
|
+
|
|
188
|
+
Response frame (200 on happy path, `{ accepted, deduped }`; 4xx on validation
|
|
189
|
+
error):
|
|
190
|
+
|
|
191
|
+
```jsonc
|
|
192
|
+
{
|
|
193
|
+
"type": "api_response",
|
|
194
|
+
"correlationId": "<same as request>",
|
|
195
|
+
"status": 200,
|
|
196
|
+
"body": { "accepted": true, "deduped": false }
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Connection lifecycle
|
|
201
|
+
|
|
202
|
+
1. Orchestrator dials `wss://…/relay` (or `ws://127.0.0.1:<port>` in tests).
|
|
203
|
+
2. Orchestrator sends a `handshake` frame carrying its cluster metadata.
|
|
204
|
+
3. Peer responds with a `heartbeat` frame — this transitions the client from
|
|
205
|
+
`authenticating → connected`. (Fake peer mirrors this pattern; see
|
|
206
|
+
`packages/cluster-relay/tests/relay.test.ts:93-100`.)
|
|
207
|
+
4. Steady state: `event` / `api_request` / `api_response` frames in both
|
|
208
|
+
directions, `heartbeat` at the configured interval.
|
|
209
|
+
|
|
210
|
+
### Retain-and-replay across disconnect
|
|
211
|
+
|
|
212
|
+
When the peer disconnects while a `cluster.cockpit` event is pending, the
|
|
213
|
+
orchestrator retains the event and replays it on the next successful
|
|
214
|
+
connection. Mirror of the `cluster.vscode-tunnel` pattern in
|
|
215
|
+
`packages/orchestrator/src/routes/retained-tunnel-event.ts`.
|
|
216
|
+
|
|
217
|
+
Assertion pattern (harness scenario S1b): `disconnect → POST /cockpit/gates
|
|
218
|
+
→ reconnect → assert peer sees the event exactly once on the new socket`.
|
|
219
|
+
|
|
220
|
+
### Further reading
|
|
221
|
+
|
|
222
|
+
- Harness invocation and troubleshooting:
|
|
223
|
+
[`specs/1024-part-cockpit-remote-gates/quickstart.md`](../../specs/1024-part-cockpit-remote-gates/quickstart.md).
|
|
224
|
+
- Fake-peer wire contract in full:
|
|
225
|
+
[`specs/1024-part-cockpit-remote-gates/contracts/fake-peer-protocol.md`](../../specs/1024-part-cockpit-remote-gates/contracts/fake-peer-protocol.md).
|
|
226
|
+
- 8-scenario catalog:
|
|
227
|
+
[`specs/1024-part-cockpit-remote-gates/contracts/scenario-catalog.md`](../../specs/1024-part-cockpit-remote-gates/contracts/scenario-catalog.md).
|
|
228
|
+
|
|
81
229
|
## References
|
|
82
230
|
|
|
83
231
|
- Spec: [`specs/806-epic-generacy-ai-tetrad/spec.md`](../../specs/806-epic-generacy-ai-tetrad/spec.md)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A single question in a clarification-gate answer set.
|
|
3
|
+
*
|
|
4
|
+
* The canonical hash projects to only `questionNumber` + `questionText` —
|
|
5
|
+
* extra fields (e.g. drafted answers, timestamps) are stripped and MUST NOT
|
|
6
|
+
* influence gate identity. Same round of asks → same generation.
|
|
7
|
+
*/
|
|
8
|
+
export interface ClarificationQuestion {
|
|
9
|
+
questionNumber: number;
|
|
10
|
+
questionText: string;
|
|
11
|
+
}
|
|
12
|
+
export interface ComputeClarificationAnswerSetHashInput {
|
|
13
|
+
questions: readonly ClarificationQuestion[];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Canonical answer-set hash for a `clarification`-gate `generation` (#1038).
|
|
17
|
+
*
|
|
18
|
+
* Algorithm (locked by SC-002 — MUST match agency sweep byte-for-byte):
|
|
19
|
+
* 1. Sort ascending by `questionNumber`.
|
|
20
|
+
* 2. Project to exactly `{ questionNumber, questionText }` (drop any extra
|
|
21
|
+
* fields — this is the mechanical enforcement of "question identity
|
|
22
|
+
* only; drafted/pending answers excluded" per spec Q1 → A).
|
|
23
|
+
* 3. `JSON.stringify` the projected array.
|
|
24
|
+
* 4. `sha256` the canonical string.
|
|
25
|
+
* 5. Return the first 12 hex characters (48 bits — collision-safe for the
|
|
26
|
+
* population; keeps `gateKey` short in logs).
|
|
27
|
+
*
|
|
28
|
+
* Consumers pass the returned string as the `batchId` argument to
|
|
29
|
+
* `deriveClarificationGeneration({ batchId })`. Both the agency-side sweep
|
|
30
|
+
* and the cluster-side live path MUST go through this helper.
|
|
31
|
+
*/
|
|
32
|
+
export declare function computeClarificationAnswerSetHash(input: ComputeClarificationAnswerSetHashInput): string;
|
|
33
|
+
//# sourceMappingURL=clarification-hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarification-hash.d.ts","sourceRoot":"","sources":["../../src/gates/clarification-hash.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,sCAAsC;IACrD,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAC7C;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,sCAAsC,GAC5C,MAAM,CASR"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Canonical answer-set hash for a `clarification`-gate `generation` (#1038).
|
|
4
|
+
*
|
|
5
|
+
* Algorithm (locked by SC-002 — MUST match agency sweep byte-for-byte):
|
|
6
|
+
* 1. Sort ascending by `questionNumber`.
|
|
7
|
+
* 2. Project to exactly `{ questionNumber, questionText }` (drop any extra
|
|
8
|
+
* fields — this is the mechanical enforcement of "question identity
|
|
9
|
+
* only; drafted/pending answers excluded" per spec Q1 → A).
|
|
10
|
+
* 3. `JSON.stringify` the projected array.
|
|
11
|
+
* 4. `sha256` the canonical string.
|
|
12
|
+
* 5. Return the first 12 hex characters (48 bits — collision-safe for the
|
|
13
|
+
* population; keeps `gateKey` short in logs).
|
|
14
|
+
*
|
|
15
|
+
* Consumers pass the returned string as the `batchId` argument to
|
|
16
|
+
* `deriveClarificationGeneration({ batchId })`. Both the agency-side sweep
|
|
17
|
+
* and the cluster-side live path MUST go through this helper.
|
|
18
|
+
*/
|
|
19
|
+
export function computeClarificationAnswerSetHash(input) {
|
|
20
|
+
const sorted = [...input.questions].sort((a, b) => a.questionNumber - b.questionNumber);
|
|
21
|
+
const canonical = JSON.stringify(sorted.map((q) => ({
|
|
22
|
+
questionNumber: q.questionNumber,
|
|
23
|
+
questionText: q.questionText,
|
|
24
|
+
})));
|
|
25
|
+
return createHash('sha256').update(canonical, 'utf8').digest('hex').slice(0, 12);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=clarification-hash.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clarification-hash.js","sourceRoot":"","sources":["../../src/gates/clarification-hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAkBzC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,iCAAiC,CAC/C,KAA6C;IAE7C,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,cAAc,CAAC,CAAC;IACxF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAC9B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACjB,cAAc,EAAE,CAAC,CAAC,cAAc;QAChC,YAAY,EAAE,CAAC,CAAC,YAAY;KAC7B,CAAC,CAAC,CACJ,CAAC;IACF,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type GateAnswer, type GateOpen, type GateOutcome, type GateType } from './schema.js';
|
|
2
|
+
import type { ClarificationQuestion } from './clarification-hash.js';
|
|
3
|
+
export declare const VALID_FIXTURES: Record<GateType, GateOpen>;
|
|
4
|
+
export declare const VALID_ANSWER_FIXTURES: Record<GateType, GateAnswer>;
|
|
5
|
+
export declare const VALID_ACK_FIXTURES: Record<'applied' | 'superseded' | 'failed', GateOutcome>;
|
|
6
|
+
export declare const MALFORMED_FIXTURES: Record<string, unknown>;
|
|
7
|
+
export interface ClarificationAnswerSetFixture {
|
|
8
|
+
readonly questions: readonly ClarificationQuestion[];
|
|
9
|
+
}
|
|
10
|
+
export declare const CLARIFICATION_ANSWER_SET_FIXTURES: Readonly<{
|
|
11
|
+
readonly singleQuestion: ClarificationAnswerSetFixture;
|
|
12
|
+
readonly threeQuestions: ClarificationAnswerSetFixture;
|
|
13
|
+
readonly unicode: ClarificationAnswerSetFixture;
|
|
14
|
+
}>;
|
|
15
|
+
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/gates/fixtures.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,QAAQ,EACd,MAAM,aAAa,CAAC;AAYrB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAmErE,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,CASrD,CAAC;AAyCF,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,CAS9D,CAAC;AAOF,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,SAAS,GAAG,YAAY,GAAG,QAAQ,EAAE,WAAW,CAqBvF,CAAC;AAqBF,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAgDtD,CAAC;AAOF,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,SAAS,EAAE,SAAS,qBAAqB,EAAE,CAAC;CACtD;AAED,eAAO,MAAM,iCAAiC;6BAKtC,6BAA6B;6BAQ7B,6BAA6B;sBAa7B,6BAA6B;EAC1B,CAAC"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { GateAnswerSchema, GateOpenSchema, GateOutcomeSchema, deriveGateId, deriveGateKey, } from './schema.js';
|
|
2
|
+
import { issueRefToString } from './schemas.js';
|
|
3
|
+
import { deriveArtifactReviewGeneration, deriveClarificationGeneration, deriveEscalationGeneration, deriveFilingGeneration, deriveImplementationReviewGeneration, deriveManualValidationGeneration, derivePhaseQueueGeneration, deriveScopeDrainedGeneration, } from './generation.js';
|
|
4
|
+
const EPIC_REF = { owner: 'generacy-ai', repo: 'generacy', number: 1000 };
|
|
5
|
+
const ISSUE_REF = { owner: 'generacy-ai', repo: 'generacy', number: 1020 };
|
|
6
|
+
const TRACKING_REF = { owner: 'generacy-ai', repo: 'generacy', number: 900 };
|
|
7
|
+
const EPIC_REF_STR = issueRefToString(EPIC_REF);
|
|
8
|
+
const ISSUE_REF_STR = issueRefToString(ISSUE_REF);
|
|
9
|
+
const SESSION_ID = 'sess-abc123def456';
|
|
10
|
+
const ASKED_AT = '2026-07-21T12:00:00.000Z';
|
|
11
|
+
const ANSWERED_AT = '2026-07-21T12:05:00.000Z';
|
|
12
|
+
const OUTCOME_AT = '2026-07-21T12:05:01.000Z';
|
|
13
|
+
const ACTOR = {
|
|
14
|
+
userId: 'user-1',
|
|
15
|
+
email: 'operator@example.com',
|
|
16
|
+
displayName: 'Operator One',
|
|
17
|
+
};
|
|
18
|
+
const DEFAULT_OPTIONS = [
|
|
19
|
+
{ id: 'opt-a', label: 'Approve', description: 'Approve and proceed' },
|
|
20
|
+
{ id: 'opt-b', label: 'Reject', description: 'Reject and halt', recommended: true },
|
|
21
|
+
];
|
|
22
|
+
const GENERATIONS = {
|
|
23
|
+
clarification: deriveClarificationGeneration({ batchId: 'batch-abc123' }),
|
|
24
|
+
'artifact-review': deriveArtifactReviewGeneration({ kind: 'spec-review', headSha: 'abc1234' }),
|
|
25
|
+
'implementation-review': deriveImplementationReviewGeneration({ headSha: 'def5678' }),
|
|
26
|
+
'manual-validation': deriveManualValidationGeneration({ phaseNumber: 2 }),
|
|
27
|
+
escalation: deriveEscalationGeneration({
|
|
28
|
+
subtype: 'stalled',
|
|
29
|
+
labelOrState: 'agent:error',
|
|
30
|
+
counter: 1,
|
|
31
|
+
}),
|
|
32
|
+
'phase-queue': derivePhaseQueueGeneration({ phaseNumber: 3 }),
|
|
33
|
+
filing: deriveFilingGeneration({ draftHash: 'feedbeef1234' }),
|
|
34
|
+
'scope-drained': deriveScopeDrainedGeneration({ trackingIssueRef: TRACKING_REF, counter: 1 }),
|
|
35
|
+
};
|
|
36
|
+
// phase-queue is the sole per-issue exception: its wire `issueRef` slot carries
|
|
37
|
+
// the EPIC ref, not a child issue (see the auto.md UI-mode gate-mapping table).
|
|
38
|
+
function issueRefFor(gateType) {
|
|
39
|
+
return gateType === 'phase-queue' ? EPIC_REF_STR : ISSUE_REF_STR;
|
|
40
|
+
}
|
|
41
|
+
function buildRecord(gateType) {
|
|
42
|
+
const generation = GENERATIONS[gateType];
|
|
43
|
+
const issueRef = issueRefFor(gateType);
|
|
44
|
+
const gateKey = deriveGateKey(issueRef, gateType, generation);
|
|
45
|
+
const gateId = deriveGateId(gateKey);
|
|
46
|
+
return {
|
|
47
|
+
type: 'gate-open',
|
|
48
|
+
gateId,
|
|
49
|
+
gateKey,
|
|
50
|
+
gateType,
|
|
51
|
+
epicRef: EPIC_REF_STR,
|
|
52
|
+
issueRef,
|
|
53
|
+
issueTitle: `Issue #${ISSUE_REF.number}: cockpit remote gates`,
|
|
54
|
+
issueUrl: `https://github.com/${ISSUE_REF.owner}/${ISSUE_REF.repo}/issues/${ISSUE_REF.number}`,
|
|
55
|
+
title: `${gateType} gate`,
|
|
56
|
+
body: `Please review the ${gateType} gate.`,
|
|
57
|
+
options: DEFAULT_OPTIONS.map((o) => ({ ...o })),
|
|
58
|
+
allowFreeText: true,
|
|
59
|
+
sessionId: SESSION_ID,
|
|
60
|
+
askedAt: ASKED_AT,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export const VALID_FIXTURES = {
|
|
64
|
+
clarification: buildRecord('clarification'),
|
|
65
|
+
'artifact-review': buildRecord('artifact-review'),
|
|
66
|
+
'implementation-review': buildRecord('implementation-review'),
|
|
67
|
+
'manual-validation': buildRecord('manual-validation'),
|
|
68
|
+
escalation: buildRecord('escalation'),
|
|
69
|
+
'phase-queue': buildRecord('phase-queue'),
|
|
70
|
+
filing: buildRecord('filing'),
|
|
71
|
+
'scope-drained': buildRecord('scope-drained'),
|
|
72
|
+
};
|
|
73
|
+
// Assert every valid fixture parses at module load — fixture drift fails the build,
|
|
74
|
+
// not a test run.
|
|
75
|
+
for (const gateType of Object.keys(VALID_FIXTURES)) {
|
|
76
|
+
GateOpenSchema.parse(VALID_FIXTURES[gateType]);
|
|
77
|
+
}
|
|
78
|
+
// optionId XOR free-text is NOT enforced on the wire (the cloud sends the unused
|
|
79
|
+
// side as an explicit null); every fixture therefore carries both fields.
|
|
80
|
+
const ANSWER_SPECS = {
|
|
81
|
+
clarification: { optionId: 'opt-a', freeText: null },
|
|
82
|
+
'artifact-review': { optionId: null, freeText: 'approve with concerns' },
|
|
83
|
+
'implementation-review': { optionId: 'opt-a', freeText: null },
|
|
84
|
+
'manual-validation': { optionId: null, freeText: 'verified manually on 2026-07-21' },
|
|
85
|
+
escalation: { optionId: 'opt-a', freeText: null },
|
|
86
|
+
'phase-queue': { optionId: null, freeText: 'proceed with next phase' },
|
|
87
|
+
filing: { optionId: 'opt-a', freeText: null },
|
|
88
|
+
'scope-drained': { optionId: null, freeText: 'confirmed scope drained' },
|
|
89
|
+
};
|
|
90
|
+
function buildAnswer(gateType) {
|
|
91
|
+
const record = VALID_FIXTURES[gateType];
|
|
92
|
+
const spec = ANSWER_SPECS[gateType];
|
|
93
|
+
return {
|
|
94
|
+
type: 'gate-answer',
|
|
95
|
+
gateId: record.gateId,
|
|
96
|
+
gateKey: record.gateKey,
|
|
97
|
+
optionId: spec.optionId,
|
|
98
|
+
freeText: spec.freeText,
|
|
99
|
+
actor: { ...ACTOR },
|
|
100
|
+
answeredAt: ANSWERED_AT,
|
|
101
|
+
deliveryId: `delivery-${gateType}-1`,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
export const VALID_ANSWER_FIXTURES = {
|
|
105
|
+
clarification: buildAnswer('clarification'),
|
|
106
|
+
'artifact-review': buildAnswer('artifact-review'),
|
|
107
|
+
'implementation-review': buildAnswer('implementation-review'),
|
|
108
|
+
'manual-validation': buildAnswer('manual-validation'),
|
|
109
|
+
escalation: buildAnswer('escalation'),
|
|
110
|
+
'phase-queue': buildAnswer('phase-queue'),
|
|
111
|
+
filing: buildAnswer('filing'),
|
|
112
|
+
'scope-drained': buildAnswer('scope-drained'),
|
|
113
|
+
};
|
|
114
|
+
for (const gateType of Object.keys(VALID_ANSWER_FIXTURES)) {
|
|
115
|
+
GateAnswerSchema.parse(VALID_ANSWER_FIXTURES[gateType]);
|
|
116
|
+
}
|
|
117
|
+
// gate-outcome (the ACK) fixtures — one per closed outcome enum value.
|
|
118
|
+
export const VALID_ACK_FIXTURES = {
|
|
119
|
+
applied: {
|
|
120
|
+
type: 'gate-outcome',
|
|
121
|
+
gateId: VALID_FIXTURES.clarification.gateId,
|
|
122
|
+
outcome: 'applied',
|
|
123
|
+
at: OUTCOME_AT,
|
|
124
|
+
},
|
|
125
|
+
superseded: {
|
|
126
|
+
type: 'gate-outcome',
|
|
127
|
+
gateId: VALID_FIXTURES['artifact-review'].gateId,
|
|
128
|
+
outcome: 'superseded',
|
|
129
|
+
detail: 'A newer answer arrived first',
|
|
130
|
+
at: OUTCOME_AT,
|
|
131
|
+
},
|
|
132
|
+
failed: {
|
|
133
|
+
type: 'gate-outcome',
|
|
134
|
+
gateId: VALID_FIXTURES.escalation.gateId,
|
|
135
|
+
outcome: 'failed',
|
|
136
|
+
detail: 'Label mutation returned 422',
|
|
137
|
+
at: OUTCOME_AT,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
for (const key of Object.keys(VALID_ACK_FIXTURES)) {
|
|
141
|
+
GateOutcomeSchema.parse(VALID_ACK_FIXTURES[key]);
|
|
142
|
+
}
|
|
143
|
+
const BASE_RECORD_UNKNOWN = VALID_FIXTURES.clarification;
|
|
144
|
+
const BASE_ANSWER_UNKNOWN = VALID_ANSWER_FIXTURES.clarification;
|
|
145
|
+
function withoutKey(obj, key) {
|
|
146
|
+
const clone = { ...obj };
|
|
147
|
+
delete clone[key];
|
|
148
|
+
return clone;
|
|
149
|
+
}
|
|
150
|
+
export const MALFORMED_FIXTURES = {
|
|
151
|
+
// Wrong up-path discriminator (must be the 'gate-open' literal).
|
|
152
|
+
'wrong-type-literal': {
|
|
153
|
+
...BASE_RECORD_UNKNOWN,
|
|
154
|
+
type: 'gate-ack',
|
|
155
|
+
},
|
|
156
|
+
// Option missing its required `id` (description is OPTIONAL in the frozen shape).
|
|
157
|
+
'option-missing-id': {
|
|
158
|
+
...BASE_RECORD_UNKNOWN,
|
|
159
|
+
options: [{ label: 'Approve' }],
|
|
160
|
+
},
|
|
161
|
+
// allowFreeText is a REQUIRED boolean — a non-boolean must reject.
|
|
162
|
+
'allow-free-text-non-boolean': {
|
|
163
|
+
...BASE_RECORD_UNKNOWN,
|
|
164
|
+
allowFreeText: 'yes',
|
|
165
|
+
},
|
|
166
|
+
// gateId is pinned to exactly 24 chars.
|
|
167
|
+
'empty-gate-id': {
|
|
168
|
+
...BASE_RECORD_UNKNOWN,
|
|
169
|
+
gateId: '',
|
|
170
|
+
},
|
|
171
|
+
'wrong-length-gate-id': {
|
|
172
|
+
...BASE_RECORD_UNKNOWN,
|
|
173
|
+
gateId: '0123456789abcdef0123', // 20 chars
|
|
174
|
+
},
|
|
175
|
+
'unknown-gate-type': {
|
|
176
|
+
...BASE_RECORD_UNKNOWN,
|
|
177
|
+
gateType: 'not-a-real-gate-type',
|
|
178
|
+
},
|
|
179
|
+
'invalid-issue-url': {
|
|
180
|
+
...BASE_RECORD_UNKNOWN,
|
|
181
|
+
issueUrl: 'not-a-url',
|
|
182
|
+
},
|
|
183
|
+
'naive-timestamp': {
|
|
184
|
+
...BASE_RECORD_UNKNOWN,
|
|
185
|
+
askedAt: 'Tue Jul 21 2026 12:00:00 GMT+0000',
|
|
186
|
+
},
|
|
187
|
+
'record-missing-title': withoutKey(BASE_RECORD_UNKNOWN, 'title'),
|
|
188
|
+
// Down-path: actor.email must be a valid email OR null; a malformed string rejects.
|
|
189
|
+
'answer-invalid-email': {
|
|
190
|
+
...BASE_ANSWER_UNKNOWN,
|
|
191
|
+
actor: { ...ACTOR, email: 'not-an-email' },
|
|
192
|
+
},
|
|
193
|
+
// Down-path: wrong discriminator (must be the 'gate-answer' literal).
|
|
194
|
+
'answer-wrong-type-literal': {
|
|
195
|
+
...BASE_ANSWER_UNKNOWN,
|
|
196
|
+
type: 'gate-open',
|
|
197
|
+
},
|
|
198
|
+
};
|
|
199
|
+
export const CLARIFICATION_ANSWER_SET_FIXTURES = Object.freeze({
|
|
200
|
+
singleQuestion: Object.freeze({
|
|
201
|
+
questions: Object.freeze([
|
|
202
|
+
Object.freeze({ questionNumber: 1, questionText: 'Which auth method?' }),
|
|
203
|
+
]),
|
|
204
|
+
}),
|
|
205
|
+
// Deliberately out-of-order to prove sort determinism (SC-002).
|
|
206
|
+
threeQuestions: Object.freeze({
|
|
207
|
+
questions: Object.freeze([
|
|
208
|
+
Object.freeze({ questionNumber: 3, questionText: 'Timezone?' }),
|
|
209
|
+
Object.freeze({ questionNumber: 1, questionText: 'Which auth method?' }),
|
|
210
|
+
Object.freeze({ questionNumber: 2, questionText: 'Which DB?' }),
|
|
211
|
+
]),
|
|
212
|
+
}),
|
|
213
|
+
// Non-ASCII bytes to exercise UTF-8 canonicalization end to end.
|
|
214
|
+
unicode: Object.freeze({
|
|
215
|
+
questions: Object.freeze([
|
|
216
|
+
Object.freeze({
|
|
217
|
+
questionNumber: 1,
|
|
218
|
+
questionText: 'Préférence pour l’heure locale? 🌍',
|
|
219
|
+
}),
|
|
220
|
+
Object.freeze({
|
|
221
|
+
questionNumber: 2,
|
|
222
|
+
questionText: '中文文本 — 数据库偏好?',
|
|
223
|
+
}),
|
|
224
|
+
]),
|
|
225
|
+
}),
|
|
226
|
+
});
|
|
227
|
+
//# sourceMappingURL=fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/gates/fixtures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Back-compat shim. Canonical gateKey/gateId derivation now lives in
|
|
3
|
+
* `./schema.ts` — the single source. Prefer importing `deriveGateKey` /
|
|
4
|
+
* `deriveGateId` from `./schema.js` (or the package index).
|
|
5
|
+
*
|
|
6
|
+
* NOTE the signature moved: `deriveGateKey(issueRef: string, gateType, generation)`
|
|
7
|
+
* now takes the FLAT `owner/repo#N` ref string, not an object. Use
|
|
8
|
+
* `issueRefToString` (schemas.ts) to convert an object ref first.
|
|
9
|
+
*/
|
|
10
|
+
export { deriveGateKey, deriveGateId } from './schema.js';
|
|
11
|
+
//# sourceMappingURL=gate-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-id.d.ts","sourceRoot":"","sources":["../../src/gates/gate-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Back-compat shim. Canonical gateKey/gateId derivation now lives in
|
|
3
|
+
* `./schema.ts` — the single source. Prefer importing `deriveGateKey` /
|
|
4
|
+
* `deriveGateId` from `./schema.js` (or the package index).
|
|
5
|
+
*
|
|
6
|
+
* NOTE the signature moved: `deriveGateKey(issueRef: string, gateType, generation)`
|
|
7
|
+
* now takes the FLAT `owner/repo#N` ref string, not an object. Use
|
|
8
|
+
* `issueRefToString` (schemas.ts) to convert an object ref first.
|
|
9
|
+
*/
|
|
10
|
+
export { deriveGateKey, deriveGateId } from './schema.js';
|
|
11
|
+
//# sourceMappingURL=gate-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-id.js","sourceRoot":"","sources":["../../src/gates/gate-id.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { IssueRef } from './schemas.js';
|
|
2
|
+
import type { ArtifactReviewKind } from './types.js';
|
|
3
|
+
export interface ClarificationGenerationInput {
|
|
4
|
+
batchId: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function deriveClarificationGeneration(input: ClarificationGenerationInput): string;
|
|
7
|
+
export interface ArtifactReviewGenerationInput {
|
|
8
|
+
kind: ArtifactReviewKind;
|
|
9
|
+
headSha: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function deriveArtifactReviewGeneration(input: ArtifactReviewGenerationInput): string;
|
|
12
|
+
export interface ImplementationReviewGenerationInput {
|
|
13
|
+
headSha: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function deriveImplementationReviewGeneration(input: ImplementationReviewGenerationInput): string;
|
|
16
|
+
export interface ManualValidationGenerationInput {
|
|
17
|
+
phaseNumber: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function deriveManualValidationGeneration(input: ManualValidationGenerationInput): string;
|
|
20
|
+
export interface EscalationGenerationInput {
|
|
21
|
+
subtype: string;
|
|
22
|
+
labelOrState: string;
|
|
23
|
+
counter: number;
|
|
24
|
+
}
|
|
25
|
+
export declare function deriveEscalationGeneration(input: EscalationGenerationInput): string;
|
|
26
|
+
export interface PhaseQueueGenerationInput {
|
|
27
|
+
phaseNumber: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function derivePhaseQueueGeneration(input: PhaseQueueGenerationInput): string;
|
|
30
|
+
export interface FilingGenerationInput {
|
|
31
|
+
draftHash: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function deriveFilingGeneration(input: FilingGenerationInput): string;
|
|
34
|
+
export interface ScopeDrainedGenerationInput {
|
|
35
|
+
trackingIssueRef: IssueRef;
|
|
36
|
+
counter: number;
|
|
37
|
+
}
|
|
38
|
+
export declare function deriveScopeDrainedGeneration(input: ScopeDrainedGenerationInput): string;
|
|
39
|
+
//# sourceMappingURL=generation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../src/gates/generation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAIrD,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,4BAA4B,GAAG,MAAM,CAEzF;AAED,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,6BAA6B,GAAG,MAAM,CAE3F;AAED,MAAM,WAAW,mCAAmC;IAClD,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,mCAAmC,GACzC,MAAM,CAER;AAED,MAAM,WAAW,+BAA+B;IAC9C,WAAW,EAAE,MAAM,CAAC;CACrB;AACD,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,+BAA+B,GACrC,MAAM,CAER;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,yBAAyB,GAAG,MAAM,CAEnF;AAED,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,MAAM,CAAC;CACrB;AACD,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,yBAAyB,GAAG,MAAM,CAEnF;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAE3E;AAED,MAAM,WAAW,2BAA2B;IAC1C,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,2BAA2B,GAAG,MAAM,CAGvF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// #1038 — the canonical `batchId` construction path is
|
|
2
|
+
// `computeClarificationAnswerSetHash` in ./clarification-hash.ts. This helper's
|
|
3
|
+
// signature is intentionally unchanged (additive, not breaking); consumers on
|
|
4
|
+
// the sweep and live paths call the hash helper first and pass its 12-hex
|
|
5
|
+
// output as `batchId` to keep sweep-derived and live-derived gateIds coalesced.
|
|
6
|
+
export function deriveClarificationGeneration(input) {
|
|
7
|
+
return input.batchId;
|
|
8
|
+
}
|
|
9
|
+
export function deriveArtifactReviewGeneration(input) {
|
|
10
|
+
return `${input.kind}:${input.headSha}`;
|
|
11
|
+
}
|
|
12
|
+
export function deriveImplementationReviewGeneration(input) {
|
|
13
|
+
return input.headSha;
|
|
14
|
+
}
|
|
15
|
+
export function deriveManualValidationGeneration(input) {
|
|
16
|
+
return String(input.phaseNumber);
|
|
17
|
+
}
|
|
18
|
+
export function deriveEscalationGeneration(input) {
|
|
19
|
+
return `${input.subtype}:${input.labelOrState}:${input.counter}`;
|
|
20
|
+
}
|
|
21
|
+
export function derivePhaseQueueGeneration(input) {
|
|
22
|
+
return String(input.phaseNumber);
|
|
23
|
+
}
|
|
24
|
+
export function deriveFilingGeneration(input) {
|
|
25
|
+
return input.draftHash;
|
|
26
|
+
}
|
|
27
|
+
export function deriveScopeDrainedGeneration(input) {
|
|
28
|
+
const { trackingIssueRef, counter } = input;
|
|
29
|
+
return `${trackingIssueRef.owner}/${trackingIssueRef.repo}#${trackingIssueRef.number}:${counter}`;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=generation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generation.js","sourceRoot":"","sources":["../../src/gates/generation.ts"],"names":[],"mappings":"AAQA,uDAAuD;AACvD,gFAAgF;AAChF,8EAA8E;AAC9E,0EAA0E;AAC1E,gFAAgF;AAChF,MAAM,UAAU,6BAA6B,CAAC,KAAmC;IAC/E,OAAO,KAAK,CAAC,OAAO,CAAC;AACvB,CAAC;AAMD,MAAM,UAAU,8BAA8B,CAAC,KAAoC;IACjF,OAAO,GAAG,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;AAC1C,CAAC;AAKD,MAAM,UAAU,oCAAoC,CAClD,KAA0C;IAE1C,OAAO,KAAK,CAAC,OAAO,CAAC;AACvB,CAAC;AAKD,MAAM,UAAU,gCAAgC,CAC9C,KAAsC;IAEtC,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AAOD,MAAM,UAAU,0BAA0B,CAAC,KAAgC;IACzE,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;AACnE,CAAC;AAKD,MAAM,UAAU,0BAA0B,CAAC,KAAgC;IACzE,OAAO,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AACnC,CAAC;AAKD,MAAM,UAAU,sBAAsB,CAAC,KAA4B;IACjE,OAAO,KAAK,CAAC,SAAS,CAAC;AACzB,CAAC;AAMD,MAAM,UAAU,4BAA4B,CAAC,KAAkC;IAC7E,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC5C,OAAO,GAAG,gBAAgB,CAAC,KAAK,IAAI,gBAAgB,CAAC,IAAI,IAAI,gBAAgB,CAAC,MAAM,IAAI,OAAO,EAAE,CAAC;AACpG,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { GateOpenSchema, GateOutcomeSchema, GateAnswerSchema, type GateOpen, type GateOutcome, type GateAnswer, GateTypeSchema, GateOptionSchema, type GateType, type GateOption, deriveGateKey, deriveGateId, } from './schema.js';
|
|
2
|
+
/** The 8 gate-type values as a readonly tuple (single source: GateTypeSchema). */
|
|
3
|
+
export declare const GATE_TYPES: ["clarification", "artifact-review", "implementation-review", "manual-validation", "escalation", "phase-queue", "filing", "scope-drained"];
|
|
4
|
+
export { IssueRefSchema, issueRefToString, type IssueRef, } from './schemas.js';
|
|
5
|
+
export { ArtifactReviewKindSchema, ARTIFACT_REVIEW_KINDS, type ArtifactReviewKind, } from './types.js';
|
|
6
|
+
export { deriveClarificationGeneration, deriveArtifactReviewGeneration, deriveImplementationReviewGeneration, deriveManualValidationGeneration, deriveEscalationGeneration, derivePhaseQueueGeneration, deriveFilingGeneration, deriveScopeDrainedGeneration, type ClarificationGenerationInput, type ArtifactReviewGenerationInput, type ImplementationReviewGenerationInput, type ManualValidationGenerationInput, type EscalationGenerationInput, type PhaseQueueGenerationInput, type FilingGenerationInput, type ScopeDrainedGenerationInput, } from './generation.js';
|
|
7
|
+
export { computeClarificationAnswerSetHash, type ClarificationQuestion, type ComputeClarificationAnswerSetHashInput, } from './clarification-hash.js';
|
|
8
|
+
export { VALID_FIXTURES, MALFORMED_FIXTURES, VALID_ANSWER_FIXTURES, VALID_ACK_FIXTURES, CLARIFICATION_ANSWER_SET_FIXTURES, type ClarificationAnswerSetFixture, } from './fixtures.js';
|
|
9
|
+
export { gateOpenFixture, gateOutcomeFixture, answerLineFixture, DEFAULT_WIRE_SCOPE, DEFAULT_WIRE_EPIC_REF, type WireScope, type GateOpenFixtureOverrides, type GateOutcomeFixtureOverrides, type AnswerLineFixtureOverrides, } from './wire-fixtures.js';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/gates/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,cAAc,EACd,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,UAAU,EAEf,cAAc,EACd,gBAAgB,EAChB,KAAK,QAAQ,EACb,KAAK,UAAU,EAEf,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AAIrB,kFAAkF;AAClF,eAAO,MAAM,UAAU,4IAAyB,CAAC;AAEjD,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,KAAK,QAAQ,GACd,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,kBAAkB,GACxB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,EAC9B,oCAAoC,EACpC,gCAAgC,EAChC,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACtB,4BAA4B,EAC5B,KAAK,4BAA4B,EACjC,KAAK,6BAA6B,EAClC,KAAK,mCAAmC,EACxC,KAAK,+BAA+B,EACpC,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,GACjC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,iCAAiC,EACjC,KAAK,qBAAqB,EAC1B,KAAK,sCAAsC,GAC5C,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,iCAAiC,EACjC,KAAK,6BAA6B,GACnC,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,SAAS,EACd,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,GAChC,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Canonical cockpit gate wire contract — single source is ./schema.ts.
|
|
2
|
+
// See tetrad-development/docs/cockpit-remote-gates-plan.md § "Wire contracts".
|
|
3
|
+
export {
|
|
4
|
+
// Wire shapes (the frozen contract, Shapes 1/2/3)
|
|
5
|
+
GateOpenSchema, GateOutcomeSchema, GateAnswerSchema,
|
|
6
|
+
// Enum + option
|
|
7
|
+
GateTypeSchema, GateOptionSchema,
|
|
8
|
+
// gateKey/gateId derivation
|
|
9
|
+
deriveGateKey, deriveGateId, } from './schema.js';
|
|
10
|
+
import { GateTypeSchema } from './schema.js';
|
|
11
|
+
/** The 8 gate-type values as a readonly tuple (single source: GateTypeSchema). */
|
|
12
|
+
export const GATE_TYPES = GateTypeSchema.options;
|
|
13
|
+
export { IssueRefSchema, issueRefToString, } from './schemas.js';
|
|
14
|
+
export { ArtifactReviewKindSchema, ARTIFACT_REVIEW_KINDS, } from './types.js';
|
|
15
|
+
export { deriveClarificationGeneration, deriveArtifactReviewGeneration, deriveImplementationReviewGeneration, deriveManualValidationGeneration, deriveEscalationGeneration, derivePhaseQueueGeneration, deriveFilingGeneration, deriveScopeDrainedGeneration, } from './generation.js';
|
|
16
|
+
export { computeClarificationAnswerSetHash, } from './clarification-hash.js';
|
|
17
|
+
export { VALID_FIXTURES, MALFORMED_FIXTURES, VALID_ANSWER_FIXTURES, VALID_ACK_FIXTURES, CLARIFICATION_ANSWER_SET_FIXTURES, } from './fixtures.js';
|
|
18
|
+
export { gateOpenFixture, gateOutcomeFixture, answerLineFixture, DEFAULT_WIRE_SCOPE, DEFAULT_WIRE_EPIC_REF, } from './wire-fixtures.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/gates/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,+EAA+E;AAE/E,OAAO;AACL,kDAAkD;AAClD,cAAc,EACd,iBAAiB,EACjB,gBAAgB;AAIhB,gBAAgB;AAChB,cAAc,EACd,gBAAgB;AAGhB,4BAA4B;AAC5B,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,kFAAkF;AAClF,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC;AAEjD,OAAO,EACL,cAAc,EACd,gBAAgB,GAEjB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,wBAAwB,EACxB,qBAAqB,GAEtB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,6BAA6B,EAC7B,8BAA8B,EAC9B,oCAAoC,EACpC,gCAAgC,EAChC,0BAA0B,EAC1B,0BAA0B,EAC1B,sBAAsB,EACtB,4BAA4B,GAS7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,iCAAiC,GAGlC,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,qBAAqB,EACrB,kBAAkB,EAClB,iCAAiC,GAElC,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,GAKtB,MAAM,oBAAoB,CAAC"}
|