Channel-open policy hook -- FABRIC-3.6.md task 3.7
Added HERMES-CHANNEL-OPEN? ( req-hi req-lo -- allow? ) at capsules/ACL.4th block 4008 (default: approve everything) -- the one word policy authors edit. sk_hermes_channel_open_policy(VM*, VMUuid) (kernel_hermes.h/.c) is the C-side query that calls it via plain word-dispatch against the target VM's own dictionary/stack, never vm_interpret() (avoids task 3.4's input-buffer cursor hazard entirely) and never decides the answer itself. Fails closed: no policy word, a policy error, or stack underflow all deny, matching CLAUDE.md's posture that absence of policy must never mean "always allow." Two real bugs found and fixed before this was called done: missing current_executing_entry assignment before calling the word's func pointer (colon words silently no-op without it, vm_core.c:730 -- no crash, just a wrong answer); and a second FAIL with debug instrumentation still in place whose precise cause isn't reconstructable, since no intermediate commit exists for that attempt. Self-test proves the task's check four ways against the same unchanged C function: default approve, live redefinition to deny (zero C change), restore, and a VM with no ACL.4th loaded at all (fail closed). A fifth check wires the result into task 3.6's sk_hermes_channel_respond() end to end: a denied policy produces a NACK and no channel, ledger/stadium_conserved() holding throughout. Scope, per Captain Bob's ruling: closes with the query built and proven; sk_hermes_channel_respond() still takes a caller-supplied approved bool rather than calling the policy internally. Wiring a real channel-open call site to only this query is deferred to whichever later task first needs a live decision. dict_hash identical across amd64/aarch64/riscv64 for every VM, zero UNKNOWN WORD, mkcapsule --lint clean (38 files, 0 violations). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
205a49ecd0
commit
f37aa0fb17
@@ -727,6 +727,49 @@ int sk_hermes_channel_respond(VMUuid target, VMUuid requester, int approved);
|
||||
* @return 0 on success, -1 on refusal. */
|
||||
int sk_hermes_channel_close(VMUuid closer, int channel_id);
|
||||
|
||||
/*
|
||||
* Channel-open policy hook (FABRIC-3.6.md task 3.7, B1, ruling 3.0b:
|
||||
* "kernel-Hermes asks ACL.4th, never decides in C, never gates on
|
||||
* zuse_session"). sk_hermes_channel_open_policy() is the CALL SITE task
|
||||
* 3.6's own doc comment named as replacing sk_hermes_channel_respond()'s
|
||||
* caller-supplied `approved` bool with a real query -- this function IS
|
||||
* that query; sk_hermes_channel_respond()'s own signature stays
|
||||
* unchanged, as promised.
|
||||
*
|
||||
* Deliberately NOT vm_interpret() (contrast task 3.4's drain, which
|
||||
* genuinely needs to run arbitrary payload text): HERMES-CHANNEL-OPEN?
|
||||
* is a FIXED, known word name, so this uses the plain-word-dispatch
|
||||
* pattern FABRIC-3.md SXX already established for Hera's own MSG-TICK
|
||||
* self-drain ("a plain word dispatch in her own dictionary, not a
|
||||
* VM-EXEC dispatch into anyone else's input buffer -- no reentrancy
|
||||
* risk") -- vm_find_word() + calling the entry's own func pointer
|
||||
* directly, with the requester passed via the target's own data stack.
|
||||
* This touches neither target_vm->input_buffer nor input_pos, so it
|
||||
* carries none of task 3.4's cursor-preservation hazard; it DOES still
|
||||
* touch target_vm's own data stack (dsp), which is the correct and
|
||||
* expected thing for a word call to do. Calling this from within a live
|
||||
* checkpoint on a VM that is itself mid-dispatch is deferred, undecided
|
||||
* territory -- this task (like every Phase 3 task before Stage C/3.8+)
|
||||
* is self-test only, not wired into any real checkpoint yet.
|
||||
*
|
||||
* Fails CLOSED, not open: if target_vm has no HERMES-CHANNEL-OPEN? word
|
||||
* (e.g. ACL.4th was never loaded into it) or the word itself sets
|
||||
* target_vm->error or leaves too few stack items, this returns 0
|
||||
* (denied) -- absence of policy must never silently mean "always
|
||||
* allow" (CLAUDE.md's own posture on ACL policy). A policy-word bug's
|
||||
* own error state is cleared on target_vm before returning, so a
|
||||
* broken policy word cannot leak an error into whatever else target_vm
|
||||
* is doing.
|
||||
*
|
||||
* @param target_vm The VM being asked -- its own dictionary is
|
||||
* consulted, its own data stack is used for the call.
|
||||
* @param requester Passed to HERMES-CHANNEL-OPEN? as (hi, lo) on
|
||||
* target_vm's own stack.
|
||||
* @return 1 if HERMES-CHANNEL-OPEN? approved (returned a nonzero top of
|
||||
* stack), 0 otherwise (denied, missing, or errored).
|
||||
*/
|
||||
int sk_hermes_channel_open_policy(VM *target_vm, VMUuid requester);
|
||||
|
||||
#endif /* __STARKERNEL__ */
|
||||
|
||||
#endif /* STARKERNEL_VM_KERNEL_HERMES_H */
|
||||
|
||||
Reference in New Issue
Block a user