Skip to content

feat(delegation): revoking someone stops only them unless the revocation cascades - #1197

Merged
coodos merged 3 commits into
mainfrom
feat/delegation-no-cascade
Oct 9, 2026
Merged

coodos merged 3 commits into
mainfrom
feat/delegation-no-cascade

Conversation

@coodos

@coodos coodos commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Description of change

Firing someone no longer takes down everything they handed on.

  • Firing stops only that person. If Bob's delegation is revoked, Bob can't sign, but what he granted before the revocation (by the eVault's storage clock, not dates the signer wrote) stays valid, and so does everything below it.
  • Role revocation works the same way. Holders granted before it keep their delegations.
  • Cascading is explicit. A revocation with revocationCascade: true (new field on Role and Delegation, only allowed on revoked records) revokes everything handed on from it.
  • Nothing signed after a revocation counts. A fired Bob can't grant, update or revoke anything. Holders below a fired link can still re-delegate if their own record allows it.
  • Narrowing still follows the parent now. Effective scopes are the intersection of every link's current scopes, role included. This replaces the NOT_A_SUBSET failure.
  • packages/delegation: history resolution attaches meta { grantedAt, revokedAt, cascade } from storage times; evaluateDelegation lets a revoked link back what it granted before, unless the revocation cascades; entitlement checks that the grantor's authority was live when each version was stored.
  • Demo: Act 10 becomes "Dana fires Bob" (Bob refused, Tim accepted, Bob's hop shown as "fired after granting"); new Act 11 "Dana revokes Dave and everything he handed on" (Tim refused at Dave). Healing follows the new rule.
  • Docs and skill: a new "Firing and cascading" section with a diagram, plus updated failure table, platform guide and skill reference.

Issue Number

Type of change

  • Update (a change which updates existing functionality)

How the change has been tested

packages/delegation 67/67, including new cases: fired grantor keeps earlier grants; cascade drops everything below; grants and revocations signed after firing ignored; re-delegation below a fired parent; role revoked with and without cascade; narrowing shrinks the child. packages/auth 97/97 against the rebuilt package. Ontology schemas validated with Ajv (cascade only on revoked records). Full demo replay against pnpm dev:core: all seven acts end as expected (Act 10: Bob refused, Tim valid; Act 11: Tim refused at Dave); every slide screenshotted.

Change checklist

  • I have ensured that the CI Checks pass locally
  • I have removed any unnecessary logic
  • My code is well documented
  • I have signed my commits
  • My code follows the pattern of the application
  • I have self reviewed my code

@coodos

coodos commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T10:49:00.933058Z 4ce65be New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 22488169-84e8-4857-9877-934085cda3b7

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 70416c5dcc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/delegation/src/chain.ts Outdated
Comment thread packages/delegation/src/chain.ts Outdated
Comment thread packages/delegation/src/chain.ts Outdated
@coodos

coodos commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6921f2033d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/delegation/src/history.ts
Comment thread packages/delegation/src/history.ts Outdated
Comment thread packages/delegation/src/history.ts Outdated
Comment thread packages/delegation/src/chain.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4f63c87008

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +267 to +270
const cascade =
parent.meta?.cascade ??
(flag !== undefined && flag !== null && flag !== false);
if (cascade) return false;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve limits from before a non-cascading revocation

When a non-cascading revocation is stored as a complete record that omits or loosens the optional appLimits, stillBacks keeps earlier children valid but the evaluator later uses only the revoked record's final limits. Those children therefore receive a less restrictive appLimits list and a platform may authorize operations above the limit that applied when they were granted. Preserve the last active limits for surviving grants, or reject revocation versions that loosen them.

Useful? React with 👍 / 👎.

return fail("REVOKED", current.roleId, "role revoked");
}
narrow(role.scopes);
if (current.mayRedelegate && !role.mayRedelegate) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exempt revoked roles from the current redelegation check

When a role is revoked without cascade and that revocation also sets mayRedelegate: false, every previously granted holder whose delegation still has mayRedelegate: true fails here with REDELEGATION_NOT_ALLOWED. This makes the role revocation cascade despite stillBacks accepting it; the parent-delegation branch already avoids the same problem for revoked parents. Judge this flag from the role state when the holder was granted, or skip the current-state check for a revoked role that still backs the grant.

Useful? React with 👍 / 👎.

@coodos
coodos force-pushed the feat/delegation-no-cascade branch from 4f63c87 to 4ce65be Compare October 9, 2026 10:43
@coodos
coodos changed the base branch from feat/company-delegation-demo to main October 9, 2026 10:43
@coodos
coodos merged commit 34701ba into main Oct 9, 2026
4 checks passed
@coodos
coodos deleted the feat/delegation-no-cascade branch October 9, 2026 10:44

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4ce65bec97

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +164 to +168
const problem = linkProblem(
current,
leaf.companyEName,
now,
current !== leaf,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the validity window before non-cascading revocation

When a non-cascading revocation changes an ancestor's validFrom or validUntil, this call still runs windowProblem against the revoked version, so an earlier valid child can fail with EXPIRED or NOT_YET_VALID even though revocationCascade is false. These fields are mutable and history accepts complete revocation versions containing changed values; preserve the last active window for surviving grants or skip the revoked ancestor's current window check.

Useful? React with 👍 / 👎.

Comment on lines +356 to +360
cascade:
revokedAt !== undefined &&
state.revocationCascade !== undefined &&
state.revocationCascade !== null &&
state.revocationCascade !== false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Honor legacy cascade revocations

When an existing delegation was revoked with revocationReason: "cascade" before revocationCascade existed, this calculation records cascade: false, so descendants that the old explicit cascade revoked become authorized again. The delegation schema still permits and describes revocationReason: "cascade", making this state reachable even for newly validated records; treat that legacy reason as cascading or migrate those records before changing the default.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant