# Lighthouse × Gloas: EIP-8282, EIP-7688, EIP-8045, EIP-8061 spec-conformance review

Item `lighthouse`, batch `cl-misc`. I only read public pages. Nothing was run against a network or a node.

## 0. Method and limits (read first)

- **No shell, no clone.** Every Bash command on this worker failed with
  `apply-seccomp: write /proc/self/setgroups ... Permission denied`, so I could not make a shallow clone.
  All code was read from `raw.githubusercontent.com` at the pinned commits, plus `api.github.com` for pins, trees, PRs and issue search. The reading went through a web-fetch tool that hands file text to a helper model.
- **No line numbers.** That tool cannot count lines in long files, and asked to try, it declined. Every
  citation below is therefore **`path@commit` + function name**. Line ranges are **not given**, and none were guessed.
  The quoted lines are exact strings returned by the fetch tool. I did not check them byte for byte against a checkout.
- Anyone with a checkout can recover the `#Lstart-Lend` anchors with `git grep -n '<fn name>' <pin>`.

## 1. Pins

| Repo / branch | Commit | Commit date | Head message |
|---|---|---|---|
| sigp/lighthouse `stable` | `a376defa30470923556d91bdeb15a802e297f31f` | 2026-10-22 | Release v8.3.2 (#10433) |
| sigp/lighthouse `unstable` | `301f3bf2323cd2b3f946ceed026be8075d24e1c3` | 2026-10-27 | Exclude slashed validators in FCR's get_proposer_score (#10380) |
| ethereum/consensus-specs `master` | `8a80ffa82bd49aac0dd6db17f9e8150aa257fbc2` | 2026-10-27 | Fix block access list hash in EL block hash test helper (#5773) |
| OffchainLabs/prysm `develop` | `eb681c1d13b57c2d0c5da27a63bb41ac9d071e1a` | 2026-10-27 | Add `SaveBlindedExecutionPayloadEnvelope` ... (#17674) |

The pins came from `api.github.com/repos/<repo>/commits/<branch>`.

**Spec version the client targets.** Lighthouse merged PR #10307 "Gloas spec v1.7.0-beta.4" on 2026-10-12. Its fork-time builder
onboarding matches **v1.7.0-beta.4**, not master (see C1). Spec PR ethereum/consensus-specs#5736, "Separate builder and validator deposits at the Gloas fork" (fixes #5735), was merged 2026-10-26T19:16:28Z as merge commit `8b374fa8…`. It is on master but not in Lighthouse.

**Stable vs unstable.** At the stable pin I re-read two things:
- `upgrade/gloas.rs`: same onboarding order (existing validator → builder credential → pending validator → signature) and same move of `proposer_lookahead`.
- `execution_requests.rs`: same Gloas fields and limits, same `progressive_container` / `active_fields(1,1,1,1,1)`, same `RequestType` 0..4 mapping.

I did not re-read the other functions at stable, so for those only the unstable result is established.

## 2. Candidates

### C1. Spec-version lag: fork-time builder onboarding follows v1.7.0-beta.4, not master (EIP-8282)

**(1) Spec (master), `specs/gloas/fork.md` `onboard_builders_from_pending_deposits`.**
Source: https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa82bd49aac0dd6db17f9e8150aa257fbc2/specs/gloas/fork.md

```python
    for deposit in state.pending_deposits:
        # Only builder-credential deposits can fund builders at the fork.
        if not is_builder_withdrawal_credential(deposit.withdrawal_credentials):
            pending_deposits.append(deposit)
            continue
        builder_pubkeys = [builder.pubkey for builder in state.builders]
        if deposit.pubkey not in builder_pubkeys:
            if not is_valid_deposit_signature(
                deposit.pubkey, deposit.withdrawal_credentials, deposit.amount, deposit.signature,
            ):
                # Preserve validator top-ups when no builder can receive them.
                if deposit.pubkey in validator_pubkeys or is_pending_validator(
                    pending_deposits, deposit.pubkey
                ):
                    pending_deposits.append(deposit)
                continue
            add_builder_to_registry(...)
        else:
            builder_index = BuilderIndex(builder_pubkeys.index(deposit.pubkey))
            state.builders[builder_index].balance += deposit.amount
```

The same function at v1.7.0-beta.4 (https://raw.githubusercontent.com/ethereum/consensus-specs/v1.7.0-beta.4/specs/gloas/fork.md) checks things in a different order:
1. `if deposit.pubkey in validator_pubkeys:` keeps the deposit and continues.
2. `if deposit.pubkey not in builder_pubkeys:` then:
   - a non-builder credential keeps the deposit;
   - `if is_pending_validator(pending_deposits, deposit.pubkey):` keeps the deposit;
   - an invalid signature makes it `continue` (the deposit is dropped);
   - otherwise `add_builder_to_registry`.
3. `else:` credits the existing builder, whatever the credential.

**(2) Lighthouse.** `consensus/state_processing/src/upgrade/gloas.rs`, fn `onboard_builders_from_pending_deposits`, at unstable `301f3bf2…` (identical order at stable `a376defa…`).
Source: https://raw.githubusercontent.com/sigp/lighthouse/301f3bf2323cd2b3f946ceed026be8075d24e1c3/consensus/state_processing/src/upgrade/gloas.rs

```rust
for deposit in &current_pending_deposits {
    if state.get_validator_index(&deposit.pubkey)?.is_some() {
        pending_deposits.push(deposit.clone());
        continue;
    match builder_pubkey_to_index.get(&deposit.pubkey).copied() {
        None => {
            if !is_builder_withdrawal_credential(deposit.withdrawal_credentials, spec) {
                pending_deposits.push(deposit.clone());
                if is_valid_deposit_signature_cached(builder_onboarding_cache, deposit, spec) {
                    valid_pending_validator_pubkeys.insert(deposit.pubkey);
                continue;
            if valid_pending_validator_pubkeys.contains(&deposit.pubkey) {
                pending_deposits.push(deposit.clone());
                continue;
            if !is_valid_deposit_signature_cached(builder_onboarding_cache, deposit, spec) {
                continue;
            builder_pubkey_to_index.insert(deposit.pubkey, builders.len() as u64);
            builders.push(Builder::from_deposit(
        Some(builder_index) => {
            builder.balance.safe_add_assign(deposit.amount)?;
```

The fetch tool returned these as separate lines, with closing braces left out. This is the beta.4 order.

**(3) Conditions where the post-fork state differs from master** (all in the upgrade at the Gloas fork epoch). The state at the fork has `pending_deposits` containing any one of the following:
- **(a)** A deposit with 0xB0 credentials and a valid signature whose pubkey already belongs to a validator.
  - Master: registers or tops up a builder and removes the deposit from the validator queue.
  - Lighthouse: leaves the deposit in the validator queue, where it later tops up the validator.
- **(b)** A deposit with 0xB0 credentials and a valid signature whose pubkey has an earlier valid non-builder deposit in the queue.
  - Master: creates the builder.
  - Lighthouse: keeps it queued for the validator.
- **(c)** A deposit with non-0xB0 credentials whose pubkey was registered as a builder by an earlier deposit in the same queue walk.
  - Master: keeps it in the validator queue.
  - Lighthouse: credits it to the builder's balance.

In each case `state.builders`, the builder balances and `state.pending_deposits` differ, so the first Gloas state root differs. Every one of these needs a deliberately crafted deposit pair before the fork. Ordinary deposits do not trigger them.

**(4) Prysm agrees with Lighthouse (beta.4), not with master.**
`beacon-chain/state/state-native/setters_gloas.go`, fn `OnboardBuildersFromPendingDeposits`, at `eb681c1d…`.
Source: https://raw.githubusercontent.com/OffchainLabs/prysm/eb681c1d13b57c2d0c5da27a63bb41ac9d071e1a/beacon-chain/state/state-native/setters_gloas.go

The order is:
1. `if _, ok := b.validatorIndexByPubkey(pubkey); ok {` keeps the deposit pending.
2. `builderIdx, isExistingBuilder := b.builderIndexByPubkey(pubkey)` tops up an existing builder.
3. `if !helpers.IsBuilderWithdrawalCredential(deposit.WithdrawalCredentials) {` keeps it pending.
4. `isPending, err := pendingIdx.HasValid(deposit.PublicKey)` keeps it pending.
5. The signature is checked in `applyDepositForNewBuilder`.

**(5) Confidence: high** that the code differs from master; the order is quoted from both. I tried to disprove it in four ways:
- I looked for a newer Lighthouse onboarding change. Search for PRs created after 2026-10-20 mentioning gloas found 8, none touching onboarding.
- I checked whether master merely reorders code with the same outcome. It does not: PR #5736's own description lists exactly cases (a)/(b) as behaviour changes ("previous routing wrongly blocked valid builder registrations when a validator already used the key, or when an earlier valid validator deposit was queued").
- I checked whether it is reachable at all. Yes, through any 0xB0 deposit made before the fork.
- I checked what release Lighthouse targets: v1.7.0-beta.4, not master, by its own PR #10307.

This is a **spec-version lag**, not a bug against the release Lighthouse targets.

**(6) Severity: consensus split** at the fork-transition state, if any client ships master semantics while Lighthouse ships beta.4. Today Prysm matches Lighthouse.

### C2. EIP-8061 `compute_min_epochs_for_block_requests` not implemented (no Gloas formula for the envelope serving window)

**(1) Spec**, `specs/gloas/p2p-interface.md`
(https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa82bd49aac0dd6db17f9e8150aa257fbc2/specs/gloas/p2p-interface.md):

```python
def compute_min_epochs_for_block_requests() -> Epoch:
    numerator = 3 * CHURN_LIMIT_QUOTIENT_GLOAS * CONSOLIDATION_CHURN_LIMIT_QUOTIENT
    denominator = 2 * CONSOLIDATION_CHURN_LIMIT_QUOTIENT + 3 * CHURN_LIMIT_QUOTIENT_GLOAS
    return MIN_VALIDATOR_WITHDRAWABILITY_DELAY + (numerator // denominator) // 2
```

Under `ExecutionPayloadEnvelopesByRoot v1`, the spec adds: clients "MUST support requesting payload envelopes on the epoch range `[max(GLOAS_FORK_EPOCH, current_epoch - compute_min_epochs_for_block_requests()), current_epoch]`".

With mainnet values: 3·32768·65536 = 6,442,450,944 and 2·65536 + 3·32768 = 229,376. The quotient is 28,086, halved to 14,043, plus 256 gives **14,299 epochs**. My own arithmetic.

**(2) Lighthouse.**
- `consensus/types/src/core/chain_spec.rs` (unstable pin): the only definition is the static config value, `const fn default_min_epochs_for_block_requests() -> u64 {` … `33024`. There is no `compute_min_epochs_for_block_requests` and no fork-dependent variant.
- `beacon_node/network/src/network_beacon_processor/rpc_methods.rs`: the envelope handlers `handle_payload_envelopes_by_range_request_inner` and `handle_payload_envelopes_by_root_request_inner` have no oldest-epoch bound. The only checks are `if !fork_name.gloas_enabled() {` ("Requested envelopes for pre-gloas slots") and the finalized/backfill `ResourceUnavailable` path in `get_block_roots_for_slot_range`.

**(3) When results differ.** Lighthouse never applies the Gloas window of about 14,299 epochs.
- It serves envelopes from as far back as it holds, which is a superset of the MUST range and still compliant.
- If Lighthouse uses 33,024 to decide what to request, or how to judge peers that prune at the shorter Gloas window, sync or peer scoring would differ. That could happen past about 14,299 epochs after the fork. I did not confirm this.
- No state root or block validity is affected.

**(4) Prysm:** not checked (time).

**(5) Confidence: medium** that the formula is missing; I searched `chain_spec.rs` and the RPC handler file. **Low** that any visible behaviour follows. As a disproof I looked for an envelope-specific bound in the handlers and found none. Lighthouse issue #4553 "Implement min_epochs_for_block_requests" is still open, which suggests Lighthouse does not prune by this window at all.

**(6) Severity: cosmetic** (p2p serving window or peer scoring only).

### C3. EIP-7688 limits enforced at decode instead of the state transition (spec-allowed; a narrow difference remains for envelopes)

**(1) Spec.**
- Types: `class BuilderDepositRequests(ProgressiveList[BuilderDepositRequest]):` (no type-level limit).
- `apply_parent_execution_payload`: `assert len(requests.withdrawals) <= MAX_WITHDRAWAL_REQUESTS_PER_PAYLOAD`, `… builder_deposits) <= MAX_BUILDER_DEPOSIT_REQUESTS_PER_PAYLOAD`, `… builder_exits) <= MAX_BUILDER_EXIT_REQUESTS_PER_PAYLOAD` (beacon-chain.md).
- p2p-interface.md, `verify_execution_requests_limits`: "*Note*: These checks MAY be performed when deserializing `ExecutionRequests`."

**(2) Lighthouse.** `consensus/types/src/execution/execution_requests.rs` (both pins):

```rust
pub deposits: ProgressiveVariableList<DepositRequest>,
pub withdrawals: ProgressiveVariableList<WithdrawalRequest, E::MaxWithdrawalRequestsPerPayload>,
ProgressiveVariableList<BuilderDepositRequest, E::MaxBuilderDepositRequestsPerPayload>,
ProgressiveVariableList<BuilderExitRequest, E::MaxBuilderExitRequestsPerPayload>,
```

The doc comment reads: "uses progressive lists (EIP-7688) with decoder limits, except for deposit requests which are unbounded".

**(3) When results differ.** Only one case: an `ExecutionPayloadEnvelope` that arrives over **req/resp rather than gossip** and carries more requests than the limits.
- The spec has an envelope-level count check only for gossip, `[REJECT] The execution request counts are within their limits`. The length assert runs later, when the child applies the parent payload.
- Lighthouse fails to decode such an envelope, so it never records the payload as present. That could make payload-presence views in fork choice differ.
- For the block body and for gossip, the verdicts agree: the spec explicitly allows decode-time checks, and the state transition asserts the same bounds.
- It is practically unreachable: the EL would have to emit more than 16 or 64 requests, and the bid's `execution_requests_root` would have to commit to them.

**(4) Prysm:** not checked.

**(5) Confidence: low.** As a disproof I found the spec Notes that allow decode-time checks, which rule out the block and gossip paths. The preset limits are equal: Lighthouse `presets/mainnet/gloas.yaml` and spec `presets/mainnet/gloas.yaml` both give 64 builder deposits and 16 builder exits per payload. Lighthouse PR #10106 restored type-level limits on purpose.

**(6) Severity: cosmetic** (fork-choice divergence only in a contrived, likely unreachable case).

### Live-code note

The churn, proposer-selection and execution-request decoding functions have pre-Gloas branches shared with the live Fulu fork:
- `compute_proposer_index`;
- `get_activation_exit_churn_limit` for Electra/Fulu;
- request types 0x00–0x02.

I found **no candidate** in those branches, so nothing is withheld.

## 3. Rules checked and found correct (unstable `301f3bf2…`; function-level citations, line numbers not available, see §0)

| Rule (spec) | Lighthouse location | Finding |
|---|---|---|
| `process_builder_deposit_request`: 0xB0 gate before registration **and** before top-up | `consensus/state_processing/src/per_block_processing/process_operations.rs` fn `process_builder_deposit_request`: `if !is_builder_withdrawal_credential(builder_deposit_request.withdrawal_credentials, spec) { return Ok(()); }` is the first statement | matches |
| New builder: signature then `add_builder_to_registry(..., PAYLOAD_BUILDER_VERSION, ..., state.slot)` | same fn, `if builder_deposit_request.is_valid_builder_deposit_signature(spec)` → `state.add_builder_to_registry(pubkey, PAYLOAD_BUILDER_VERSION, withdrawal_credentials, amount, slot, spec)` | matches. The address is taken from the credentials inside `Builder::from_deposit` (body not read) |
| `is_valid_builder_deposit_signature`: `compute_domain(DOMAIN_BUILDER_DEPOSIT)` (genesis fork version, zero root); invalid point = invalid | `consensus/types/src/builder/builder_deposit_request.rs`: `Domain::BuilderDeposit,` `spec.genesis_fork_version,` `Hash256::ZERO,`; failed decompress returns `false` | matches. `domain_builder_deposit: 0x0E` in chain_spec.rs matches `DomainType("0x0E000000")` |
| Top-up resets `withdrawable_epoch` only if exited **and** balance == 0 | same fn: `if builder.withdrawable_epoch != spec.far_future_epoch && builder.balance == 0 {` → `current_epoch.safe_add(spec.min_builder_withdrawability_delay)` then `safe_add_assign(amount)` | matches, including the order (reset checked before credit) |
| `get_index_for_new_builder` reuse rule | `consensus/types/src/state/beacon_state.rs` fn `get_index_for_new_builder`: `if builder.withdrawable_epoch <= current_epoch && builder.balance == 0 {` | matches |
| `process_builder_exit_request`: unknown → active → source address → pending balance → exit | `process_operations.rs` fn `process_builder_exit_request` (checks in that order); `initiate_builder_exit` sets `current_epoch + min_builder_withdrawability_delay` | matches. The extra "already exiting" early return cannot be reached after the `is_active_builder` check |
| `is_active_builder` | `beacon_state.rs`: `builder.deposit_epoch < self.finalized_checkpoint().epoch && builder.withdrawable_epoch == spec.far_future_epoch` | matches |
| `get_pending_balance_to_withdraw_for_builder` sums both queues | `beacon_state.rs` (withdrawals + `payment.withdrawal.amount`) | matches |
| Execution-requests list: types 0x03/0x04, skip empty, `sha256(sha256(r0)‖…)` | `consensus/types/src/execution/execution_requests.rs`: `.filter(\|(_, is_empty, _)\| !is_empty)`, `Bytes::from_iter([request_type.to_u8()].into_iter().chain(ssz_bytes))`; `3 => BuilderDeposit`, `4 => BuilderExit`; Gloas list order Deposit, Withdrawal, Consolidation, BuilderDeposit, BuilderExit | matches |
| EIP-7688 `ExecutionRequests(ProgressiveContainer)`, `active_fields(width=5)` | same file: `struct_behaviour = "progressive_container", active_fields(1, 1, 1, 1, 1)` (Gloas only) | matches. I did not audit the `ssz_types`/`tree_hash` progressive merkleization itself |
| EIP-7688 per-payload / per-block bounds | decoder limits (C3); preset values 64 / 16 equal to spec | matches the spec's "MAY be performed when deserializing" |
| EIP-8045 `get_beacon_proposer_indices` skips slashed | `beacon_state.rs` fn `get_beacon_proposer_indices`: `if self.fork_name_unchecked().gloas_enabled() {` … `indices.retain(\|&index\| !slashings_cache.is_slashed(index));`; empty set → `InsufficientValidators` (spec `assert total > 0`) | matches |
| EIP-8045 transition: lookahead copied, not recomputed | `upgrade/gloas.rs`: `proposer_lookahead: mem::take(&mut pre.proposer_lookahead),` (spec `proposer_lookahead=pre.proposer_lookahead`). The last Fulu epoch's lookahead fill runs on a Fulu-variant state, so no filter is applied, as the spec requires | matches. Lighthouse PR #9674 added fork-boundary tests |
| EIP-8061 activation churn (deposits) | `get_activation_exit_churn_limit` Gloas branch: `min(spec.max_per_epoch_activation_churn_limit_gloas, get_balance_churn_limit)`, where `get_balance_churn_limit` uses `churn_limit_quotient_gloas`, floor `min_per_epoch_churn_limit_electra`, rounded to the increment | matches `get_activation_churn_limit`. The legacy `get_activation_churn_limit` (validator-count) match arm also covers Gloas, but per the spec it is only used before Electra. I did not check the `single_pass.rs` call site |
| EIP-8061 exit churn uncapped; `compute_exit_epoch_and_update_churn` | `get_exit_churn_limit` → `get_balance_churn_limit` (no cap); `let per_epoch_churn = if self.fork_name_unchecked().gloas_enabled() {` → `get_exit_churn_limit` | matches |
| EIP-8061 consolidation churn | Gloas branch: `total_active_balance.safe_div(spec.consolidation_churn_limit_quotient)` rounded; no subtraction | matches |
| Config values | chain_spec.rs: `churn_limit_quotient_gloas` 2^15, `consolidation_churn_limit_quotient` 2^16, `max_per_epoch_activation_churn_limit_gloas` 256·10^9, `min_builder_withdrawability_delay` 64, `builder_withdrawal_prefix_byte: 0xB0` | matches the spec tables |
| Weak-subjectivity period | `beacon_state.rs` fn `compute_weak_subjectivity_period_gloas`: `delta = exit*2/3 + activation/3 + consolidation`; `SAFETY_DECAY * t / (delta * 200)` + `min_validator_withdrawability_delay` | matches weak-subjectivity.md (same order of integer divisions) |

**Prysm cross-reads** (develop `eb681c1d…`), for the rules above:
- **Builder deposits**, `beacon-chain/core/gloas/builder_deposit_request.go` `processBuilderDepositRequest`: 0xB0 gate first, and the same reset condition `builder.WithdrawableEpoch != ...FarFutureEpoch && builder.Balance == 0`. Agrees with the spec.
- **Proposer lookahead**, `beacon-chain/core/gloas/proposer_lookahead.go` `ProcessProposerLookahead`: uses `helpers.ActiveNonSlashedValidatorIndices`. Agrees.
- **Exit churn**, `beacon-chain/core/helpers/validator_churn.go`: `ExitChurnLimitForVersion` uses `exitChurnLimitGloas` for `v >= version.Gloas`; `activationChurnLimitGloas` and `consolidationChurnLimitGloas` match the spec.
- **Gloas upgrade**, `beacon-chain/core/gloas/upgrade.go`: copies `ProposerLookahead`.
- **Weak subjectivity**, `beacon-chain/core/helpers/weak_subjectivity.go` `ComputeWeakSubjectivityPeriod`: this is the phase0 formula (`N * (200 + 3*D) / (600 * Delta)`, no Gloas branch). That is outside this item, but it differs from Gloas weak-subjectivity.md; worth checking in the Prysm item.

**Not verified:**
- byte-level progressive merkleization in `ssz_types`;
- engine-API decoding of 0x03/0x04 requests (ordering and duplicate checks are not in `execution_requests.rs`);
- the `single_pass.rs` deposit churn call site;
- `Builder::from_deposit`.

## 4. Spec/EIP-text observations (not client bugs)

- The EIP-8061 parameter table lists `MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT` = `uint64(2**8) (=256)`. The spec uses `MAX_PER_EPOCH_ACTIVATION_CHURN_LIMIT_GLOAS = Gwei(2**8 * 10**9)`, so the name and unit differ. Lighthouse follows the spec.
- EIP-8282 says the `0xB0` prefix "is deprecated afterward". Master `process_builder_deposit_request` still requires the prefix on 0x03 builder deposit requests, and Lighthouse follows the spec.

## 5. Known-check (sigp/lighthouse issues and PRs, open and closed)

| Candidate | Status | Evidence / queries |
|---|---|---|
| C1 onboarding lag vs master | **not found** in Lighthouse | Queries:<br>• `repo:sigp/lighthouse onboard builders` (5 hits: #9943 open issue, "deposit cache seeds the whole pending deposit queue", performance; #9954 merged; #9311 closed; #9511 merged; #3725)<br>• `repo:sigp/lighthouse 5736` (only unrelated issue #5736 from 2024)<br>• `repo:sigp/lighthouse builder deposit` (64 hits, first 16 read: #9817 merged 2026-08-30, the onboarding cache already indexed; #9946 closed; #10162 merged)<br>• `repo:sigp/lighthouse is:pr created:>2026-10-20 gloas` (8 hits, none on onboarding)<br>Spec side: consensus-specs#5736 merged 2026-10-26, fixing #5735. Lighthouse target: #10307 (merged 2026-10-12, "Gloas spec v1.7.0-beta.4"). |
| C2 min epochs for block requests | **related known**: #4553 "Implement min_epochs_for_block_requests" (open issue, 2023, not Gloas-specific) | Queries: `repo:sigp/lighthouse min_epochs_for_block_requests` (9 hits); `repo:sigp/lighthouse 8061` (6 hits: #9218 open "Clean up churn limit code", #9211 closed, #9190 merged; none about the envelope window) |
| C3 decoder limits | **known / intentional**: #10106 "Progressive list type-level limits", merged 2026-09-29 (it notes Transactions remain unbounded) | already indexed |
| EIP-8045 (no candidate) | context: #9602 (closed issue) / #9674 (merged PR, slashed-proposer lookahead tests at the fork); #10380 (merged 2026-10-27, slashed exclusion in FCR proposer score) | Query: `repo:sigp/lighthouse slashed proposer gloas` (11 hits) |
| WS period (no candidate) | context: #7347 merged (WS checks), #9290 merged | Query: `repo:sigp/lighthouse weak subjectivity period` (10 hits) |

GitHub code search (`api.github.com/search/code`) returned HTTP 401 without auth, so I could not use it.

Hive and execution-spec-tests results for Glamsterdam devnets: **not checked** (time).

## 6. URLs read

Specs and EIPs:
- https://raw.githubusercontent.com/ethereum/consensus-specs/8a80ffa82bd49aac0dd6db17f9e8150aa257fbc2/specs/gloas/beacon-chain.md
- …/8a80ffa8…/specs/gloas/fork.md, …/p2p-interface.md, …/validator.md, …/weak-subjectivity.md, …/presets/mainnet/gloas.yaml
- https://raw.githubusercontent.com/ethereum/consensus-specs/v1.7.0-beta.4/specs/gloas/fork.md
- https://api.github.com/repos/ethereum/consensus-specs/pulls/5736
- https://eips.ethereum.org/EIPS/eip-8282 (Last Call, deadline 2026-11-01)
- https://eips.ethereum.org/EIPS/eip-7688 (Review)
- https://eips.ethereum.org/EIPS/eip-8045 (Last Call)
- https://eips.ethereum.org/EIPS/eip-8061 (Last Call)

Lighthouse (`raw.githubusercontent.com/sigp/lighthouse/<pin>/…`):
- At 301f3bf2:
  - consensus/state_processing/src/per_block_processing/process_operations.rs
  - consensus/state_processing/src/upgrade/gloas.rs
  - consensus/types/src/builder/builder_deposit_request.rs
  - consensus/types/src/state/beacon_state.rs
  - consensus/types/src/execution/execution_requests.rs
  - consensus/types/src/core/chain_spec.rs
  - consensus/types/presets/mainnet/gloas.yaml
  - beacon_node/network/src/network_beacon_processor/rpc_methods.rs
- At a376defa:
  - upgrade/gloas.rs
  - execution_requests.rs

Prysm (`raw.githubusercontent.com/OffchainLabs/prysm/eb681c1d…/…`):
- beacon-chain/core/gloas/upgrade.go
- beacon-chain/core/gloas/builder_deposit_request.go
- beacon-chain/core/gloas/proposer_lookahead.go
- beacon-chain/state/state-native/setters_gloas.go
- beacon-chain/state/state-native/setters_churn.go
- beacon-chain/core/helpers/validators.go
- beacon-chain/core/helpers/validator_churn.go
- beacon-chain/core/helpers/weak_subjectivity.go

GitHub API:
- commits/{stable,unstable,master,develop}
- git/trees (lighthouse, prysm)
- contents/ (prysm dirs)
- pulls/10106, pulls/7347/files
- issues/9943
- search/issues (queries in §5)
