feat(hermes-tag): add additive governance and continuity kernel - #91111
feat(hermes-tag): add additive governance and continuity kernel#91111andrexibiza wants to merge 2 commits into
Conversation
andrexibiza
left a comment
There was a problem hiding this comment.
Reviewed exact head 251db038ef61e78f0c269aee22eccd7a626cc48e as the HT-01 substrate, not as a runtime-delivery claim. The additive boundary is real: all 28 changed files stay under gateway/hermes_tag/ + focused tests, and exact-head CI 32419325252, Docker 32419324150, and Nix 32419324118 are green. The canonical model/digest work, tenant-qualified identities, deny precedence, exact-intent leases, one-shot lease reservation, profile-local SQLite authority, replay fences, and failure-only shadow boundary are materially coherent.
I found two authority-boundary blockers before this becomes the contract HT-02 consumes.
1. bind_authority() can pair a new admission with stale outer decision/lease authority
gateway/hermes_tag/runtime.py sets _CURRENT_ADMISSION unconditionally, but it sets _CURRENT_DECISION and _CURRENT_LEASE only when the incoming RuntimeAuthority fields are non-None:
admission_token = _CURRENT_ADMISSION.set(authority.admission)
if authority.decision is not None:
decision_token = _CURRENT_DECISION.set(authority.decision)
if authority.lease is not None:
lease_token = _CURRENT_LEASE.set(authority.lease)That means a nested bind_authority(RuntimeAuthority(admission=B)) inside an outer authority for A leaves A's decision and lease visible while B is the current admission. capture_authority() then constructs an apparently valid RuntimeAuthority(admission=B, decision=A, lease=A) because the dataclass has no cross-object invariant either. This is exactly the other side of task-local isolation: ContextVar separation prevents cross-task bleed, but partial rebinding permits cross-scope bleed inside one task/context.
Required fix: bind all three ContextVars on every bind_authority() entry, including explicitly setting missing decision/lease to None, then reset all three on exit. Also make RuntimeAuthority (or the binding boundary) reject inconsistent tuples: admission principal/scope/continuity must match the decision and lease; decision↔lease IDs/digests must match when both are present. Add the adversarial witness A(admission+decision+lease) -> nested B(admission only) -> current_decision/current_lease are None -> exit -> A restored, plus mismatched A/B tuple rejection. HT-02 should never have to remember that invariant itself.
2. The public approval facade bypasses the approval capability/policy model it defines
The registry correctly declares approval.grant as HIGH risk with identity.authenticate, intent.exact, expiry.require, and receipt.append obligations. But HermesTagKernel.grant_approval() directly delegates to ApprovalStore.grant(). That store accepts caller-supplied principal_id, approver_id, intent digest, and scope digest; the only approver check is the SQLite FK proving the named principal exists. No approval.grant policy decision, authenticated approver evidence, role/authority check, or lease is consumed. The current high-risk test even demonstrates self-grant by passing the same principal as subject and approver.
So the kernel currently has two incompatible authorities: the capability registry says approval grants are governed effects, while the high-level grant API mints the exact token that unlocks HIGH/CRITICAL actions without traversing that governance path. Once HT-02 exposes an approval interaction, calling the obvious facade would make identity.authenticate metadata decorative rather than authoritative.
Required fix: make the externally consumable approval-grant path itself authority-bearing. For example, require an authenticated approver admission + policy-authorized approval.grant decision/lease and verify its pre-effect obligations before writing the grant; keep any raw store mutation private/internal. Self-approval can still be a deliberate policy choice if wanted, but it must be an explicit matched rule/authority, not a property of knowing an existing principal ID. Add a negative witness showing an unprivileged/self-nominated caller cannot mint a grant merely by supplying valid IDs/digests.
Topology / merge order
This PR is complementary implementation authority, not a replacement for #91036. #79772 remains the campaign meta-owner; #80338 remains the flagship acceptance matrix; #91036 remains the executable publication/reconciliation owner; #90307 remains the external publication-contract dependency for #91036. #91111 should not promote any capability to released: its own no-runtime-consumer boundary is correct. Once this implementation is accepted, #91036 does need reconciliation so its gap/candidate_* state reflects the new current repository candidate rather than the pre-#91111 packet-only topology.
Current main is e30388e409a95b30d6acc4c1f6c0cd8d0c66393c; this head is 8 commits behind from merge base 4a5b6dd4512a10c3c18da3e5b9e5c7fb681cbfbb. Those intervening changes are currently confined to Desktop Hermes Bots/tests + contributor metadata, so I do not see a semantic collision with this package, but the landing head still needs a current-main rebase and fresh exact-head receipts after these fixes.
The historical packet provenance in the PR/README is appropriately described as reconstruction evidence rather than byte-for-byte recovered implementation; I found no external contributor lineage here that should be collapsed as duplicate work.
Run the exact Hermes Tag package and focused tests without changing the upstream PR diff. Signed-off-by: Andrex Ibiza, MBA <andrexibiza@gmail.com>
Make the fork-only verifier report its exact-commit result through a queryable commit status. Signed-off-by: Andrex Ibiza, MBA <andrexibiza@gmail.com>
Run compile, Ruff, and the exact Hermes Tag test suite against the published PR branch, then attach the receipt to that exact head. Signed-off-by: Andrex Ibiza, MBA <andrexibiza@gmail.com>
Temporary fork-only exact-head verification runner. Remove after the receipt is captured.
Keep the focused fork verifier available for the cleanup merge and any exact-head rerun needed during repair. Signed-off-by: Andrex Ibiza, MBA <andrexibiza@gmail.com>
Add the profile-local Hermes Tag identity, continuity, policy, capability, lease, budget, obligation, provenance, and receipt substrate on current main. Close the two authority-boundary defects identified on NousResearch#91111: - task-local admission, decision, and lease state now binds and restores atomically, with cross-scope/principal/continuity tuples rejected; - approval creation is now a governed approval.grant effect requiring authenticated durable identity, explicit policy allow, an exact argument-bound lease, obligation evidence, one-shot completion, and rollback on failure. Hide raw approval mutation from the public package facade and add adversarial regressions for nested context reuse, self-approval, target substitution, and exact one-time approval consumption. Part of NousResearch#79772 Part of NousResearch#80338 Signed-off-by: Andrex Ibiza, MBA <andrexibiza@gmail.com>
6babece to
385e5b0
Compare
Temporarily patch the stale rollback tests through the new authenticated, policy-authorized, leased approval path, verify them, and push the implementation receipt to the PR branch. Signed-off-by: Andrex Ibiza, MBA <andrexibiza@gmail.com>
Temporary fork-only repair workflow. Remove after the target branch is green.
|
Implemented the authority-boundary fixes at exact head What changed:
Exact-head checks:
|
|
Exact-head verification: |
|
@teknium1 architecture/maintainer review requested on exact head Current GitHub truth: open, non-draft, mergeable. Exact-head CI The key review question is not whether the kernel's unit surface is green; it is whether this additive authority model is the one future consumers must consume. This PR itself grants no Slack/tool/provider effect authority and must not be credited as released #91036 remains campaign publication authority; #90307 remains the executable parity-contract validator. Please review this as the horizontal kernel boundary, not as feature-delivery closure. |
|
@teknium1 — architecture review requested on exact head Direct receipts are CI 32426102683, Docker 32426102310, and Nix 32426102250, all successful; GitHub currently reports the PR mergeable and there are no unresolved inline threads. The acceptance question is deliberately narrower than Slack delivery: does this package establish one coherent identity → scope → policy → approval → lease → budget → receipt → continuity authority kernel without granting an ambient effect path or duplicating gateway/Slack ownership? The next runtime slice must consume these exact contracts at real |
Next-consumer contract published in #91913The authority-continuity manifest records this PR as the active Hermes Tag implementation owner but keeps its status explicitly kernel-only. The next required publication is now machine-readable: Shadow evaluation is valid runtime evidence but cannot claim effect enforcement. Concurrent task isolation, stale authority generation, approval replay, lease replay, and argument-digest mismatch remain fail-closed acceptance requirements. Contract PR: #91913 |
As an isolated substrate this is coherently built: the invariant list in the README is explicit and mostly testable (fail-closed on unknown capabilities, deny-overrides-allow, one-time approvals, atomic budget reservation, single-use HMAC leases bound to the full authority tuple, hash-chained receipts, signing material by reference), and the test suite exercises authority boundaries rather than just happy paths. The honesty of the provenance boundary section — stating plainly this is a reconstruction and that runtime insertion remains a separate contract — is appreciated. That said, three structural points deserve attention before this hardens:
Nit: |
Summary
Adds the additive
gateway.hermes_tagkernel that supplies the horizontal authority model required by the Slack Feature Parity /@Hermes Tagcampaign without modifying existing gateway, tool, provider, or Slack effect paths.The kernel separates identity, scope, policy, approval, capability lease, atomic budget, receipt, continuity, fact, and task-local runtime authority into independently testable modules. It defaults to denial, binds every consequential decision to canonical scope and argument digests, and keeps runtime integration as a separate stacked publication rather than growing
gateway/run.pyor the Slack adapter.Architecture
ContextVarauthority propagation for later gateway/tool/provider seams;Scope boundary
This PR intentionally does not claim runtime delivery. It introduces no production consumer outside
gateway.hermes_tag, performs no Slack API call, does not intercept gateway turns, and does not grant an existing tool/process/provider authority. The next stacked slice will wire one real turn-admission consumer; later slices will bind effect paths and Slack-native behavior.That separation is load-bearing: a library package plus green tests is implementation evidence, not a released
@Hermes Tagcapability.Tests
The branch includes adversarial coverage for:
Topology
Part of #79772
Part of #80338
Implementation successor to the historical Hermes Tag packet evidence recorded by #91036.
Independent of #90307 at runtime; #91036 remains the campaign publication authority.