@keelcodes/policy 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright 2026 Keel contributors
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # @keelcodes/policy
2
+
3
+ Account-agnostic authorization policy for agent accounts.
4
+
5
+ A policy declares **what an agent may do** with an account: which target
6
+ contracts it may call, which methods on them, and the value / frequency
7
+ ceilings. The model contains no account-specific encoding, so the same `Policy`
8
+ works across Kernel, Nexus and Safe7579.
9
+
10
+ This package is the **off-chain core**: the DSL, a canonical commitment hash, a
11
+ pre-check / simulation layer, and multi-session lifecycle management. The
12
+ on-chain carrier for enforcement is a **Keel ERC-7579 hook module**
13
+ (account-agnostic: a hook sees the execution of any 7579 account without parsing
14
+ account-specific call data). The hook recomputes the same commitment, so the two
15
+ layers cannot disagree about what a policy means.
16
+
17
+ ## Policy DSL
18
+
19
+ ```ts
20
+ import { normalizePolicy, policyCommitment } from '@keelcodes/policy';
21
+
22
+ const policy = normalizePolicy({
23
+ validAfter: 0n, // unix seconds; 0 = immediately
24
+ validUntil: 1_800_000_000n, // 0 = never
25
+ rules: [{
26
+ target: USDC, selectors: ['0xa9059cbb'],
27
+ maxPerTx: 10n ** 6n, maxDaily: 10n ** 7n, maxCalls: 50, // native value / count
28
+ tokenLimits: [{ token: USDC, maxPerTx: 10n ** 6n, maxDaily: 10n ** 7n }], // ERC-20 amount
29
+ }],
30
+ });
31
+
32
+ policyCommitment(policy); // keccak256(abi.encode(version, validAfter, validUntil, rules))
33
+ ```
34
+
35
+ Each rule scopes to one `target` with optional `selectors` (empty = any method)
36
+ and ceilings: `maxPerTx` (native value per call), `maxDaily` (native value per
37
+ day), `maxCalls` (call count). `0` / omitted means unlimited.
38
+
39
+ `normalizePolicy` fills every optional with its zero default and lower-cases
40
+ addresses, so `{ maxPerTx: 0n }` and `{}` produce the **same** commitment. A
41
+ malformed policy throws `PolicyError` at definition time.
42
+
43
+ ## ERC-20 token limits
44
+
45
+ `tokenLimits` adds per-token amount ceilings (`maxPerTx` / `maxDaily`) on top
46
+ of the native-value caps. The token must equal the rule's `target` — a cap can
47
+ only be enforced on calls made **directly** to the token, so a limit for any
48
+ other address is rejected as dead config.
49
+
50
+ Amounts are read from the standard `transfer` / `approve` / `transferFrom` call
51
+ data (the amount is the final `uint256` word). While a limit is configured:
52
+
53
+ - `transfer` / `approve` are capped by the token ceilings;
54
+ - `transferFrom` is **refused** (`token-transfer-from-blocked`) — bounding a
55
+ pull from an arbitrary address is ambiguous, so the conservative choice is to
56
+ reject it;
57
+ - a malformed standard call is refused (`token-amount-unparsable`);
58
+ - any other selector is left to the rule's `selectors` whitelist.
59
+
60
+ Token caps apply to the immediate call target only; a token moved *inside* a
61
+ router call is not covered by this rule (use a rule on the token itself).
62
+
63
+ ## Pre-check & simulation
64
+
65
+ `evaluateCall` applies validity, rule matching (first match in declared order)
66
+ and the ceilings. `simulateCalls` dry-runs a batch, accumulating usage so a
67
+ batch that only breaches a cap together is caught, and returns the first denial
68
+ with a machine-readable reason — before a bundler round-trip that would end in
69
+ a validation failure.
70
+
71
+ ```ts
72
+ import { evaluateCall, simulateCalls, toCall } from '@keelcodes/policy';
73
+
74
+ const call = toCall({ target: USDC, value: 0n, data: transferCalldata });
75
+ evaluateCall(policy, { now: 1_700_000_000n, usage: [] }, call);
76
+ // → { allowed: true, ruleIndex: 0 }
77
+ ```
78
+
79
+ `PolicyState.usage` is aligned to `policy.rules` by index; callers reset
80
+ `dailySpent` / `tokenSpent` when the day window rolls over.
81
+
82
+ ## Hook install payload
83
+
84
+ The on-chain hook installs one session at a time. `encodeInstallData(sessionId,
85
+ policy)` builds the exact payload it decodes — `abi.encode(bytes32 sessionId,
86
+ bytes policyData)` with `policyData = encodePolicy(policy)`. The session's
87
+ on-chain commitment is therefore `keccak256(policyData) === policyCommitment(policy)`,
88
+ so an installed session can be verified against what was signed.
89
+
90
+ ```ts
91
+ import { encodeInstallData } from '@keelcodes/policy';
92
+
93
+ encodeInstallData(session.id, session.policy); // → onInstall bytes
94
+ ```
95
+
96
+ ## Multi-session lifecycle
97
+
98
+ An account may hold **many concurrent sessions** — one policy grant each — which
99
+ fixes the old "one account, one session" limitation. A session is an immutable
100
+ record carrying the policy, its commitment and lifecycle metadata, and it holds
101
+ **no key material**: it references a policy, not a private key, so key custody
102
+ stays with the caller (KMS or the client).
103
+
104
+ ```ts
105
+ import { InMemorySessionStore, issueSession, revokeSession, rotateSession } from '@keelcodes/policy';
106
+
107
+ const store = new InMemorySessionStore();
108
+ const session = await issueSession(store, { account, policy, now });
109
+ await revokeSession(store, session.id, now);
110
+ const { previous, next } = await rotateSession(store, session.id, { policy, now });
111
+ ```
112
+
113
+ `sessionStatus(session, now)` derives `pending` / `active` / `expired` /
114
+ `revoked` from the record, and `listSessions(store, account, now)` returns an
115
+ account's sessions with their status. Revocation is append-only (the record is
116
+ kept with `revokedAt`, so it stays auditable), and a rotation cross-links the
117
+ predecessor and successor (`rotatedFrom` / `rotatedTo`) — the off-chain half of
118
+ the migration "uninstall old module + install new" (docs/KEEL_PLAN.md §7.5).
119
+ Persistence goes through the async `SessionStore` port, so a database-backed
120
+ store drops in; `InMemorySessionStore` is the minimal reference (no tenancy —
121
+ one Keel stack per product, see §6.3).
122
+
123
+ ## Scope
124
+
125
+ - ✅ Declarative DSL + normalisation + validation
126
+ - ✅ Canonical commitment hash (ABI encoding shared with the on-chain carrier)
127
+ - ✅ Off-chain pre-check + batch simulation
128
+ - ✅ ERC-20 token limits (`maxPerTx` / `maxDaily` per token)
129
+ - ✅ ERC-7579 hook module (`KeelPolicyHook`, Solidity) enforcing the same rules on-chain, many sessions per account (see `contracts/`)
130
+ - ✅ Multi-session lifecycle (issue / revoke / rotate) + pluggable `SessionStore`
131
+
132
+ Pre-alpha. The public API is not stable yet.
133
+
134
+ ## Out of scope
135
+
136
+ - Account implementations (see `@keelcodes/adapters`)
137
+ - Billing and multi-tenancy
@@ -0,0 +1,192 @@
1
+ import type { Address, Hex } from './types.js';
2
+ /** Schema version mixed into `capabilityRoot`, so a future profile change can never collide with an older one. */
3
+ export declare const CAPABILITY_VERSION = 1;
4
+ /**
5
+ * Lifecycle status of an envelope, matching the standard's `Status` enum
6
+ * (including `None`, the "unknown id" result of `getStatus`).
7
+ */
8
+ export declare enum EnvelopeStatus {
9
+ None = 0,
10
+ Active = 1,
11
+ Completed = 2,
12
+ Contested = 3,
13
+ Revoked = 4,
14
+ Expired = 5
15
+ }
16
+ /**
17
+ * A committed label a consumer can require a minimum of (e.g. a target
18
+ * contract that only accepts envelopes of tier >= 2). The standard treats
19
+ * `capabilityRoot` as opaque; Keel fixes four ordered tiers so the label is
20
+ * meaningful across the policy layer, the substrate and the manifest layer.
21
+ */
22
+ export type TrustTier = 0 | 1 | 2 | 3;
23
+ /** An M-of-N approval set; `threshold` of `approvers` must sign before a release gate opens. */
24
+ export interface ApprovalInput {
25
+ /** Number of approvals required; `0` means no approval gate. */
26
+ threshold?: number;
27
+ /** Distinct approver addresses. */
28
+ approvers?: readonly Address[];
29
+ }
30
+ /** The bounded authority an envelope commits to, as authored. */
31
+ export interface CapabilityInput {
32
+ /** Asset the budget is denominated in; the zero address means native value. */
33
+ asset: Address;
34
+ /** Budget ceiling for the whole envelope; `0` means no spend authority. */
35
+ cap?: bigint;
36
+ /** Ordered trust label consumers may require a minimum of; defaults to 0. */
37
+ trustTier?: TrustTier;
38
+ /** Unix seconds before which no draw may be released; `0` means immediately. */
39
+ notBefore?: bigint;
40
+ /** M-of-N gate that must be satisfied before any draw is released. */
41
+ approvals?: ApprovalInput;
42
+ /** Whether the envelope may delegate an attenuated child. */
43
+ delegate?: boolean;
44
+ }
45
+ /** A fully-populated, hash-stable capability. */
46
+ export interface Capability {
47
+ readonly version: number;
48
+ readonly asset: Address;
49
+ readonly cap: bigint;
50
+ readonly trustTier: TrustTier;
51
+ readonly notBefore: bigint;
52
+ readonly approvals: {
53
+ readonly threshold: number;
54
+ readonly approvers: readonly Address[];
55
+ };
56
+ readonly delegate: boolean;
57
+ }
58
+ /** Running aggregate state committed by `cursorRoot`. */
59
+ export interface Cursor {
60
+ /** Total amount drawn against the capability so far. */
61
+ readonly spent: bigint;
62
+ /** Number of draws, used for idempotency and telemetry. */
63
+ readonly draws: number;
64
+ /** Unix seconds of the most recent advance; `0` until the first draw. */
65
+ readonly lastAdvance: bigint;
66
+ }
67
+ /** An on-chain envelope, as read from a registry. */
68
+ export interface Envelope {
69
+ readonly id: Hex;
70
+ readonly principal: Address;
71
+ readonly capabilityRoot: Hex;
72
+ readonly cursorRoot: Hex;
73
+ readonly createdAt: bigint;
74
+ readonly expiresAt: bigint;
75
+ readonly status: EnvelopeStatus;
76
+ }
77
+ /** Cross-chain/same-chain reference to an envelope; the pair (registry, id) suffices on one chain. */
78
+ export interface EnvelopeRef {
79
+ readonly chainId: bigint;
80
+ readonly registry: Address;
81
+ readonly id: Hex;
82
+ }
83
+ /** Why a draw was refused. */
84
+ export type DrawDenyReason = 'envelope-not-active' | 'not-yet-released' | 'cap-exceeded' | 'approval-required' | 'trust-tier-too-low';
85
+ /** The context a draw is evaluated in. */
86
+ export interface DrawContext {
87
+ /** Current unix time in seconds. */
88
+ readonly now: bigint;
89
+ /** Effective status of the envelope at `now`. */
90
+ readonly status: EnvelopeStatus;
91
+ /** Collected approvals (distinct approver addresses). */
92
+ readonly approvals?: readonly Address[];
93
+ /** Minimum trust tier the caller requires; defaults to 0. */
94
+ readonly minTier?: TrustTier;
95
+ }
96
+ /** Result of a draw evaluation; `reason` is set only when `allowed` is false. */
97
+ export interface DrawDecision {
98
+ readonly allowed: boolean;
99
+ readonly reason?: DrawDenyReason;
100
+ }
101
+ declare const ZERO_ADDRESS: Address;
102
+ /**
103
+ * Validates an authored capability and returns its normalised form. Addresses
104
+ * are lower-cased and every optional field is filled with its default, so
105
+ * semantically identical capabilities always commit to the same root.
106
+ */
107
+ export declare function normalizeCapability(input: CapabilityInput): Capability;
108
+ /** Canonical ABI encoding of a normalised capability. */
109
+ export declare function encodeCapability(capability: Capability): Hex;
110
+ /** `capabilityRoot = keccak256(encodeCapability(capability))`. */
111
+ export declare function capabilityCommitment(capability: Capability): Hex;
112
+ /** Canonical ABI encoding of a cursor. */
113
+ export declare function encodeCursor(cursor: Cursor): Hex;
114
+ /** `cursorRoot = keccak256(encodeCursor(cursor))`. */
115
+ export declare function cursorCommitment(cursor: Cursor): Hex;
116
+ /** The cursor of an envelope that has never been drawn against. */
117
+ export declare const ZERO_CURSOR: Cursor;
118
+ /**
119
+ * Deterministic envelope id, per the standard's recommended derivation
120
+ * `keccak256(abi.encode(registry, principal, capabilityRoot, salt))`. A
121
+ * registry may precompute it before registering so a reference can be embedded
122
+ * upstream.
123
+ */
124
+ export declare function envelopeId(params: {
125
+ registry: Address;
126
+ principal: Address;
127
+ capabilityRoot: Hex;
128
+ salt: Hex;
129
+ }): Hex;
130
+ /** Remaining headroom under a capability's cap. Never negative. */
131
+ export declare function remaining(capability: Capability, cursor: Cursor): bigint;
132
+ /**
133
+ * The budget invariant, `spent + amount <= cap`. Exposed separately so a
134
+ * caller can check a prospective draw without constructing a full context.
135
+ */
136
+ export declare function withinCap(capability: Capability, cursor: Cursor, amount: bigint): boolean;
137
+ /** Whether the collected approvals satisfy the capability's M-of-N gate. */
138
+ export declare function approvalsSatisfied(capability: Capability, approvals: readonly Address[]): boolean;
139
+ /**
140
+ * Evaluates a prospective draw. Mirrors the on-chain substrate's gates in the
141
+ * same order — status, release time, trust tier, approvals, then the budget
142
+ * invariant — so an off-chain denial is never more permissive than the chain.
143
+ */
144
+ export declare function canDraw(capability: Capability, cursor: Cursor, amount: bigint, context: DrawContext): DrawDecision;
145
+ /**
146
+ * Advances the cursor by one accepted draw. The caller must have obtained an
147
+ * allowed {@link canDraw} first; this function does not re-check the cap.
148
+ */
149
+ export declare function advanceCursor(cursor: Cursor, amount: bigint, now: bigint): Cursor;
150
+ /** Derived status: an envelope past its expiry reads as `Expired` while it is not terminal. */
151
+ export declare function effectiveStatus(envelope: Envelope, now: bigint): EnvelopeStatus;
152
+ /** Throws unless `allocations` sum to at most `rootCap` (conservation). */
153
+ export declare function assertConservation(rootCap: bigint, allocations: readonly bigint[]): void;
154
+ /**
155
+ * Derives an attenuated child capability from a parent.
156
+ *
157
+ * Narrowing only: the child's cap and trust tier may not exceed the parent's,
158
+ * its release time may not be earlier, its approval gate may not be weaker
159
+ * (threshold no lower, approvers a subset of the parent's) and its asset must
160
+ * match. A parent that is not allowed to delegate (or is itself attenuated) may
161
+ * not spawn a child at all. The child is always barred from delegating further,
162
+ * which is what makes attenuation non-transitive widening impossible.
163
+ */
164
+ export declare function attenuate(parent: Capability, child: CapabilityInput, options?: {
165
+ parentAttenuated?: boolean;
166
+ }): Capability;
167
+ /** Whether `to` is a legal successor of `from`. */
168
+ export declare function canSetStatus(from: EnvelopeStatus, to: EnvelopeStatus): boolean;
169
+ /** Applies a status transition, throwing {@link EnvelopeError} when it is illegal. */
170
+ export declare function applyStatus(envelope: Envelope, to: EnvelopeStatus): Envelope;
171
+ /** Whether a status is terminal (no successor). */
172
+ export declare function isTerminal(status: EnvelopeStatus): boolean;
173
+ /**
174
+ * The contest window a challenge opens. Any party the substrate permits may
175
+ * contest an Active envelope; once contested, resolution must land within the
176
+ * window or any caller may resolve to the documented default (`Active`), which
177
+ * stops an accused party from running out the clock to foreclose a verdict.
178
+ */
179
+ export interface ContestWindow {
180
+ /** Unix seconds the contest was opened. */
181
+ readonly contestedAt: bigint;
182
+ /** Unix seconds after which a default resolution is permitted. */
183
+ readonly resolutionDeadline: bigint;
184
+ }
185
+ /** Opens a contest window of `windowSeconds` from `now`. */
186
+ export declare function openContest(now: bigint, windowSeconds: bigint): ContestWindow;
187
+ /** Whether the window has elapsed at `now`, letting any caller resolve to the default. */
188
+ export declare function contestExpired(window: ContestWindow, now: bigint): boolean;
189
+ /** The documented default resolution: a still-open contest lapses back to Active. */
190
+ export declare function defaultResolution(): EnvelopeStatus;
191
+ export { ZERO_ADDRESS as ZERO_ASSET };
192
+ //# sourceMappingURL=bounded.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bounded.d.ts","sourceRoot":"","sources":["../src/bounded.ts"],"names":[],"mappings":"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"}