§H.12 steps 10-11: creator-ceiling enforcement, birth-time ACL snapshot
dictionary_snapshot_acl_from_parent(child, parent): walks the child's dictionary, copies acl_allow/acl_mode/acl_pinned/acl_ttl from the parent's matching word (by name, via vm_find_word() -- FIND's own lookup, not modified) onto the child's entry. One-time snapshot at birth, no live sync, matching H.3's decided rationale (a program developed against one ACL set must not have it silently changed by later parent changes). Called once, after dict_hash/parity logging rather than before -- the snapshot depends on the parent's current ACL state, which can vary run-to-run once Zuse elevations exist, so applying it earlier would break the "same capsule twice produces the same dict hash" determinism invariant. Verified 3-arch boot to ok> (amd64/aarch64/riscv64). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ed86a759e1
commit
a268abe925
+15
-5
@@ -4024,11 +4024,21 @@ work, not new invention.
|
||||
which also exercises 8 and 9 unchanged.
|
||||
|
||||
**Phase 4 — Creator-ceiling enforcement (H.3, birth-time snapshot)**
|
||||
- [ ] **10.** `dictionary_snapshot_acl_from_parent(child, parent)`: for each word also present
|
||||
in the parent's dictionary, copy `acl_allow`/`acl_mode`/`acl_pinned`/`acl_ttl` into the
|
||||
child's matching entry.
|
||||
- [ ] **11.** Call it once, right after a child's dictionary finishes loading in
|
||||
`capsule_birth.c`.
|
||||
- [x] **10. DONE 2026-09-03.** `dictionary_snapshot_acl_from_parent(child, parent)` added as a
|
||||
static helper in `capsule_birth.c`: walks `child->latest`'s link chain, looks up each name
|
||||
in `parent` via `vm_find_word()` (the same C-level lookup `FIND` itself uses — not a
|
||||
modification to `FIND`, per the standing "never modify `FIND`" rule), copies
|
||||
`acl_allow`/`acl_mode`/`acl_pinned`/`acl_ttl` onto the child's matching entry when found.
|
||||
Baby-specific words the parent doesn't have are left untouched — nothing to cap them
|
||||
against.
|
||||
- [x] **11. DONE 2026-09-03.** Called once via `vm_find_entry_ptr(parent)` (the same internal
|
||||
registry lookup `capsule_birth_mama()` already uses for Hera's own entry) to get the
|
||||
parent's live `VM*`, right after `dict_hash`/parity logging — deliberately *after*, not
|
||||
before: the snapshot depends on the parent's *current* ACL state, which can vary run-to-run
|
||||
once Zuse-granted elevations exist, so applying it before the hash would make
|
||||
`birth_dict_hash` no longer a pure function of capsule content, breaking the "same capsule
|
||||
booted twice produces the same dict hash" determinism invariant this codebase relies on
|
||||
elsewhere. Verified 3-arch boot to `ok>` (amd64/aarch64/riscv64).
|
||||
|
||||
**Phase 5 — `BMAPFMT` (§F.4/§H.6, independent, can run any time)**
|
||||
- [ ] **12.** Edit `blk_meta_t` in `include/block_subsystem.h`: replace the old 4 ownership
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Capsule Block Manifest — Auto-generated
|
||||
<!-- Generated by mkcapsule --manifest 2026-09-03T10:36:42Z -->
|
||||
<!-- Generated by mkcapsule --manifest 2026-09-03T10:43:13Z -->
|
||||
<!-- DO NOT EDIT — re-run mkcapsule --manifest to refresh. -->
|
||||
<!-- Hand-written justifications and immutability notes live -->
|
||||
<!-- in MANIFEST.md alongside this auto-generated index. -->
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -104,6 +104,33 @@ static VMRegistryEntry *vm_find_entry_ptr(VMUuid vm_id) {
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
/* FABRIC-3.md §H.12 step 10: creator-ceiling enforcement, birth-time
|
||||
* snapshot only, no live sync (§H.3, decided 2026-09-03 -- "if something
|
||||
* was developed with a particular set of ACLs, it should remain at
|
||||
* that... otherwise parent changes break the child's program"). For
|
||||
* every word in child's dictionary also present, by name, in parent's,
|
||||
* copy parent's CURRENT acl_allow/acl_mode/acl_pinned/acl_ttl onto
|
||||
* child's matching entry -- caps the child at whatever the parent
|
||||
* allowed at this exact moment, once, never re-applied afterward. Words
|
||||
* the child has that the parent doesn't (baby-specific vocabulary) are
|
||||
* left untouched -- there's nothing to cap them against. vm_find_word()
|
||||
* is the same C-level lookup FIND itself uses; not modifying FIND, just
|
||||
* calling the same lookup it does (CLAUDE.md: "FIND is a proven, tested,
|
||||
* registered word. Never modify it" -- this doesn't). */
|
||||
static void dictionary_snapshot_acl_from_parent(VM *child, VM *parent) {
|
||||
DictEntry *ce;
|
||||
if (!child || !parent) return;
|
||||
|
||||
for (ce = child->latest; ce != NULL; ce = ce->link) {
|
||||
DictEntry *pe = vm_find_word(parent, ce->name, ce->name_len);
|
||||
if (!pe) continue;
|
||||
ce->acl_allow = pe->acl_allow;
|
||||
ce->acl_mode = pe->acl_mode;
|
||||
ce->acl_pinned = pe->acl_pinned;
|
||||
ce->acl_ttl = pe->acl_ttl;
|
||||
}
|
||||
}
|
||||
|
||||
void capsule_vm_registry_init(void *mama_vm_ptr) {
|
||||
uint32_t i;
|
||||
vm_node_t *node;
|
||||
@@ -674,6 +701,20 @@ CapsuleRunResult capsule_birth_baby(
|
||||
|
||||
capsule_parity_log_birth(vm_id, cap->capsule_id, cap->content_hash, dict_hash);
|
||||
|
||||
/* §H.12 step 11: applied AFTER dict_hash/parity logging above, not
|
||||
* before -- a runtime ACL snapshot depends on the parent's CURRENT
|
||||
* state (which can vary run-to-run once Zuse-granted elevations
|
||||
* exist), so applying it before the hash would make birth_dict_hash
|
||||
* no longer a pure function of capsule content, breaking the "same
|
||||
* capsule booted twice produces the same dict hash" determinism
|
||||
* invariant this codebase relies on elsewhere. */
|
||||
{
|
||||
VMRegistryEntry *parent_entry = vm_find_entry_ptr(parent);
|
||||
if (parent_entry && parent_entry->vm_ptr) {
|
||||
dictionary_snapshot_acl_from_parent(new_vm, (VM *)parent_entry->vm_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
if (out_vm_id) *out_vm_id = vm_id;
|
||||
if (out_vm_ctx) *out_vm_ctx = new_vm;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user