@githolon/dsl 0.98.2 → 0.98.3
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/package.json +1 -1
- package/src/framework/home.ts +29 -14
- package/src/framework/signing_identity.ts +9 -0
- package/src/index.ts +9 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@githolon/dsl",
|
|
3
|
-
"version": "0.98.
|
|
3
|
+
"version": "0.98.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Nomos 2 domain-authoring DSL: aggregates + directives in TS, executed and encoded to the Rust kernel's wire shapes.",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.md",
|
package/src/framework/home.ts
CHANGED
|
@@ -231,6 +231,30 @@ export const birthHome = directive("birthHome")
|
|
|
231
231
|
.plan((p) => {
|
|
232
232
|
const founder = p.owner; // the actor for the child's own genesis steps (its self-bound owner subject)
|
|
233
233
|
const homeName = homeNameOf(p.owner); // workspace name == seeded homeName — derived from the SAME owner
|
|
234
|
+
// THE PARENT'S DECLARED VERIFIER (one captured read serves BOTH consumers below): the inherited
|
|
235
|
+
// `setAuthProvider` genesis step AND the enroll step's `verifiedVia` provenance stamp. Read it up
|
|
236
|
+
// front so the enroll step (which precedes the inheritance step in the chain) can see the issuer.
|
|
237
|
+
const apRows = p.inheritAuthProvider !== false
|
|
238
|
+
? readFrameworkDeclared<Array<Record<string, unknown>>>("authProvider", { scope: "platform" })
|
|
239
|
+
: undefined;
|
|
240
|
+
const apRaw = Array.isArray(apRows) && apRows.length > 0 ? apRows[0] : undefined;
|
|
241
|
+
// Projected rows are `{type,id,data:{…fields}}`; folded shapes may be flat — accept both.
|
|
242
|
+
const ap = (apRaw && typeof apRaw === "object" && typeof (apRaw as { data?: unknown }).data === "object"
|
|
243
|
+
? (apRaw as { data: Record<string, unknown> }).data
|
|
244
|
+
: apRaw) as Record<string, unknown> | undefined;
|
|
245
|
+
const apStr = (k: string): string | undefined => {
|
|
246
|
+
const v = ap?.[k];
|
|
247
|
+
return typeof v === "string" && v.length > 0 ? v : undefined;
|
|
248
|
+
};
|
|
249
|
+
// PROVENANCE (the verified-lineage thread, 2026-07-16): the kernel derives every later write's
|
|
250
|
+
// `principal_verified` from the ENROLL LEAF's `verifiedVia` — so a verified birth must stamp it or the
|
|
251
|
+
// born home's owner writes UNVERIFIED forever (and its own children are then born `verified:false`,
|
|
252
|
+
// whose chains refuse `verify_to_root`). The cert's `verified` IS the gate verdict post-admission
|
|
253
|
+
// (assemble_birth_attestation CAS-refuses a mismatch), so reading it in-plan is trustworthy — a lying
|
|
254
|
+
// cert never reaches this fold. An unverified birth stamps nothing (the unverified lane stays honest).
|
|
255
|
+
let certVerified = false;
|
|
256
|
+
try { certVerified = p.homeCert !== undefined && JSON.parse(p.homeCert).verified === true; } catch { /* malformed cert ⇒ unverified (the gate will refuse the birth anyway) */ }
|
|
257
|
+
const verifiedVia = certVerified ? apStr("issuer") : undefined;
|
|
234
258
|
const genesisChain: Array<{ domain: string; directiveId: string; actor: string; payload: Record<string, unknown>; domainHash?: string; domainPackageB64?: string }> = [
|
|
235
259
|
// THE ORDER-DECLARED LAW INSTALL: two layers, bytes-by-hash (empty package — the kernel resolves them
|
|
236
260
|
// from the parent's custody when it folds the birth; never the host). Matches buildGenesisChain's shape.
|
|
@@ -248,22 +272,13 @@ export const birthHome = directive("birthHome")
|
|
|
248
272
|
// ladder: every seed runs UNSIGNED on the still-warrant-free prefix; the warrant closes it). ERA-SAFE: a
|
|
249
273
|
// home born earlier (pre-feature law, no such step in its recipe) replays byte-identical — the era rule
|
|
250
274
|
// rides the LAW hash, not this branch.
|
|
251
|
-
{ domain: HOME_LAW_DOMAIN, directiveId: "enrollSigner", actor: founder, payload: { keyHash: p.ownerKeyHash, grantedBy: p.owner, grantedAt: 1 } },
|
|
275
|
+
{ domain: HOME_LAW_DOMAIN, directiveId: "enrollSigner", actor: founder, payload: { keyHash: p.ownerKeyHash, grantedBy: p.owner, grantedAt: 1, ...(verifiedVia !== undefined ? { verifiedVia } : {}) } },
|
|
252
276
|
];
|
|
253
|
-
// AUTHPROVIDER INHERITANCE (default ON — see the payload doc):
|
|
254
|
-
// (
|
|
255
|
-
//
|
|
277
|
+
// AUTHPROVIDER INHERITANCE (default ON — see the payload doc): copy the parent's declared provider
|
|
278
|
+
// (the up-front captured read above) AS DATA into the child genesis. The child owns the copy as its
|
|
279
|
+
// own law-state; nothing is inherited-by-reference. Opt out: `inheritAuthProvider: false`.
|
|
256
280
|
if (p.inheritAuthProvider !== false) {
|
|
257
|
-
const
|
|
258
|
-
const raw = Array.isArray(rows) && rows.length > 0 ? rows[0] : undefined;
|
|
259
|
-
// Projected rows are `{type,id,data:{…fields}}`; folded shapes may be flat — accept both.
|
|
260
|
-
const ap = (raw && typeof raw === "object" && typeof (raw as { data?: unknown }).data === "object"
|
|
261
|
-
? (raw as { data: Record<string, unknown> }).data
|
|
262
|
-
: raw) as Record<string, unknown> | undefined;
|
|
263
|
-
const str = (k: string): string | undefined => {
|
|
264
|
-
const v = ap?.[k];
|
|
265
|
-
return typeof v === "string" && v.length > 0 ? v : undefined;
|
|
266
|
-
};
|
|
281
|
+
const str = apStr;
|
|
267
282
|
const issuer = str("issuer");
|
|
268
283
|
if (issuer !== undefined) {
|
|
269
284
|
genesisChain.push({
|
|
@@ -212,6 +212,14 @@ export const enrollSigner = directive("enrollSigner")
|
|
|
212
212
|
keyHash: sha256Hex, // sha256hex of the ed25519 device PUBLIC key
|
|
213
213
|
grantedBy: z.string().min(1),
|
|
214
214
|
grantedAt: z.number().int().nonnegative(), // epoch ms, caller-stamped (determinism)
|
|
215
|
+
/** OPTIONAL PROVENANCE — the IdP/issuer that VOUCHED for this principal at the enrolling birth.
|
|
216
|
+
* The kernel's `verify_captured_principal` derives `principal_verified` from THIS leaf field on
|
|
217
|
+
* every later write, so a genesis enroll that omits it leaves the workspace's owner permanently
|
|
218
|
+
* UNVERIFIED (their children are then born `verified:false` and their chains refuse
|
|
219
|
+
* `verify_to_root` — the 2026-07-16 estate holarchy RED). Birth recipes stamp it from the
|
|
220
|
+
* CAS-verified birth cert (`cert.verified` IS the gate verdict post-admission) + the inherited
|
|
221
|
+
* AuthProvider issuer; an unverified birth omits it (the unverified lane stays honest). */
|
|
222
|
+
verifiedVia: z.string().min(1).optional(),
|
|
215
223
|
}),
|
|
216
224
|
)
|
|
217
225
|
.plan((p, ctx) => {
|
|
@@ -227,6 +235,7 @@ export const enrollSigner = directive("enrollSigner")
|
|
|
227
235
|
subject: "key:" + p.keyHash,
|
|
228
236
|
grantedBy: p.grantedBy,
|
|
229
237
|
grantedAt: String(p.grantedAt),
|
|
238
|
+
...(p.verifiedVia !== undefined ? { verifiedVia: p.verifiedVia } : {}),
|
|
230
239
|
});
|
|
231
240
|
});
|
|
232
241
|
|
package/src/index.ts
CHANGED
|
@@ -416,6 +416,15 @@ export {
|
|
|
416
416
|
type SignerEpochHandle,
|
|
417
417
|
type SignerAuthority,
|
|
418
418
|
} from "./framework/signing_identity.js";
|
|
419
|
+
// THE WORKSPACE VERIFIER is framework-owned law-state. Ordinary birth/onboarding flows compose and
|
|
420
|
+
// inherit it automatically; these exports exist for governance and acceptance laws that need to author
|
|
421
|
+
// the provider explicitly, without re-declaring the kernel's security schema in tenant code.
|
|
422
|
+
export {
|
|
423
|
+
AUTH_PROVIDER_ID,
|
|
424
|
+
AuthProvider,
|
|
425
|
+
setAuthProvider,
|
|
426
|
+
authProvider,
|
|
427
|
+
} from "./framework/auth_provider_law.js";
|
|
419
428
|
// THE HOME HOLON (home_holons_and_cross_custody.md §4) — the identity-role law: the shared-with-me access
|
|
420
429
|
// index + the owner lane to maintain it (the key directory is the `signer` relation above).
|
|
421
430
|
export {
|