@githolon/dsl 0.103.7 → 0.103.8
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/dart/CHANGELOG.md +6 -0
- package/dart/lib/src/runner/node-entry.mjs +42 -24
- package/dart/lib/src/runner/offline-install.mjs +1 -1
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart/test/errors_test.dart +10 -0
- package/dart_types/CHANGELOG.md +5 -0
- package/dart_types/lib/src/errors.dart +4 -2
- package/dart_types/pubspec.yaml +2 -2
- package/package.json +1 -1
- package/runtime/generated-application-host.js +41 -23
- package/src/codegen_dart_application.ts +10 -4
- package/src/compile_package_main.ts +22 -10
- package/src/intent.ts +80 -17
package/dart/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## 0.64.7
|
|
2
|
+
|
|
3
|
+
- Bound generated application startup and referenced-workspace opens, preserving typed custody failures and
|
|
4
|
+
retryable custody while keeping law adoption inside the generated lifecycle.
|
|
5
|
+
- Preserve compound action output contracts through generated clients.
|
|
6
|
+
|
|
1
7
|
## 0.64.6
|
|
2
8
|
|
|
3
9
|
- Publish the complete generated-application runtime already present in the coordinated source release,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// <define:__NOMOS_KERNEL_RELEASE__>
|
|
4
|
-
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "
|
|
4
|
+
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "171bd538ffccfbf248b2b25962d44676cf78466d5da2dfa32c8618ba5f38bf45", version: "kernel-171bd538", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 }, testMint: { hash: "8b521aba87dd4dd54a81db9c3571c79ec5d0c600f84ca3796379fc5ba098068b", version: "kernel-8b521aba", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 } };
|
|
5
5
|
|
|
6
6
|
// runner/node-entry.ts
|
|
7
7
|
import { createInterface } from "node:readline";
|
|
@@ -2345,7 +2345,7 @@ function recommendedActionSentence(action) {
|
|
|
2345
2345
|
case "recompileClient":
|
|
2346
2346
|
return "recompile the client (githolon compile / npx nomos-compile) against the deployed law";
|
|
2347
2347
|
case "redeployLaw":
|
|
2348
|
-
return "
|
|
2348
|
+
return "let the generated application prove, stage and govern adoption of its packaged law";
|
|
2349
2349
|
case "reauth":
|
|
2350
2350
|
return "re-authenticate (acquire a fresh auth-provider token) and reconnect";
|
|
2351
2351
|
case "quarantineLocalSnapshotAndReclone":
|
|
@@ -8498,7 +8498,7 @@ function lawStatusOf(installed, clientHash) {
|
|
|
8498
8498
|
function lawDriftMessage({ what, workspace, clientHash, installed }) {
|
|
8499
8499
|
const short = (h) => `${String(h).slice(0, 12)}\u2026`;
|
|
8500
8500
|
const runs = installed.length ? `runs law ${installed.slice(0, 6).map(short).join(", ")}${installed.length > 6 ? ` (+${installed.length - 6} more)` : ""}` : "has NO active law installed";
|
|
8501
|
-
return `${what}: this client was generated under law ${short(clientHash)}, but workspace '${workspace}' ${runs} \u2014 the client and the workspace have drifted (or this domain was never
|
|
8501
|
+
return `${what}: this client was generated under law ${short(clientHash)}, but workspace '${workspace}' ${runs} \u2014 the client and the workspace have drifted (or this domain was never installed here). The generated application will now prove, stage and govern adoption of its packaged model; if adoption is refused it surfaces a typed model decision instead of requiring application code to deploy law. [law-drift]`;
|
|
8502
8502
|
}
|
|
8503
8503
|
function birthOutcomeFailure(birthOutcomes) {
|
|
8504
8504
|
if (!Array.isArray(birthOutcomes)) return null;
|
|
@@ -8736,7 +8736,12 @@ ${String(commit).toLowerCase()}`;
|
|
|
8736
8736
|
remoteMain = await resolveBranchHead().catch(() => null);
|
|
8737
8737
|
} else {
|
|
8738
8738
|
await writeSkeleton();
|
|
8739
|
-
|
|
8739
|
+
const _remoteStatus = span("receive", "boot: fetch remote status", "cloud-status");
|
|
8740
|
+
try {
|
|
8741
|
+
remoteMain = await fetchRemoteHead();
|
|
8742
|
+
} finally {
|
|
8743
|
+
_remoteStatus.end();
|
|
8744
|
+
}
|
|
8740
8745
|
if (!remoteMain) {
|
|
8741
8746
|
_bootLedger.end();
|
|
8742
8747
|
if (!allowUnborn) throw new Error(`workspace '${workspace}' has no ledger main \u2014 create it first (POST /v2/workspaces/${workspace})`);
|
|
@@ -8759,6 +8764,10 @@ ${String(commit).toLowerCase()}`;
|
|
|
8759
8764
|
let cloudLedgerCache = null;
|
|
8760
8765
|
const watchTicks = /* @__PURE__ */ new Set();
|
|
8761
8766
|
const watchStops = /* @__PURE__ */ new Set();
|
|
8767
|
+
let installedLawRowsCache;
|
|
8768
|
+
const invalidateInstalledLawRows = () => {
|
|
8769
|
+
installedLawRowsCache = void 0;
|
|
8770
|
+
};
|
|
8762
8771
|
let _disposed = false;
|
|
8763
8772
|
const nudgeWatches = () => {
|
|
8764
8773
|
try {
|
|
@@ -9025,25 +9034,29 @@ ${String(commit).toLowerCase()}`;
|
|
|
9025
9034
|
}
|
|
9026
9035
|
};
|
|
9027
9036
|
const installRowsInner = () => {
|
|
9037
|
+
if (installedLawRowsCache !== void 0) return installedLawRowsCache;
|
|
9028
9038
|
try {
|
|
9029
9039
|
const answer = JSON.parse(call("query", { queryBytes: qBytes({ op: "installedLaw" }) }));
|
|
9030
|
-
if (Array.isArray(answer?.domains))
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9040
|
+
if (Array.isArray(answer?.domains)) {
|
|
9041
|
+
installedLawRowsCache = answer.domains.map((domain) => ({
|
|
9042
|
+
id: domain.installationId,
|
|
9043
|
+
data: {
|
|
9044
|
+
"spec.domainHash": domain.domainHash,
|
|
9045
|
+
"spec.packageHash": domain.packageHash,
|
|
9046
|
+
"spec.policyAggregate": domain.policyId,
|
|
9047
|
+
"spec.installedBy": domain.installedBy,
|
|
9048
|
+
"spec.authorityScope": domain.authorityScope,
|
|
9049
|
+
"spec.supersedes": domain.supersedes,
|
|
9050
|
+
"spec.lawClosureIdentity": domain.lawClosureIdentity,
|
|
9051
|
+
"spec.dependencies": Array.isArray(domain.dependencies) ? domain.dependencies : [],
|
|
9052
|
+
"spec.domainKeys": Array.isArray(domain.domainKeys) ? domain.domainKeys : [],
|
|
9053
|
+
"status.phase": domain.phase,
|
|
9054
|
+
"status.supersededBy": domain.supersededBy,
|
|
9055
|
+
"metadata.generation": domain.generation
|
|
9056
|
+
}
|
|
9057
|
+
}));
|
|
9058
|
+
return installedLawRowsCache;
|
|
9059
|
+
}
|
|
9047
9060
|
if (typeof process !== "undefined" && process.env?.NOMOS_DEBUG_RAW) {
|
|
9048
9061
|
console.error("[nomos] installedLaw meta-read returned no domains; using legacy projection fallback", answer);
|
|
9049
9062
|
}
|
|
@@ -9053,10 +9066,11 @@ ${String(commit).toLowerCase()}`;
|
|
|
9053
9066
|
}
|
|
9054
9067
|
}
|
|
9055
9068
|
try {
|
|
9056
|
-
|
|
9069
|
+
installedLawRowsCache = JSON.parse(call("query", { queryBytes: qBytes({ kind: "query", queryId: "aggregatesByType", paramsJson: JSON.stringify({ __type: "DomainInstallation" }) }) })) || [];
|
|
9057
9070
|
} catch {
|
|
9058
|
-
|
|
9071
|
+
installedLawRowsCache = null;
|
|
9059
9072
|
}
|
|
9073
|
+
return installedLawRowsCache;
|
|
9060
9074
|
};
|
|
9061
9075
|
const installedLawInner = () => {
|
|
9062
9076
|
const rows = installRowsInner();
|
|
@@ -9226,6 +9240,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
9226
9240
|
}
|
|
9227
9241
|
}
|
|
9228
9242
|
}
|
|
9243
|
+
invalidateInstalledLawRows();
|
|
9229
9244
|
nudgeWatches();
|
|
9230
9245
|
return {
|
|
9231
9246
|
upToDate: false,
|
|
@@ -9857,6 +9872,9 @@ ${String(commit).toLowerCase()}`;
|
|
|
9857
9872
|
created = Array.isArray(res.created) ? res.created : [];
|
|
9858
9873
|
affected = Array.isArray(res.affected) ? res.affected : [];
|
|
9859
9874
|
}
|
|
9875
|
+
if ((domain === "nomos" || domain === "bootstrap") && ["installDomain", "stageDomain", "promoteDomain", "rollbackDomain"].includes(directiveId)) {
|
|
9876
|
+
invalidateInstalledLawRows();
|
|
9877
|
+
}
|
|
9860
9878
|
scheduleMaintenanceSoon();
|
|
9861
9879
|
nudgeWatchesSoon();
|
|
9862
9880
|
const bornFailure = birthOutcomeFailure(res.birthOutcomes);
|
|
@@ -9880,7 +9898,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
9880
9898
|
if (!domain.trim() || !candidateHash.trim()) {
|
|
9881
9899
|
return { ok: false, stage: "preflight", error: "the generated model identity is missing" };
|
|
9882
9900
|
}
|
|
9883
|
-
const candidateInstallation = installRowsInner().find(
|
|
9901
|
+
const candidateInstallation = (installRowsInner() ?? []).find(
|
|
9884
9902
|
(row) => row?.id === `domain-installation:${candidateHash}`
|
|
9885
9903
|
);
|
|
9886
9904
|
const candidatePhase = String(candidateInstallation?.data?.["status.phase"] ?? "");
|
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// <define:__NOMOS_KERNEL_RELEASE__>
|
|
9
|
-
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "
|
|
9
|
+
var define_NOMOS_KERNEL_RELEASE_default = { production: { hash: "171bd538ffccfbf248b2b25962d44676cf78466d5da2dfa32c8618ba5f38bf45", version: "kernel-171bd538", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 }, testMint: { hash: "8b521aba87dd4dd54a81db9c3571c79ec5d0c600f84ca3796379fc5ba098068b", version: "kernel-8b521aba", features: ["compoundKeys", "capturedReads", "invariantGate", "surfacedMerge", "fieldProvenance", "nullSemantics", "attestedReads", "conflictSnapshots", "ownedAudience"], protocol: 1 } };
|
|
10
10
|
|
|
11
11
|
// runner/offline-install.ts
|
|
12
12
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync } from "node:fs";
|
package/dart/pubspec.lock
CHANGED
package/dart/pubspec.yaml
CHANGED
|
@@ -7,7 +7,7 @@ repository: https://github.com/Captain-App/nomos2
|
|
|
7
7
|
description: >-
|
|
8
8
|
Nomos 2 Dart client — generated domain values, intent payloads and application
|
|
9
9
|
lifecycle types over the typed Nomos kernel protocol and USDA custody model.
|
|
10
|
-
version: 0.64.
|
|
10
|
+
version: 0.64.7
|
|
11
11
|
|
|
12
12
|
environment:
|
|
13
13
|
sdk: ^3.5.0
|
|
@@ -16,7 +16,7 @@ dependencies:
|
|
|
16
16
|
# The pure-data core (wire types, offer codec, NomosReads, schema validation, error
|
|
17
17
|
# info). nomos_client depends on and re-exports it, so existing imports are unchanged.
|
|
18
18
|
# For local monorepo dev, pubspec_overrides.yaml points this at ../dart_types.
|
|
19
|
-
nomos_types: ^0.8.
|
|
19
|
+
nomos_types: ^0.8.4
|
|
20
20
|
json_schema: ^5.2.2
|
|
21
21
|
crypto: ^3.0.0
|
|
22
22
|
package_config: ^2.1.0
|
|
@@ -92,6 +92,16 @@ void main() {
|
|
|
92
92
|
expect(a.recommendedAction, NomosRecommendedAction.reauth);
|
|
93
93
|
});
|
|
94
94
|
|
|
95
|
+
test('law adoption advice keeps cloud deployment inside generated runtime',
|
|
96
|
+
() {
|
|
97
|
+
final advice =
|
|
98
|
+
NomosRecommendedAction.sentence(NomosRecommendedAction.redeployLaw);
|
|
99
|
+
expect(advice, contains('generated application'));
|
|
100
|
+
expect(advice, contains('govern adoption'));
|
|
101
|
+
expect(advice, isNot(contains('POST')));
|
|
102
|
+
expect(advice, isNot(contains('/v2/workspaces')));
|
|
103
|
+
});
|
|
104
|
+
|
|
95
105
|
test('load.* mints LoadError carrying the artifact + source URL', () {
|
|
96
106
|
final e = nomosErrorFromInfo(info('nomos.load.wasm_fetch_failed', attrs: {
|
|
97
107
|
'nomos.load.artifact': 'holon.wasm',
|
package/dart_types/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
## 0.8.4
|
|
2
|
+
|
|
3
|
+
- Expose bounded generated-startup and referenced-workspace custody failures as typed data so applications
|
|
4
|
+
can render and retry the exact kernel refusal instead of remaining on an indefinite loading surface.
|
|
5
|
+
|
|
1
6
|
## 0.8.3
|
|
2
7
|
|
|
3
8
|
- Add the typed `GitObjectId` value used to identify immutable custody objects without falling back to
|
|
@@ -51,7 +51,9 @@ class NomosRecommendedAction {
|
|
|
51
51
|
/// Regenerate the typed client against the deployed law (`githolon compile` / `npx nomos-compile`).
|
|
52
52
|
static const recompileClient = 'recompileClient';
|
|
53
53
|
|
|
54
|
-
///
|
|
54
|
+
/// Ask the generated application to govern adoption of its packaged law.
|
|
55
|
+
/// The stable value retains its original spelling for wire compatibility;
|
|
56
|
+
/// application code must not implement deployment itself.
|
|
55
57
|
static const redeployLaw = 'redeployLaw';
|
|
56
58
|
|
|
57
59
|
/// Re-acquire a fresh auth-provider token and reconnect.
|
|
@@ -98,7 +100,7 @@ class NomosRecommendedAction {
|
|
|
98
100
|
case recompileClient:
|
|
99
101
|
return 'recompile the client (githolon compile / npx nomos-compile) against the deployed law';
|
|
100
102
|
case redeployLaw:
|
|
101
|
-
return '
|
|
103
|
+
return 'let the generated application prove, stage and govern adoption of its packaged law';
|
|
102
104
|
case reauth:
|
|
103
105
|
return 're-authenticate (acquire a fresh auth-provider token) and reconnect';
|
|
104
106
|
case quarantineLocalSnapshotAndReclone:
|
package/dart_types/pubspec.yaml
CHANGED
|
@@ -7,9 +7,9 @@ name: nomos_types
|
|
|
7
7
|
repository: https://github.com/Captain-App/nomos2
|
|
8
8
|
description: >-
|
|
9
9
|
Pure kernel wire/data types for Nomos Dart frontends — no transport, no bridge,
|
|
10
|
-
no runtime.
|
|
10
|
+
no runtime. Typed protobuf and USDA boundary values plus the offer codec,
|
|
11
11
|
reactive read engine, schema validation, and data-only error/trace types.
|
|
12
|
-
version: 0.8.
|
|
12
|
+
version: 0.8.4
|
|
13
13
|
|
|
14
14
|
environment:
|
|
15
15
|
sdk: ^3.5.0
|
package/package.json
CHANGED
|
@@ -1404,7 +1404,7 @@ function recommendedActionSentence(action) {
|
|
|
1404
1404
|
case "recompileClient":
|
|
1405
1405
|
return "recompile the client (githolon compile / npx nomos-compile) against the deployed law";
|
|
1406
1406
|
case "redeployLaw":
|
|
1407
|
-
return "
|
|
1407
|
+
return "let the generated application prove, stage and govern adoption of its packaged law";
|
|
1408
1408
|
case "reauth":
|
|
1409
1409
|
return "re-authenticate (acquire a fresh auth-provider token) and reconnect";
|
|
1410
1410
|
case "quarantineLocalSnapshotAndReclone":
|
|
@@ -7557,7 +7557,7 @@ function lawStatusOf(installed, clientHash) {
|
|
|
7557
7557
|
function lawDriftMessage({ what, workspace, clientHash, installed }) {
|
|
7558
7558
|
const short = (h) => `${String(h).slice(0, 12)}\u2026`;
|
|
7559
7559
|
const runs = installed.length ? `runs law ${installed.slice(0, 6).map(short).join(", ")}${installed.length > 6 ? ` (+${installed.length - 6} more)` : ""}` : "has NO active law installed";
|
|
7560
|
-
return `${what}: this client was generated under law ${short(clientHash)}, but workspace '${workspace}' ${runs} \u2014 the client and the workspace have drifted (or this domain was never
|
|
7560
|
+
return `${what}: this client was generated under law ${short(clientHash)}, but workspace '${workspace}' ${runs} \u2014 the client and the workspace have drifted (or this domain was never installed here). The generated application will now prove, stage and govern adoption of its packaged model; if adoption is refused it surfaces a typed model decision instead of requiring application code to deploy law. [law-drift]`;
|
|
7561
7561
|
}
|
|
7562
7562
|
function birthOutcomeFailure(birthOutcomes) {
|
|
7563
7563
|
if (!Array.isArray(birthOutcomes)) return null;
|
|
@@ -7795,7 +7795,12 @@ ${String(commit).toLowerCase()}`;
|
|
|
7795
7795
|
remoteMain = await resolveBranchHead().catch(() => null);
|
|
7796
7796
|
} else {
|
|
7797
7797
|
await writeSkeleton();
|
|
7798
|
-
|
|
7798
|
+
const _remoteStatus = span("receive", "boot: fetch remote status", "cloud-status");
|
|
7799
|
+
try {
|
|
7800
|
+
remoteMain = await fetchRemoteHead();
|
|
7801
|
+
} finally {
|
|
7802
|
+
_remoteStatus.end();
|
|
7803
|
+
}
|
|
7799
7804
|
if (!remoteMain) {
|
|
7800
7805
|
_bootLedger.end();
|
|
7801
7806
|
if (!allowUnborn) throw new Error(`workspace '${workspace}' has no ledger main \u2014 create it first (POST /v2/workspaces/${workspace})`);
|
|
@@ -7818,6 +7823,10 @@ ${String(commit).toLowerCase()}`;
|
|
|
7818
7823
|
let cloudLedgerCache = null;
|
|
7819
7824
|
const watchTicks = /* @__PURE__ */ new Set();
|
|
7820
7825
|
const watchStops = /* @__PURE__ */ new Set();
|
|
7826
|
+
let installedLawRowsCache;
|
|
7827
|
+
const invalidateInstalledLawRows = () => {
|
|
7828
|
+
installedLawRowsCache = void 0;
|
|
7829
|
+
};
|
|
7821
7830
|
let _disposed = false;
|
|
7822
7831
|
const nudgeWatches = () => {
|
|
7823
7832
|
try {
|
|
@@ -8084,25 +8093,29 @@ ${String(commit).toLowerCase()}`;
|
|
|
8084
8093
|
}
|
|
8085
8094
|
};
|
|
8086
8095
|
const installRowsInner = () => {
|
|
8096
|
+
if (installedLawRowsCache !== void 0) return installedLawRowsCache;
|
|
8087
8097
|
try {
|
|
8088
8098
|
const answer = JSON.parse(call("query", { queryBytes: qBytes({ op: "installedLaw" }) }));
|
|
8089
|
-
if (Array.isArray(answer?.domains))
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8094
|
-
|
|
8095
|
-
|
|
8096
|
-
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8099
|
+
if (Array.isArray(answer?.domains)) {
|
|
8100
|
+
installedLawRowsCache = answer.domains.map((domain) => ({
|
|
8101
|
+
id: domain.installationId,
|
|
8102
|
+
data: {
|
|
8103
|
+
"spec.domainHash": domain.domainHash,
|
|
8104
|
+
"spec.packageHash": domain.packageHash,
|
|
8105
|
+
"spec.policyAggregate": domain.policyId,
|
|
8106
|
+
"spec.installedBy": domain.installedBy,
|
|
8107
|
+
"spec.authorityScope": domain.authorityScope,
|
|
8108
|
+
"spec.supersedes": domain.supersedes,
|
|
8109
|
+
"spec.lawClosureIdentity": domain.lawClosureIdentity,
|
|
8110
|
+
"spec.dependencies": Array.isArray(domain.dependencies) ? domain.dependencies : [],
|
|
8111
|
+
"spec.domainKeys": Array.isArray(domain.domainKeys) ? domain.domainKeys : [],
|
|
8112
|
+
"status.phase": domain.phase,
|
|
8113
|
+
"status.supersededBy": domain.supersededBy,
|
|
8114
|
+
"metadata.generation": domain.generation
|
|
8115
|
+
}
|
|
8116
|
+
}));
|
|
8117
|
+
return installedLawRowsCache;
|
|
8118
|
+
}
|
|
8106
8119
|
if (typeof process !== "undefined" && process.env?.NOMOS_DEBUG_RAW) {
|
|
8107
8120
|
console.error("[nomos] installedLaw meta-read returned no domains; using legacy projection fallback", answer);
|
|
8108
8121
|
}
|
|
@@ -8112,10 +8125,11 @@ ${String(commit).toLowerCase()}`;
|
|
|
8112
8125
|
}
|
|
8113
8126
|
}
|
|
8114
8127
|
try {
|
|
8115
|
-
|
|
8128
|
+
installedLawRowsCache = JSON.parse(call("query", { queryBytes: qBytes({ kind: "query", queryId: "aggregatesByType", paramsJson: JSON.stringify({ __type: "DomainInstallation" }) }) })) || [];
|
|
8116
8129
|
} catch {
|
|
8117
|
-
|
|
8130
|
+
installedLawRowsCache = null;
|
|
8118
8131
|
}
|
|
8132
|
+
return installedLawRowsCache;
|
|
8119
8133
|
};
|
|
8120
8134
|
const installedLawInner = () => {
|
|
8121
8135
|
const rows = installRowsInner();
|
|
@@ -8285,6 +8299,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
8285
8299
|
}
|
|
8286
8300
|
}
|
|
8287
8301
|
}
|
|
8302
|
+
invalidateInstalledLawRows();
|
|
8288
8303
|
nudgeWatches();
|
|
8289
8304
|
return {
|
|
8290
8305
|
upToDate: false,
|
|
@@ -8916,6 +8931,9 @@ ${String(commit).toLowerCase()}`;
|
|
|
8916
8931
|
created = Array.isArray(res.created) ? res.created : [];
|
|
8917
8932
|
affected = Array.isArray(res.affected) ? res.affected : [];
|
|
8918
8933
|
}
|
|
8934
|
+
if ((domain === "nomos" || domain === "bootstrap") && ["installDomain", "stageDomain", "promoteDomain", "rollbackDomain"].includes(directiveId)) {
|
|
8935
|
+
invalidateInstalledLawRows();
|
|
8936
|
+
}
|
|
8919
8937
|
scheduleMaintenanceSoon();
|
|
8920
8938
|
nudgeWatchesSoon();
|
|
8921
8939
|
const bornFailure = birthOutcomeFailure(res.birthOutcomes);
|
|
@@ -8939,7 +8957,7 @@ ${String(commit).toLowerCase()}`;
|
|
|
8939
8957
|
if (!domain.trim() || !candidateHash.trim()) {
|
|
8940
8958
|
return { ok: false, stage: "preflight", error: "the generated model identity is missing" };
|
|
8941
8959
|
}
|
|
8942
|
-
const candidateInstallation = installRowsInner().find(
|
|
8960
|
+
const candidateInstallation = (installRowsInner() ?? []).find(
|
|
8943
8961
|
(row) => row?.id === `domain-installation:${candidateHash}`
|
|
8944
8962
|
);
|
|
8945
8963
|
const candidatePhase = String(candidateInstallation?.data?.["status.phase"] ?? "");
|
|
@@ -284,7 +284,7 @@ function dartActionOutputs(
|
|
|
284
284
|
const fields = new Set<string>();
|
|
285
285
|
return outputs.map((output) => {
|
|
286
286
|
const dartType = concreteClassName(output.aggregateId);
|
|
287
|
-
const field = member(dartType);
|
|
287
|
+
const field = member(output.many ? plural(dartType) : dartType);
|
|
288
288
|
if (fields.has(field)) {
|
|
289
289
|
throw new Error(
|
|
290
290
|
`Dart application result for '${directive.id}' has two aggregate consequences named '${field}'; ` +
|
|
@@ -1140,7 +1140,11 @@ export function generateDartApplication(
|
|
|
1140
1140
|
` Future<${targetApplication}> _nmsOpenReference(NomosRef<${rootType}> reference) {`,
|
|
1141
1141
|
` final workspace = NmsInternalNomosRefs.workspace(reference);`,
|
|
1142
1142
|
` final existing = _nmsApplications[workspace];`,
|
|
1143
|
-
` if (existing != null)
|
|
1143
|
+
` if (existing != null) {`,
|
|
1144
|
+
` return NmsInternalApplicationHost.nmsInternalAwaitReferencedApplication(`,
|
|
1145
|
+
` workspace: workspace, opening: existing,`,
|
|
1146
|
+
` );`,
|
|
1147
|
+
` }`,
|
|
1144
1148
|
` late final Future<${targetApplication}> opened;`,
|
|
1145
1149
|
` opened = (() async {`,
|
|
1146
1150
|
` try {`,
|
|
@@ -1153,7 +1157,9 @@ export function generateDartApplication(
|
|
|
1153
1157
|
` }`,
|
|
1154
1158
|
` })();`,
|
|
1155
1159
|
` _nmsApplications[workspace] = opened;`,
|
|
1156
|
-
` return
|
|
1160
|
+
` return NmsInternalApplicationHost.nmsInternalAwaitReferencedApplication(`,
|
|
1161
|
+
` workspace: workspace, opening: opened,`,
|
|
1162
|
+
` );`,
|
|
1157
1163
|
` }`,
|
|
1158
1164
|
``,
|
|
1159
1165
|
` /// Open the workspace named by a typed ${rootType} custody reference.`,
|
|
@@ -2080,7 +2086,7 @@ export function generateDartApplication(
|
|
|
2080
2086
|
` Widget Function(BuildContext context, Object error, VoidCallback retry)? errorBuilder,`,
|
|
2081
2087
|
` ApplicationModelChange? onModelChange,`,
|
|
2082
2088
|
` ValueChanged<NomosApplicationStartupState>? onStartupStateChanged,`,
|
|
2083
|
-
` Duration startupTimeout = const Duration(
|
|
2089
|
+
` Duration startupTimeout = const Duration(minutes: 3),`,
|
|
2084
2090
|
` }) => NmsInternalApplicationHost.home<${application}>(`,
|
|
2085
2091
|
` key: key, cloud: cloud, application: application, signIn: signIn,`,
|
|
2086
2092
|
` bind: nomosInternalBind${application}, builder: builder,`,
|
|
@@ -1642,12 +1642,12 @@ const dartTypesImportFor = (generatedSource: string): string => {
|
|
|
1642
1642
|
* just the floor generated code needs — a lagging pin forces tenants into dependency_overrides. */
|
|
1643
1643
|
// 0.3.0: SurfacedValue<T>/SurfacedObservation/PendingConflictRow — generated Surfaced-field typing +
|
|
1644
1644
|
// the pendingConflicts read rows.
|
|
1645
|
-
const NOMOS_TYPES_DEP = "^0.8.
|
|
1645
|
+
const NOMOS_TYPES_DEP = "^0.8.4";
|
|
1646
1646
|
// 0.48.x: session-bound clients (XClient.bind/NomosClientInterface/DomainClientSessionMismatch/
|
|
1647
1647
|
// DomainNotInstalledForSession, engine.follow, pendingConflicts lanes) — the generated client
|
|
1648
1648
|
// REQUIRES this surface. 0.48.1 fixes NomosSession.watchPendingConflicts delegation.
|
|
1649
|
-
const NOMOS_CLIENT_DEP = "^0.64.
|
|
1650
|
-
const NOMOS_FLUTTER_DEP = "^0.63.
|
|
1649
|
+
const NOMOS_CLIENT_DEP = "^0.64.7";
|
|
1650
|
+
const NOMOS_FLUTTER_DEP = "^0.63.10";
|
|
1651
1651
|
// DRIFT TRIPWIRE: pubspec_pins.test.ts asserts these equal the CURRENT versions in dsl/dart/pubspec.yaml
|
|
1652
1652
|
// and dsl/dart_types/pubspec.yaml — a Dart release without this bump fails the suite, so tenants never
|
|
1653
1653
|
// land back in dependency_overrides (the exact co2 report this closes, third occurrence).
|
|
@@ -1917,14 +1917,25 @@ function generatedPackageApplication(
|
|
|
1917
1917
|
` /// Prove, adopt or restore the package law against this workspace's exact history.`,
|
|
1918
1918
|
` ${rootMember.prefix}.NomosModel get model => ${rootMember.member}.model;`,
|
|
1919
1919
|
``,
|
|
1920
|
-
` /// Current durability and convergence
|
|
1921
|
-
`
|
|
1920
|
+
` /// Current durability and convergence for the receiving-group workspace.`,
|
|
1921
|
+
` /// A slow or offline sibling never makes this workspace's readiness ambiguous.`,
|
|
1922
|
+
` ApplicationStatus get currentStatus => NmsInternalApplicationHost.currentStatus(_nmsSession);`,
|
|
1922
1923
|
``,
|
|
1923
|
-
` /// React whenever this
|
|
1924
|
-
` Stream<ApplicationStatus> watchStatus() => NmsInternalApplicationHost.
|
|
1924
|
+
` /// React whenever this receiving group saves, receives work, goes offline or needs attention.`,
|
|
1925
|
+
` Stream<ApplicationStatus> watchStatus() => NmsInternalApplicationHost.watchStatus(_nmsSession);`,
|
|
1925
1926
|
``,
|
|
1926
|
-
` /// Wait until accepted
|
|
1927
|
+
` /// Wait until this receiving group's accepted work is in custody and caught up.`,
|
|
1927
1928
|
` Future<void> whenCurrent({Duration timeout = const Duration(minutes: 2)}) =>`,
|
|
1929
|
+
` NmsInternalApplicationHost.whenCurrent(_nmsSession, timeout: timeout);`,
|
|
1930
|
+
``,
|
|
1931
|
+
` /// Aggregate posture across every child currently owned by this generated application.`,
|
|
1932
|
+
` ApplicationStatus get applicationStatus => NmsInternalApplicationHost.currentApplicationStatus(_nmsSession);`,
|
|
1933
|
+
``,
|
|
1934
|
+
` /// React to aggregate posture across every generated child currently in this application plane.`,
|
|
1935
|
+
` Stream<ApplicationStatus> watchApplicationStatus() => NmsInternalApplicationHost.watchApplicationStatus(_nmsSession);`,
|
|
1936
|
+
``,
|
|
1937
|
+
` /// Explicitly wait for every generated child currently owned by this application.`,
|
|
1938
|
+
` Future<void> whenApplicationCurrent({Duration timeout = const Duration(minutes: 2)}) =>`,
|
|
1928
1939
|
` NmsInternalApplicationHost.whenApplicationCurrent(_nmsSession, timeout: timeout);`,
|
|
1929
1940
|
...(hasInvitations
|
|
1930
1941
|
? [
|
|
@@ -1973,7 +1984,7 @@ function generatedPackageApplication(
|
|
|
1973
1984
|
` Widget Function(BuildContext context, Object error, VoidCallback retry)? errorBuilder,`,
|
|
1974
1985
|
` ApplicationModelChange? onModelChange,`,
|
|
1975
1986
|
` ValueChanged<NomosApplicationStartupState>? onStartupStateChanged,`,
|
|
1976
|
-
` Duration startupTimeout = const Duration(
|
|
1987
|
+
` Duration startupTimeout = const Duration(minutes: 3),`,
|
|
1977
1988
|
` }) => NmsInternalApplicationHost.home<${application}>(`,
|
|
1978
1989
|
` key: key, cloud: cloud, application: application, signIn: signIn,`,
|
|
1979
1990
|
` bind: nomosInternalBind${application}, builder: builder,`,
|
|
@@ -2544,7 +2555,8 @@ function emitDartPackages(
|
|
|
2544
2555
|
"library;",
|
|
2545
2556
|
"",
|
|
2546
2557
|
`export 'package:${packages.types}/${genRel}/${businessSharedFile}';`,
|
|
2547
|
-
`export 'package:nomos_flutter/src/generated_application_host.dart' show ApplicationModelApproval, ApplicationModelDecision, ApplicationModelPolicy, ApplicationModelReview;`,
|
|
2558
|
+
`export 'package:nomos_flutter/src/generated_application_host.dart' show ApplicationModelApproval, ApplicationModelDecision, ApplicationModelPolicy, ApplicationModelReview, NomosApplicationStartupPhase, NomosApplicationStartupState, NomosApplicationStartupTimeout, NomosWorkspaceOpenTimeout;`,
|
|
2559
|
+
`export 'package:nomos_types/nomos_types.dart' show CustodyError, CustodyPhase, CustodySource, NomosRecommendedAction;`,
|
|
2548
2560
|
...tenantTypesExportKeys
|
|
2549
2561
|
.map((file) => {
|
|
2550
2562
|
const names = tenantDartExportNames(typesSources.get(file) ?? "");
|
package/src/intent.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { z } from "zod";
|
|
10
10
|
|
|
11
11
|
import type {
|
|
12
|
+
BusinessSourceTrust,
|
|
12
13
|
Directive,
|
|
13
14
|
PreconditionDescriptor,
|
|
14
15
|
ReferentialMarker,
|
|
@@ -233,11 +234,38 @@ function unsupportedKernelGate(directive: Directive<any>): string | undefined {
|
|
|
233
234
|
if (directive.delegatedRoleGate !== undefined) return "delegated authority";
|
|
234
235
|
if (directive.firstDeviceEnrollGate !== undefined) return "first-device enrollment";
|
|
235
236
|
if (directive.certifiesEraGate !== undefined) return "era certification";
|
|
236
|
-
if (directive.businessSourceTrust !== undefined) return "source-trust preflight";
|
|
237
237
|
if ((directive.businessRecordInputs?.length ?? 0) > 0) return "record-input binding";
|
|
238
238
|
return undefined;
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
+
function remapBusinessSourceTrust<I>(
|
|
242
|
+
step: IntentStep<I, any>,
|
|
243
|
+
trust: BusinessSourceTrust,
|
|
244
|
+
): BusinessSourceTrust {
|
|
245
|
+
const field = (privatePath: string): string => {
|
|
246
|
+
const mapped = remapStepPayloadPath(step, privatePath.split("."));
|
|
247
|
+
if (mapped === undefined || mapped.length === 0) {
|
|
248
|
+
throw new Error(
|
|
249
|
+
`compound intent cannot remap source-trust field '${privatePath}' from '${step.directive.id}'`,
|
|
250
|
+
);
|
|
251
|
+
}
|
|
252
|
+
return mapped.join(".");
|
|
253
|
+
};
|
|
254
|
+
return {
|
|
255
|
+
viaDirectiveId: trust.viaDirectiveId,
|
|
256
|
+
fromPayload: field(trust.fromPayload),
|
|
257
|
+
queryId: trust.queryId,
|
|
258
|
+
queryArgs: Object.fromEntries(
|
|
259
|
+
Object.entries(trust.queryArgs).map(([target, source]) => [target, field(source)]),
|
|
260
|
+
),
|
|
261
|
+
copy: Object.fromEntries(
|
|
262
|
+
Object.entries(trust.copy).map(([target, source]) => [target, field(source)]),
|
|
263
|
+
),
|
|
264
|
+
genesisField: trust.genesisField,
|
|
265
|
+
keyHashesField: trust.keyHashesField,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
|
|
241
269
|
const dedupeBy = <T>(values: readonly T[], key: (value: T) => string): T[] => {
|
|
242
270
|
const out: T[] = [];
|
|
243
271
|
const seen = new Set<string>();
|
|
@@ -333,24 +361,44 @@ class IntentBuilder<I> {
|
|
|
333
361
|
|
|
334
362
|
const primary = this.steps.find((step) => step.directive.birthsChild !== true)?.directive
|
|
335
363
|
?? this.steps[0]!.directive;
|
|
336
|
-
const
|
|
337
|
-
for (const
|
|
364
|
+
const allOutputs: SecondaryOutput[] = [];
|
|
365
|
+
for (const step of this.steps) {
|
|
338
366
|
const candidate = step.directive;
|
|
339
|
-
if (
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
367
|
+
if (candidate.birthsChild !== true) {
|
|
368
|
+
allOutputs.push({
|
|
369
|
+
aggregateId: candidate.aggregateId,
|
|
370
|
+
marker: candidate.marker,
|
|
371
|
+
...(candidate.outputCardinality === "many" ? { many: true } : {}),
|
|
372
|
+
...(candidate.outputCardinality === "optional" ? { optional: true } : {}),
|
|
373
|
+
});
|
|
374
|
+
allOutputs.push(...(candidate.secondaryOutputs ?? []));
|
|
345
375
|
}
|
|
346
|
-
if (candidate.birthsChild !== true) outputs.push(...(candidate.secondaryOutputs ?? []));
|
|
347
376
|
}
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
),
|
|
352
|
-
|
|
377
|
+
const outputGroups = new Map<string, SecondaryOutput[]>();
|
|
378
|
+
for (const output of allOutputs) {
|
|
379
|
+
const key = `${output.marker}\0${output.aggregateId}`;
|
|
380
|
+
outputGroups.set(key, [...(outputGroups.get(key) ?? []), output]);
|
|
381
|
+
}
|
|
382
|
+
const composedOutput = (group: readonly SecondaryOutput[]): SecondaryOutput => ({
|
|
383
|
+
aggregateId: group[0]!.aggregateId,
|
|
384
|
+
marker: group[0]!.marker,
|
|
385
|
+
...(group.length > 1 || group.some((output) => output.many === true)
|
|
386
|
+
? { many: true }
|
|
387
|
+
: group[0]!.optional === true
|
|
388
|
+
? { optional: true }
|
|
389
|
+
: {}),
|
|
390
|
+
});
|
|
391
|
+
const primaryOutput = composedOutput(
|
|
392
|
+
outputGroups.get(`${primary.marker}\0${primary.aggregateId}`) ?? [{
|
|
393
|
+
aggregateId: primary.aggregateId,
|
|
394
|
+
marker: primary.marker,
|
|
395
|
+
}],
|
|
353
396
|
);
|
|
397
|
+
const secondaryOutputs = [...outputGroups.values()]
|
|
398
|
+
.map(composedOutput)
|
|
399
|
+
.filter(
|
|
400
|
+
(output) => !(output.aggregateId === primary.aggregateId && output.marker === primary.marker),
|
|
401
|
+
);
|
|
354
402
|
const inferredReturns = [
|
|
355
403
|
primary.aggregateId,
|
|
356
404
|
...secondaryOutputs.map((output) => output.aggregateId),
|
|
@@ -421,6 +469,16 @@ class IntentBuilder<I> {
|
|
|
421
469
|
}
|
|
422
470
|
}
|
|
423
471
|
const relationGate = oneStaticRelationGate(this.steps);
|
|
472
|
+
const sourceTrusts = this.steps.flatMap((step) =>
|
|
473
|
+
step.directive.businessSourceTrust === undefined
|
|
474
|
+
? []
|
|
475
|
+
: [remapBusinessSourceTrust(step, step.directive.businessSourceTrust)],
|
|
476
|
+
);
|
|
477
|
+
if (sourceTrusts.length > 1) {
|
|
478
|
+
throw new Error(
|
|
479
|
+
`intent('${this.id}') composes more than one source-trust preflight — split the business action by source`,
|
|
480
|
+
);
|
|
481
|
+
}
|
|
424
482
|
const steps = [...this.steps];
|
|
425
483
|
const plan = (facts: I, ctx: Ports): PlannedOp[] => {
|
|
426
484
|
const returned: PlannedOp[] = [];
|
|
@@ -455,8 +513,10 @@ class IntentBuilder<I> {
|
|
|
455
513
|
// engine cannot rebuild its aggregate registry entry and silently drops
|
|
456
514
|
// compound intents that also birth a child.
|
|
457
515
|
...(primary.aggregate === undefined ? {} : { aggregate: primary.aggregate }),
|
|
458
|
-
...(
|
|
459
|
-
? { outputCardinality:
|
|
516
|
+
...(primaryOutput.many === true
|
|
517
|
+
? { outputCardinality: "many" as const }
|
|
518
|
+
: primaryOutput.optional === true
|
|
519
|
+
? { outputCardinality: "optional" as const }
|
|
460
520
|
: {}),
|
|
461
521
|
...(secondaryOutputs.length > 0 ? { secondaryOutputs } : {}),
|
|
462
522
|
payloadSchema: (birthSteps[0]?.directive.payloadSchema ?? this.contractDeclaration.accepts) as unknown as z.ZodType<I>,
|
|
@@ -475,6 +535,9 @@ class IntentBuilder<I> {
|
|
|
475
535
|
].sort(),
|
|
476
536
|
...(preconditions.length > 0 ? { preconditions } : {}),
|
|
477
537
|
...(relationGate !== undefined ? { requiresRelationGate: relationGate } : {}),
|
|
538
|
+
...(sourceTrusts[0] === undefined
|
|
539
|
+
? {}
|
|
540
|
+
: { businessSourceTrust: sourceTrusts[0] }),
|
|
478
541
|
...(businessBirth === undefined
|
|
479
542
|
? {}
|
|
480
543
|
: {
|