@lazyingart/agintiflow 0.20.242 → 0.20.243
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/docs/deep-research-engine.md +13 -1
- package/package.json +4 -2
- package/scripts/smoke-deep-research.js +46 -1
- package/scripts/smoke-dynamic-step-budget.js +12 -0
- package/scripts/smoke-integration-production-mount.js +33 -0
- package/scripts/smoke-integration-production-runtime-bundle.js +398 -0
- package/scripts/smoke-integration-retained-event-ledger-bundle.js +6 -1
- package/scripts/smoke-integration-retained-native-session-repository-state.js +13 -0
- package/scripts/smoke-integration-retained-session-state-store.js +21 -3
- package/scripts/smoke-progressive-tool-selection.js +26 -0
- package/src/agent-runner.js +3 -1
- package/src/deep-research.js +2 -1
- package/src/integration-cli.js +12 -2
- package/src/integration-event-ledger-store.js +2 -2
- package/src/integration-production-runtime-bundle.js +931 -0
- package/src/research-routing.js +37 -18
|
@@ -10,6 +10,15 @@ Simple questions should stay on the fast path. A deep-research run spends more
|
|
|
10
10
|
queries and model calls only when breadth, verification, and traceability add
|
|
11
11
|
real value.
|
|
12
12
|
|
|
13
|
+
For a request that combines local workspace evidence with web research, the
|
|
14
|
+
outer agent first receives normal inspection tools. After it has read two
|
|
15
|
+
relevant files, or read one file plus inspected/searched the project, the next
|
|
16
|
+
research turn is constrained to `deep_research` and `finish`. This keeps local
|
|
17
|
+
notes authoritative without letting an agent silently replace a requested
|
|
18
|
+
multi-source review with ad hoc browsing. Tool history is scoped to the newest
|
|
19
|
+
genuine user request, so a completed research call from an older task does not
|
|
20
|
+
suppress a later correction or refresh.
|
|
21
|
+
|
|
13
22
|
## Architecture
|
|
14
23
|
|
|
15
24
|
The implementation follows the strongest production patterns without making
|
|
@@ -205,7 +214,10 @@ To resume a partial or completed same-query run, pass the returned
|
|
|
205
214
|
`refresh=true` is explicit. A transient run that retrieved zero allowed sources
|
|
206
215
|
is marked failed, preserves its attempts, and retries retrieval on resume
|
|
207
216
|
instead of caching an empty report as success. Checkpoint schema changes
|
|
208
|
-
invalidate old cached runs automatically.
|
|
217
|
+
invalidate old cached runs automatically. The public tool result also carries
|
|
218
|
+
the research schema version; the outer session reuses a completed result only
|
|
219
|
+
when that version matches the installed engine. Versionless or older retained
|
|
220
|
+
results are refreshed instead of being presented as current evidence.
|
|
209
221
|
|
|
210
222
|
`outputPath` is optional and must name a Markdown file inside the active
|
|
211
223
|
workspace. Repository internals such as `.git`, dependency trees such as
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lazyingart/agintiflow",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.243",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AgInTiFlow is a project-aware agent workspace for hybrid wet-dry R&D, hardware-aware intelligence, software automation, and industrial workflows.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"scripts/supervision-ledger.js",
|
|
67
67
|
"scripts/smoke-supervision-ledger.js",
|
|
68
68
|
"scripts/smoke-integration-production-mount.js",
|
|
69
|
+
"scripts/smoke-integration-production-runtime-bundle.js",
|
|
69
70
|
"scripts/smoke-integration-storage-authority.js",
|
|
70
71
|
"scripts/smoke-integration-retained-durable-common.js",
|
|
71
72
|
"scripts/smoke-integration-retained-file-lock.js",
|
|
@@ -203,6 +204,7 @@
|
|
|
203
204
|
"supervision:ledger": "node scripts/supervision-ledger.js",
|
|
204
205
|
"smoke:supervision-ledger": "node scripts/smoke-supervision-ledger.js",
|
|
205
206
|
"smoke:integration-production-mount": "node scripts/smoke-integration-production-mount.js",
|
|
207
|
+
"smoke:integration-production-runtime-bundle": "node scripts/smoke-integration-production-runtime-bundle.js",
|
|
206
208
|
"smoke:integration-storage-authority": "node scripts/smoke-integration-storage-authority.js",
|
|
207
209
|
"smoke:integration-retained-durable-common": "node scripts/smoke-integration-retained-durable-common.js",
|
|
208
210
|
"smoke:integration-retained-file-lock": "node scripts/smoke-integration-retained-file-lock.js",
|
|
@@ -219,7 +221,7 @@
|
|
|
219
221
|
"storage:migrate": "node bin/aginti-cli.js storage migrate",
|
|
220
222
|
"publish:env": "node scripts/npm-publish-from-env.js publish --access public",
|
|
221
223
|
"publish:env:whoami": "node scripts/npm-publish-from-env.js whoami",
|
|
222
|
-
"test": "npm run check && npm run smoke:integration-production-mount && npm run smoke:integration-storage-authority && npm run smoke:integration-retained-durable-common && npm run smoke:integration-retained-file-lock && npm run smoke:integration-retained-event-ledger && npm run smoke:integration-retained-event-ledger-bundle && npm run smoke:integration-retained-repository-kernel && npm run smoke:integration-retained-session-state-store && npm run smoke:integration-retained-native-session-repository-state && npm run smoke:integration-retained-native-execution-evidence && npm run smoke:integration-retained-runtime-repository-surface && npm run smoke:integration-retained-runtime-repository-phase-b && npm run smoke:integration-runtime-repository-contract && npm run smoke:integration-runtime-authority && npm run smoke:localllm-provider && npm run smoke:localllm-model-tiers && npm run smoke:localllm-code-routing && npm run smoke:local-failure-recovery && npm run smoke:localllm-auto-max && npm run smoke:local-resource-policy && npm run smoke:context-budget-recovery && npm run smoke:session-runtime && npm run smoke:runtime-core && npm run smoke:progressive-tools && npm run smoke:truthful-completion && npm run smoke:document-artifact-quality && npm run smoke:writing-specialist-routing && npm run eval:local-first-agent && npm run eval:provider-attribution && npm run smoke:runtime-compat && npm run smoke:autoupdate && npm run smoke:web-api && npm run smoke:math-rendering && npm run smoke:web-ui && npm run smoke:web-autostart && npm run smoke:webapp-command && npm run smoke:web-port-fallback && npm run smoke:docker-command && npm run smoke:coding-tools && npm run smoke:dynamic-step-budget && npm run smoke:execution-policy && npm run smoke:aaps-adapter && npm run smoke:auxiliary-tools && npm run smoke:perception-research && npm run smoke:deep-research && npm run smoke:public-research && npm run smoke:safe-chat && npm run smoke:auth && npm run smoke:agentlink && npm run smoke:canvas-artifacts && npm run smoke:capabilities && npm run smoke:mcp && npm run smoke:model-roles && npm run smoke:platform && npm run smoke:permission-modes && npm run smoke:skills && npm run smoke:skillmesh && npm run smoke:supervision-ledger && npm run smoke:tmux-tools && npm run smoke:long-jobs && npm run smoke:run-stdin && npm run smoke:cli-chat && npm run smoke:inbox",
|
|
224
|
+
"test": "npm run check && npm run smoke:integration-production-mount && npm run smoke:integration-production-runtime-bundle && npm run smoke:integration-storage-authority && npm run smoke:integration-retained-durable-common && npm run smoke:integration-retained-file-lock && npm run smoke:integration-retained-event-ledger && npm run smoke:integration-retained-event-ledger-bundle && npm run smoke:integration-retained-repository-kernel && npm run smoke:integration-retained-session-state-store && npm run smoke:integration-retained-native-session-repository-state && npm run smoke:integration-retained-native-execution-evidence && npm run smoke:integration-retained-runtime-repository-surface && npm run smoke:integration-retained-runtime-repository-phase-b && npm run smoke:integration-runtime-repository-contract && npm run smoke:integration-runtime-authority && npm run smoke:localllm-provider && npm run smoke:localllm-model-tiers && npm run smoke:localllm-code-routing && npm run smoke:local-failure-recovery && npm run smoke:localllm-auto-max && npm run smoke:local-resource-policy && npm run smoke:context-budget-recovery && npm run smoke:session-runtime && npm run smoke:runtime-core && npm run smoke:progressive-tools && npm run smoke:truthful-completion && npm run smoke:document-artifact-quality && npm run smoke:writing-specialist-routing && npm run eval:local-first-agent && npm run eval:provider-attribution && npm run smoke:runtime-compat && npm run smoke:autoupdate && npm run smoke:web-api && npm run smoke:math-rendering && npm run smoke:web-ui && npm run smoke:web-autostart && npm run smoke:webapp-command && npm run smoke:web-port-fallback && npm run smoke:docker-command && npm run smoke:coding-tools && npm run smoke:dynamic-step-budget && npm run smoke:execution-policy && npm run smoke:aaps-adapter && npm run smoke:auxiliary-tools && npm run smoke:perception-research && npm run smoke:deep-research && npm run smoke:public-research && npm run smoke:safe-chat && npm run smoke:auth && npm run smoke:agentlink && npm run smoke:canvas-artifacts && npm run smoke:capabilities && npm run smoke:mcp && npm run smoke:model-roles && npm run smoke:platform && npm run smoke:permission-modes && npm run smoke:skills && npm run smoke:skillmesh && npm run smoke:supervision-ledger && npm run smoke:tmux-tools && npm run smoke:long-jobs && npm run smoke:run-stdin && npm run smoke:cli-chat && npm run smoke:inbox",
|
|
223
225
|
"pack:dry-run": "npm pack --dry-run",
|
|
224
226
|
"smoke:capabilities": "node scripts/smoke-capabilities.js"
|
|
225
227
|
},
|
|
@@ -3,7 +3,7 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import os from "node:os";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
|
|
6
|
-
import { auditResearchSynthesis, deepResearch } from "../src/deep-research.js";
|
|
6
|
+
import { auditResearchSynthesis, deepResearch, RESEARCH_VERSION } from "../src/deep-research.js";
|
|
7
7
|
import { checkToolUse } from "../src/guardrails.js";
|
|
8
8
|
import { flushHousekeeping } from "../src/housekeeping.js";
|
|
9
9
|
import { requestNextStep, toolChoiceForProvider } from "../src/model-client.js";
|
|
@@ -59,6 +59,50 @@ async function main() {
|
|
|
59
59
|
!shouldStartWithDeepResearch(localEvidenceGoal),
|
|
60
60
|
"local-source research incorrectly forced deep_research before workspace inspection"
|
|
61
61
|
);
|
|
62
|
+
const inspectedLocalEvidenceMessages = [
|
|
63
|
+
{ role: "user", content: localEvidenceGoal },
|
|
64
|
+
{
|
|
65
|
+
role: "assistant",
|
|
66
|
+
tool_calls: [{ id: "inspect-notes", function: { name: "read_file", arguments: '{"path":"PROJECT_NOTES.md"}' } }],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
role: "assistant",
|
|
70
|
+
tool_calls: [{ id: "inspect-sources", function: { name: "read_file", arguments: '{"path":"sources.json"}' } }],
|
|
71
|
+
},
|
|
72
|
+
];
|
|
73
|
+
assert(
|
|
74
|
+
shouldStartWithDeepResearch(localEvidenceGoal, inspectedLocalEvidenceMessages),
|
|
75
|
+
"local-source research did not enter bounded deep research after workspace inspection"
|
|
76
|
+
);
|
|
77
|
+
assert(
|
|
78
|
+
!shouldStartWithDeepResearch(localEvidenceGoal, [
|
|
79
|
+
...inspectedLocalEvidenceMessages,
|
|
80
|
+
{
|
|
81
|
+
role: "assistant",
|
|
82
|
+
tool_calls: [{ id: "current-research", function: { name: "deep_research", arguments: "{}" } }],
|
|
83
|
+
},
|
|
84
|
+
]),
|
|
85
|
+
"the current request repeated deep research after already requesting it"
|
|
86
|
+
);
|
|
87
|
+
assert(
|
|
88
|
+
shouldStartWithDeepResearch(localEvidenceGoal, [
|
|
89
|
+
...inspectedLocalEvidenceMessages,
|
|
90
|
+
{
|
|
91
|
+
role: "assistant",
|
|
92
|
+
tool_calls: [{ id: "old-research", function: { name: "deep_research", arguments: "{}" } }],
|
|
93
|
+
},
|
|
94
|
+
{ role: "user", content: "Refresh this evidence review because the current report quality is not acceptable." },
|
|
95
|
+
{
|
|
96
|
+
role: "assistant",
|
|
97
|
+
tool_calls: [{ id: "refresh-report", function: { name: "read_file", arguments: '{"path":"agent-reliability-evidence-review.md"}' } }],
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
role: "assistant",
|
|
101
|
+
tool_calls: [{ id: "refresh-sources", function: { name: "read_file", arguments: '{"path":"sources.json"}' } }],
|
|
102
|
+
},
|
|
103
|
+
]),
|
|
104
|
+
"a completed research call from an older user intent suppressed a fresh bounded research pass"
|
|
105
|
+
);
|
|
62
106
|
assert(
|
|
63
107
|
shouldStartWithDeepResearch("Write a deep web research report comparing three primary papers."),
|
|
64
108
|
"standalone deep research no longer starts with the bounded research workflow"
|
|
@@ -509,6 +553,7 @@ async function main() {
|
|
|
509
553
|
},
|
|
510
554
|
store
|
|
511
555
|
);
|
|
556
|
+
assert(research.version === RESEARCH_VERSION, "deep research did not expose its result-schema version");
|
|
512
557
|
assert(research.ok && research.sourceCount === 2, `deep research failed: ${research.error || "unknown"}`);
|
|
513
558
|
assert(
|
|
514
559
|
researchSearchProviders.length === 2 && researchSearchProviders.every((provider) => provider === "multi"),
|
|
@@ -4,6 +4,7 @@ import os from "node:os";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { runAgent } from "../src/agent-runner.js";
|
|
7
|
+
import { RESEARCH_VERSION } from "../src/deep-research.js";
|
|
7
8
|
import { resolveRuntimeConfig } from "../src/config.js";
|
|
8
9
|
import { classifyCommand, evaluateCommandPolicy } from "../src/command-policy.js";
|
|
9
10
|
import {
|
|
@@ -4338,6 +4339,7 @@ try {
|
|
|
4338
4339
|
{
|
|
4339
4340
|
ok: true,
|
|
4340
4341
|
toolName: "deep_research",
|
|
4342
|
+
version: RESEARCH_VERSION,
|
|
4341
4343
|
researchId: "research-one",
|
|
4342
4344
|
status: "completed",
|
|
4343
4345
|
reportPath: path.join(workspace, "report.md"),
|
|
@@ -4354,6 +4356,16 @@ try {
|
|
|
4354
4356
|
reusedResearch?.duplicateSuppressed && reusedResearch.reportPath === path.join(workspace, "report.md"),
|
|
4355
4357
|
"same-goal deep research did not reuse an already completed exact report"
|
|
4356
4358
|
);
|
|
4359
|
+
completedResearchState.meta.completedDeepResearch[0].result.version = RESEARCH_VERSION - 1;
|
|
4360
|
+
assert(
|
|
4361
|
+
completedDeepResearchReuse(
|
|
4362
|
+
completedResearchState,
|
|
4363
|
+
{ query: "A model-expanded query", outputPath: "report.md", refresh: true },
|
|
4364
|
+
{ commandCwd: workspace }
|
|
4365
|
+
) === null,
|
|
4366
|
+
"a stale deep-research engine result was reused after the report contract changed"
|
|
4367
|
+
);
|
|
4368
|
+
completedResearchState.meta.completedDeepResearch[0].result.version = RESEARCH_VERSION;
|
|
4357
4369
|
completedResearchState.meta.goalContract = { revision: 2, currentHash: "goal-two" };
|
|
4358
4370
|
assert(
|
|
4359
4371
|
completedDeepResearchReuse(
|
|
@@ -547,6 +547,7 @@ async function verifyPackagedBinAndScriptClosure() {
|
|
|
547
547
|
"scripts/eval-provider-attribution.js",
|
|
548
548
|
"scripts/smoke-context-budget-recovery.js",
|
|
549
549
|
"scripts/smoke-integration-production-mount.js",
|
|
550
|
+
"scripts/smoke-integration-production-runtime-bundle.js",
|
|
550
551
|
]) {
|
|
551
552
|
assert.equal(packageJson.files.includes(requiredFile), true);
|
|
552
553
|
}
|
|
@@ -1087,6 +1088,38 @@ async function main() {
|
|
|
1087
1088
|
"INTEGRATION_CREDENTIAL_SOURCE_FORBIDDEN"
|
|
1088
1089
|
);
|
|
1089
1090
|
|
|
1091
|
+
let cliCheckOutput = "";
|
|
1092
|
+
await withCanonicalCredentialFixture(async () => {
|
|
1093
|
+
const summary = await integrationCliMain(["check", "--config", configPath], {
|
|
1094
|
+
env: { CREDENTIALS_DIRECTORY: INTEGRATION_SYSTEMD_CREDENTIALS_DIRECTORY },
|
|
1095
|
+
stdout: { write(chunk) { cliCheckOutput += String(chunk); } },
|
|
1096
|
+
});
|
|
1097
|
+
assert.equal(summary.status, "checked-disabled");
|
|
1098
|
+
assert.equal(summary.capability?.enabled, false);
|
|
1099
|
+
assert.equal(summary.implementationReady, false);
|
|
1100
|
+
assert.equal(typeof summary.runtimeBundle?.healthy, "boolean");
|
|
1101
|
+
assert.equal(summary.runtimeBundle?.implementationReady, false);
|
|
1102
|
+
assert.equal(summary.runtimeBundle?.capabilityEnabled, false);
|
|
1103
|
+
assert.equal(summary.runtimeBundle?.httpServingEnabled, false);
|
|
1104
|
+
if (summary.runtimeBundle.healthy) {
|
|
1105
|
+
assert.equal(summary.runtimeBundle.firstBlocker?.component, "idempotencyStore");
|
|
1106
|
+
assert.equal(
|
|
1107
|
+
summary.runtimeBundle.firstBlocker?.code,
|
|
1108
|
+
"INTEGRATION_DESCRIPTOR_BOUND_IDEMPOTENCY_UNAVAILABLE"
|
|
1109
|
+
);
|
|
1110
|
+
} else {
|
|
1111
|
+
assert.equal(summary.runtimeBundle.firstBlocker?.component, "storageAuthority");
|
|
1112
|
+
assert.match(
|
|
1113
|
+
summary.runtimeBundle.firstBlocker?.code || "",
|
|
1114
|
+
/^INTEGRATION_STORAGE_/u
|
|
1115
|
+
);
|
|
1116
|
+
}
|
|
1117
|
+
assert.deepEqual(
|
|
1118
|
+
JSON.parse(cliCheckOutput.trim()),
|
|
1119
|
+
JSON.parse(JSON.stringify(summary))
|
|
1120
|
+
);
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1090
1123
|
const cliServePort = await unusedLoopbackPort();
|
|
1091
1124
|
const cliServeConfigPath = path.join(tempRoot, "integration-serve.json");
|
|
1092
1125
|
await fs.writeFile(
|
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import {
|
|
7
|
+
INTEGRATION_PRODUCTION_RUNTIME_BUNDLE_HEALTH_VERSION,
|
|
8
|
+
INTEGRATION_PRODUCTION_RUNTIME_BUNDLE_LIMITATIONS,
|
|
9
|
+
INTEGRATION_PRODUCTION_RUNTIME_BUNDLE_VERSION,
|
|
10
|
+
checkIntegrationProductionRuntimeBundle,
|
|
11
|
+
integrationProductionRuntimeBundlePaths,
|
|
12
|
+
openIntegrationProductionRuntimeBundle,
|
|
13
|
+
preflightIntegrationProductionRuntimeBundle,
|
|
14
|
+
} from "../src/integration-production-runtime-bundle.js";
|
|
15
|
+
import { contractDigest } from "../src/integration-policy.js";
|
|
16
|
+
|
|
17
|
+
const UID = process.getuid();
|
|
18
|
+
const GID = process.getgid();
|
|
19
|
+
|
|
20
|
+
async function expectCode(action, expectedCode) {
|
|
21
|
+
let captured = null;
|
|
22
|
+
try {
|
|
23
|
+
await action();
|
|
24
|
+
} catch (error) {
|
|
25
|
+
captured = error;
|
|
26
|
+
}
|
|
27
|
+
assert(captured, `Expected ${expectedCode}`);
|
|
28
|
+
assert.equal(captured.publicCode || captured.code, expectedCode, captured.stack || captured.message);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function expectNoUnhandledRejections(action) {
|
|
32
|
+
const unhandled = [];
|
|
33
|
+
const onUnhandled = (reason) => unhandled.push(reason);
|
|
34
|
+
process.on("unhandledRejection", onUnhandled);
|
|
35
|
+
try {
|
|
36
|
+
await action();
|
|
37
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
38
|
+
} finally {
|
|
39
|
+
process.removeListener("unhandledRejection", onUnhandled);
|
|
40
|
+
}
|
|
41
|
+
assert.deepEqual(unhandled, []);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function ensureOwnerDirectory(directoryPath) {
|
|
45
|
+
await fs.mkdir(directoryPath, { recursive: true, mode: 0o700 });
|
|
46
|
+
await fs.chmod(directoryPath, 0o700);
|
|
47
|
+
await fs.chown(directoryPath, UID, GID);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function ensureLockFile(filePath) {
|
|
51
|
+
try {
|
|
52
|
+
await fs.writeFile(filePath, "", { flag: "wx", mode: 0o600 });
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (error?.code !== "EEXIST") throw error;
|
|
55
|
+
}
|
|
56
|
+
await fs.chmod(filePath, 0o600);
|
|
57
|
+
await fs.chown(filePath, UID, GID);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function provisionRuntimeRoot(stateRoot, { omitEventLock = false } = {}) {
|
|
61
|
+
const paths = integrationProductionRuntimeBundlePaths(stateRoot);
|
|
62
|
+
for (const directoryPath of [
|
|
63
|
+
paths.stateRoot,
|
|
64
|
+
path.dirname(paths.repository),
|
|
65
|
+
paths.repository,
|
|
66
|
+
paths.sessions,
|
|
67
|
+
paths.workspace,
|
|
68
|
+
paths.eventLedger,
|
|
69
|
+
paths.idempotency,
|
|
70
|
+
]) {
|
|
71
|
+
await ensureOwnerDirectory(directoryPath);
|
|
72
|
+
}
|
|
73
|
+
await ensureLockFile(paths.repositoryLock);
|
|
74
|
+
await ensureLockFile(paths.sessionLock);
|
|
75
|
+
if (!omitEventLock) await ensureLockFile(paths.eventLedgerLock);
|
|
76
|
+
return paths;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function inventory(stateRoot) {
|
|
80
|
+
const names = await fs.readdir(stateRoot, { recursive: true });
|
|
81
|
+
return names.map((name) => String(name)).sort();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function assertEvidenceDigest(evidence) {
|
|
85
|
+
const { digest, ...unsigned } = evidence;
|
|
86
|
+
assert.equal(digest, contractDigest(unsigned));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function run() {
|
|
90
|
+
const missingRoot = path.join(
|
|
91
|
+
os.tmpdir(),
|
|
92
|
+
`aginti-production-runtime-bundle-missing-${process.pid}-${Date.now()}`
|
|
93
|
+
);
|
|
94
|
+
const missing = await checkIntegrationProductionRuntimeBundle({ stateRoot: missingRoot });
|
|
95
|
+
assert.equal(missing.schemaVersion, INTEGRATION_PRODUCTION_RUNTIME_BUNDLE_HEALTH_VERSION);
|
|
96
|
+
assert.equal(missing.healthy, false);
|
|
97
|
+
assert.equal(missing.implementationReady, false);
|
|
98
|
+
assert.equal(missing.capabilityEnabled, false);
|
|
99
|
+
assert.equal(missing.httpServingEnabled, false);
|
|
100
|
+
assert.equal(missing.firstBlocker.component, "storageAuthority");
|
|
101
|
+
assert.equal(missing.firstBlocker.code, "INTEGRATION_STORAGE_UNAVAILABLE");
|
|
102
|
+
assert.equal(missing.blockers[1].component, "idempotencyStore");
|
|
103
|
+
assertEvidenceDigest(missing);
|
|
104
|
+
|
|
105
|
+
let proxyTrapCalls = 0;
|
|
106
|
+
const proxiedInput = new Proxy(Object.freeze({ stateRoot: missingRoot }), {
|
|
107
|
+
get() {
|
|
108
|
+
proxyTrapCalls += 1;
|
|
109
|
+
throw new Error("bundle input get trap must not run");
|
|
110
|
+
},
|
|
111
|
+
ownKeys() {
|
|
112
|
+
proxyTrapCalls += 1;
|
|
113
|
+
throw new Error("bundle input ownKeys trap must not run");
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
await expectCode(
|
|
117
|
+
() => openIntegrationProductionRuntimeBundle(proxiedInput),
|
|
118
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
119
|
+
);
|
|
120
|
+
assert.equal(proxyTrapCalls, 0);
|
|
121
|
+
const revocable = Proxy.revocable(Object.freeze({ stateRoot: missingRoot }), {});
|
|
122
|
+
revocable.revoke();
|
|
123
|
+
await expectCode(
|
|
124
|
+
() => openIntegrationProductionRuntimeBundle(revocable.proxy),
|
|
125
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
let accessorCalls = 0;
|
|
129
|
+
const accessorInput = {};
|
|
130
|
+
Object.defineProperty(accessorInput, "stateRoot", {
|
|
131
|
+
configurable: true,
|
|
132
|
+
enumerable: true,
|
|
133
|
+
get() {
|
|
134
|
+
accessorCalls += 1;
|
|
135
|
+
return missingRoot;
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
await expectCode(
|
|
139
|
+
() => openIntegrationProductionRuntimeBundle(accessorInput),
|
|
140
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
141
|
+
);
|
|
142
|
+
assert.equal(accessorCalls, 0);
|
|
143
|
+
await expectCode(
|
|
144
|
+
() => openIntegrationProductionRuntimeBundle(Object.create({ stateRoot: missingRoot })),
|
|
145
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
146
|
+
);
|
|
147
|
+
await expectNoUnhandledRejections(async () => {
|
|
148
|
+
const rejectedInput = Promise.reject(new Error("already rejected bundle input"));
|
|
149
|
+
await expectCode(
|
|
150
|
+
() => openIntegrationProductionRuntimeBundle(rejectedInput),
|
|
151
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
152
|
+
);
|
|
153
|
+
const rejectedStateRoot = Promise.reject(new Error("already rejected stateRoot"));
|
|
154
|
+
await expectCode(
|
|
155
|
+
() => openIntegrationProductionRuntimeBundle({ stateRoot: rejectedStateRoot }),
|
|
156
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
157
|
+
);
|
|
158
|
+
const rejectedOpenExtra = Promise.reject(new Error("already rejected open extra"));
|
|
159
|
+
await expectCode(
|
|
160
|
+
() => openIntegrationProductionRuntimeBundle({ stateRoot: missingRoot }, rejectedOpenExtra),
|
|
161
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
162
|
+
);
|
|
163
|
+
const rejectedPreflightExtra = Promise.reject(new Error("already rejected preflight extra"));
|
|
164
|
+
await expectCode(
|
|
165
|
+
() => preflightIntegrationProductionRuntimeBundle({ stateRoot: missingRoot }, rejectedPreflightExtra),
|
|
166
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
167
|
+
);
|
|
168
|
+
const rejectedCheckExtra = Promise.reject(new Error("already rejected check extra"));
|
|
169
|
+
await expectCode(
|
|
170
|
+
() => checkIntegrationProductionRuntimeBundle({ stateRoot: missingRoot }, rejectedCheckExtra),
|
|
171
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
172
|
+
);
|
|
173
|
+
const rejectedPathsExtra = Promise.reject(new Error("already rejected paths extra"));
|
|
174
|
+
await expectCode(
|
|
175
|
+
() => integrationProductionRuntimeBundlePaths(missingRoot, rejectedPathsExtra),
|
|
176
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
177
|
+
);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const nonDirectoryRoot = await fs.mkdtemp(
|
|
181
|
+
path.join(os.tmpdir(), "aginti-production-runtime-nondirectory-")
|
|
182
|
+
);
|
|
183
|
+
try {
|
|
184
|
+
const nonDirectory = path.join(nonDirectoryRoot, "not-a-directory");
|
|
185
|
+
await fs.writeFile(nonDirectory, "blocked", { mode: 0o600 });
|
|
186
|
+
const unavailable = await checkIntegrationProductionRuntimeBundle({
|
|
187
|
+
stateRoot: path.join(nonDirectory, "child"),
|
|
188
|
+
});
|
|
189
|
+
assert.equal(unavailable.healthy, false);
|
|
190
|
+
assert.equal(unavailable.firstBlocker.component, "storageAuthority");
|
|
191
|
+
assert.equal(unavailable.firstBlocker.code, "INTEGRATION_STORAGE_UNAVAILABLE");
|
|
192
|
+
if (UID !== 0) {
|
|
193
|
+
const deniedParent = path.join(nonDirectoryRoot, "denied");
|
|
194
|
+
await fs.mkdir(deniedParent, { mode: 0o700 });
|
|
195
|
+
await fs.chmod(deniedParent, 0o000);
|
|
196
|
+
try {
|
|
197
|
+
const denied = await checkIntegrationProductionRuntimeBundle({
|
|
198
|
+
stateRoot: path.join(deniedParent, "child"),
|
|
199
|
+
});
|
|
200
|
+
assert.equal(denied.healthy, false);
|
|
201
|
+
assert.equal(denied.firstBlocker.component, "storageAuthority");
|
|
202
|
+
assert.equal(denied.firstBlocker.code, "INTEGRATION_STORAGE_UNAVAILABLE");
|
|
203
|
+
} finally {
|
|
204
|
+
await fs.chmod(deniedParent, 0o700);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
} finally {
|
|
208
|
+
await fs.rm(nonDirectoryRoot, { recursive: true, force: true });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const stateRoot = await fs.mkdtemp(path.join(os.tmpdir(), "aginti-production-runtime-bundle-"));
|
|
212
|
+
const poisonRoot = await fs.mkdtemp(path.join(os.tmpdir(), "aginti-production-runtime-poison-"));
|
|
213
|
+
const lockModeRoot = await fs.mkdtemp(path.join(os.tmpdir(), "aginti-production-runtime-lock-mode-"));
|
|
214
|
+
const lockReplacementRoot = await fs.mkdtemp(
|
|
215
|
+
path.join(os.tmpdir(), "aginti-production-runtime-lock-replacement-")
|
|
216
|
+
);
|
|
217
|
+
const failedRoot = await fs.mkdtemp(path.join(os.tmpdir(), "aginti-production-runtime-failed-"));
|
|
218
|
+
try {
|
|
219
|
+
const paths = await provisionRuntimeRoot(stateRoot);
|
|
220
|
+
assert.equal(paths.repository, path.join(stateRoot, "runtime-authority", "repository"));
|
|
221
|
+
assert.equal(paths.sessions, path.join(stateRoot, "runtime-authority", "sessions"));
|
|
222
|
+
assert.equal(paths.workspace, path.join(stateRoot, "runtime-authority", "workspace"));
|
|
223
|
+
assert.equal(paths.eventLedger, path.join(stateRoot, "event-ledger"));
|
|
224
|
+
assert.equal(paths.idempotency, path.join(stateRoot, "idempotency-store"));
|
|
225
|
+
|
|
226
|
+
const beforePreflight = await inventory(stateRoot);
|
|
227
|
+
const check = await checkIntegrationProductionRuntimeBundle({ stateRoot });
|
|
228
|
+
assert.equal(check.healthy, true);
|
|
229
|
+
assert.equal(check.implementationReady, false);
|
|
230
|
+
assert.equal(check.firstBlocker.component, "idempotencyStore");
|
|
231
|
+
assert.equal(
|
|
232
|
+
check.firstBlocker.code,
|
|
233
|
+
"INTEGRATION_DESCRIPTOR_BOUND_IDEMPOTENCY_UNAVAILABLE"
|
|
234
|
+
);
|
|
235
|
+
assert.equal(check.components.storageAuthority.descriptorBound, true);
|
|
236
|
+
assert.equal(check.components.repository.descriptorBound, true);
|
|
237
|
+
assert.equal(check.components.repository.runtimeFenceAcquired, false);
|
|
238
|
+
assert.equal(check.components.sessionState.descriptorBound, true);
|
|
239
|
+
assert.equal(check.components.sessionState.nativeWriteFenceBound, false);
|
|
240
|
+
assert.equal(check.components.eventLedger.runtimeAppendView, true);
|
|
241
|
+
assert.equal(check.components.eventLedger.sessionReadView, true);
|
|
242
|
+
assert.equal(check.components.idempotencyStore.namespaceDescriptorBound, true);
|
|
243
|
+
assert.equal(check.components.idempotencyStore.transactionalStore, false);
|
|
244
|
+
assert.equal(check.components.nativeExecutor.lexicalProofPresent, true);
|
|
245
|
+
assert.equal(check.components.nativeExecutor.retainedSessionStateBound, false);
|
|
246
|
+
assert.equal(check.components.nativeExecutor.artifactEvents, false);
|
|
247
|
+
assert.equal(check.components.sandbox.capabilityEnabled, false);
|
|
248
|
+
assert.equal(check.components.runtimeAuthority.composed, false);
|
|
249
|
+
assert.equal(check.components.sessionService.composed, false);
|
|
250
|
+
assertEvidenceDigest(check);
|
|
251
|
+
assert.deepEqual(await inventory(stateRoot), beforePreflight);
|
|
252
|
+
|
|
253
|
+
const directPreflight = await preflightIntegrationProductionRuntimeBundle({ stateRoot });
|
|
254
|
+
assert.equal(directPreflight.probe, "preflight");
|
|
255
|
+
assert.equal(directPreflight.healthy, true);
|
|
256
|
+
assert.equal(directPreflight.implementationReady, false);
|
|
257
|
+
assert.deepEqual(await inventory(stateRoot), beforePreflight);
|
|
258
|
+
|
|
259
|
+
const bundle = await openIntegrationProductionRuntimeBundle({ stateRoot });
|
|
260
|
+
assert.equal(Object.getPrototypeOf(bundle), null);
|
|
261
|
+
assert.equal(Object.isFrozen(bundle), true);
|
|
262
|
+
assert.equal(bundle.schemaVersion, INTEGRATION_PRODUCTION_RUNTIME_BUNDLE_VERSION);
|
|
263
|
+
assert.equal(bundle.attestation.descriptorBound, true);
|
|
264
|
+
assert.equal(bundle.attestation.storageLifecycleOwned, true);
|
|
265
|
+
assert.equal(bundle.attestation.implementationReady, false);
|
|
266
|
+
assert.equal(bundle.attestation.capabilityEnabled, false);
|
|
267
|
+
assert.equal(bundle.attestation.httpServingEnabled, false);
|
|
268
|
+
assert.equal(bundle.attestation.runtimeActivated, false);
|
|
269
|
+
assert.equal(bundle.attestation.idempotencyProofDigest, "0".repeat(64));
|
|
270
|
+
assert.equal(bundle.attestation.blockers[0].component, "idempotencyStore");
|
|
271
|
+
assert.equal(bundle.attestation.limitations, INTEGRATION_PRODUCTION_RUNTIME_BUNDLE_LIMITATIONS);
|
|
272
|
+
assert.equal("start" in bundle, false);
|
|
273
|
+
assert.equal("serve" in bundle, false);
|
|
274
|
+
assert.equal("runtimeAuthority" in bundle, false);
|
|
275
|
+
assert.equal("sessionService" in bundle, false);
|
|
276
|
+
assert.throws(() => Object.defineProperty(bundle, "start", { value() {} }), TypeError);
|
|
277
|
+
await expectCode(() => bundle.health({}), "INTEGRATION_RUNTIME_BUNDLE_INVALID");
|
|
278
|
+
await expectCode(() => bundle.preflight({}), "INTEGRATION_RUNTIME_BUNDLE_INVALID");
|
|
279
|
+
await expectCode(() => bundle.close({}), "INTEGRATION_RUNTIME_BUNDLE_INVALID");
|
|
280
|
+
await expectCode(() => bundle.isClosed({}), "INTEGRATION_RUNTIME_BUNDLE_INVALID");
|
|
281
|
+
await expectNoUnhandledRejections(async () => {
|
|
282
|
+
const rejectedHealthExtra = Promise.reject(new Error("already rejected health extra"));
|
|
283
|
+
await expectCode(() => bundle.health(rejectedHealthExtra), "INTEGRATION_RUNTIME_BUNDLE_INVALID");
|
|
284
|
+
const rejectedPreflightExtra = Promise.reject(new Error("already rejected preflight extra"));
|
|
285
|
+
await expectCode(
|
|
286
|
+
() => bundle.preflight(rejectedPreflightExtra),
|
|
287
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
288
|
+
);
|
|
289
|
+
const rejectedCloseExtra = Promise.reject(new Error("already rejected close extra"));
|
|
290
|
+
await expectCode(() => bundle.close(rejectedCloseExtra), "INTEGRATION_RUNTIME_BUNDLE_INVALID");
|
|
291
|
+
const rejectedClosedExtra = Promise.reject(new Error("already rejected isClosed extra"));
|
|
292
|
+
await expectCode(
|
|
293
|
+
() => bundle.isClosed(rejectedClosedExtra),
|
|
294
|
+
"INTEGRATION_RUNTIME_BUNDLE_INVALID"
|
|
295
|
+
);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
const healthy = await bundle.health();
|
|
299
|
+
assert.equal(healthy.probe, "health");
|
|
300
|
+
assert.equal(healthy.status, "healthy-disabled");
|
|
301
|
+
assert.equal(healthy.healthy, true);
|
|
302
|
+
assert.equal(healthy.implementationReady, false);
|
|
303
|
+
assertEvidenceDigest(healthy);
|
|
304
|
+
|
|
305
|
+
const concurrentHealth = await Promise.all([
|
|
306
|
+
bundle.health(),
|
|
307
|
+
bundle.preflight(),
|
|
308
|
+
bundle.health(),
|
|
309
|
+
]);
|
|
310
|
+
assert.deepEqual(
|
|
311
|
+
concurrentHealth.map((item) => item.healthy),
|
|
312
|
+
[true, true, true]
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
const racingProbe = bundle.health();
|
|
316
|
+
const racingClose = bundle.close();
|
|
317
|
+
await expectCode(() => racingProbe, "INTEGRATION_RUNTIME_BUNDLE_CLOSED");
|
|
318
|
+
assert.deepEqual(await racingClose, { closed: true, poisoned: false });
|
|
319
|
+
assert.equal(bundle.isClosed(), true);
|
|
320
|
+
assert.deepEqual(await bundle.close(), { closed: true, poisoned: false });
|
|
321
|
+
await expectCode(() => bundle.health(), "INTEGRATION_RUNTIME_BUNDLE_CLOSED");
|
|
322
|
+
await expectCode(() => bundle.preflight(), "INTEGRATION_RUNTIME_BUNDLE_CLOSED");
|
|
323
|
+
|
|
324
|
+
await provisionRuntimeRoot(poisonRoot);
|
|
325
|
+
const poisonedBundle = await openIntegrationProductionRuntimeBundle({ stateRoot: poisonRoot });
|
|
326
|
+
await fs.chmod(poisonRoot, 0o755);
|
|
327
|
+
await expectCode(() => poisonedBundle.health(), "INTEGRATION_STORAGE_POISONED");
|
|
328
|
+
await fs.chmod(poisonRoot, 0o700);
|
|
329
|
+
await expectCode(() => poisonedBundle.health(), "INTEGRATION_RUNTIME_BUNDLE_POISONED");
|
|
330
|
+
assert.deepEqual(await poisonedBundle.close(), { closed: true, poisoned: true });
|
|
331
|
+
|
|
332
|
+
const lockModePaths = await provisionRuntimeRoot(lockModeRoot);
|
|
333
|
+
const lockModeBundle = await openIntegrationProductionRuntimeBundle({ stateRoot: lockModeRoot });
|
|
334
|
+
await fs.chmod(lockModePaths.repositoryLock, 0o640);
|
|
335
|
+
await expectCode(() => lockModeBundle.health(), "INTEGRATION_STORAGE_LOCK_POISONED");
|
|
336
|
+
await fs.chmod(lockModePaths.repositoryLock, 0o600);
|
|
337
|
+
await expectCode(() => lockModeBundle.health(), "INTEGRATION_RUNTIME_BUNDLE_POISONED");
|
|
338
|
+
assert.deepEqual(await lockModeBundle.close(), { closed: true, poisoned: true });
|
|
339
|
+
|
|
340
|
+
const replacementPaths = await provisionRuntimeRoot(lockReplacementRoot);
|
|
341
|
+
const replacementBundle = await openIntegrationProductionRuntimeBundle({
|
|
342
|
+
stateRoot: lockReplacementRoot,
|
|
343
|
+
});
|
|
344
|
+
const displacedSessionLock = `${replacementPaths.sessionLock}.displaced`;
|
|
345
|
+
await fs.rename(replacementPaths.sessionLock, displacedSessionLock);
|
|
346
|
+
await ensureLockFile(replacementPaths.sessionLock);
|
|
347
|
+
await expectCode(
|
|
348
|
+
() => replacementBundle.health(),
|
|
349
|
+
"INTEGRATION_STORAGE_LOCK_POISONED"
|
|
350
|
+
);
|
|
351
|
+
await expectCode(
|
|
352
|
+
() => replacementBundle.preflight(),
|
|
353
|
+
"INTEGRATION_RUNTIME_BUNDLE_POISONED"
|
|
354
|
+
);
|
|
355
|
+
assert.deepEqual(await replacementBundle.close(), { closed: true, poisoned: true });
|
|
356
|
+
|
|
357
|
+
const failedPaths = await provisionRuntimeRoot(failedRoot, { omitEventLock: true });
|
|
358
|
+
await expectCode(
|
|
359
|
+
() => openIntegrationProductionRuntimeBundle({ stateRoot: failedRoot }),
|
|
360
|
+
"INTEGRATION_STORAGE_UNAVAILABLE"
|
|
361
|
+
);
|
|
362
|
+
await ensureLockFile(failedPaths.eventLedgerLock);
|
|
363
|
+
const recoveredFromFactoryFailure = await openIntegrationProductionRuntimeBundle({
|
|
364
|
+
stateRoot: failedRoot,
|
|
365
|
+
});
|
|
366
|
+
assert.equal((await recoveredFromFactoryFailure.health()).healthy, true);
|
|
367
|
+
await recoveredFromFactoryFailure.close();
|
|
368
|
+
|
|
369
|
+
const [cliSource, serverSource, bundleSource] = await Promise.all([
|
|
370
|
+
fs.readFile(new URL("../src/integration-cli.js", import.meta.url), "utf8"),
|
|
371
|
+
fs.readFile(new URL("../src/integration-server.js", import.meta.url), "utf8"),
|
|
372
|
+
fs.readFile(new URL("../src/integration-production-runtime-bundle.js", import.meta.url), "utf8"),
|
|
373
|
+
]);
|
|
374
|
+
assert.match(cliSource, /checkIntegrationProductionRuntimeBundle/u);
|
|
375
|
+
assert.doesNotMatch(serverSource, /integration-production-runtime-bundle/u);
|
|
376
|
+
assert.doesNotMatch(
|
|
377
|
+
bundleSource,
|
|
378
|
+
/acquireRetainedIntegrationRuntimeRepositoryFence|createAgintiIntegrationRuntimeAuthority|createNativeIntegrationSessionService|createFileIntegrationIdempotencyStore/u
|
|
379
|
+
);
|
|
380
|
+
} finally {
|
|
381
|
+
await fs.chmod(poisonRoot, 0o700).catch(() => {});
|
|
382
|
+
await fs.rm(stateRoot, { recursive: true, force: true });
|
|
383
|
+
await fs.rm(poisonRoot, { recursive: true, force: true });
|
|
384
|
+
await fs.rm(lockModeRoot, { recursive: true, force: true });
|
|
385
|
+
await fs.rm(lockReplacementRoot, { recursive: true, force: true });
|
|
386
|
+
await fs.rm(failedRoot, { recursive: true, force: true });
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
process.stdout.write("integration production runtime bundle smoke: ok\n");
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
run().catch((error) => {
|
|
393
|
+
process.stderr.write(
|
|
394
|
+
`integration production runtime bundle smoke: failed (${String(error?.publicCode || error?.code || error?.name || "ERROR")})\n`
|
|
395
|
+
);
|
|
396
|
+
process.stderr.write(`${String(error?.stack || error?.message || error)}\n`);
|
|
397
|
+
process.exitCode = 1;
|
|
398
|
+
});
|
|
@@ -482,15 +482,20 @@ async function runCore() {
|
|
|
482
482
|
const authorities = [];
|
|
483
483
|
let consumerMocks = [];
|
|
484
484
|
try {
|
|
485
|
-
const [serverSource, runtimeSource, sessionSource] = await Promise.all([
|
|
485
|
+
const [serverSource, runtimeSource, sessionSource, productionBundleSource] = await Promise.all([
|
|
486
486
|
fs.readFile(new URL("../src/integration-server.js", import.meta.url), "utf8"),
|
|
487
487
|
fs.readFile(new URL("../src/integration-runtime-authority.js", import.meta.url), "utf8"),
|
|
488
488
|
fs.readFile(new URL("../src/integration-session-service.js", import.meta.url), "utf8"),
|
|
489
|
+
fs.readFile(new URL("../src/integration-production-runtime-bundle.js", import.meta.url), "utf8"),
|
|
489
490
|
]);
|
|
490
491
|
assert.match(serverSource, /export const INTEGRATION_MOUNT_CAPABILITY_ENABLED = false;/u);
|
|
491
492
|
assert.equal(serverSource.includes("createRetainedIntegrationEventLedgerBundle"), false);
|
|
492
493
|
assert.equal(runtimeSource.includes("createRetainedIntegrationEventLedgerBundle"), false);
|
|
493
494
|
assert.equal(sessionSource.includes("createRetainedIntegrationEventLedgerBundle"), false);
|
|
495
|
+
assert.equal(productionBundleSource.includes("createRetainedIntegrationEventLedgerBundle"), true);
|
|
496
|
+
assert.match(productionBundleSource, /capabilityEnabled:\s*false/u);
|
|
497
|
+
assert.match(productionBundleSource, /httpServingEnabled:\s*false/u);
|
|
498
|
+
assert.match(productionBundleSource, /runtimeActivationIncluded:\s*false/u);
|
|
494
499
|
|
|
495
500
|
const main = await openFixture(path.join(smokeRoot, "main"), "retained-ledger-bundle-main");
|
|
496
501
|
authorities.push(main.authority);
|
|
@@ -791,6 +791,7 @@ async function runStaticBoundaryChecks(surface) {
|
|
|
791
791
|
assert.match(config, /capability:\s*Object\.freeze\(\{ enabled: false \}\)/u);
|
|
792
792
|
const sourceDirectory = fileURLToPath(new URL("../src/", import.meta.url));
|
|
793
793
|
for (const consumerName of [
|
|
794
|
+
"integration-production-runtime-bundle.js",
|
|
794
795
|
"integration-native-executor.js",
|
|
795
796
|
"integration-runtime-authority.js",
|
|
796
797
|
"integration-native-runtime-roots.js",
|
|
@@ -800,6 +801,18 @@ async function runStaticBoundaryChecks(surface) {
|
|
|
800
801
|
"session-store.js",
|
|
801
802
|
]) {
|
|
802
803
|
const consumer = await fs.readFile(path.join(sourceDirectory, consumerName), "utf8");
|
|
804
|
+
if (consumerName === "integration-production-runtime-bundle.js") {
|
|
805
|
+
assert.match(consumer, /capabilityEnabled:\s*false/u);
|
|
806
|
+
assert.match(consumer, /runtimeActivationIncluded:\s*false/u);
|
|
807
|
+
assert.match(consumer, /repositoryFenceAcquisitionIncluded:\s*false/u);
|
|
808
|
+
assert.match(consumer, /descriptorBoundIdempotencyStore:\s*false/u);
|
|
809
|
+
assert.doesNotMatch(
|
|
810
|
+
consumer,
|
|
811
|
+
/acquireRetainedIntegrationRuntimeRepositoryFence|createAgintiIntegrationRuntimeAuthority|createIntegrationServer|createNativeIntegrationSessionService/u,
|
|
812
|
+
`${consumerName} may compose the repository-state surface only before runtime activation.`
|
|
813
|
+
);
|
|
814
|
+
continue;
|
|
815
|
+
}
|
|
803
816
|
assert.doesNotMatch(
|
|
804
817
|
consumer,
|
|
805
818
|
/integration-retained-native-session-repository-state|(?:create|assert)RetainedIntegrationNativeSessionRepositoryState/u,
|