@githolon/dsl 0.9.0 → 0.10.0
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 +42 -8
- package/src/index.ts +3 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@githolon/dsl",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
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
|
@@ -32,8 +32,14 @@ import { directive } from "../directive.js";
|
|
|
32
32
|
import { create } from "../authoring.js";
|
|
33
33
|
import { set, type PlannedOp } from "../ops.js";
|
|
34
34
|
import { query } from "../query.js";
|
|
35
|
+
import { workspaceInvariant, refAs } from "./workspace_invariant.js";
|
|
35
36
|
import { identityRelations } from "./signing_identity.js";
|
|
36
37
|
|
|
38
|
+
// `nomos.sha256` — the TRUSTLESS, pure hash computed IN the githolon (Rust sha2 bound in the sealed engine;
|
|
39
|
+
// see deterministic-rquickjs). Available as a global to plans + invariant predicates (like `nomos.mint`); it
|
|
40
|
+
// lets the home law re-derive `home-<hash(owner)>` itself, so the SQUAT invariant runs in-law on every peer.
|
|
41
|
+
declare const nomos: { sha256(input: string): string };
|
|
42
|
+
|
|
37
43
|
/** The KEY DIRECTORY is the `signer` relation — re-exported so a home holon's law composes it (the
|
|
38
44
|
* identity's public device keys, enrolled via `enrollSigner`, checked by the gate). */
|
|
39
45
|
export { identityRelations };
|
|
@@ -47,30 +53,58 @@ export { identityRelations };
|
|
|
47
53
|
* `seedHomeOwner`, kept off the open session lane), so a tenant cannot forge ownership.
|
|
48
54
|
*/
|
|
49
55
|
export const HOME_OWNER_ID = "home-owner:self";
|
|
56
|
+
/** A home holon's SELF-COMMITTED NAME prefix — `home-<sha256(subject)>` (the client's `homeNameOf` + the
|
|
57
|
+
* squat invariant both derive it). The home's chain commits to its own routing name, so the bailiff can
|
|
58
|
+
* bind the name to the CONTENT (custody) while the LAW guarantees the name hashes its owner. */
|
|
59
|
+
export const HOME_NAME_PREFIX = "home-";
|
|
60
|
+
export const HOME_NAME_HASH_LEN = 40;
|
|
50
61
|
export const HomeOwner = aggregate("HomeOwner", {
|
|
51
62
|
/** The identity this home belongs to — the canonical `user:<uid>` subject the §3 gate binds quotes to. */
|
|
52
63
|
principal: t.string().merge(Lww),
|
|
64
|
+
/** THE HOME'S SELF-COMMITTED NAME (`home-<sha256(principal)>`) — the squat invariant asserts it hashes the
|
|
65
|
+
* owner, so the chain's claimed name can ONLY be its rightful owner's slot (home_holons §5). */
|
|
66
|
+
homeName: t.string().merge(Lww),
|
|
53
67
|
/** ISO-8601, caller-stamped (determinism — no clock in the plan). */
|
|
54
68
|
bornAt: t.string().merge(Lww),
|
|
55
69
|
});
|
|
56
70
|
|
|
57
|
-
/** The framework PRIMITIVE plan: stamp the home's owner (singleton at the fixed id
|
|
58
|
-
export function writeHomeOwner(p: { principal: string; bornAt: string }): PlannedOp[] {
|
|
71
|
+
/** The framework PRIMITIVE plan: stamp the home's owner + its self-committed name (singleton at the fixed id). */
|
|
72
|
+
export function writeHomeOwner(p: { principal: string; homeName: string; bornAt: string }): PlannedOp[] {
|
|
59
73
|
const h = instance(HomeOwner, HOME_OWNER_ID);
|
|
60
|
-
return [set(h, "principal", p.principal), set(h, "bornAt", p.bornAt)];
|
|
74
|
+
return [set(h, "principal", p.principal), set(h, "homeName", p.homeName), set(h, "bornAt", p.bornAt)];
|
|
61
75
|
}
|
|
62
76
|
|
|
63
77
|
/**
|
|
64
|
-
* `seedHomeOwner` — the birth-door directive that stamps the home's owner
|
|
65
|
-
* CONTROL-PLANE write: the host authors it once at lazy birth
|
|
66
|
-
*
|
|
67
|
-
*
|
|
78
|
+
* `seedHomeOwner` — the birth-door directive that stamps the home's owner + its self-committed `homeName` at
|
|
79
|
+
* the fixed singleton id. A CONTROL-PLANE write: the host authors it once at lazy birth; the open session
|
|
80
|
+
* lane structurally REFUSES it (by directive id). `.ensures` (a deterministic-keyed singleton). The `homeName`
|
|
81
|
+
* is caller-supplied but the {@link homeNameBindsOwner} invariant proves it `== home-<sha256(principal)>`,
|
|
82
|
+
* so a squatter cannot claim a name slot that doesn't hash to ITS own owner.
|
|
68
83
|
*/
|
|
69
84
|
export const seedHomeOwner = directive("seedHomeOwner")
|
|
70
85
|
.ensures(HomeOwner)
|
|
71
|
-
.payload(z.object({ principal: z.string().min(1), bornAt: z.string().min(1) }))
|
|
86
|
+
.payload(z.object({ principal: z.string().min(1), homeName: z.string().min(1), bornAt: z.string().min(1) }))
|
|
72
87
|
.plan((p) => writeHomeOwner(p));
|
|
73
88
|
|
|
89
|
+
/**
|
|
90
|
+
* THE SQUAT INVARIANT (home_holons §5) — a home holon's self-committed `homeName` MUST be the hash of its
|
|
91
|
+
* owner: `homeName == home-<sha256(principal)>`. Declared by the home law, it EXECUTES at the one gate — and
|
|
92
|
+
* crucially at `verify_chain` (the bailiff's upload-birth): a squatter's chain (claiming `home-<hash(bob)>`
|
|
93
|
+
* but owned by `mallory`) FAILS the home law's OWN gate during adoption — refused IN THE GITHOLON, BY THE LAW,
|
|
94
|
+
* never by a host check. The host only routes the chain to the name it commits to (custody). `nomos.sha256`
|
|
95
|
+
* re-derives the hash in-law on every peer, so the verdict is identical everywhere.
|
|
96
|
+
*/
|
|
97
|
+
export const homeNameBindsOwner = workspaceInvariant("HomeNameBindsOwner")
|
|
98
|
+
.on("seedHomeOwner")
|
|
99
|
+
.reads(() => [refAs("owner", "HomeOwner", HOME_OWNER_ID)])
|
|
100
|
+
.assert(({ owner }) => {
|
|
101
|
+
const o = (owner ?? {}) as { principal?: string; homeName?: string };
|
|
102
|
+
const expected = HOME_NAME_PREFIX + nomos.sha256(String(o.principal ?? "")).slice(0, HOME_NAME_HASH_LEN);
|
|
103
|
+
return o.homeName === expected
|
|
104
|
+
? { accept: true }
|
|
105
|
+
: { reject: "a home's name must hash its owner (home-<sha256(principal)>) — refusing a squatted home" };
|
|
106
|
+
});
|
|
107
|
+
|
|
74
108
|
/**
|
|
75
109
|
* THE SHARED-WITH-ME INDEX (§5) — one record per cross-custody attestation delivered to this home holon:
|
|
76
110
|
* a signed edge `<asserterWorkspace> : <object> # <relation> @ this-identity`, indexed LOCALLY so the
|
package/src/index.ts
CHANGED
|
@@ -243,8 +243,11 @@ export {
|
|
|
243
243
|
sharedByWorkspace,
|
|
244
244
|
HomeOwner,
|
|
245
245
|
HOME_OWNER_ID,
|
|
246
|
+
HOME_NAME_PREFIX,
|
|
247
|
+
HOME_NAME_HASH_LEN,
|
|
246
248
|
seedHomeOwner,
|
|
247
249
|
writeHomeOwner,
|
|
250
|
+
homeNameBindsOwner,
|
|
248
251
|
} from "./framework/home.js";
|
|
249
252
|
// THE GENESIS WARRANT (identity_keys.md step 0) — the in-history birth fact that lets
|
|
250
253
|
// the gate's genesis clause admit a founding control-plane grant on a virgin chain.
|