Skip to content

docs(PolicyRegistry): document activation gating contract#157

Merged
stevieraykatz merged 2 commits into
mainfrom
docs/policy-registry-activation-contract
Jun 10, 2026
Merged

docs(PolicyRegistry): document activation gating contract#157
stevieraykatz merged 2 commits into
mainfrom
docs/policy-registry-activation-contract

Conversation

@stevieraykatz

Copy link
Copy Markdown
Member

What

Adds an Activation section to docs/PolicyRegistry/README.md documenting the precompile dispatcher's activation contract — previously undocumented in the reference.

Contract documented

  • View entry points (isAuthorized, policyExists, policyAdmin, pendingPolicyAdmin) are always callable, regardless of activation state. Consumers (B20 transfer-time auth checks, off-chain indexers) see identical view behavior whether or not the feature is active.
  • Mutating entry points are gated; calling one while the feature is inactive reverts FeatureNotActivated.
  • Error classification is independent of activation state: the dispatcher resolves the selector and decodes arguments before applying the activation gate, so UnknownFunctionSelector and ABI-decode errors are preserved even while the feature is inactive. A malformed call produces the same error on both sides of an activation boundary.

Scope

Docs only — no interface or behavior change. Captures the intended dispatcher contract so the reference spec, tests, and cross-environment simulations agree on behavior near activation boundaries.

Add an Activation section to the PolicyRegistry reference spelling out the
dispatcher's activation contract:

- view entry points (isAuthorized, policyExists, policyAdmin,
  pendingPolicyAdmin) are always callable, regardless of activation state;
- mutating entry points are gated and revert FeatureNotActivated while the
  feature is inactive;
- selector/ABI error classification is independent of activation state, so
  UnknownFunctionSelector and ABI-decode errors are preserved even when the
  feature is inactive (the gate is reached only after a call resolves to a
  known mutator with well-formed args).

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

Interface Coverage

✅ All interface functions have test coverage.

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

📊 Forge Coverage (src/lib/)

🟢 ≥99% across all metrics.

File Lines Stmts Branches Funcs
🟢 B20FactoryLib.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockActivationRegistry.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockActivationRegistryStorage.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockB20.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockB20Asset.sol 100.00% 100.00% 100.00% 100.00%
🟡 MockB20Factory.sol 98.96% 99.10% 100.00% 100.00%
🟢 MockB20Stablecoin.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockB20Storage.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockPolicyRegistry.sol 100.00% 100.00% 100.00% 100.00%
🟢 MockPolicyRegistryStorage.sol 100.00% 100.00% 100.00% 100.00%
Total 99.86% 99.88% 100.00% 100.00%

Full report: download artifact. To browse locally: make coverage (runs forge coverage + genhtml + opens the HTML report).

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown

✅ Fork tests: all 610 passed

base/base is fully in sync with the base-std spec.

Comment thread docs/PolicyRegistry/README.md Outdated
Comment thread docs/PolicyRegistry/README.md Outdated

Keeping the views ungated means consumers — B20 tokens running `isAuthorized` on transfer, off-chain indexers reading membership and admin state — observe identical behavior whether or not the feature is active. Calling a gated mutator while the feature is inactive reverts with `FeatureNotActivated`.

> **Error classification is independent of activation state.** The dispatcher recognizes the selector and decodes arguments *before* it applies the activation gate. An unrecognized selector reverts `UnknownFunctionSelector` and malformed calldata reverts with an ABI-decode error whether the feature is active or not — the activation gate is reached only once a call has been resolved to a known mutating function with well-formed arguments. Clients, tests, and cross-environment simulations can therefore distinguish "feature inactive" from "bad call" reliably, and a given malformed call produces the same error on both sides of an activation boundary.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is a bit hard for me to understand which means our customers probably will as well. Is there a way we can dumb it down or be more concise without losing important information?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe we could also flag this with "For auditors:" if we are going to dump this. Maybe this just deserves to be in base/base though

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Dropped the dense block. Kept the builder-facing contract (reads always callable, writes gated with FeatureNotActivated while inactive) and removed the selector/ABI error-classification detail.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Agree it's auditor-oriented — removed it here rather than tagging "For auditors:". Will follow up separately with the team on capturing the error-semantics detail in base/base.

Comment thread docs/PolicyRegistry/README.md Outdated
Address review feedback:
- table of views/mutators -> two plain bullet lists
- code-format `PolicyRegistry` to match `ActivationRegistry`
- drop the dense error-classification blockquote; the selector/ABI
  error-semantics detail is auditor-oriented and is better placed in
  base/base. Keep the builder-facing contract: reads always callable,
  writes gated with FeatureNotActivated while inactive.

Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
@stevieraykatz stevieraykatz merged commit b748b0f into main Jun 10, 2026
10 checks passed
@stevieraykatz stevieraykatz deleted the docs/policy-registry-activation-contract branch June 10, 2026 18:57
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.

3 participants