@telora/daemon 0.22.181 → 0.22.187
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/build-info.json +9 -3
- package/dist/audit/audit-floor-policy.d.ts +188 -0
- package/dist/audit/audit-floor-policy.d.ts.map +1 -0
- package/dist/audit/audit-floor-policy.js +353 -0
- package/dist/audit/audit-floor-policy.js.map +1 -0
- package/dist/audit/audit-prompt.d.ts +4 -177
- package/dist/audit/audit-prompt.d.ts.map +1 -1
- package/dist/audit/audit-prompt.js +6 -329
- package/dist/audit/audit-prompt.js.map +1 -1
- package/dist/completion/escalations.d.ts.map +1 -1
- package/dist/completion/escalations.js +3 -1
- package/dist/completion/escalations.js.map +1 -1
- package/dist/focus/focus-executor.d.ts.map +1 -1
- package/dist/focus/focus-executor.js +2 -0
- package/dist/focus/focus-executor.js.map +1 -1
- package/dist/focus/session-health.d.ts.map +1 -1
- package/dist/focus/session-health.js +2 -1
- package/dist/focus/session-health.js.map +1 -1
- package/dist/focus-stage-lifecycle/planning-release.d.ts +52 -17
- package/dist/focus-stage-lifecycle/planning-release.d.ts.map +1 -1
- package/dist/focus-stage-lifecycle/planning-release.js +58 -70
- package/dist/focus-stage-lifecycle/planning-release.js.map +1 -1
- package/dist/focus-stage-lifecycle/ratify-bar-gate.d.ts +108 -0
- package/dist/focus-stage-lifecycle/ratify-bar-gate.d.ts.map +1 -0
- package/dist/focus-stage-lifecycle/ratify-bar-gate.js +174 -0
- package/dist/focus-stage-lifecycle/ratify-bar-gate.js.map +1 -0
- package/dist/git/merge-to-main.d.ts.map +1 -1
- package/dist/git/merge-to-main.js.map +1 -1
- package/dist/nexus/index.d.ts.map +1 -1
- package/dist/nexus/index.js +2 -1
- package/dist/nexus/index.js.map +1 -1
- package/dist/nexus/intake-prompt-sections.d.ts +70 -0
- package/dist/nexus/intake-prompt-sections.d.ts.map +1 -0
- package/dist/nexus/intake-prompt-sections.js +145 -0
- package/dist/nexus/intake-prompt-sections.js.map +1 -0
- package/dist/nexus/intake-spawn.d.ts +49 -13
- package/dist/nexus/intake-spawn.d.ts.map +1 -1
- package/dist/nexus/intake-spawn.js +45 -122
- package/dist/nexus/intake-spawn.js.map +1 -1
- package/dist/nexus/intake.d.ts +55 -0
- package/dist/nexus/intake.d.ts.map +1 -1
- package/dist/nexus/intake.js +62 -1
- package/dist/nexus/intake.js.map +1 -1
- package/dist/prd/arm-readiness.d.ts +93 -0
- package/dist/prd/arm-readiness.d.ts.map +1 -0
- package/dist/prd/arm-readiness.js +254 -0
- package/dist/prd/arm-readiness.js.map +1 -0
- package/dist/prd/arm-refusal.d.ts +149 -0
- package/dist/prd/arm-refusal.d.ts.map +1 -0
- package/dist/prd/arm-refusal.js +219 -0
- package/dist/prd/arm-refusal.js.map +1 -0
- package/dist/prd/controller-shared.d.ts +111 -0
- package/dist/prd/controller-shared.d.ts.map +1 -1
- package/dist/prd/controller-shared.js +3 -1
- package/dist/prd/controller-shared.js.map +1 -1
- package/dist/prd/controller.d.ts +16 -10
- package/dist/prd/controller.d.ts.map +1 -1
- package/dist/prd/controller.js +28 -35
- package/dist/prd/controller.js.map +1 -1
- package/dist/prd/frontier-arming.d.ts +151 -0
- package/dist/prd/frontier-arming.d.ts.map +1 -0
- package/dist/prd/frontier-arming.js +315 -0
- package/dist/prd/frontier-arming.js.map +1 -0
- package/dist/prd/index.d.ts +10 -1
- package/dist/prd/index.d.ts.map +1 -1
- package/dist/prd/index.js +9 -1
- package/dist/prd/index.js.map +1 -1
- package/dist/prd/scoping-prompt.d.ts +68 -0
- package/dist/prd/scoping-prompt.d.ts.map +1 -0
- package/dist/prd/scoping-prompt.js +86 -0
- package/dist/prd/scoping-prompt.js.map +1 -0
- package/dist/prompt/prompt-contradictions.d.ts +20 -1
- package/dist/prompt/prompt-contradictions.d.ts.map +1 -1
- package/dist/prompt/prompt-contradictions.js +35 -0
- package/dist/prompt/prompt-contradictions.js.map +1 -1
- package/dist/prompt/team-prompt-base.d.ts +18 -0
- package/dist/prompt/team-prompt-base.d.ts.map +1 -1
- package/dist/prompt/team-prompt-base.js +56 -11
- package/dist/prompt/team-prompt-base.js.map +1 -1
- package/dist/prompt-sections/persona-sections.d.ts +36 -13
- package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
- package/dist/prompt-sections/persona-sections.js +93 -16
- package/dist/prompt-sections/persona-sections.js.map +1 -1
- package/dist/prompt-sections/scoping-sections.d.ts +19 -5
- package/dist/prompt-sections/scoping-sections.d.ts.map +1 -1
- package/dist/prompt-sections/scoping-sections.js +45 -38
- package/dist/prompt-sections/scoping-sections.js.map +1 -1
- package/dist/prompt-sections/shared.d.ts +8 -0
- package/dist/prompt-sections/shared.d.ts.map +1 -1
- package/dist/prompt-sections/shared.js.map +1 -1
- package/dist/queries/focus-criteria-standing.d.ts +170 -7
- package/dist/queries/focus-criteria-standing.d.ts.map +1 -1
- package/dist/queries/focus-criteria-standing.js +143 -8
- package/dist/queries/focus-criteria-standing.js.map +1 -1
- package/dist/queries/focus-ratify-release.d.ts +43 -0
- package/dist/queries/focus-ratify-release.d.ts.map +1 -0
- package/dist/queries/focus-ratify-release.js +45 -0
- package/dist/queries/focus-ratify-release.js.map +1 -0
- package/dist/queries/focuses.d.ts +0 -10
- package/dist/queries/focuses.d.ts.map +1 -1
- package/dist/queries/focuses.js +0 -14
- package/dist/queries/focuses.js.map +1 -1
- package/dist/queries/prd.d.ts +31 -0
- package/dist/queries/prd.d.ts.map +1 -1
- package/dist/queries/prd.js +26 -1
- package/dist/queries/prd.js.map +1 -1
- package/dist/queries/shared.js +1 -1
- package/dist/resolvers/focus-criteria-standing.d.ts.map +1 -1
- package/dist/resolvers/focus-criteria-standing.js +324 -25
- package/dist/resolvers/focus-criteria-standing.js.map +1 -1
- package/dist/security/security-auto-inject.d.ts +51 -0
- package/dist/security/security-auto-inject.d.ts.map +1 -1
- package/dist/security/security-auto-inject.js +101 -11
- package/dist/security/security-auto-inject.js.map +1 -1
- package/dist/security/security-scan-engine.d.ts +4 -4
- package/dist/security/security-scan-engine.d.ts.map +1 -1
- package/dist/security/security-scan-engine.js +6 -0
- package/dist/security/security-scan-engine.js.map +1 -1
- package/dist/session/session-lineage.d.ts.map +1 -1
- package/dist/session/session-lineage.js +2 -0
- package/dist/session/session-lineage.js.map +1 -1
- package/dist/shell/constants.d.ts +5 -0
- package/dist/shell/constants.d.ts.map +1 -1
- package/dist/shell/constants.js +5 -0
- package/dist/shell/constants.js.map +1 -1
- package/dist/shell/daemon-instance.d.ts +74 -64
- package/dist/shell/daemon-instance.d.ts.map +1 -1
- package/dist/shell/daemon-instance.js +16 -121
- package/dist/shell/daemon-instance.js.map +1 -1
- package/dist/shell/health-events.js +1 -1
- package/dist/shell/health-events.js.map +1 -1
- package/dist/shell/instance-liveness.d.ts +112 -0
- package/dist/shell/instance-liveness.d.ts.map +1 -0
- package/dist/shell/instance-liveness.js +205 -0
- package/dist/shell/instance-liveness.js.map +1 -0
- package/dist/shell/schema-version-gate.d.ts +22 -0
- package/dist/shell/schema-version-gate.d.ts.map +1 -1
- package/dist/shell/schema-version-gate.js +116 -6
- package/dist/shell/schema-version-gate.js.map +1 -1
- package/dist/shell/worker-pidfile.d.ts +21 -8
- package/dist/shell/worker-pidfile.d.ts.map +1 -1
- package/dist/shell/worker-pidfile.js +38 -9
- package/dist/shell/worker-pidfile.js.map +1 -1
- package/dist/spawn/lead-launch.d.ts.map +1 -1
- package/dist/spawn/lead-launch.js +2 -1
- package/dist/spawn/lead-launch.js.map +1 -1
- package/dist/spawn/one-shot-scoping-spawn.d.ts +51 -0
- package/dist/spawn/one-shot-scoping-spawn.d.ts.map +1 -0
- package/dist/spawn/one-shot-scoping-spawn.js +156 -0
- package/dist/spawn/one-shot-scoping-spawn.js.map +1 -0
- package/dist/spawn/process-spawn.d.ts +12 -0
- package/dist/spawn/process-spawn.d.ts.map +1 -1
- package/dist/spawn/process-spawn.js +1 -1
- package/dist/spawn/process-spawn.js.map +1 -1
- package/dist/spawn/prompt-assembly.d.ts +8 -0
- package/dist/spawn/prompt-assembly.d.ts.map +1 -1
- package/dist/spawn/prompt-assembly.js +15 -3
- package/dist/spawn/prompt-assembly.js.map +1 -1
- package/dist/spawn/worktree-session.d.ts +24 -6
- package/dist/spawn/worktree-session.d.ts.map +1 -1
- package/dist/spawn/worktree-session.js +37 -14
- package/dist/spawn/worktree-session.js.map +1 -1
- package/dist/testing/arm-coverage-model.d.ts +75 -0
- package/dist/testing/arm-coverage-model.d.ts.map +1 -0
- package/dist/testing/arm-coverage-model.js +114 -0
- package/dist/testing/arm-coverage-model.js.map +1 -0
- package/dist/testing/fixtures/index.js +1 -1
- package/dist/types/index.js +1 -1
- package/dist/verify/verification-boundary-env.d.ts +7 -2
- package/dist/verify/verification-boundary-env.d.ts.map +1 -1
- package/dist/verify/verification-boundary-env.js +9 -4
- package/dist/verify/verification-boundary-env.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,42 +1,19 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by:
|
|
2
|
+
// Pinned by: packages/daemon/src/nexus/nexus-intake-arm-covers-stated-effects.test.ts,
|
|
3
|
+
// packages/daemon/src/spawn/one-shot-scoping-spawn.test.ts
|
|
3
4
|
// PINNED-BY-END
|
|
5
|
+
import { SCOPING_AGENT_TIMEOUT_MS, spawnOneShotScopingAgent, } from '../spawn/one-shot-scoping-spawn.js';
|
|
6
|
+
import { renderContractRules, renderObservationSection, renderScopingSteps, } from './intake-prompt-sections.js';
|
|
7
|
+
/** Logger module tag for this caller's scoping-agent lines. */
|
|
8
|
+
const LOG_MODULE = 'nexus-intake';
|
|
4
9
|
/**
|
|
5
|
-
*
|
|
10
|
+
* Kill the scoping agent if it has not exited within this window (15 minutes).
|
|
6
11
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* acceptanceContract and the role UUID to assign; its sole job is:
|
|
11
|
-
*
|
|
12
|
-
* 1. telora_product_focus create -- a per-request focus named from the request,
|
|
13
|
-
* then assign it the intake role so the spawn loop picks it up.
|
|
14
|
-
* 2. telora_reality_tree create + author nodes/edges -- the acceptanceContract
|
|
15
|
-
* becomes the goal / desired-effect the tree drives toward.
|
|
16
|
-
* 3. telora_product_delivery create -- injection-anchored deliveries.
|
|
17
|
-
* 4. telora_product_request materialize -- stamp the new focus (+ a
|
|
18
|
-
* representative delivery) back on the request so it leaves the
|
|
19
|
-
* intake-pending set and advances accepted -> in_progress.
|
|
20
|
-
* 5. exit.
|
|
21
|
-
*
|
|
22
|
-
* Mirrors spawn/lifecycle.ts spawnResolutionAgent (the merge-conflict resolution agent): a
|
|
23
|
-
* one-shot `--print` Claude Code process, prompt passed as a CLI arg, cleaned
|
|
24
|
-
* env, a kill timeout, no team mode and no streaming. It makes NO git changes
|
|
25
|
-
* (MCP calls only), so it runs in the product repo (config.repoPath) where the
|
|
26
|
-
* per-product .mcp.json + CLAUDE.md live -- no isolated worktree required.
|
|
27
|
-
*
|
|
28
|
-
* FIRE-AND-FORGET: the scoping agent runs for minutes; spawnScopingAgent resolves
|
|
29
|
-
* the moment the process has spawned (the 'spawn' event), NOT on close, so the
|
|
30
|
-
* daemon poll loop is never blocked. The close/error handlers only log; the
|
|
31
|
-
* intake_scoping_started_at stamp (written by the caller before this spawn) is
|
|
32
|
-
* the in-flight guard that prevents a re-spawn until the staleness window.
|
|
12
|
+
* An alias of the shared one-shot timeout, kept under its original name because
|
|
13
|
+
* DEFAULT_INTAKE_STALE_MS is documented and tested as strictly greater than it
|
|
14
|
+
* (`nexus-intake.test.ts`) -- the relation is intake's, the number is shared.
|
|
33
15
|
*/
|
|
34
|
-
|
|
35
|
-
import { stripClaudeCodeEnvVars } from '@telora/daemon-core';
|
|
36
|
-
import { createLogger } from '../shell/log.js';
|
|
37
|
-
const log = createLogger({ module: 'nexus-intake' });
|
|
38
|
-
/** Kill the scoping agent if it has not exited within this window (15 minutes). */
|
|
39
|
-
export const INTAKE_SCOPING_TIMEOUT_MS = 15 * 60 * 1000;
|
|
16
|
+
export const INTAKE_SCOPING_TIMEOUT_MS = SCOPING_AGENT_TIMEOUT_MS;
|
|
40
17
|
/**
|
|
41
18
|
* Build the scoping prompt seeded with the request + acceptanceContract + the
|
|
42
19
|
* role to assign. Pure (string) so it is unit-tested without spawning a process.
|
|
@@ -45,119 +22,65 @@ export function buildIntakeScopingPrompt(req, roleId) {
|
|
|
45
22
|
const title = req.title ?? '(untitled request)';
|
|
46
23
|
const acceptanceContract = req.acceptanceContract ?? '(no acceptance contract supplied)';
|
|
47
24
|
const description = req.description ?? '(no description supplied)';
|
|
25
|
+
const targetProductId = req.targetProductId ?? '(unknown)';
|
|
26
|
+
const observation = req.observation ?? null;
|
|
27
|
+
const hasObservation = observation !== null;
|
|
48
28
|
// Stable marker embedded in the focus description so a re-spawn (after a
|
|
49
29
|
// crashed prior run) can find and REUSE the focus this request already
|
|
50
30
|
// authored instead of creating a duplicate.
|
|
51
31
|
const marker = `Nexus request: ${req.id}`;
|
|
52
|
-
|
|
32
|
+
const sections = [
|
|
53
33
|
`You are the nexus-intake SCOPING agent for an accepted cross-product (Nexus) request.`,
|
|
54
34
|
`Your SOLE job is to author a per-request focus for this product's team to execute, then exit.`,
|
|
55
35
|
`You author intent + structure via the telora_* MCP tools only -- you write NO application code here.`,
|
|
56
36
|
``,
|
|
57
37
|
`## The accepted request`,
|
|
58
38
|
`- requestId: ${req.id}`,
|
|
59
|
-
`- targetProductId (THIS product -- author the focus here): ${
|
|
39
|
+
`- targetProductId (THIS product -- author the focus here): ${targetProductId}`,
|
|
60
40
|
`- title: ${title}`,
|
|
61
41
|
`- description: ${description}`,
|
|
62
42
|
``,
|
|
63
|
-
|
|
43
|
+
// Renders nothing at all when the request carries no observation.
|
|
44
|
+
renderObservationSection(observation),
|
|
45
|
+
hasObservation
|
|
46
|
+
? `## Acceptance contract (the BAR your derived future must clear -- NOT the tree to build)`
|
|
47
|
+
: `## Acceptance contract (the goal / definition of done)`,
|
|
64
48
|
acceptanceContract,
|
|
65
49
|
``,
|
|
66
50
|
`## IDEMPOTENCY (read first -- a previous scoping run for this request may have crashed)`,
|
|
67
51
|
`Before creating anything, telora_product_focus list (productId = ${req.targetProductId ?? '<targetProductId>'}) and look for a focus whose description carries the marker "${marker}".`,
|
|
68
|
-
`- If one EXISTS, a prior run already created it. REUSE it: skip step 1 (create), and resume from whichever later step is unfinished
|
|
52
|
+
`- If one EXISTS, a prior run already created it. REUSE it: skip step 1 (create), and resume from whichever later step is unfinished, checking them IN ORDER (materialized? tree built? deliveries created + second materialize?). The LAST unfinished step to check for is the ARM: a marked focus with assignedAgentRoleId still null is a run that crashed before arming -- finish every earlier step first, then arm. Do NOT create a second focus.`,
|
|
69
53
|
`- If none exists, start at step 1.`,
|
|
70
54
|
``,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
55
|
+
renderScopingSteps({
|
|
56
|
+
requestId: req.id,
|
|
57
|
+
title,
|
|
58
|
+
targetProductId,
|
|
59
|
+
roleId,
|
|
60
|
+
marker,
|
|
61
|
+
hasObservation,
|
|
62
|
+
}),
|
|
79
63
|
``,
|
|
64
|
+
renderContractRules(req.id, hasObservation),
|
|
80
65
|
`Refer to focuses/deliveries/issues by title in any prose, never by UUID. Follow CLAUDE.md.`,
|
|
81
|
-
]
|
|
66
|
+
];
|
|
67
|
+
// A section that rendered to nothing leaves an empty string in place; joining
|
|
68
|
+
// and collapsing runs of blank lines is what makes its absence invisible --
|
|
69
|
+
// no gap a reader could mistake for a heading that failed to render.
|
|
70
|
+
return sections.join('\n').replace(/\n{3,}/g, '\n\n');
|
|
82
71
|
}
|
|
83
|
-
const defaultSeam = {
|
|
84
|
-
spawnProcess: (command, args, cwd, env) => spawn(command, args, { cwd, env, stdio: ['pipe', 'pipe', 'pipe'] }),
|
|
85
|
-
};
|
|
86
72
|
/**
|
|
87
73
|
* Spawn the intake scoping agent for one accepted request. Resolves once the
|
|
88
74
|
* process has SPAWNED (fire-and-forget -- the agent runs for minutes); rejects
|
|
89
|
-
* only if the process fails to spawn. The
|
|
90
|
-
*
|
|
75
|
+
* only if the process fails to spawn. The shared seam logs the outcome and its
|
|
76
|
+
* kill timeout bounds a hung agent.
|
|
91
77
|
*/
|
|
92
|
-
export function spawnScopingAgent(config, req, roleId, seam
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
];
|
|
100
|
-
const env = stripClaudeCodeEnvVars(process.env);
|
|
101
|
-
const cwd = config.repoPath ?? process.cwd();
|
|
102
|
-
return new Promise((resolve, reject) => {
|
|
103
|
-
let settled = false;
|
|
104
|
-
let proc;
|
|
105
|
-
try {
|
|
106
|
-
proc = seam.spawnProcess(config.claudeCodePath, args, cwd, env);
|
|
107
|
-
}
|
|
108
|
-
catch (err) {
|
|
109
|
-
reject(err instanceof Error ? err : new Error(String(err)));
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
// Prompt is a CLI arg; close stdin immediately.
|
|
113
|
-
proc.stdin?.end?.();
|
|
114
|
-
const timeout = setTimeout(() => {
|
|
115
|
-
log.warn(`scoping agent for request ${req.id} timed out after ${INTAKE_SCOPING_TIMEOUT_MS / 1000}s, killing`);
|
|
116
|
-
if (proc.pid) {
|
|
117
|
-
try {
|
|
118
|
-
process.kill(proc.pid, 'SIGTERM');
|
|
119
|
-
}
|
|
120
|
-
catch { /* ignore */ }
|
|
121
|
-
setTimeout(() => {
|
|
122
|
-
if (proc.pid) {
|
|
123
|
-
try {
|
|
124
|
-
process.kill(proc.pid, 'SIGKILL');
|
|
125
|
-
}
|
|
126
|
-
catch { /* ignore */ }
|
|
127
|
-
}
|
|
128
|
-
}, 10_000);
|
|
129
|
-
}
|
|
130
|
-
}, INTAKE_SCOPING_TIMEOUT_MS);
|
|
131
|
-
// Do not let the kill timer keep the daemon event loop alive.
|
|
132
|
-
timeout.unref?.();
|
|
133
|
-
proc.on('spawn', () => {
|
|
134
|
-
// Process is up -- the daemon poll continues; the agent runs to completion
|
|
135
|
-
// in the background.
|
|
136
|
-
log.info(`scoping agent spawned for request ${req.id} (PID: ${proc.pid ?? '?'})`);
|
|
137
|
-
if (!settled) {
|
|
138
|
-
settled = true;
|
|
139
|
-
resolve();
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
proc.on('close', (code) => {
|
|
143
|
-
clearTimeout(timeout);
|
|
144
|
-
log.info(`scoping agent for request ${req.id} exited (code: ${code ?? '?'})`);
|
|
145
|
-
// If 'spawn' never fired (very early exit), still resolve -- the stamp guard
|
|
146
|
-
// already prevents an immediate re-spawn.
|
|
147
|
-
if (!settled) {
|
|
148
|
-
settled = true;
|
|
149
|
-
resolve();
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
proc.on('error', (err) => {
|
|
153
|
-
clearTimeout(timeout);
|
|
154
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
155
|
-
log.error(`scoping agent spawn error for request ${req.id}: ${message}`);
|
|
156
|
-
if (!settled) {
|
|
157
|
-
settled = true;
|
|
158
|
-
reject(new Error(message));
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
});
|
|
78
|
+
export function spawnScopingAgent(config, req, roleId, seam) {
|
|
79
|
+
return spawnOneShotScopingAgent(config, {
|
|
80
|
+
label: `request ${req.id}`,
|
|
81
|
+
prompt: buildIntakeScopingPrompt(req, roleId),
|
|
82
|
+
logModule: LOG_MODULE,
|
|
83
|
+
timeoutMs: INTAKE_SCOPING_TIMEOUT_MS,
|
|
84
|
+
}, seam);
|
|
162
85
|
}
|
|
163
86
|
//# sourceMappingURL=intake-spawn.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intake-spawn.js","sourceRoot":"","sources":["../../src/nexus/intake-spawn.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"intake-spawn.js","sourceRoot":"","sources":["../../src/nexus/intake-spawn.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,uFAAuF;AACvF,6DAA6D;AAC7D,gBAAgB;AA2ChB,OAAO,EACL,wBAAwB,EACxB,wBAAwB,GAEzB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AAErC,+DAA+D;AAC/D,MAAM,UAAU,GAAG,cAAc,CAAC;AAElC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,wBAAwB,CAAC;AAMlE;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAyB,EAAE,MAAc;IAChF,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,IAAI,oBAAoB,CAAC;IAChD,MAAM,kBAAkB,GAAG,GAAG,CAAC,kBAAkB,IAAI,mCAAmC,CAAC;IACzF,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,IAAI,2BAA2B,CAAC;IACnE,MAAM,eAAe,GAAG,GAAG,CAAC,eAAe,IAAI,WAAW,CAAC;IAC3D,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC;IAC5C,MAAM,cAAc,GAAG,WAAW,KAAK,IAAI,CAAC;IAC5C,yEAAyE;IACzE,uEAAuE;IACvE,4CAA4C;IAC5C,MAAM,MAAM,GAAG,kBAAkB,GAAG,CAAC,EAAE,EAAE,CAAC;IAE1C,MAAM,QAAQ,GAAG;QACf,uFAAuF;QACvF,+FAA+F;QAC/F,sGAAsG;QACtG,EAAE;QACF,yBAAyB;QACzB,gBAAgB,GAAG,CAAC,EAAE,EAAE;QACxB,8DAA8D,eAAe,EAAE;QAC/E,YAAY,KAAK,EAAE;QACnB,kBAAkB,WAAW,EAAE;QAC/B,EAAE;QACF,kEAAkE;QAClE,wBAAwB,CAAC,WAAW,CAAC;QACrC,cAAc;YACZ,CAAC,CAAC,0FAA0F;YAC5F,CAAC,CAAC,wDAAwD;QAC5D,kBAAkB;QAClB,EAAE;QACF,yFAAyF;QACzF,oEAAoE,GAAG,CAAC,eAAe,IAAI,mBAAmB,gEAAgE,MAAM,IAAI;QACxL,wbAAwb;QACxb,oCAAoC;QACpC,EAAE;QACF,kBAAkB,CAAC;YACjB,SAAS,EAAE,GAAG,CAAC,EAAE;YACjB,KAAK;YACL,eAAe;YACf,MAAM;YACN,MAAM;YACN,cAAc;SACf,CAAC;QACF,EAAE;QACF,mBAAmB,CAAC,GAAG,CAAC,EAAE,EAAE,cAAc,CAAC;QAC3C,4FAA4F;KAC7F,CAAC;IACF,8EAA8E;IAC9E,4EAA4E;IAC5E,qEAAqE;IACrE,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACxD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAoB,EACpB,GAAyB,EACzB,MAAc,EACd,IAAuB;IAEvB,OAAO,wBAAwB,CAC7B,MAAM,EACN;QACE,KAAK,EAAE,WAAW,GAAG,CAAC,EAAE,EAAE;QAC1B,MAAM,EAAE,wBAAwB,CAAC,GAAG,EAAE,MAAM,CAAC;QAC7C,SAAS,EAAE,UAAU;QACrB,SAAS,EAAE,yBAAyB;KACrC,EACD,IAAI,CACL,CAAC;AACJ,CAAC"}
|
package/dist/nexus/intake.d.ts
CHANGED
|
@@ -68,6 +68,29 @@ export declare const MAX_INTAKE_SPAWNS_PER_CYCLE = 5;
|
|
|
68
68
|
* Minimal shape of an intake-pending product_request (camelCase from the edge
|
|
69
69
|
* fn). Defensive: the daemon must not assume any optional field is present.
|
|
70
70
|
*/
|
|
71
|
+
/** One node of the observation fragment, as product-api serves it. */
|
|
72
|
+
export interface IntakeObservationNode {
|
|
73
|
+
nodeId: string;
|
|
74
|
+
seq: number;
|
|
75
|
+
nodeType: string;
|
|
76
|
+
statement: string;
|
|
77
|
+
evidence: string | null;
|
|
78
|
+
frtStatement: string | null;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* What the REQUESTER observed, carried on the request: the undesired effect the
|
|
82
|
+
* request asks to be cleared, plus its upstream causes and their evidence. This
|
|
83
|
+
* is the material the target's intake authors its own CRT from -- without it,
|
|
84
|
+
* the only thing intake has to build from is the acceptance contract, and a
|
|
85
|
+
* contract is a statement of the desired FUTURE, so building downward from it
|
|
86
|
+
* produces a tree of the requester's mechanism and never reaches the cause.
|
|
87
|
+
*/
|
|
88
|
+
export interface IntakeObservation {
|
|
89
|
+
sourceNode: IntakeObservationNode;
|
|
90
|
+
upstreamCauses: IntakeObservationNode[];
|
|
91
|
+
/** True when a cap stopped the walk -- the fragment is partial and says so. */
|
|
92
|
+
truncated: boolean;
|
|
93
|
+
}
|
|
71
94
|
export interface IntakePendingRequest {
|
|
72
95
|
id: string;
|
|
73
96
|
targetProductId?: string | null;
|
|
@@ -77,7 +100,39 @@ export interface IntakePendingRequest {
|
|
|
77
100
|
title?: string | null;
|
|
78
101
|
description?: string | null;
|
|
79
102
|
acceptanceContract?: string | null;
|
|
103
|
+
/** The UDE in the requester's tree this request is born from, when it has one. */
|
|
104
|
+
sourceNodeId?: string | null;
|
|
105
|
+
/**
|
|
106
|
+
* The SNAPSHOT stored on the request at create, carried by the list page the
|
|
107
|
+
* poll already fetches -- no second read per request, and no walk of the
|
|
108
|
+
* requester's tree from here at all.
|
|
109
|
+
*
|
|
110
|
+
* Absent -- not an empty fragment -- for an endpoint-typed request or one
|
|
111
|
+
* raised before requests carried one, so the prompt renders nothing rather
|
|
112
|
+
* than a placeholder that reads as content. Absent ALONGSIDE a sourceNodeId
|
|
113
|
+
* is a different thing entirely, and never scoped: see `isScopable`.
|
|
114
|
+
*/
|
|
115
|
+
observation?: IntakeObservation | null;
|
|
80
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Why this request cannot be scoped from its observation, or null if it can.
|
|
119
|
+
*
|
|
120
|
+
* Only source-backed requests are judged. An endpoint-typed request carries no
|
|
121
|
+
* observation BY DESIGN and scopes from its contract; so does a request raised
|
|
122
|
+
* before requests carried one. Neither is a defect, and neither is held.
|
|
123
|
+
*
|
|
124
|
+
* A source-backed request is different in kind. Its contract was DERIVED from a
|
|
125
|
+
* node, the prompt tells the agent to build its CRT from that node's evidence
|
|
126
|
+
* and to mirror the effect, and the materialize gate then judges the plan
|
|
127
|
+
* against the mirror. Hand that agent the contract alone and every one of those
|
|
128
|
+
* steps is missing -- which is the precise shape this focus exists to delete, so
|
|
129
|
+
* it is not something to arrive at by falling back.
|
|
130
|
+
*
|
|
131
|
+
* The check is deliberately shallow: the fields the prompt actually renders.
|
|
132
|
+
* Validating more would reject rows the prompt could use; validating less would
|
|
133
|
+
* spawn an agent to read an empty heading.
|
|
134
|
+
*/
|
|
135
|
+
export declare function observationDefect(req: IntakePendingRequest): string | null;
|
|
81
136
|
/** What the gate decides for one request. */
|
|
82
137
|
export type IntakeDecision = 'spawn' | 'in_flight' | 'skip';
|
|
83
138
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../src/nexus/intake.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"intake.d.ts","sourceRoot":"","sources":["../../src/nexus/intake.ts"],"names":[],"mappings":"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"}
|
package/dist/nexus/intake.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// PINNED-BY-BEGIN (generated by gen:pinned-by -- do not hand-edit; checked by lint:pinned-by)
|
|
2
|
-
// Pinned by:
|
|
2
|
+
// Pinned by: packages/daemon/src/nexus/nexus-intake-arm-covers-stated-effects.test.ts,
|
|
3
|
+
// packages/daemon/src/spawn/one-shot-scoping-spawn.test.ts
|
|
3
4
|
// PINNED-BY-END
|
|
4
5
|
import { callApi } from '../queries/shared.js';
|
|
5
6
|
import { getAgentRoles } from '../queries/roles.js';
|
|
@@ -65,6 +66,47 @@ export const DEFAULT_INTAKE_STALE_MS = 20 * 60 * 1000;
|
|
|
65
66
|
* rate-limited. Surfaced via a log line so the cap is never silent.
|
|
66
67
|
*/
|
|
67
68
|
export const MAX_INTAKE_SPAWNS_PER_CYCLE = 5;
|
|
69
|
+
/** A usable observation node: both fields the prompt renders must be real text. */
|
|
70
|
+
function isObservationNode(value) {
|
|
71
|
+
if (typeof value !== 'object' || value === null)
|
|
72
|
+
return false;
|
|
73
|
+
const n = value;
|
|
74
|
+
return typeof n.nodeId === 'string' && n.nodeId !== ''
|
|
75
|
+
&& typeof n.statement === 'string' && n.statement !== '';
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Why this request cannot be scoped from its observation, or null if it can.
|
|
79
|
+
*
|
|
80
|
+
* Only source-backed requests are judged. An endpoint-typed request carries no
|
|
81
|
+
* observation BY DESIGN and scopes from its contract; so does a request raised
|
|
82
|
+
* before requests carried one. Neither is a defect, and neither is held.
|
|
83
|
+
*
|
|
84
|
+
* A source-backed request is different in kind. Its contract was DERIVED from a
|
|
85
|
+
* node, the prompt tells the agent to build its CRT from that node's evidence
|
|
86
|
+
* and to mirror the effect, and the materialize gate then judges the plan
|
|
87
|
+
* against the mirror. Hand that agent the contract alone and every one of those
|
|
88
|
+
* steps is missing -- which is the precise shape this focus exists to delete, so
|
|
89
|
+
* it is not something to arrive at by falling back.
|
|
90
|
+
*
|
|
91
|
+
* The check is deliberately shallow: the fields the prompt actually renders.
|
|
92
|
+
* Validating more would reject rows the prompt could use; validating less would
|
|
93
|
+
* spawn an agent to read an empty heading.
|
|
94
|
+
*/
|
|
95
|
+
export function observationDefect(req) {
|
|
96
|
+
if (!req.sourceNodeId)
|
|
97
|
+
return null;
|
|
98
|
+
const obs = req.observation;
|
|
99
|
+
if (obs === null || obs === undefined) {
|
|
100
|
+
return 'it carries no observation snapshot';
|
|
101
|
+
}
|
|
102
|
+
if (!isObservationNode(obs.sourceNode)) {
|
|
103
|
+
return 'its observation has no readable source node';
|
|
104
|
+
}
|
|
105
|
+
if (!Array.isArray(obs.upstreamCauses) || !obs.upstreamCauses.every(isObservationNode)) {
|
|
106
|
+
return 'its observation has a malformed upstream cause';
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
68
110
|
/**
|
|
69
111
|
* Pure intake gate. A request needs a scoping spawn when it is accepted, not yet
|
|
70
112
|
* materialized, and either has never been spawned or its last spawn is stale.
|
|
@@ -178,6 +220,25 @@ export async function checkIntakePendingRequests(config, deps = defaultNexusInta
|
|
|
178
220
|
return;
|
|
179
221
|
}
|
|
180
222
|
for (const req of batch) {
|
|
223
|
+
// A source-backed request whose observation is missing or malformed is NOT
|
|
224
|
+
// scoped, and nothing about it is stamped. Degrading to the no-observation
|
|
225
|
+
// prompt was the old behaviour and it is unrecoverable: the prompt's first
|
|
226
|
+
// materialize moves the request to in_progress, which removes it from the
|
|
227
|
+
// intake-pending set forever, and the second materialize is then held for a
|
|
228
|
+
// mirror the agent was never told to create. One transient read, and the
|
|
229
|
+
// request is permanently stuck in exactly the contract-seeded,
|
|
230
|
+
// observation-free shape this whole focus exists to delete.
|
|
231
|
+
//
|
|
232
|
+
// Skipping leaves the request retryable BY CONSTRUCTION: it stays accepted
|
|
233
|
+
// with no materialized focus, so it is intake-pending again on the very
|
|
234
|
+
// next tick, with no stale stamp to wait out.
|
|
235
|
+
const defect = observationDefect(req);
|
|
236
|
+
if (defect) {
|
|
237
|
+
log(`[nexus-intake] NOT scoping request ${req.id} (product ${productId}): ${defect}. ` +
|
|
238
|
+
`It names a source node, so it must be scoped from its observation -- ` +
|
|
239
|
+
`left intake-pending for the next tick.`);
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
181
242
|
try {
|
|
182
243
|
// Stamp BEFORE the spawn so a slow/failed spawn does not re-fire next tick;
|
|
183
244
|
// a stale stamp re-arms it after staleMs.
|
package/dist/nexus/intake.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/nexus/intake.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,
|
|
1
|
+
{"version":3,"file":"intake.js","sourceRoot":"","sources":["../../src/nexus/intake.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/** A delivery as this check reads it. */
|
|
2
|
+
export interface ArmReadinessDelivery {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
/**
|
|
6
|
+
* The delivery's execution status. Nullable on the wire; a null status is
|
|
7
|
+
* NOT 'cancelled', so it counts as live -- the bar below turns on the anchor
|
|
8
|
+
* and the restatements, and a missing status must not silently drop a
|
|
9
|
+
* delivery out of the evidence.
|
|
10
|
+
*/
|
|
11
|
+
executionStatus: string | null;
|
|
12
|
+
/** The injection the delivery is anchored to, or null when unanchored. */
|
|
13
|
+
injectionId: string | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* One effect an injection promises to flip: the node id, and the restatement
|
|
17
|
+
* declared on it (`frt_statement`), or null when none was declared.
|
|
18
|
+
*/
|
|
19
|
+
export interface ArmReadinessTarget {
|
|
20
|
+
nodeId: string;
|
|
21
|
+
frtStatement: string | null;
|
|
22
|
+
}
|
|
23
|
+
/** The answer, with the reason it came out that way (logged, never escalated). */
|
|
24
|
+
export interface FocusArmReadiness {
|
|
25
|
+
ready: boolean;
|
|
26
|
+
/** Human-readable why -- goes straight into the daemon log line. */
|
|
27
|
+
reason: string;
|
|
28
|
+
/** The anchored deliveries that met the bar (empty when not ready). */
|
|
29
|
+
readyDeliveryIds: string[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The bar, PURE. `targetsByInjectionId` maps each anchored delivery's injection
|
|
33
|
+
* to the effects it promises to flip.
|
|
34
|
+
*
|
|
35
|
+
* A delivery is COUNTED when it is anchored, not cancelled, and its injection's
|
|
36
|
+
* targets all carry a restatement. An injection with NO targets is not counted:
|
|
37
|
+
* "every target carries a restatement" is vacuously true of an empty set, and
|
|
38
|
+
* an arm over an empty set is precisely the zero-effect arm this check refuses.
|
|
39
|
+
*/
|
|
40
|
+
export declare function assessArmReadiness(deliveries: ArmReadinessDelivery[], targetsByInjectionId: Map<string, ArmReadinessTarget[]>): FocusArmReadiness;
|
|
41
|
+
/** The reads this check needs (injected so it is testable without the API). */
|
|
42
|
+
export interface ArmReadinessDeps {
|
|
43
|
+
loadDeliveries?: (focusId: string) => Promise<ArmReadinessDelivery[]>;
|
|
44
|
+
loadTargetsByInjectionId?: (injectionIds: string[]) => Promise<Map<string, ArmReadinessTarget[]>>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Read a focus's arm readiness. NEVER throws: an unreadable input answers "not
|
|
48
|
+
* ready" with the failure as its reason, and the caller logs it and re-tries on
|
|
49
|
+
* a later tick. Nothing is escalated -- an unscoped focus is a waiting state,
|
|
50
|
+
* not an incident.
|
|
51
|
+
*/
|
|
52
|
+
export declare function readFocusArmReadiness(focusId: string, deps?: ArmReadinessDeps): Promise<FocusArmReadiness>;
|
|
53
|
+
/**
|
|
54
|
+
* What a live read of the focus's covered effects says about its bar.
|
|
55
|
+
*
|
|
56
|
+
* `readable` is carried separately from `statesABar` on purpose: "the tree says
|
|
57
|
+
* this focus states nothing" and "I could not read the tree" are the same
|
|
58
|
+
* DECISION (hold) and completely different FACTS. A caller that records the
|
|
59
|
+
* first as an operator-facing refusal must not record the second as one.
|
|
60
|
+
*/
|
|
61
|
+
export interface FocusBarStanding {
|
|
62
|
+
/** True only when the covered set holds >= 1 effect and none is unstated. */
|
|
63
|
+
statesABar: boolean;
|
|
64
|
+
/** False when a read failed; the verdict is then a hold, not a finding. */
|
|
65
|
+
readable: boolean;
|
|
66
|
+
/** Human-readable why -- goes straight into a log line or a record. */
|
|
67
|
+
reason: string;
|
|
68
|
+
/** Covered undesired effects, however they stand. */
|
|
69
|
+
coveredEffectCount: number;
|
|
70
|
+
/** The covered effects whose `frt_statement` is null or blank. */
|
|
71
|
+
unstatedNodeIds: string[];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The database's rule, PURE, over the same inputs `assessArmReadiness` reads.
|
|
75
|
+
*
|
|
76
|
+
* Mirrors `stamp_focus_arm_baseline()` / `focus_arm_baseline_snapshot()`: the
|
|
77
|
+
* covered set is the union of every non-cancelled anchored delivery's injection
|
|
78
|
+
* targets (the injection-context read's `nowTargets`, which reports the
|
|
79
|
+
* UNDESIRED EFFECT targets -- the same node type the trigger counts), it must be
|
|
80
|
+
* non-empty, and every member must carry a non-blank restatement.
|
|
81
|
+
*
|
|
82
|
+
* It is a PRE-CHECK, never the authority: the trigger derives its own answer at
|
|
83
|
+
* the instant of the write, and the two are read seconds apart. A caller still
|
|
84
|
+
* handles the refusal arriving anyway.
|
|
85
|
+
*/
|
|
86
|
+
export declare function assessFocusStatesABar(deliveries: ArmReadinessDelivery[], targetsByInjectionId: Map<string, ArmReadinessTarget[]>): FocusBarStanding;
|
|
87
|
+
/**
|
|
88
|
+
* Read whether a focus states a bar, live. NEVER throws: an unreadable input
|
|
89
|
+
* answers `{ statesABar: false, readable: false }` with the failure as its
|
|
90
|
+
* reason, so the caller holds rather than crossing on an unproven bar.
|
|
91
|
+
*/
|
|
92
|
+
export declare function readFocusStatesABar(focusId: string, deps?: ArmReadinessDeps): Promise<FocusBarStanding>;
|
|
93
|
+
//# sourceMappingURL=arm-readiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"arm-readiness.d.ts","sourceRoot":"","sources":["../../src/prd/arm-readiness.ts"],"names":[],"mappings":"AAoEA,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,0EAA0E;IAC1E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,kFAAkF;AAClF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AAQD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,oBAAoB,EAAE,EAClC,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,GACtD,iBAAiB,CA8BnB;AAED,+EAA+E;AAC/E,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACtE,wBAAwB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;CACnG;AAyCD;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,iBAAiB,CAAC,CAoB5B;AAKD;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,UAAU,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;IAClB,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kEAAkE;IAClE,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,oBAAoB,EAAE,EAClC,oBAAoB,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,GACtD,gBAAgB,CA0ClB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAsB3B"}
|