Skip to content

Commit 4c08875

Browse files
ArchieIndianclaude
andauthored
feat: add expansion-grant-guard skill — delegation grant ledger with token budgets (#43)
YAML-based grant ledger that issues time-limited, token-budgeted permission grants for sub-agent expansions. Supports issuance, validation, consumption tracking, revocation, and auto-expiry sweeps. Inspired by lossless-claw's delegation grant system. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3b351de commit 4c08875

4 files changed

Lines changed: 759 additions & 0 deletions

File tree

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
---
2+
name: expansion-grant-guard
3+
version: "1.0"
4+
category: openclaw-native
5+
description: YAML-based delegation grant ledger — issues, validates, and tracks scoped permission grants for sub-agent expansions with token budgets and auto-expiry.
6+
stateful: true
7+
---
8+
9+
# Expansion Grant Guard
10+
11+
## What it does
12+
13+
When an agent delegates work to a sub-agent (or expands context via DAG recall), it needs a controlled way to grant scoped permissions. Expansion Grant Guard maintains a YAML-based grant ledger that issues time-limited, token-budgeted grants — ensuring sub-agent operations stay within defined boundaries.
14+
15+
Inspired by [lossless-claw](https://github.com/Martian-Engineering/lossless-claw)'s delegation grant system, where a parent agent issues a signed grant specifying what a sub-agent can access, how many tokens it may consume, and when the grant expires.
16+
17+
## When to invoke
18+
19+
- Before any sub-agent expansion or delegation — issue a grant first
20+
- When a sub-agent requests resources — validate the grant before proceeding
21+
- When checking token budgets — verify remaining budget in the grant
22+
- Periodically to clean up expired grants — auto-expiry sweep
23+
24+
## How to use
25+
26+
```bash
27+
python3 guard.py --issue --scope "dag-recall" --budget 4000 --ttl 30 # Issue a grant
28+
python3 guard.py --validate <grant-id> # Check if grant is valid
29+
python3 guard.py --consume <grant-id> --tokens 500 # Record token usage
30+
python3 guard.py --revoke <grant-id> # Revoke a grant early
31+
python3 guard.py --list # List all active grants
32+
python3 guard.py --sweep # Clean up expired grants
33+
python3 guard.py --audit # Full audit log
34+
python3 guard.py --stats # Grant statistics
35+
python3 guard.py --status # Current status summary
36+
python3 guard.py --format json # Machine-readable output
37+
```
38+
39+
## Grant structure
40+
41+
Each grant is a YAML entry in the ledger:
42+
43+
```yaml
44+
grant_id: "g-20260316-001"
45+
scope: "dag-recall" # What the grant allows
46+
issued_at: "2026-03-16T10:00:00Z"
47+
expires_at: "2026-03-16T10:30:00Z"
48+
token_budget: 4000 # Max tokens allowed
49+
tokens_consumed: 1250 # Tokens used so far
50+
status: active # active | expired | revoked | exhausted
51+
issuer: "parent-session"
52+
metadata:
53+
query: "auth migration"
54+
reason: "Recalling auth decisions for new implementation"
55+
```
56+
57+
## Grant lifecycle
58+
59+
```
60+
Issue → Active → { Consumed | Expired | Revoked | Exhausted }
61+
│ │
62+
│ ├─ tokens_consumed < budget → still active
63+
│ ├─ tokens_consumed >= budget → exhausted
64+
│ ├─ now > expires_at → expired
65+
│ └─ explicit revoke → revoked
66+
67+
└─ Validation checks: status=active AND not expired AND budget remaining
68+
```
69+
70+
## Procedure
71+
72+
**Step 1 — Issue a grant before expansion**
73+
74+
```bash
75+
python3 guard.py --issue --scope "dag-recall" --budget 4000 --ttl 30
76+
```
77+
78+
Output:
79+
```
80+
Grant Issued
81+
─────────────────────────────────────────────
82+
Grant ID: g-20260316-001
83+
Scope: dag-recall
84+
Token budget: 4,000
85+
Expires: 2026-03-16T10:30:00Z (in 30 min)
86+
Status: active
87+
```
88+
89+
**Step 2 — Validate before consuming resources**
90+
91+
```bash
92+
python3 guard.py --validate g-20260316-001
93+
```
94+
95+
Returns status, remaining budget, and time until expiry. Non-zero exit code if invalid.
96+
97+
**Step 3 — Record token consumption**
98+
99+
```bash
100+
python3 guard.py --consume g-20260316-001 --tokens 1250
101+
```
102+
103+
Deducts from the grant's remaining budget. Fails if exceeding budget.
104+
105+
**Step 4 — Sweep expired grants**
106+
107+
```bash
108+
python3 guard.py --sweep
109+
```
110+
111+
Marks all expired grants and cleans up the active list.
112+
113+
## Scope types
114+
115+
- `dag-recall` — Permission to walk DAG nodes and assemble answers
116+
- `session-search` — Permission to search session persistence database
117+
- `file-access` — Permission to read externalized large files
118+
- `context-expand` — Permission to expand context window with external data
119+
- `tool-invoke` — Permission to invoke external tools/MCP servers
120+
- Custom scopes accepted — any string is valid
121+
122+
## Integration with other skills
123+
124+
- **dag-recall**: Should issue a grant before expanding DAG nodes; checks budget during expansion
125+
- **session-persistence**: Grant-gated search — validate grant before querying message database
126+
- **large-file-interceptor**: Grant-gated file restore — validate before loading large files back
127+
- **context-assembly-scorer**: Token budget tracking feeds into assembly scoring
128+
129+
## State
130+
131+
Grant ledger and audit log stored in `~/.openclaw/skill-state/expansion-grant-guard/state.yaml`.
132+
133+
Fields: `active_grants`, `total_issued`, `total_expired`, `total_revoked`, `total_exhausted`, `total_tokens_granted`, `total_tokens_consumed`, `grant_history`.
134+
135+
## Notes
136+
137+
- Uses Python's built-in modules only — no external dependencies
138+
- Grant IDs are timestamped and sequential within a day
139+
- Ledger file is append-friendly YAML — safe for concurrent reads
140+
- Expired grants kept in history for audit; active list stays clean after sweep
141+
- Default TTL is 30 minutes; max TTL is 24 hours
142+
- Token budget is advisory — enforcement depends on consuming skill cooperation
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
version: "1.0"
2+
description: Grant ledger, consumption tracking, and audit history.
3+
fields:
4+
active_grants:
5+
type: list
6+
description: Currently active grants
7+
items:
8+
grant_id: { type: string }
9+
scope: { type: string }
10+
issued_at: { type: datetime }
11+
expires_at: { type: datetime }
12+
token_budget: { type: integer }
13+
tokens_consumed: { type: integer }
14+
status: { type: enum, values: [active, expired, revoked, exhausted] }
15+
issuer: { type: string }
16+
total_issued:
17+
type: integer
18+
total_expired:
19+
type: integer
20+
total_revoked:
21+
type: integer
22+
total_exhausted:
23+
type: integer
24+
total_tokens_granted:
25+
type: integer
26+
total_tokens_consumed:
27+
type: integer
28+
grant_history:
29+
type: list
30+
description: Rolling log of completed grants (last 50)
31+
items:
32+
grant_id: { type: string }
33+
scope: { type: string }
34+
issued_at: { type: datetime }
35+
closed_at: { type: datetime }
36+
token_budget: { type: integer }
37+
tokens_consumed: { type: integer }
38+
final_status: { type: string }
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Example runtime state for expansion-grant-guard
2+
active_grants:
3+
- grant_id: "g-20260316-003"
4+
scope: "dag-recall"
5+
issued_at: "2026-03-16T10:30:00Z"
6+
expires_at: "2026-03-16T11:00:00Z"
7+
token_budget: 4000
8+
tokens_consumed: 1250
9+
status: active
10+
issuer: "parent-session"
11+
- grant_id: "g-20260316-004"
12+
scope: "session-search"
13+
issued_at: "2026-03-16T10:45:00Z"
14+
expires_at: "2026-03-16T11:15:00Z"
15+
token_budget: 2000
16+
tokens_consumed: 0
17+
status: active
18+
issuer: "parent-session"
19+
total_issued: 12
20+
total_expired: 6
21+
total_revoked: 1
22+
total_exhausted: 3
23+
total_tokens_granted: 48000
24+
total_tokens_consumed: 28750
25+
grant_history:
26+
- grant_id: "g-20260316-001"
27+
scope: "dag-recall"
28+
issued_at: "2026-03-16T09:00:00Z"
29+
closed_at: "2026-03-16T09:22:15Z"
30+
token_budget: 4000
31+
tokens_consumed: 3840
32+
final_status: exhausted
33+
- grant_id: "g-20260316-002"
34+
scope: "context-expand"
35+
issued_at: "2026-03-16T09:30:00Z"
36+
closed_at: "2026-03-16T10:00:00Z"
37+
token_budget: 8000
38+
tokens_consumed: 2100
39+
final_status: expired
40+
# ── Walkthrough ──────────────────────────────────────────────────────────────
41+
# python3 guard.py --issue --scope "dag-recall" --budget 4000 --ttl 30
42+
#
43+
# Grant Issued
44+
# ─────────────────────────────────────────────
45+
# Grant ID: g-20260316-003
46+
# Scope: dag-recall
47+
# Token budget: 4,000
48+
# Expires: 2026-03-16T11:00:00Z (in 30 min)
49+
# Status: active
50+
#
51+
# python3 guard.py --validate g-20260316-003
52+
#
53+
# ✓ Grant: g-20260316-003
54+
# Status: active
55+
# Scope: dag-recall
56+
# Tokens remaining: 2,750 / 4,000
57+
# Expires in: 18.5 min
58+
#
59+
# python3 guard.py --consume g-20260316-003 --tokens 500
60+
#
61+
# Consumed 500 tokens from g-20260316-003
62+
# Remaining: 2,250 / 4,000
63+
#
64+
# python3 guard.py --stats
65+
#
66+
# Expansion Grant Statistics
67+
# ──────────────────────────────────────────────
68+
# Active grants: 2
69+
# Total issued: 12
70+
# Total expired: 6
71+
# Total revoked: 1
72+
# Total exhausted: 3
73+
# Tokens granted: 48,000
74+
# Tokens consumed: 28,750
75+
# Utilization: 59.9%

0 commit comments

Comments
 (0)