@githolon/dsl 0.105.14 → 0.105.16
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
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## 0.64.32
|
|
2
|
+
|
|
3
|
+
- Prove a restored generated-application device is enrolled before exposing business APIs, including recovery from an interrupted bootstrap journal.
|
|
4
|
+
|
|
5
|
+
## 0.64.31
|
|
6
|
+
|
|
7
|
+
- Restage the validated intent-offer byte gate and deterministic signer-posture reader into the immutable Dart runner.
|
|
8
|
+
|
|
9
|
+
## 0.64.30
|
|
10
|
+
|
|
11
|
+
- Recover an authenticated generated application's replacement device through the established repeated-birth compatibility lane when guardian policy refuses keyless enrolment.
|
|
12
|
+
- Resolve signer posture from the relation tuple's deterministic aggregate address so composed application law cannot make framework query aliases ambiguous.
|
|
13
|
+
|
|
1
14
|
## 0.64.29
|
|
2
15
|
|
|
3
16
|
- Restaged with the current kernel candidate: regenerated vendored assets (kernel release identity is baked into them). Published pub.dev archives are immutable, so regenerated bytes ride their own version.
|
|
@@ -8152,8 +8152,8 @@ function createGovernanceOffers(ctx) {
|
|
|
8152
8152
|
},
|
|
8153
8153
|
/**
|
|
8154
8154
|
* PARENT-AUTHORITY POSTURE (read-only diagnostic): is `identity:<principal>#signer@key:<keyHash>`
|
|
8155
|
-
* a LIVE tuple on `parent`'s chain? Reads the
|
|
8156
|
-
*
|
|
8155
|
+
* a LIVE tuple on `parent`'s chain? Reads the tuple's deterministic aggregate address over the
|
|
8156
|
+
* generic record lane — one O(1) read, no authoring and no ambiguous query alias in composed law. Returns
|
|
8157
8157
|
* `{ parent, principal, keyHash, object, relation, enrolled, revoked, checkedAt }`.
|
|
8158
8158
|
* `revoked: true` means the subject's leaf was flipped `status:revoked` (remove-wins — a lawful
|
|
8159
8159
|
* re-enroll of the SAME key is refused; mint + enroll a new device key instead).
|
|
@@ -8167,19 +8167,13 @@ function createGovernanceOffers(ctx) {
|
|
|
8167
8167
|
keyHash = await sha256hexBytes2(bytesUnb642(publicKey));
|
|
8168
8168
|
}
|
|
8169
8169
|
const object = signerObjectOf(p);
|
|
8170
|
+
const aggregateId = `reltuple-${object}-signer`;
|
|
8170
8171
|
let rows;
|
|
8171
8172
|
if (parent === workspace && !remote) {
|
|
8172
|
-
rows = JSON.parse(call("query", { queryBytes: qBytes2({
|
|
8173
|
+
rows = JSON.parse(call("query", { queryBytes: qBytes2({ op: "byId", aggregateId }) })) || [];
|
|
8173
8174
|
} else {
|
|
8174
8175
|
const headers = authToken ? { Authorization: `Bearer ${authToken}`, "x-nomos-auth": authToken } : authHeaders;
|
|
8175
|
-
const
|
|
8176
|
-
parent,
|
|
8177
|
-
operationId: "relationTuplesByObject",
|
|
8178
|
-
method: "get",
|
|
8179
|
-
token: authToken,
|
|
8180
|
-
principal: p
|
|
8181
|
-
});
|
|
8182
|
-
const r = await _fetch(`${base}/v2/workspaces/${parent}${route.path}?object=${encodeURIComponent(object)}`, { headers });
|
|
8176
|
+
const r = await _fetch(`${base}/v2/workspaces/${parent}/aggregates/${encodeURIComponent(aggregateId)}`, { headers });
|
|
8183
8177
|
const text = await r.text();
|
|
8184
8178
|
let body;
|
|
8185
8179
|
try {
|
|
@@ -8187,7 +8181,7 @@ function createGovernanceOffers(ctx) {
|
|
|
8187
8181
|
} catch {
|
|
8188
8182
|
body = text;
|
|
8189
8183
|
}
|
|
8190
|
-
if (!r.ok) throw new Error(`parentSignerEnrollment: reading ${parent}'s
|
|
8184
|
+
if (!r.ok) throw new Error(`parentSignerEnrollment: reading ${parent}'s signer tuple failed (${r.status}): ${typeof body === "string" ? body.slice(0, 200) : JSON.stringify(body).slice(0, 200)}`);
|
|
8191
8185
|
rows = Array.isArray(body) ? body : body && Array.isArray(body.rows) ? body.rows : [];
|
|
8192
8186
|
}
|
|
8193
8187
|
let enrolled = false, revoked = false, verifiedVia;
|
|
@@ -102,6 +102,8 @@ async function refreshRuntimeDir(cloud, dir, { fetchImpl = globalThis.fetch, log
|
|
|
102
102
|
// src/_adapter/engine.ts
|
|
103
103
|
var engine_exports = {};
|
|
104
104
|
__export(engine_exports, {
|
|
105
|
+
MAX_INLINE_INTENT_OFFER_BYTES: () => MAX_INLINE_INTENT_OFFER_BYTES,
|
|
106
|
+
MAX_STAGED_INTENT_OFFER_BYTES: () => MAX_STAGED_INTENT_OFFER_BYTES,
|
|
105
107
|
NOMOS_SHARD_ROWS_READ: () => NOMOS_SHARD_ROWS_READ,
|
|
106
108
|
admitAll: () => admitAll,
|
|
107
109
|
admitIntentOffers: () => admitIntentOffers,
|
|
@@ -164,6 +166,7 @@ __export(engine_exports, {
|
|
|
164
166
|
ingestPackAsCustody: () => ingestPackAsCustody,
|
|
165
167
|
installedLaw: () => installedLaw,
|
|
166
168
|
intentOfferResidencies: () => intentOfferResidencies,
|
|
169
|
+
intentOfferSizeRefusal: () => intentOfferSizeRefusal,
|
|
167
170
|
isDirty: () => isDirty,
|
|
168
171
|
isWarranted: () => isWarranted,
|
|
169
172
|
kernelStamp: () => kernelStamp,
|
|
@@ -6781,6 +6784,12 @@ async function replicateIntents(eng2, ws, ledger, intents, { push = true } = {})
|
|
|
6781
6784
|
log("replicate-globals", { ws, replicated: replicated.length, skipped: skipped.length, refused: refused.length });
|
|
6782
6785
|
return { replicated, skipped, refused };
|
|
6783
6786
|
}
|
|
6787
|
+
var MAX_INLINE_INTENT_OFFER_BYTES = 32 * 1024 * 1024;
|
|
6788
|
+
var MAX_STAGED_INTENT_OFFER_BYTES = 64 * 1024 * 1024;
|
|
6789
|
+
function intentOfferSizeRefusal(staged, byteLength) {
|
|
6790
|
+
const maxOfferBytes = staged ? MAX_STAGED_INTENT_OFFER_BYTES : MAX_INLINE_INTENT_OFFER_BYTES;
|
|
6791
|
+
return byteLength <= 0 || byteLength > maxOfferBytes ? `intent offer must carry changeB64 <= ${maxOfferBytes / (1024 * 1024)} MiB` : null;
|
|
6792
|
+
}
|
|
6784
6793
|
async function admitIntentOffers(eng2, ws, ledger, offers, { receiptFence = null, shardRouting = null, clientBase = null } = {}) {
|
|
6785
6794
|
const main = await mainIntentIds(eng2, ws);
|
|
6786
6795
|
const sessions = /* @__PURE__ */ new Map();
|
|
@@ -6852,9 +6861,16 @@ async function admitIntentOffers(eng2, ws, ledger, offers, { receiptFence = null
|
|
|
6852
6861
|
let blob = offer?.blob instanceof Uint8Array ? offer.blob : null;
|
|
6853
6862
|
try {
|
|
6854
6863
|
if (!blob && typeof offer?.changeB64 === "string") blob = Uint8Array.from(atob(offer.changeB64), (c) => c.charCodeAt(0));
|
|
6855
|
-
|
|
6856
|
-
|
|
6857
|
-
|
|
6864
|
+
if (!blob) {
|
|
6865
|
+
rec.rejected.push({
|
|
6866
|
+
oid: String(offer?.oid || "").slice(0, 10),
|
|
6867
|
+
error: intentOfferSizeRefusal(!!offer?.staged, 0)
|
|
6868
|
+
});
|
|
6869
|
+
continue;
|
|
6870
|
+
}
|
|
6871
|
+
const sizeRefusal = intentOfferSizeRefusal(!!offer?.staged, blob.byteLength);
|
|
6872
|
+
if (sizeRefusal !== null) {
|
|
6873
|
+
rec.rejected.push({ oid: String(offer?.oid || "").slice(0, 10), error: sizeRefusal });
|
|
6858
6874
|
continue;
|
|
6859
6875
|
}
|
|
6860
6876
|
const inspected = kgit.inspectChange(eng2, blob);
|
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.32
|
|
11
11
|
|
|
12
12
|
environment:
|
|
13
13
|
sdk: ^3.5.0
|
package/package.json
CHANGED
|
@@ -7183,8 +7183,8 @@ function createGovernanceOffers(ctx) {
|
|
|
7183
7183
|
},
|
|
7184
7184
|
/**
|
|
7185
7185
|
* PARENT-AUTHORITY POSTURE (read-only diagnostic): is `identity:<principal>#signer@key:<keyHash>`
|
|
7186
|
-
* a LIVE tuple on `parent`'s chain? Reads the
|
|
7187
|
-
*
|
|
7186
|
+
* a LIVE tuple on `parent`'s chain? Reads the tuple's deterministic aggregate address over the
|
|
7187
|
+
* generic record lane — one O(1) read, no authoring and no ambiguous query alias in composed law. Returns
|
|
7188
7188
|
* `{ parent, principal, keyHash, object, relation, enrolled, revoked, checkedAt }`.
|
|
7189
7189
|
* `revoked: true` means the subject's leaf was flipped `status:revoked` (remove-wins — a lawful
|
|
7190
7190
|
* re-enroll of the SAME key is refused; mint + enroll a new device key instead).
|
|
@@ -7198,19 +7198,13 @@ function createGovernanceOffers(ctx) {
|
|
|
7198
7198
|
keyHash = await sha256hexBytes2(bytesUnb642(publicKey));
|
|
7199
7199
|
}
|
|
7200
7200
|
const object = signerObjectOf(p);
|
|
7201
|
+
const aggregateId = `reltuple-${object}-signer`;
|
|
7201
7202
|
let rows;
|
|
7202
7203
|
if (parent === workspace && !remote) {
|
|
7203
|
-
rows = JSON.parse(call("query", { queryBytes: qBytes2({
|
|
7204
|
+
rows = JSON.parse(call("query", { queryBytes: qBytes2({ op: "byId", aggregateId }) })) || [];
|
|
7204
7205
|
} else {
|
|
7205
7206
|
const headers = authToken ? { Authorization: `Bearer ${authToken}`, "x-nomos-auth": authToken } : authHeaders;
|
|
7206
|
-
const
|
|
7207
|
-
parent,
|
|
7208
|
-
operationId: "relationTuplesByObject",
|
|
7209
|
-
method: "get",
|
|
7210
|
-
token: authToken,
|
|
7211
|
-
principal: p
|
|
7212
|
-
});
|
|
7213
|
-
const r = await _fetch(`${base}/v2/workspaces/${parent}${route.path}?object=${encodeURIComponent(object)}`, { headers });
|
|
7207
|
+
const r = await _fetch(`${base}/v2/workspaces/${parent}/aggregates/${encodeURIComponent(aggregateId)}`, { headers });
|
|
7214
7208
|
const text2 = await r.text();
|
|
7215
7209
|
let body;
|
|
7216
7210
|
try {
|
|
@@ -7218,7 +7212,7 @@ function createGovernanceOffers(ctx) {
|
|
|
7218
7212
|
} catch {
|
|
7219
7213
|
body = text2;
|
|
7220
7214
|
}
|
|
7221
|
-
if (!r.ok) throw new Error(`parentSignerEnrollment: reading ${parent}'s
|
|
7215
|
+
if (!r.ok) throw new Error(`parentSignerEnrollment: reading ${parent}'s signer tuple failed (${r.status}): ${typeof body === "string" ? body.slice(0, 200) : JSON.stringify(body).slice(0, 200)}`);
|
|
7222
7216
|
rows = Array.isArray(body) ? body : body && Array.isArray(body.rows) ? body.rows : [];
|
|
7223
7217
|
}
|
|
7224
7218
|
let enrolled = false, revoked = false, verifiedVia;
|
|
@@ -13504,6 +13498,27 @@ function applicationError(message, code, cause) {
|
|
|
13504
13498
|
if (cause !== void 0) error.cause = cause;
|
|
13505
13499
|
return error;
|
|
13506
13500
|
}
|
|
13501
|
+
function applicationOpenFailure(application, requestedModel, cause) {
|
|
13502
|
+
const typed = cause;
|
|
13503
|
+
if (typed?.name === "NomosApplicationError" && typeof typed.code === "string") {
|
|
13504
|
+
return cause;
|
|
13505
|
+
}
|
|
13506
|
+
const raw = String(cause?.message ?? cause ?? "unknown failure");
|
|
13507
|
+
if (/birth-current-law-unavailable|birth install target|\[nomos\.birth\.model_not_active\]/i.test(raw)) {
|
|
13508
|
+
const model = /(?:birth install target|under model)\s+([0-9a-f]{64})/i.exec(raw)?.[1] ?? requestedModel;
|
|
13509
|
+
const shortModel = /^[0-9a-f]{64}$/i.test(model) ? `${model.slice(0, 16)}\u2026` : "the requested model";
|
|
13510
|
+
return applicationError(
|
|
13511
|
+
`Nomos application '${application}' cannot create this private workspace because its parent does not currently serve model ${shortModel}. No workspace was created. A current generated client should inherit the parent's active model at birth and then govern adoption of its packaged model; regenerate the application client before retrying, or have an authorised application release adopt that model on the parent.`,
|
|
13512
|
+
"nomos.application.bootstrap_model_not_active",
|
|
13513
|
+
cause
|
|
13514
|
+
);
|
|
13515
|
+
}
|
|
13516
|
+
return applicationError(
|
|
13517
|
+
`Nomos could not finish preparing the signed-in '${application}' application: ${raw}`,
|
|
13518
|
+
"nomos.application.open_failed",
|
|
13519
|
+
cause
|
|
13520
|
+
);
|
|
13521
|
+
}
|
|
13507
13522
|
async function ensureGeneratedModelCurrent(application, approveModel) {
|
|
13508
13523
|
if (application.model?.adopt === void 0) {
|
|
13509
13524
|
throw applicationError(
|
|
@@ -13869,7 +13884,6 @@ async function nomosInternalOpenGeneratedApplication(options, bind, internals =
|
|
|
13869
13884
|
let authorityHolon = await measureOpen("open private application custody", () => mountAuthority(secret, authToken));
|
|
13870
13885
|
const storedJournal = await measureOpen("load application bootstrap state", () => store.loadText(journalState));
|
|
13871
13886
|
const completed = storedJournal === "complete";
|
|
13872
|
-
const hadDurableSecret = secret !== null;
|
|
13873
13887
|
let publicKey;
|
|
13874
13888
|
if (secret === null) {
|
|
13875
13889
|
const device = await measureOpen("create application device identity", () => authorityHolon.authorKeygen());
|
|
@@ -13890,6 +13904,43 @@ async function nomosInternalOpenGeneratedApplication(options, bind, internals =
|
|
|
13890
13904
|
throw applicationError("Sign in changed authority while preparing this application device.", "nomos.authority.changed_during_open");
|
|
13891
13905
|
}
|
|
13892
13906
|
authToken = deviceToken;
|
|
13907
|
+
const birthOrRepeat = async () => {
|
|
13908
|
+
const birth = await measureOpen("establish private application custody", () => authorityHolon.nomosInternalBirthReceivingGroup({
|
|
13909
|
+
parent: application,
|
|
13910
|
+
principal,
|
|
13911
|
+
subject,
|
|
13912
|
+
device: { secret, public: publicKey },
|
|
13913
|
+
authToken,
|
|
13914
|
+
idToken: authToken,
|
|
13915
|
+
verifiedVia: issuer,
|
|
13916
|
+
bornAt: now().toISOString(),
|
|
13917
|
+
confirm: true
|
|
13918
|
+
}));
|
|
13919
|
+
const verdict = birth.verify;
|
|
13920
|
+
if (verdict !== void 0 && verdict.valid !== true) throw new Error(`the born application failed replay verification: ${String(verdict.error ?? "unknown")}`);
|
|
13921
|
+
};
|
|
13922
|
+
const ensureSignerEnrollment = async () => {
|
|
13923
|
+
const enroll = () => authorityHolon.ensureParentSignerEnrollment({
|
|
13924
|
+
// The write gate that this device will use is the receiving-group workspace itself.
|
|
13925
|
+
// The application root authorises/births that home; it is not a substitute signer index.
|
|
13926
|
+
parent: receivingGroup,
|
|
13927
|
+
// The author gate speaks canonical Nomos principals. A provider subject is deliberately
|
|
13928
|
+
// opaque and may contain its own namespace separators; never enrol that raw value as the actor.
|
|
13929
|
+
principal: subject,
|
|
13930
|
+
publicKey,
|
|
13931
|
+
authorSecret: secret,
|
|
13932
|
+
authToken,
|
|
13933
|
+
idToken: authToken,
|
|
13934
|
+
verifiedVia: issuer
|
|
13935
|
+
});
|
|
13936
|
+
try {
|
|
13937
|
+
await measureOpen("confirm private-custody signer enrolment", enroll);
|
|
13938
|
+
} catch (error) {
|
|
13939
|
+
if (!String(error).includes("receiving-group-additional-device-requires-current-device-or-guardian")) throw error;
|
|
13940
|
+
await birthOrRepeat();
|
|
13941
|
+
await measureOpen("verify recovered private-custody signer enrolment", enroll);
|
|
13942
|
+
}
|
|
13943
|
+
};
|
|
13893
13944
|
if (!completed) {
|
|
13894
13945
|
let homeAvailable = false;
|
|
13895
13946
|
try {
|
|
@@ -13897,33 +13948,7 @@ async function nomosInternalOpenGeneratedApplication(options, bind, internals =
|
|
|
13897
13948
|
} catch {
|
|
13898
13949
|
}
|
|
13899
13950
|
if (!homeAvailable) {
|
|
13900
|
-
|
|
13901
|
-
parent: application,
|
|
13902
|
-
principal,
|
|
13903
|
-
subject,
|
|
13904
|
-
device: { secret, public: publicKey },
|
|
13905
|
-
authToken,
|
|
13906
|
-
idToken: authToken,
|
|
13907
|
-
verifiedVia: issuer,
|
|
13908
|
-
bornAt: now().toISOString(),
|
|
13909
|
-
confirm: true
|
|
13910
|
-
}));
|
|
13911
|
-
const verdict = birth.verify;
|
|
13912
|
-
if (verdict !== void 0 && verdict.valid !== true) throw new Error(`the born application failed replay verification: ${String(verdict.error ?? "unknown")}`);
|
|
13913
|
-
} else if (!hadDurableSecret) {
|
|
13914
|
-
await measureOpen("enrol application device in its private custody", () => authorityHolon.ensureParentSignerEnrollment({
|
|
13915
|
-
// The write gate that this device will use is the receiving-group workspace itself.
|
|
13916
|
-
// The application root authorises/births that home; it is not a substitute signer index.
|
|
13917
|
-
parent: receivingGroup,
|
|
13918
|
-
// The author gate speaks canonical Nomos principals. A provider subject is deliberately
|
|
13919
|
-
// opaque and may contain its own namespace separators; never enrol that raw value as the actor.
|
|
13920
|
-
principal: subject,
|
|
13921
|
-
publicKey,
|
|
13922
|
-
authorSecret: secret,
|
|
13923
|
-
authToken,
|
|
13924
|
-
idToken: authToken,
|
|
13925
|
-
verifiedVia: issuer
|
|
13926
|
-
}));
|
|
13951
|
+
await birthOrRepeat();
|
|
13927
13952
|
}
|
|
13928
13953
|
await measureOpen("save application bootstrap progress", () => store.saveText(journalState, "home-available"));
|
|
13929
13954
|
authorityHolon = await measureOpen("rebind durable application authority", () => mountAuthority(secret, authToken));
|
|
@@ -13936,23 +13961,11 @@ async function nomosInternalOpenGeneratedApplication(options, bind, internals =
|
|
|
13936
13961
|
const verified = await measureOpen("verify new application custody", () => authorityHolon.verifyChain());
|
|
13937
13962
|
if (verified.valid !== true) throw new Error(`the private authority context failed replay verification: ${String(verified.error ?? "unknown")}`);
|
|
13938
13963
|
await measureOpen("save application bootstrap progress", () => store.saveText(journalState, "verified"));
|
|
13939
|
-
|
|
13940
|
-
await measureOpen("confirm private-custody signer enrolment", () => authorityHolon.ensureParentSignerEnrollment({
|
|
13941
|
-
parent: receivingGroup,
|
|
13942
|
-
principal: subject,
|
|
13943
|
-
authorSecret: secret,
|
|
13944
|
-
authToken,
|
|
13945
|
-
idToken: authToken,
|
|
13946
|
-
verifiedVia: issuer
|
|
13947
|
-
}));
|
|
13948
|
-
} catch (error) {
|
|
13949
|
-
if (/revoked/i.test(String(error))) throw error;
|
|
13950
|
-
}
|
|
13951
|
-
await measureOpen("complete application bootstrap journal", async () => {
|
|
13964
|
+
await measureOpen("save verified application bootstrap journal", async () => {
|
|
13952
13965
|
await store.saveText(journalState, "complete");
|
|
13953
|
-
await store.remove(journalState);
|
|
13954
13966
|
});
|
|
13955
13967
|
}
|
|
13968
|
+
await ensureSignerEnrollment();
|
|
13956
13969
|
holon = authorityHolon;
|
|
13957
13970
|
const authorityVerified = await measureOpen("verify application custody", () => holon.verifyChain());
|
|
13958
13971
|
if (authorityVerified.valid !== true) throw new Error(`the private authority context failed replay verification: ${String(authorityVerified.error ?? "unknown")}`);
|
|
@@ -14042,7 +14055,7 @@ async function nomosInternalOpenGeneratedApplication(options, bind, internals =
|
|
|
14042
14055
|
} catch (cause) {
|
|
14043
14056
|
await closeRealm().catch(() => {
|
|
14044
14057
|
});
|
|
14045
|
-
throw
|
|
14058
|
+
throw applicationOpenFailure(application, options.lawHash, cause);
|
|
14046
14059
|
}
|
|
14047
14060
|
}
|
|
14048
14061
|
export {
|
|
@@ -1664,8 +1664,8 @@ const NOMOS_TYPES_DEP = "^0.8.7";
|
|
|
1664
1664
|
// 0.48.x: session-bound clients (XClient.bind/NomosClientInterface/DomainClientSessionMismatch/
|
|
1665
1665
|
// DomainNotInstalledForSession, engine.follow, pendingConflicts lanes) — the generated client
|
|
1666
1666
|
// REQUIRES this surface. 0.48.1 fixes NomosSession.watchPendingConflicts delegation.
|
|
1667
|
-
const NOMOS_CLIENT_DEP = "^0.64.
|
|
1668
|
-
const NOMOS_FLUTTER_DEP = "^0.63.
|
|
1667
|
+
const NOMOS_CLIENT_DEP = "^0.64.32";
|
|
1668
|
+
const NOMOS_FLUTTER_DEP = "^0.63.55";
|
|
1669
1669
|
// DRIFT TRIPWIRE: pubspec_pins.test.ts asserts these equal the CURRENT versions in dsl/dart/pubspec.yaml
|
|
1670
1670
|
// and dsl/dart_types/pubspec.yaml — a Dart release without this bump fails the suite, so tenants never
|
|
1671
1671
|
// land back in dependency_overrides (the exact co2 report this closes, third occurrence).
|