diff --git a/docs/AGENTS.md b/docs/AGENTS.md
index 4dd492f89..300b9719d 100644
--- a/docs/AGENTS.md
+++ b/docs/AGENTS.md
@@ -57,7 +57,7 @@ npx skills add base/base-skills
|Specifications/Specifications/Base Protocol/Consensus:specifications/base-protocol/consensus/specification,specifications/base-protocol/consensus/derivation,specifications/base-protocol/consensus/p2p,specifications/base-protocol/consensus/rpc
|Specifications/Specifications/Base Protocol/Execution:specifications/base-protocol/execution/l2-execution-engine,specifications/base-protocol/execution/precompiles,specifications/base-protocol/execution/predeploys,specifications/base-protocol/execution/preinstalls
|Specifications/Specifications/Base Protocol/Bridging:specifications/base-protocol/bridging/standard-bridges,specifications/base-protocol/bridging/deposits,specifications/base-protocol/bridging/withdrawals,specifications/base-protocol/bridging/cross-domain-messengers,specifications/base-protocol/bridging/base-solana-bridge
-|Specifications/Specifications/Base Protocol/Proofs:specifications/base-protocol/proofs/overview,specifications/base-protocol/proofs/challenger,specifications/base-protocol/proofs/proposer,specifications/base-protocol/proofs/registrar,specifications/base-protocol/proofs/tee-prover,specifications/base-protocol/proofs/zk-prover,specifications/base-protocol/proofs/proof-contracts
+|Specifications/Specifications/Base Protocol/Proofs:specifications/base-protocol/proofs/overview,specifications/base-protocol/proofs/challenger,specifications/base-protocol/proofs/proposer,specifications/base-protocol/proofs/hinted-tee-registration,specifications/base-protocol/proofs/registrar,specifications/base-protocol/proofs/tee-prover,specifications/base-protocol/proofs/zk-prover,specifications/base-protocol/proofs/proof-contracts
|Specifications/Specifications/B20:specifications/b20/index,specifications/b20/specification-overview,specifications/b20/architecture,specifications/b20/changelog
|Specifications/Specifications/B20/Concepts:specifications/b20/concepts/token-types,specifications/b20/concepts/policies,specifications/b20/concepts/roles-and-pause,specifications/b20/concepts/multipliers
|Specifications/Specifications/B20/Reference:specifications/b20/reference/interfaces,specifications/b20/reference/constants,specifications/b20/reference/errors,specifications/b20/reference/events
@@ -75,7 +75,7 @@ npx skills add base/base-skills
|SDKs & APIs/Base Chain API/Debug API:base-chain/api-reference/debug-api/debug_traceTransaction,base-chain/api-reference/debug-api/debug_traceBlockByHash,base-chain/api-reference/debug-api/debug_traceBlockByNumber
|SDKs & APIs/Base Verify API:sdks/base-verify/overview,sdks/base-verify/verify-social-accounts,sdks/base-verify/verify-users-onchain
|SDKs & APIs/Migrated Documentation:sdks/migrated-products
-|Upgrades/Overview:upgrades/overview,base-chain/network-information/configuration-changelog
+|Upgrades/Overview:upgrades/overview,upgrades/upcoming-features,base-chain/network-information/configuration-changelog
|Upgrades/Denim:upgrades/denim/overview,upgrades/denim/200ms-blocks,upgrades/denim/migrate-from-flashblocks
|Upgrades/Cobalt:upgrades/cobalt/overview,upgrades/cobalt/dynamic-upgrades,base-chain/specs/reference/b20/changelog/02-cobalt-b20asset-multiplier,base-chain/specs/reference/b20/changelog/02-cobalt-b20-seize,base-chain/specs/reference/b20/changelog/02-cobalt-policyregistry-composite-policy,upgrades/cobalt/validity-transactions
|Upgrades/Beryl:upgrades/beryl/overview,upgrades/beryl/reth-v2,upgrades/beryl/reducing-canonical-withdrawal-delay,upgrades/beryl/b20
diff --git a/docs/docs.json b/docs/docs.json
index 53835efd6..f595db7bd 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -232,6 +232,7 @@
"specifications/base-protocol/proofs/overview",
"specifications/base-protocol/proofs/challenger",
"specifications/base-protocol/proofs/proposer",
+ "specifications/base-protocol/proofs/hinted-tee-registration",
"specifications/base-protocol/proofs/registrar",
"specifications/base-protocol/proofs/tee-prover",
"specifications/base-protocol/proofs/zk-prover",
@@ -449,6 +450,7 @@
"group": "Overview",
"pages": [
"upgrades/overview",
+ "upgrades/upcoming-features",
"base-chain/network-information/configuration-changelog"
]
},
diff --git a/docs/llms-full.txt b/docs/llms-full.txt
index 8bf70c8c7..3c608f681 100644
--- a/docs/llms-full.txt
+++ b/docs/llms-full.txt
@@ -280,7 +280,9 @@ const client = createPublicClient({ chain: base, transport: http() })
- [Proposer](https://docs.base.org/specifications/base-protocol/proofs/proposer): Specification of the proposer, an offchain service that turns canonical L2 checkpoint ranges into AggregateVerifier games on L1.
-- [Registrar](https://docs.base.org/specifications/base-protocol/proofs/registrar): Specification of the registrar, an offchain service that maintains the onchain registry of accepted TEE signer identities via attestation ZK proofs.
+- [Hinted TEE Registration](https://docs.base.org/specifications/base-protocol/proofs/hinted-tee-registration): Migration from external ZK proving to checked P-384 hints for registering new AWS Nitro Enclave signers.
+
+- [Registrar](https://docs.base.org/specifications/base-protocol/proofs/registrar): Specification of the registrar and the hinted P-384 flow used to register AWS Nitro Enclave signer identities on L1.
- [TEE Prover](https://docs.base.org/specifications/base-protocol/proofs/tee-prover): Specification of the TEE prover, an offchain service that re-executes L2 block ranges inside AWS Nitro Enclaves to produce signed proof material for AggregateVerifier games.
@@ -498,6 +500,8 @@ const client = createPublicClient({ chain: base, transport: http() })
- [Upgrades](https://docs.base.org/upgrades/overview): Track Base network upgrades, activation dates, and the protocol changes included in each release.
+- [Upcoming Features](https://docs.base.org/upgrades/upcoming-features): Planned Base protocol features and their ballpark target quarters, tracked independently of a specific network upgrade.
+
- [Configuration Changelog](https://docs.base.org/base-chain/network-information/configuration-changelog): A log of configuration changes to the Base networks.
### Denim
diff --git a/docs/llms.txt b/docs/llms.txt
index 9c78beeb1..0d42fd8ba 100644
--- a/docs/llms.txt
+++ b/docs/llms.txt
@@ -214,7 +214,9 @@
- [Proposer](https://docs.base.org/specifications/base-protocol/proofs/proposer): Specification of the proposer, an offchain service that turns canonical L2 checkpoint ranges into AggregateVerifier games on L1.
-- [Registrar](https://docs.base.org/specifications/base-protocol/proofs/registrar): Specification of the registrar, an offchain service that maintains the onchain registry of accepted TEE signer identities via attestation ZK proofs.
+- [Hinted TEE Registration](https://docs.base.org/specifications/base-protocol/proofs/hinted-tee-registration): Migration from external ZK proving to checked P-384 hints for registering new AWS Nitro Enclave signers.
+
+- [Registrar](https://docs.base.org/specifications/base-protocol/proofs/registrar): Specification of the registrar and the hinted P-384 flow used to register AWS Nitro Enclave signer identities on L1.
- [TEE Prover](https://docs.base.org/specifications/base-protocol/proofs/tee-prover): Specification of the TEE prover, an offchain service that re-executes L2 block ranges inside AWS Nitro Enclaves to produce signed proof material for AggregateVerifier games.
@@ -432,6 +434,8 @@
- [Upgrades](https://docs.base.org/upgrades/overview): Track Base network upgrades, activation dates, and the protocol changes included in each release.
+- [Upcoming Features](https://docs.base.org/upgrades/upcoming-features): Planned Base protocol features and their ballpark target quarters, tracked independently of a specific network upgrade.
+
- [Configuration Changelog](https://docs.base.org/base-chain/network-information/configuration-changelog): A log of configuration changes to the Base networks.
### Denim
diff --git a/docs/specifications/base-protocol/proofs/hinted-tee-registration.mdx b/docs/specifications/base-protocol/proofs/hinted-tee-registration.mdx
new file mode 100644
index 000000000..2960ac9b1
--- /dev/null
+++ b/docs/specifications/base-protocol/proofs/hinted-tee-registration.mdx
@@ -0,0 +1,77 @@
+---
+title: "Hinted TEE Registration"
+description: "Migration from external ZK proving to checked P-384 hints for registering new AWS Nitro Enclave signers."
+---
+
+Base is replacing the RISC Zero and Boundless flow used to register new TEE signers with direct
+AWS Nitro attestation verification using checked P-384 hints.
+
+The change makes registration faster and removes the dependency on an external ZK proving service.
+It does not change how enclaves produce TEE state proofs or how those proofs are verified.
+
+## Previous Flow
+
+The registrar previously sent each Nitro attestation to an external proving service. That service
+produced a RISC Zero proof showing that the attestation and its AWS certificate chain were valid.
+The registrar then submitted the proof to `TEEProverRegistry` on L1.
+
+This added an external availability dependency and could delay new signer registration while the ZK
+proof was generated.
+
+## New Flow
+
+The registrar now:
+
+1. Fetches a fresh AWS Nitro attestation for the new enclave signer.
+2. Generates P-384 modular inverse hints locally.
+3. Verifies and caches any missing AWS certificates through `CertManager`.
+4. Submits the attestation, its signature, and the final hint stream to `TEEProverRegistry`.
+5. Records the signer and its attested PCR0 after all onchain checks pass.
+
+`TEEProverRegistry` permits only its owner or manager to perform the final registration. Certificate
+cache writes are permissionless because `CertManager` verifies the certificate, its parent chain,
+and every supplied hint before storing it.
+
+## Checked Hints
+
+P-384 verification requires many modular inversions. Computing those inversions in the EVM is
+expensive, but checking a proposed inverse is comparatively cheap. The registrar computes the
+values offchain and supplies them as hints.
+
+Every hint is checked onchain before use. Incorrect, missing, or surplus hints revert, so the hint
+generator is required for liveness but is not trusted for correctness. A faulty or malicious hint
+cannot make an invalid certificate or attestation pass.
+
+## Certificate Caching
+
+The AWS Nitro root is pinned in `CertManager`. Non-root CA certificates and the leaf certificate are
+verified and cached in parent-first order. Later registrations can reuse cached certificates while
+they remain valid and unrevoked.
+
+For a typical Nitro certificate chain:
+
+| Cache state | Registration transactions |
+| --- | ---: |
+| Empty | 5 |
+| CA chain cached, new leaf | 2 |
+| CA chain and leaf cached | 1 |
+
+The registrar reads onchain cache state before each write, allowing it to resume after a partial
+registration or process restart without repeating completed certificate transactions.
+
+## Unchanged Behavior
+
+This migration does not change:
+
+- signer key generation inside the Nitro Enclave;
+- the attestation fields produced by AWS Nitro;
+- PCR0-based enclave image selection;
+- TEE proposal or dispute proof formats;
+- `TEEVerifier` or `AggregateVerifier` behavior; or
+- SP1 state-proof verification.
+
+The existing `TEEProverRegistry` proxy is upgraded without changing its storage layout. Existing
+owners, managers, proposers, registered signers, and signer image hashes are preserved.
+
+For the full registration lifecycle, validation rules, revocation handling, and operator
+requirements, see the [Registrar specification](/specifications/base-protocol/proofs/registrar).
diff --git a/docs/specifications/base-protocol/proofs/registrar.mdx b/docs/specifications/base-protocol/proofs/registrar.mdx
index 48668a06a..560e92347 100644
--- a/docs/specifications/base-protocol/proofs/registrar.mdx
+++ b/docs/specifications/base-protocol/proofs/registrar.mdx
@@ -1,412 +1,306 @@
---
title: "Registrar"
-description: "Specification of the registrar, an offchain service that maintains the onchain registry of accepted TEE signer identities via attestation ZK proofs."
+description: "Specification of the registrar and the hinted P-384 flow used to register AWS Nitro Enclave signer identities on L1."
---
-The registrar is an offchain service that maintains the onchain registry of accepted TEE signer
-identities. It discovers running TEE prover instances, fetches AWS Nitro Enclave attestation
-documents from each enclave, generates a ZK proof that the attestation is well-formed, and submits
-the resulting signer registration to [`TEEProverRegistry`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEProverRegistry.sol)
-on L1. It also deregisters signers whose backing instances are no longer reachable, and revokes
-intermediate certificates that AWS has withdrawn.
+The registrar is an offchain service that maintains the signer set in
+[`TEEProverRegistry`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEProverRegistry.sol).
+It discovers Base TEE prover instances, obtains an AWS Nitro attestation for each enclave signer,
+generates P-384 verification hints locally, caches the attestation certificate chain on L1, and
+submits the final signer registration.
-A registrar is operated by Base. The proof system trusts only signers that this registrar has
-registered, so registrar correctness is a prerequisite for accepting TEE proofs onchain. Its output
-is still self-validating: the attestation ZK proof, the enclave PCR0 measurement, and the signer
-public key are all checked by `TEEProverRegistry` and [`NitroEnclaveVerifier`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/NitroEnclaveVerifier.sol)
-before the signer becomes valid.
+This flow replaces the previous RISC Zero attestation proof and external Boundless proving path.
+There is no runtime backend selector or fallback to ZK verification. The TEE proof format,
+`TEEVerifier`, `AggregateVerifier`, `TEE_IMAGE_HASH`, and SP1 state-proof behavior are unchanged.
+Registration requires the hinted-compatible registrar and prover-host signer API.
## Responsibilities
A conforming registrar performs the following work:
-1. Discover the current set of TEE prover instances behind the production load balancer.
-2. Fetch the per-enclave signer public keys and Nitro attestation documents from each instance.
-3. Optionally check the attestation certificate chain against AWS-published CRLs and against the
- onchain durable revocation set.
-4. Generate a ZK proof of attestation correctness for every enclave that is not yet registered.
-5. Submit `TEEProverRegistry.registerSigner()` for newly attested signers.
-6. Submit `TEEProverRegistry.deregisterSigner()` for onchain signers whose instances are gone.
-7. Submit `NitroEnclaveVerifier.revokeCert()` for intermediate certificates discovered to be
- revoked.
-8. Recover in-flight proof requests across process restarts without re-spending proving work.
-
-The registrar does not gate which PCR0 measurements are accepted. Registration is PCR0-agnostic so
-that the next image's signers can be pre-registered ahead of a hardfork. Acceptance of proofs
-produced by a given signer is enforced onchain by [`TEEVerifier`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEVerifier.sol)
-against the current `TEE_IMAGE_HASH` of the active game implementation.
-
-The registrar also does not create proposals, generate proof material for proposals or disputes,
-or dispute invalid state transitions. Those responsibilities belong to the proposer, the TEE
-provers, and the challenger.
-
-## Startup Configuration
-
-At startup, the registrar connects to:
-
-- an L1 execution RPC for contract reads and transaction submission
-- AWS APIs for ELBv2 target health and EC2 instance metadata
-- a JSON-RPC endpoint on each discovered TEE prover instance
-- a proving backend (Boundless marketplace or a self-hosted RISC Zero prover)
-- `TEEProverRegistry`
-- an optional `NitroEnclaveVerifier`, required only when CRL checking is enabled
-
-The registrar reads no contract configuration at startup beyond the registry and verifier
-addresses provided by the operator. It treats every onchain signer it has not seen in its own
-instance set as an orphan candidate, so a single registrar must be the sole writer for a given
-registry.
+1. Discover TEE prover instances behind the configured AWS load balancer.
+2. Fetch each enclave's secp256k1 public key and a fresh Nitro attestation bound to that signer.
+3. Parse the COSE and X.509 data without changing the signed encodings.
+4. Validate the expected signer, nonce, PCR0, trust anchor, certificate order, and freshness locally.
+5. Generate the checked P-384 inverse hints required by the onchain verifier.
+6. Reuse valid cached certificates and cache missing certificates in parent-first order.
+7. Submit the final attestation to `TEEProverRegistry.registerSigner()`.
+8. Optionally monitor AWS certificate revocation lists and persist confirmed revocations on L1.
+9. Deregister signers whose backing prover instances are no longer active.
+
+The registrar does not select the accepted enclave image. Registration records the attested PCR0,
+but [`TEEVerifier`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEVerifier.sol)
+accepts a signer only when its recorded image hash matches the active `TEE_IMAGE_HASH`. This allows
+the next image's signers to be registered before an image rotation without allowing them to produce
+accepted proofs early.
+
+## Architecture
+
+```mermaid TEE Signer Registration lines wrap expandable
+flowchart LR
+ registrar[Registrar]
+ prover[TEE prover instance]
+ registry[TEEProverRegistry]
+ validator[NitroValidator]
+ certs[CertManager]
+ p384[P384Verifier]
+
+ prover -- "signer key + attestation" --> registrar
+ registrar -- "cache certificate + hints" --> certs
+ registrar -- "attestation TBS + signature + hints" --> registry
+ registry --> validator
+ validator --> certs
+ certs --> p384
+ validator --> p384
+```
-## Driver Loop
+The onchain validation stack contains three contracts:
-The registrar runs a single driver loop:
-
-1. Discover the current instance set.
-2. Process every instance concurrently, bounded by `max_concurrency`.
-3. Read the onchain signer set.
-4. Deregister orphan signers.
-5. Sleep `poll_interval` seconds, or exit on cancellation.
-
-The loop runs `step()` once on startup before sleeping. Cancellation is observed promptly between
-ticks and inside long-running tx retries so the service can shut down without leaving partial
-state.
-
-## Instance Discovery
-
-The registrar uses AWS ALB target group polling. DNS, SRV, and Kubernetes discovery are not
-supported.
-
-Each discovery cycle:
-
-1. Calls `elasticloadbalancingv2.DescribeTargetHealth(target_group_arn)`.
-2. Filters out non-instance targets (target IDs that do not start with `i-`).
-3. Deduplicates instance IDs that appear on more than one port.
-4. Calls `ec2.DescribeInstances(instance_ids)` to read each instance's private IP and launch time.
-5. Builds JSON-RPC endpoint URLs of the form `http://{private_ip}:{prover_port}` and pairs each
- with its ALB-reported health state.
-
-Health states map as follows:
-
-| AWS state | Internal state | `should_register()` |
-| ------------ | -------------- | ------------------- |
-| `initial` | `Initial` | true |
-| `healthy` | `Healthy` | true |
-| `draining` | `Draining` | false |
-| anything else| `Unhealthy` | false |
-
-`Unhealthy` instances within `unhealthy_registration_window` seconds of `launch_time` are still
-allowed to register. This is a warm-up grace period: it lets a new instance whose JSON-RPC
-endpoint is briefly slow finish enclave attestation and registration before the next ALB health
-check would deregister it. The window must be smaller than the Boundless proving timeout so that
-a started proof can complete before the instance becomes ineligible.
-
-Discovery failures abort that tick and skip orphan cleanup. They do not deregister live signers.
-
-## Per-Instance Processing
-
-For each discovered instance, the registrar:
-
-1. Calls `enclave_signerPublicKey` to fetch the per-enclave SEC1 public keys. Each instance can
- host multiple enclaves and each enclave has its own signer key.
-2. Derives the Ethereum signer address from each public key as the last 20 bytes of
- `keccak256(uncompressed_pubkey_xy)`.
-3. Returns immediately if no signers were reported. The address set still contributes nothing for
- this instance and the call is a no-op.
-4. Decides whether the instance is currently registerable:
- - `Initial` and `Healthy` instances proceed.
- - `Unhealthy` instances within the warm-up window proceed.
- - All other instances contribute their addresses to the active set but do not generate new
- proofs or transactions.
-5. Generates a single 32-byte random nonce and calls `enclave_signerAttestation` once with that
- nonce. The nonce binds every per-enclave attestation in the returned batch to the same
- freshness commitment.
-6. Performs CRL checks once per batch when CRL checking is enabled. Each enclave has its own
- signing key, but AWS Nitro attestations are signed by the parent EC2 instance's Nitro
- Hypervisor, whose signing key is endorsed by a per-instance AWS-issued certificate chain.
- Every enclave on the same instance therefore produces an attestation under the same parent
- chain, so a single CRL check per instance is sufficient.
-7. For each signer address, runs the registration pipeline.
-
-All reachable instances contribute to the active signer set, including `Draining` and `Unhealthy`
-ones. This prevents an instance that is rotating in or out from being deregistered prematurely.
-
-## Attestation Proof Generation
-
-The registrar produces proof material for every signer not yet onchain by calling an
-`AttestationProofProvider`. The provider returns:
-
-```text Attestation Proof Provider Output
-output // ABI-encoded VerifierJournal (PCRs, public key, timestamp, cert hashes)
-proofBytes // Groth16 seal
-```
+| Contract | Role |
+| --- | --- |
+| `P384Verifier` | Verifies P-384 signatures while checking caller-supplied modular inverse hints. |
+| `CertManager` | Pins the AWS Nitro root, verifies and caches non-root certificates, and enforces certificate expiry and revocation. |
+| `NitroValidator` | Parses the signed Nitro attestation, re-walks the cached certificate chain, and verifies the final COSE signature. |
+
+`TEEProverRegistry` holds an immutable `NitroValidator` reference. The registrar discovers
+`CertManager` through `TEEProverRegistry.NITRO_VALIDATOR()` and `NitroValidator.certManager()`;
+operators do not configure those addresses separately.
-`output` is the `VerifierJournal` consumed by `NitroEnclaveVerifier.verify()` during
-`registerSigner()`. `proofBytes` is the Groth16 SNARK that proves the journal corresponds to a
-valid Nitro attestation document.
+## Driver Loop
-The registrar supports two backends:
+The registrar runs one polling loop:
-| Backend | Description |
-| ----------- | ------------------------------------------------------------------------------------------------------------ |
-| `boundless` | Submits the proving job to the Boundless marketplace using a dedicated wallet. |
-| `direct` | Loads the guest ELF locally and proves via `risc0_zkvm::default_prover()`, routing to Bonsai or a local prover according to RISC Zero environment variables. |
+1. Query AWS ALB and EC2 for the current prover instances.
+2. Probe `/readyz` on every non-draining target. The load balancer's `/healthz` is registration-gated,
+ so it cannot be used to bootstrap registration.
+3. Resolve signer public keys and attestations concurrently, bounded by `max_concurrency`.
+4. Start one registration task per eligible signer and cancel tasks whose signer is no longer eligible.
+5. Read the onchain signer set and deregister unprotected signers when discovery was conclusive.
+6. Sleep for `poll_interval`, or stop on cancellation.
-Both backends are valid production paths. `boundless` is the primary production backend.
-`direct` is also used for local development and tests, but it is suitable for production fallback
-when an operator needs to bypass the marketplace, for example during a Boundless incident or for
-private-deployment scenarios.
+Only instances that pass `/readyz` are eligible for new registrations. Draining instances still
+contribute their known signer addresses to the active set so a rotation does not immediately
+deregister them.
-For Boundless, the registrar submits a `RequestParams` containing the program URL, the attestation
-input, the expected `image_id`, and a `prefix_match(image_id)` requirement so a fulfilled request
-cannot be replayed against a different program. Onchain Boundless submissions are serialized
-behind a mutex to avoid wallet nonce races.
+When an instance disappears or becomes unhealthy, the registrar preserves its last-known signers
+for `instance_cache_ttl_cycles`. It skips the entire orphan pass while any instance remains
+unresolved. Pending registration tasks are also protected from orphan cleanup.
-### Restart Recovery
+Discovery supports AWS ELBv2 target groups whose targets are EC2 instances. Targets whose IDs do
+not start with `i-` are ignored. AWS API errors and missing EC2 data abort the tick and skip orphan
+cleanup, but an empty target group is a conclusive result. The last-known-signer cache is in memory
+and starts empty after a process restart. Operators must therefore configure and monitor the target
+group carefully: a cold registrar pointed at an empty target group has no cached signers to protect.
-The registrar process is itself ephemeral. Across restarts, it must not re-spend proving work and
-must not submit stale proofs. Boundless `RequestId` slots are derived deterministically:
+## Attestation Challenge
-```text Request Index Derivation
-request_index(signer, attempt) = u32::from_be_bytes(keccak256(signer || attempt)[..4])
-```
+Each signer receives a deterministic 32-byte nonce:
-For each signer, the registrar probes `max_recovery_attempts` consecutive deterministic slots
-before submitting a fresh request. The action depends on the slot status:
+```text Attestation Nonce
+keccak256(
+ "base-proof-tee-registrar:attestation-nonce:v1" ||
+ teeProverRegistryAddress ||
+ signerAddress
+)
+```
-| Slot status | Registrar action |
-| ------------- | --------------------------------------------------------------------------------- |
-| `Unknown` | Record the first such slot as the candidate fresh-submission slot; keep scanning. |
-| `Locked` | Resume `wait_for_request_fulfillment` and use the resulting receipt. |
-| `Fulfilled` | Fetch the receipt and check journal freshness before accepting it. |
-| `Expired` | Skip the slot permanently; continue scanning. |
+The registrar requests one attestation per signer with that nonce. It rejects the response unless:
-A `RequestIsNotLocked` revert encountered mid-scan is treated as in-flight and short-circuits to
-waiting on that slot.
+- the attested `public_key` derives to the expected signer address;
+- the attested nonce exactly matches the deterministic challenge;
+- PCR0 is present, is 48 bytes, and is not the all-zero debug-mode measurement;
+- the certificate chain starts at the pinned AWS Nitro root;
+- the certificate chain is ordered parent-first and ends in one leaf certificate; and
+- the attestation remains within the configured local freshness window.
-If a recovered receipt's attestation timestamp is older than `max_attestation_age`, the registrar
-discards it and submits a fresh request in the candidate slot. The default freshness window is
-3300 seconds, kept strictly under the onchain `MAX_AGE` of 3600 seconds so a recovered proof can
-still be submitted before it ages out onchain.
+The deterministic challenge binds the attestation to one registry and signer without requiring
+registrar state across restarts. `TEEProverRegistry` independently enforces timestamp freshness,
+but nonce matching is a registrar policy check because `NitroValidator` only exposes the signed
+nonce to its caller.
-After an `ExecutionReverted` from `registerSigner()`, the signer is added to a per-process
-`recovery_blocked` set. The next cycle skips the recovery scan for that signer and submits a fresh
-request, so a known-bad recovered proof is never tried twice. The set is cleared on restart, which
-gives one fresh attempt per process even for previously blocked signers.
+## Registration Plan
-## Registration Transactions
+The registrar preserves the exact protected-header and payload encodings from the input
+`COSE_Sign1` document when constructing the signed `Sig_structure`. Re-encoding signed CBOR would
+change the message and invalidate the AWS signature.
-For each unregistered signer, the registrar:
+For parity with the pinned `NitroValidator`, the registrar accepts an optional compact `0xD2` tag
+followed by the compact `0x84` `COSE_Sign1` array, the ES384 protected header `0x44a1013822`, a
+96-byte P-384 signature, and no trailing COSE or TBS data. The payload, `pcrs`, and `cabundle`
+containers may use definite or indefinite lengths. Unknown payload keys are skipped, but recognized
+keys must be unique.
-1. Calls `TEEProverRegistry.isRegisteredSigner(signer)`. If true, the signer is skipped.
-2. Generates or recovers proof material as described above.
-3. ABI-encodes `registerSigner(output, proofBytes)`.
-4. Submits the transaction through the L1 transaction manager.
-5. Retries failed submissions according to the rules below.
-6. On a successful receipt, increments the registration counter.
+The parsed plan contains:
-The transaction retry rules are:
+- the signer derived from the 65-byte `0x04 || x || y` secp256k1 public key;
+- PCR0, timestamp, and nonce;
+- the pinned root certificate;
+- non-root CA certificates followed by the leaf certificate;
+- the exact attestation to-be-signed bytes and 96-byte P-384 signature; and
+- cache and revocation identifiers matching `CertManager`.
-| Failure | Required behavior |
-| ----------------------------- | ------------------------------------------------------------------------------------------------------- |
-| Retryable error | Sleep `tx_retry_delay`, then retry, up to `max_tx_retries` total attempts. |
-| `ExecutionReverted` revert | Block recovery for this signer so the next cycle generates a fresh proof, then return the error. |
-| Insufficient funds, fee cap | Treat as non-retryable. Surface the error and stop attempting this signer for the current cycle. |
-| Reverted receipt | Treat as a transaction failure even when submission succeeded. |
-| Reported error after mining | Re-read `isRegisteredSigner(signer)`. If true, treat the attempt as success. |
+The pinned root cache key is `keccak256(root DER)`. Every non-root cache key is
+`keccak256(TBSCertificate DER)`, excluding the malleable outer ECDSA signature. Non-root revocation
+uses `keccak256(issuerHash || serialHash)`. `issuerHash` hashes the issuer Name content octets,
+excluding its DER tag and length. `serialHash` hashes the serial INTEGER content octets, including a
+leading `0x00` used for DER sign extension. These identities remain stable across equivalent outer
+certificate encodings.
-The post-error reconciliation is required because fee-bumping and nonce races can return errors
-even when the underlying transaction has already been mined. Without the recheck, the registrar
-would burn proving work generating a fresh proof for an already-registered signer.
+## P-384 Hints
-Transaction submission is cancellation-aware: both the active send and the inter-attempt sleep
-abort cleanly on shutdown, so the next process starts from a clean nonce state without committing
-a partial transaction.
+AWS signs Nitro certificates and attestations with ECDSA over P-384. P-384 verification requires
+many modular inversions, which are expensive to compute in the EVM. The registrar computes each
+inverse offchain and supplies it as a hint.
-## Orphan Deregistration
+For every division by `b` modulo a prime `m`, the contract checks:
-After processing every instance, the registrar reconciles the onchain signer set against the
-active set:
+```text Inverse Check
+b * hint == 1 (mod m)
+```
-1. If discovery failed for this tick, skip cleanup.
-2. If cancellation was requested, skip cleanup.
-3. Compare the number of reachable instances against the total discovered instances. If
- `reachable_instances * 2 <= total_instances`, skip cleanup.
-4. Read the onchain set with `TEEProverRegistry.getRegisteredSigners()`.
-5. Compute `orphans = onchain_signers \ active_signers`.
-6. For each orphan, in order:
- 1. Recheck `isRegisteredSigner(signer)`. Skip if it returns false.
- 2. ABI-encode `deregisterSigner(signer)` and submit it through the transaction manager.
+The hint is used only after this equality holds. Since an invertible value has one inverse modulo a
+prime, a passing hint is the same value the contract would have computed. Incorrect, truncated, or
+surplus hints revert. Hints affect liveness, not correctness: a faulty generator can prevent a
+registration but cannot make an invalid signature pass.
-The majority-reachable guard prevents a transient AWS or VPC outage from deregistering most of
-the prover fleet at once. The per-orphan `isRegisteredSigner` recheck is a race guard: the set
-returned by `getRegisteredSigners()` is read once per cycle, and another writer could have
-deregistered a signer between that read and this transaction. Skipping already-deregistered
-addresses avoids wasted gas on a no-op transaction.
+Each hint stream is a concatenation of 48-byte big-endian inverses in the verifier's deterministic
+consumption order. The registrar generates one stream for every non-root certificate signature and
+one for the final attestation signature. Production hint generation is native Rust and does not
+invoke Node, Go, or an external proving service.
-This procedure assumes a single registrar per `TEEProverRegistry`. Two registrars sharing a
-registry would each treat the other's signers as orphans.
+## Certificate Cache
-## Certificate Revocation
+`CertManager` stores the pinned AWS Nitro root at deployment. The registrar processes every
+remaining certificate in parent-first order:
-When the operator enables CRL checking, the registrar enforces revocation using two layers in
-order. Both are required to make CRL handling safe.
+1. Read the candidate's cached metadata and revocation state.
+2. If cached, require the expected CA or leaf role, an unexpired validity period, the original
+ parent binding, and a complete unrevoked path to the pinned root.
+3. If not cached, call `verifyCACertWithHints()` or `verifyClientCertWithHints()` with the DER
+ certificate, parent cache key, and signature hints.
+4. Re-read state after the transaction. A transaction error is treated as success if the expected
+ usable cache entry is now present.
-### Layer 1: Onchain Durable Revocation Pre-Check
+Cache writes are permissionless because all certificate data and hints are verified onchain.
+Per-certificate locks prevent concurrent signer tasks from submitting duplicate cache transactions
+for a shared chain. On restart or after a partial failure, the registrar reads the cache again and
+continues from the first missing certificate.
-For each intermediate certificate in the attestation chain, the registrar reads
-`NitroEnclaveVerifier.revokedCerts(certPathDigest)`. Any hit blocks registration for that batch
-and skips Layer 2 entirely.
+For a typical Nitro chain with three non-root CAs, transaction counts are:
-This layer protects against a known attack against the cached-cert path: an intermediate that was
-once revoked onchain could be reintroduced through a later `_cacheNewCert` write if its CRL entry
-is later pruned by AWS. Reading the durable mapping first ensures a revoked cert cannot be
-silently rehabilitated.
+| Cache state | Transactions |
+| --- | ---: |
+| Empty | 5: three CA cache writes, one leaf cache write, one registration |
+| CA chain cached, new leaf | 2: one leaf cache write, one registration |
+| CA chain and leaf cached | 1: registration only |
-RPC errors against `revokedCerts` fail open and fall through to Layer 2, but are counted as
-revocation check errors. `RegistrationDriver::new` requires a `NitroEnclaveVerifier` client when
-CRL checking is enabled and rejects misconfiguration at startup.
+Each signature verification is split into its own transaction so it remains below the EIP-7825
+per-transaction gas limit. Final registration intentionally supplies no certificate hints;
+`NitroValidator` succeeds only if the complete chain is already cached and usable.
-### Layer 2: AWS CRL Distribution Points
+## Final Registration
-For intermediates that pass Layer 1, the registrar:
+After the cache is ready, the registrar calls:
-1. Parses each CRL distribution point from the chain.
-2. Validates the URL host against an allowlist requiring the `.amazonaws.com` suffix and the
- `nitro-enclave` keyword. HTTP redirects are disabled and responses are bounded to 10 MiB.
-3. Fetches the CRL with a configurable timeout.
-4. Searches for the certificate's serial number.
-5. For each revoked intermediate, submits `NitroEnclaveVerifier.revokeCert(certPathDigest)`.
-6. Returns true if any intermediate is revoked, blocking registration for the batch.
+```solidity Registration Call
+TEEProverRegistry.registerSigner(attestationTbs, signature, hints)
+```
-`revokeCert` failures are counted but do not abort registration of other instances on the same
-tick. The submitted revocations transition Layer 1 to a hit on the next cycle so subsequent
-registrations can short-circuit without re-fetching the CRL.
+The registry permits only its owner or manager to call this method. It delegates cryptographic and
+certificate validation to `NitroValidator`, then applies Base-specific policy:
-## Pending Registration Lifecycle
+1. Reject attestations at least 60 minutes old.
+2. Reject attestations whose second-level timestamp is greater than or equal to `block.timestamp`.
+3. Require PCR0 at index zero, exactly 48 bytes, and not the debug-mode measurement.
+4. Require a 65-byte uncompressed secp256k1 public key.
+5. Derive the signer as the last 20 bytes of `keccak256(x || y)`.
+6. Store the signer as registered and record `keccak256(PCR0)` as its image hash.
-Each per-signer pipeline is keyed by Ethereum signer address. The Boundless proof slot for a
-signer transitions through:
+The registrar uses a 3,300-second default local freshness limit, leaving submission headroom under
+the registry's 3,600-second limit. It checks freshness before every certificate, revocation, and
+registration transaction so a multi-transaction cold flow stops before submitting stale material.
-```mermaid Pending Registration Lifecycle lines wrap expandable
-flowchart TB
- Start([process_instance]) --> Recover[Recovery scan]
- Recover -->|Locked slot| Wait[wait_for_request_fulfillment]
- Recover -->|Fulfilled slot| Fresh{Journal fresh?}
- Recover -->|All slots Unknown/Expired| Submit[Submit fresh request]
- Recover -->|Blocked recovery| Submit
+Before each registration attempt, and after ambiguous transaction errors, the registrar reads
+`isRegisteredSigner(signer)`. An observed registration is treated as success. Retryable transaction
+errors use bounded exponential backoff; reverted receipts and non-retryable errors fail the current
+task.
- Fresh -->|yes| Receipt[Use recovered receipt]
- Fresh -->|no| Submit
- Wait --> Receipt
- Submit --> Wait
+## Certificate Revocation
- Receipt --> Send[tx_manager.send registerSigner]
- Send -->|Ok| Done([Registered])
- Send -->|Retryable| Send
- Send -->|ExecutionReverted| Block[Block recovery for signer]
- Block --> Done
-```
+`CertManager` maintains a durable revocation set and an immutable pinned AWS Nitro root. The owner
+can revoke or unrevoke the root as an emergency halt, set the non-root revoker, and unrevoke
+certificate identities. The revoker role can revoke non-root issuer/serial identities. Revocation
+is checked during cold verification, cache reuse, and the final cached-chain walk.
-A pending recovery state, a fulfilled-but-stale receipt, and an `ExecutionReverted` revert all
-funnel back to a fresh submission on the next tick rather than wedging the signer.
+For every registration attempt, the registrar checks the pinned root and every planned certificate
+against `CertManager.isRevoked()`. A confirmed onchain revocation rejects the registration.
-## Onchain Interactions
+When CRL fetching is additionally enabled, the registrar:
-The registrar uses the following contract calls. `TEEProverRegistry.isValidSigner()` is
-intentionally not called by the registrar; that predicate is enforced by `TEEVerifier` at proof
-submission time and includes an image-hash match that the registrar cannot satisfy by itself.
+1. Fetches CRLs only from allowlisted AWS Nitro hosts, without redirects and with a 10 MiB response
+ limit.
+2. Matches intermediate certificate serial numbers against the CRLs.
+3. Calls `CertManager.revokeCert()` for confirmed revocations before rejecting the registration.
-| Contract | Method | Caller path |
-| -------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | --------------------------------------------------- |
-| [`TEEProverRegistry`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEProverRegistry.sol) | `registerSigner(output, proof)` | Per-signer registration transaction. |
-| [`TEEProverRegistry`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEProverRegistry.sol) | `deregisterSigner(signer)` | Per-orphan deregistration transaction. |
-| [`TEEProverRegistry`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEProverRegistry.sol) | `isRegisteredSigner(signer)` | Pre-check, post-error reconciliation, orphan race guard. |
-| [`TEEProverRegistry`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/TEEProverRegistry.sol) | `getRegisteredSigners()` | Once per cycle for orphan computation. |
-| [`NitroEnclaveVerifier`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/NitroEnclaveVerifier.sol) | `revokeCert(certHash)` | When AWS CRL revokes an intermediate. |
-| [`NitroEnclaveVerifier`](https://github.com/base/contracts/blob/main/src/L1/proofs/tee/NitroEnclaveVerifier.sol) | `revokedCerts(certHash)` | Layer-1 onchain durable revocation pre-check. |
+CRL fetch and parse failures are fail-open and retried on later cycles. Confirmed onchain
+revocations always fail closed.
-PCR0 enforcement happens onchain at proof submission, not at registration. The registrar registers
-any enclave whose Nitro attestation verifies, regardless of its PCR0. This allows the next image's
-fleet to be brought up and pre-registered in advance of a hardfork; those signers cannot produce
-accepted proposals until the active game implementation's `TEE_IMAGE_HASH` matches their
-registered image hash.
+## Orphan Deregistration
-## Service Lifecycle
+After registration task reconciliation, the registrar computes:
-At startup, the registrar:
+```text Orphan Formula
+orphans = registered signers - active signers - pending signers
+```
-1. Parses CLI configuration and validates it.
-2. Initializes tracing and installs the `rustls` ring crypto provider.
-3. Installs a signal handler that triggers a cancellation token.
-4. Initializes Prometheus metrics, including L1 wallet and Boundless wallet balance monitoring.
-5. Builds the L1 provider, transaction manager, AWS SDK clients, and discovery client.
-6. Builds the registry client and the optional Nitro verifier client.
-7. Builds the proof provider for the configured backend.
-8. Starts the health server and marks readiness.
-9. Starts the driver loop.
+It calls `deregisterSigner()` for each orphan only when discovery completed without unresolved
+instances and the configured last-known-signer grace period has expired. Deregistration removes the
+registered flag and stored image hash. This flow assumes one registrar controls a given registry;
+independent registrars would otherwise classify each other's signers as orphans.
-The health endpoint reports ready as soon as wiring completes. Connectivity gating is intentionally
-omitted because the registrar is outbound-only.
+## Upgrade Compatibility
-Each driver tick:
+The hinted migration upgrades the existing `TEEProverRegistry` proxy implementation. It preserves
+the proxy storage layout, owner, manager, game type, proposers, registered signers, and stored signer
+image hashes. The active registrar and registry support only the new three-argument hinted API.
-1. Discovers instances.
-2. Processes instances concurrently.
-3. Computes orphans subject to the majority-reachable guard.
-4. Submits deregistration transactions for confirmed orphans.
+The migration does not change:
-Shutdown is driven by a cancellation token. The driver loop exits, in-flight per-instance futures
-are dropped, the readiness flag clears, the `up` metric is set to zero, and the health server is
-joined.
+- Nitro enclave signer generation or attestation production;
+- PCR0-based image selection in `TEEVerifier`;
+- `AggregateVerifier` behavior;
+- TEE proposal and dispute proof formats; or
+- SP1 state-proof behavior.
## Operator Inputs
-A registrar needs:
-
-- L1 RPC endpoint and chain ID.
-- `TEEProverRegistry` address.
-- AWS region and ALB target group ARN.
-- Prover JSON-RPC port shared by the fleet.
-- L1 transaction signer (local key, or remote signing endpoint plus expected address).
-- Proving backend selection: `boundless` or `direct`.
-- For `boundless`: marketplace RPC URL, dedicated wallet key, guest program URL, polling interval,
- prove timeout, recovery attempt limit, and attestation freshness window.
-- For `direct`: path to the guest ELF.
-- Poll interval, prover JSON-RPC timeout, max concurrency, max transaction retries, transaction
- retry delay, and the unhealthy registration warm-up window.
+A registrar requires:
-Optional inputs:
+- an L1 RPC endpoint and `TEEProverRegistry` address;
+- AWS region and ALB target group ARN;
+- the prover JSON-RPC port;
+- an L1 transaction signer and transaction-manager limits;
+- attestation freshness, polling, timeout, concurrency, cache-grace, and retry settings; and
+- health, logging, and Prometheus metrics settings.
-- CRL checking enable flag.
-- `NitroEnclaveVerifier` address, required when CRL checking is enabled.
-- CRL fetch timeout.
-- Health server bind address and port.
-- Logging filter and Prometheus metrics settings.
+No Boundless wallet, marketplace endpoint, RISC Zero program identifier, guest ELF, or proof-backend
+selection is used. CRL monitoring is optional and requires the registrar transaction signer to hold
+the configured `CertManager` revoker role. In the current CLI,
+`--crl-nitro-verifier-address` or `BASE_REGISTRAR_CRL_NITRO_VERIFIER_ADDRESS` enables CRL fetching.
+This legacy-named value is only an enable flag; contract discovery still follows the registry to
+`NitroValidator` and then `CertManager`.
## Safety Requirements
-A registrar implementation must preserve these safety properties:
-
-- Do not deregister live signers because of a transient AWS or VPC outage. Apply a
- majority-reachable guard before any deregistration.
-- Treat `Draining` and `Unhealthy` instances as part of the active set as long as their JSON-RPC
- endpoint responds, so rotations do not race deregistration.
-- Use a fresh random nonce per instance batch and pass it to the enclave attestation request so
- the verifier journal carries an unguessable freshness commitment.
-- Derive Boundless request slots deterministically from the signer address so a restarted process
- can recover in-flight proving work without spending fresh proof costs.
-- Reject recovered proofs whose attestation timestamp is older than `max_attestation_age` to keep
- recovered proofs strictly inside the onchain `MAX_AGE` window.
-- Block recovery for a signer after an `ExecutionReverted` so the next cycle proves freshly
- rather than re-submitting the same bad proof.
-- Recheck `isRegisteredSigner` after a transaction error to absorb fee-bump and nonce-race false
- negatives.
-- Recheck `isRegisteredSigner` for every orphan candidate immediately before submitting a
- deregistration, so a concurrent writer or earlier in-flight tx cannot cause a redundant
- deregistration transaction.
-- When CRL checking is enabled, run the onchain durable revocation pre-check before fetching
- network CRLs so a previously revoked intermediate cannot be silently rehabilitated.
-- Restrict CRL fetches to allowlisted hosts and bound the response size to defeat SSRF and
- resource-exhaustion attacks.
-- Treat unavailable AWS APIs, unreachable prover endpoints, transient RPC errors, and Boundless
- polling failures as retryable conditions for the next tick rather than as deregistration or
- failure signals.
+A conforming implementation must preserve these properties:
+
+- Preserve the exact signed COSE encodings when constructing the attestation TBS.
+- Match the attested signer and deterministic nonce before any transaction is submitted.
+- Pin the AWS Nitro root and reject malformed, expired, revoked, or parent-mismatched chains.
+- Generate hints in the exact verifier order and rely on onchain checks for every supplied inverse.
+- Cache certificates parent-first and recover by reading onchain state after every ambiguous result.
+- Recheck freshness before each costly transaction in a cold registration.
+- Recheck registration state before submission and after ambiguous transaction errors.
+- Do not deregister signers while discovery is unresolved or during the configured grace period.
+- Keep PCR0 acceptance at proof-submission time so image rotations can be staged safely.
+- Do not add an unhinted, ZK, or externally proved runtime fallback to the hinted registration path.
diff --git a/docs/upgrades/overview.mdx b/docs/upgrades/overview.mdx
index 9dd629b1b..a508c18a2 100644
--- a/docs/upgrades/overview.mdx
+++ b/docs/upgrades/overview.mdx
@@ -7,6 +7,10 @@ Base evolves through named network upgrades. Each release introduces protocol ch
A month without a confirmed activation timestamp is a planning target and may change.
+
+For planned protocol features that are not yet tied to a scheduled upgrade, see [Upcoming Features](/upgrades/upcoming-features).
+
+
## Denim
diff --git a/docs/upgrades/upcoming-features.mdx b/docs/upgrades/upcoming-features.mdx
new file mode 100644
index 000000000..4334df2e6
--- /dev/null
+++ b/docs/upgrades/upcoming-features.mdx
@@ -0,0 +1,27 @@
+---
+title: "Upcoming Features"
+description: "Planned Base protocol features and their ballpark target quarters, tracked independently of a specific network upgrade."
+---
+
+This page lists Base protocol features that are planned or in development, independent of the named upgrade that eventually ships them. Each entry links to its specification where one exists.
+
+
+Targets are ballpark quarters and may change. A feature moves onto a named upgrade page (for example, [Cobalt](/upgrades/cobalt/overview)) only once that upgrade is scheduled and locked in, at which point the official activation dates and final feature list are published.
+
+
+## Planned Features
+
+| Feature | Summary | Details | Target |
+|---------|---------|---------|--------|
+| 200ms Native Blocks | Five canonical blocks per second, replacing Flashblocks with canonical block and RPC streams. | [200ms Native Blocks](/upgrades/denim/200ms-blocks) | Q4 2026 |
+| B20 Improvements | Pay fees in B20s, scheduled multiplier updates, and composite policies for the B20 token standard. | [B20 changelog](/specifications/b20/changelog) | Q3 2026 |
+| Validity Transactions | A transaction type with onchain predicate checks for safer, conditional execution. | [Validity Transactions](/specifications/build-transaction/validity-transactions) | Q3 2026 |
+| Dynamic Upgrades | An onchain upgrade schedule that lets nodes activate forks live, without a client restart. | [Dynamic Upgrades](/upgrades/cobalt/dynamic-upgrades) | Q3 2026 |
+| TEE Registration Migration | Speed up the registration of new TEE signers by replacing external ZK proving with P-384 hints verified onchain. | [Hinted TEE Registration](/specifications/base-protocol/proofs/hinted-tee-registration) | Q3 2026 |
+| Native Account Abstraction (EIP-8130) | Onchain smart accounts, scoped session keys, and native gas sponsorship, with no bundlers or relays. | [Native Account Abstraction](/specifications/native-account-abstraction) | TBD |
+
+## How Features Ship
+
+1. **Proposed** — a feature is designed and, where applicable, written up as a specification. It appears in the table above with a ballpark target.
+2. **Scheduled** — once an upgrade that carries the feature is locked in, a named upgrade page is published with official Base Sepolia and Base Mainnet activation dates.
+3. **Live** — the upgrade activates and moves to the [Upgrades](/upgrades/overview) timeline.