chore(deps): bump @nestjs/core from 11.1.27 to 11.1.28 - #200
Open
dependabot[bot] wants to merge 1 commit into
Open
chore(deps): bump @nestjs/core from 11.1.27 to 11.1.28#200dependabot[bot] wants to merge 1 commit into
dependabot[bot] wants to merge 1 commit into
Conversation
Bumps [@nestjs/core](https://github.com/nestjs/nest/tree/HEAD/packages/core) from 11.1.27 to 11.1.28. - [Release notes](https://github.com/nestjs/nest/releases) - [Commits](https://github.com/nestjs/nest/commits/v11.1.28/packages/core) --- updated-dependencies: - dependency-name: "@nestjs/core" dependency-version: 11.1.28 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
dependabot
Bot
force-pushed
the
dependabot/npm_and_yarn/nestjs/core-11.1.28
branch
from
July 10, 2026 06:20
5ec6d0d to
d0e23c5
Compare
clestons
approved these changes
Jul 11, 2026
clestons
left a comment
There was a problem hiding this comment.
Review — APPROVE [2-round: dependabot bump + CI 核验]
chore(deps): bump @nestjs/core 11.1.27 → 11.1.28
- 全部 CI check 绿(已核实:build / test / typecheck / lint / security 均 pass;
skipping为路径过滤的正常跳过)。 - 仅
package.json+ lockfile 变动,无源码逻辑改动。 - patch/minor 或 CI 已验证可解析的升级,无 peer 冲突。
结论:APPROVE — 低风险依赖升级,CI 全绿。(合并由维护者/$pr-fix 决定,本 review 不合并。)
jhfnetboy
added a commit
that referenced
this pull request
Aug 17, 2026
…d, held) pr-daemon RC on #237 found two design-level Criticals that dvt cannot fix unilaterally -- escalated on CC-98, PR held draft: B1: sortition curve never requires an honest signer + m<=110 caps the tail at ~6.6e-6 (no n reaches 1e-9). Needs DSR's written security target and a corrected m/T curve. B2: accountId is calldata-trusted and enforcement is cross-repo while airaccount #200 is draft -- no interlock; needs airaccount + enrollment. This commit fixes the SELF-CONTAINED findings (curve-independent, all correct regardless of how B1 resolves): - B3 (High): setOversample now bumps configVersion (symmetric with setEpochLength) so it cannot retroactively collapse the sortition gate on an already-pinned epoch. Test proves a valid op fails-closed after the change. - Medium: requiredQuorum() reads epochLength directly instead of via currentEpoch(), so the default epochLength==0 config returns the fail-closed sentinel instead of reverting. - Medium: snapshotEpoch requires lastSetMutationBlock < block.number, so a permissionless syncNode eviction cannot be atomically composed with the freeze to depress epochSetCount (feeds B1's budget). - Low: setEpochLength floor raised to 64 (real pin window is min(256, epochLength-1); tiny values leave no keeper window). - Low: emit SlotAssigned/SlotCleared so aggregators reconstruct frozen trees from logs without re-deriving the slot allocator. - Info: drop unused G1_LEN. - Coverage: added a DISCRIMINATING look-ahead test (verified: fails on the setRoot[e-1]->setRoot[e] mutant) and a syncNode->_deactivate SMT-hook test (verified: fails on the hook-deletion mutant). registerWithProof-path hook coverage still open (needs stake/PoP mock) -- deferred to the post-B1 pass. 105 tests pass. #237 stays draft pending B1 (DSR) + B2 (airaccount).
jhfnetboy
added a commit
that referenced
this pull request
Aug 17, 2026
* feat(CC-98): production per-proposal committee BLS validator
AAStarCommitteeValidator extends AAStarValidator with the converged CC-98
model: per-operation random committee the submitter cannot choose.
- Incremental sparse Merkle commitment of the active set (TREE_DEPTH=14),
maintained O(depth) via _onNodeActivated/_onNodeDeactivated hooks added to
the base at every set mutation (register/dereg/revoke/batch).
- snapshotEpoch(): permissionless double-snapshot. seed[e]=blockhash(e*L)
pinned within the 256-block window; setRoot[e]=runningRoot frozen for use
ONE EPOCH AHEAD (look-ahead) so the committed set is frozen strictly before
the seed is revealed -> closes the register-to-order grinding window.
- validate(): per signer verifies Merkle membership in setRoot[e-1] +
sortition H(CMT_SELECT, seed[e], accountId, nodeId) < T, zero extra
pairings, then the base aggregate BLS verify. accountId is account-injected
(root of trust). Threshold requiredQuorum = ceil(2*m_e/3), m_e per the DSR
curve capped at n. epochLength==0 -> legacy whole-set fallback.
Self-review (4 rounds) fixed two real bugs before commit:
1. expectedCommittee floor-16 not capped at n -> 9..15 pools had
quorum > n (unsatisfiable, liveness DoS). Now capped at n.
2. whole-set (T=max) spuriously excluded a draw==max node (2^-256).
Now skips the draw when T==max.
18 committee tests + 96 total pass. Base changes are additive virtual hooks
(no behavior change to the legacy validator; all existing tests green).
* style(CC-98): forge fmt committee validator + tests
* fix(CC-98): address Codex adversarial review
Codex Tier-1 review (via codex exec) of PR #237. Code fixes:
- High: setEpochLength rejects epochLength==1 (startBlock==block.number =>
never pinnable => committee mode permanently dead). Now requires 0 or >=2.
- Medium: submitter now provides the signer's slot in the payload,
authenticated by the Merkle proof against the FROZEN setRoot[e-1] (each
nodeId is at one slot in that tree, so a wrong slot cannot verify). Fixes
the slot-reuse liveness edge where a re-registered node's live slot no
longer matched its historical slot. Wire adds slot(32)/signer.
- Medium: setOversample bounds num/den ([1,8], den<=1e9) so oversampleNum*m
in _thresholdOf cannot overflow and turn a fail-closed return-1 into a
revert (uniform malformed-op handling preserved).
- Low: configVersion namespaces epoch snapshots; setEpochLength bumps it so a
seed/root pinned under a previous schedule is never reused under a new one
(validate + requiredQuorum fail-closed until re-pinned).
Documented as SECURITY ASSUMPTIONS (residuals inherent to the architecture,
not code-fixable here):
- accountId is account-injected (router breaks msg.sender binding) — a
load-bearing account-side invariant (airaccount MUST enforce).
- frozen-member removal is a BFT liveness bound (DSR oversampling + SP
unbonding + epoch retry mitigate; lowering quorum on churn would break
safety, intentionally not done).
- missed pin window => <=2-epoch self-healing outage (no grindable late-seed
fallback); run redundant permissionless keepers.
- caller-chosen freeze time within the pin window is minor fairness griefing,
not safety (seed still unknowable at freeze).
22 committee tests (4 new for the fixes) + 99 total pass.
* fix(CC-98): resolve Codex round-2 findings (self-introduced by round-1 fixes)
- round-2 High: snapshotEpoch allows re-pinning an epoch whose pin belongs to
a previous configVersion (else colliding epoch numbers after an epochLength
change strand committee mode until the counter passes every old ID).
- round-2 Low: validate rejects non-canonical slot (slot >= 2^TREE_DEPTH),
which _verifyMerkle would otherwise alias to slot mod 2^TREE_DEPTH.
Codex Tier-1: APPROVED - no remaining findings (3 rounds). 24 committee + 99 total pass.
* fix(CC-98): address pr-daemon self-contained findings (B1/B2 escalated, held)
pr-daemon RC on #237 found two design-level Criticals that dvt cannot fix
unilaterally -- escalated on CC-98, PR held draft:
B1: sortition curve never requires an honest signer + m<=110 caps the tail
at ~6.6e-6 (no n reaches 1e-9). Needs DSR's written security target and
a corrected m/T curve.
B2: accountId is calldata-trusted and enforcement is cross-repo while
airaccount #200 is draft -- no interlock; needs airaccount + enrollment.
This commit fixes the SELF-CONTAINED findings (curve-independent, all correct
regardless of how B1 resolves):
- B3 (High): setOversample now bumps configVersion (symmetric with
setEpochLength) so it cannot retroactively collapse the sortition gate on an
already-pinned epoch. Test proves a valid op fails-closed after the change.
- Medium: requiredQuorum() reads epochLength directly instead of via
currentEpoch(), so the default epochLength==0 config returns the fail-closed
sentinel instead of reverting.
- Medium: snapshotEpoch requires lastSetMutationBlock < block.number, so a
permissionless syncNode eviction cannot be atomically composed with the
freeze to depress epochSetCount (feeds B1's budget).
- Low: setEpochLength floor raised to 64 (real pin window is
min(256, epochLength-1); tiny values leave no keeper window).
- Low: emit SlotAssigned/SlotCleared so aggregators reconstruct frozen trees
from logs without re-deriving the slot allocator.
- Info: drop unused G1_LEN.
- Coverage: added a DISCRIMINATING look-ahead test (verified: fails on the
setRoot[e-1]->setRoot[e] mutant) and a syncNode->_deactivate SMT-hook test
(verified: fails on the hook-deletion mutant). registerWithProof-path hook
coverage still open (needs stake/PoP mock) -- deferred to the post-B1 pass.
105 tests pass. #237 stays draft pending B1 (DSR) + B2 (airaccount).
* feat(CC-98): B2 defense-in-depth — account enrollment + committeeActive view + migration interlock
airaccount locked the B2 account-side design (f444db89): accountId injection
(account-side, mandatory) + these dvt-side pieces (curve-independent, land now):
- committeeActive() view: the account reads validator mode to pick its
signature framing instead of guessing from payload shape (the shape-collision
root of the flip-order attack). Same state drives parse + framing => no desync.
- enroll()/unenroll() + enrolledAccount mapping (self-proving: msg.sender IS
the account). validate() fails closed unless the injected accountId maps to an
enrolled address. This (a) blocks the flip-order legacy-shaped payload on-chain
(fabricated accountId prefix -> non-enrolled -> reject) and (b) turns a free
offline grind over 2^256 accountIds into a gas-metered grind over enrolled
addresses. Defense-in-depth, NOT a replacement for account-side injection.
- setEpochLength migration-interlock doc: deploy+mount+enroll injecting accounts
BEFORE flipping committee mode.
Does not touch the sortition m/T math -> independent of B1 (still on DSR).
31 committee tests (4 new: committeeActive, enroll self-proving, unenrolled
fail-closed) + 107 total pass.
* fix(CC-98): B1 — DSR-locked m_e curve + oversample 1.0 (resolves last blocker)
DSR delivered the security target and curve (CC-98 9a9f47c9, Jason-adjudicated):
target ε = P(Poisson(β*m_e) >= ceil(2*m_e/3)) <= 1e-6 per (account, epoch)
under β <= 10%; N>=430 meets 1e-6 even at worst-case β=1/3.
Curve: m_e(N) = N (N<=8); else clamp(ceil(N/5), 17, 86).
- floor 16 -> 17 (16 gave ε=1.02e-6, just over; 17 gives 2.6e-7)
- cap 110 -> 86 (86 is the β=1/3 1e-6 point; 110 was over-provisioned)
- floor(N/5) -> ceil(N/5)
- oversample 1.15 -> 1.0: DSR's calc assumes E[committee]=m_e (λ=β*m_e); any
oversample>1 inflates λ and breaks the N>=430 β=1/3 razor-thin margin.
Independently verified the whole ε table with an exact log-space Poisson tail
(matches DSR row-for-row: N=20 2.55e-7, N=100 2.93e-8, N=150 8.3e-11,
N=300 4.8e-20, N=430 β=1/3 9.77e-7). Sampling regime (N>=17) meets ε<=1e-6;
the N<=16 bootstrap band is whole-set, governed by the structural 2/3-of-nodes
argument (impossible at β<=10%) — airaccount's N0 gate keeps small pools off
the sampling path.
Added pr-daemon's B1 discriminators: a DSR-table triple test (m_e,
requiredQuorum) and a monotonicity test (m_e non-decreasing in N => ε
non-increasing, closing 'security worsens as the pool grows').
110 tests pass.
* fix(CC-98): B4 — reject non-canonical accountId (high 96 bits must be zero)
pr-daemon round-2 B4: the enrollment gate reads accountId's low 160 bits but
the sortition draw consumes all 256, so the high 96 bits were a free offline
grind surface (probe: 232 tries to find a high-bit value whose low 160 still
map to an enrolled address, flipping the same attacker committee from reject to
accept). Fix: reject any accountId with non-zero high bits (symmetric to the
canonical-slot check), and correct the false 'gas-metered grind' natspec claim.
Tests: non-canonical accountId rejected, 300-iteration high-bit grind all
rejected, requiredQuorum sentinel pinned to max (not fail-open 0). 36 committee
tests pass. NOT pushed — held with B5 (needs an architectural decision).
* fix(CC-98): B5 two-tail curve (loose-liveness, Jason-adjudicated) + round-2 follow-ups
B5 (Blocking): B1's floor-17/oversample-1.0 curve was single-tailed — ~6.3% of
(account,epoch) had NO satisfiable signer set (honest-liveness stall). Jason's
call: a liveness miss is a retryable one-epoch stall (not fund loss), so hold it
to a LOOSER target than forgery. Verified two-tail operating point (exact
Binom/Poisson scan over n in [9,20000]):
m_e(N) = clamp(ceil(N/5), 30, 86), oversample = 1.25
forgery @β<=10% <= ~4.4e-9 (sampling regime) [target 1e-6]
liveness <= 1.65e-4 (100% online) / 5.9e-4 (95% online) [loose target 1e-3]
floor 30 (up from 17) buys the forgery headroom to afford oversample 1.25;
floor 17 could not (its forgery tail was 4.6e-7, razor thin). Gives up the old
β=1/3 'free gift' (out of scope under β<=10%). Cost: requiredQuorum 20..58,
~10KB (N<=150) .. ~29KB (N>=430) calldata/op — far below the strict-liveness
34-51KB. Added a two-tail table test (asserts E[committee] clears quorum) and a
constructor-oversample pin.
round-2 follow-ups:
- High: lastSetMutationBlock revert was a zero-capital migration-boundary DoS
(setRequireStake(true) makes every bootstrap node permissionlessly
syncNode-able; a forced same-block collision could block pinning a whole
epoch). Replaced with a block-start LATCH: snapshotEpoch freezes the
pre-mutation root/count when the set changed in its own block, and is now
UNCONDITIONAL (no revert). Discriminating test added (verified via mutation).
- Medium: unenroll() natspec no longer suggests the self-bricking order; warns
instead.
B4 (prior commit ea1e6a7): reject non-canonical accountId.
115 tests pass.
* fix(CC-98): resolve forge-coverage stack-too-deep in validate()
The Smart Contracts CI job runs `forge coverage`, which disables via-IR (the
optimizer that makes the frame fit) — so validate()'s large frame failed to
compile there (Stack too deep), even though forge build/test (via_ir=true)
compiled fine. Refactor to stay within the non-via-IR stack limit:
- extract the per-signer membership+sortition loop into _verifyCommitteeSigners
- pack its params into a memory _Ctx struct (one stack word, not four)
- block-scope the parse/quorum intermediates in validate()
No behavior change: 115 tests pass; verified the exact coverage compile
condition (FOUNDRY_VIA_IR=false FOUNDRY_OPTIMIZER=false) now succeeds with zero
stack-too-deep. (Security Audit CI failure is pre-existing npm-dep advisories,
unrelated to contracts.)
* fix(CC-98): restore uniform fail-closed + add sortition regression tests (pr-daemon round-3)
The forge-coverage refactor (59cf455) introduced a behavior regression and
exposed a pre-existing coverage hole in the core mechanism:
1. Regression (mine): the refactor moved the accountId calldata slice ahead of
the length guard, so signature.length < 32 REVERTED instead of returning 1,
breaking the base contract's uniform fail-closed. Fix: hoist
`if (signature.length < 32 + G2_LEN) return 1` to the top of the committee
path, before ANY slice. Regression test: empty / 4-byte / 31-byte sigs all
return 1 (verified via mutation: reverting the order makes it revert again).
2. Coverage hole (pre-existing, dismissed the false APPROVE): the sortition draw
had NO regression protection — the account-binding test guarded its only
assert behind `if (someExcluded)`, which was always false, so deleting the
entire draw check left 115/115 green. Replaced with:
- test_validate_sortition_rejects_noncommittee_signer: baseline committee
validates; swapping one member for a non-committee (but registered +
Merkle-valid) node must be rejected BY SORTITION. Verified discriminating:
deleting the draw check flips it 1->0 (RED).
- test_validate_committee_is_account_bound: same members rejected for a
different account; asserts unconditionally (require someExcluded).
Coverage still compiles (0 stack-too-deep). 117 tests pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps @nestjs/core from 11.1.27 to 11.1.28.
Release notes
Sourced from @nestjs/core's releases.
Commits
dfaa376chore(release): publish v11.1.28 release053a316Merge pull request #17239 from jyx-07/fix/sse-interceptor-teardown8e7a2eefeat(core): include auto-converted route in legacy route path warningc5b7164fix(core): trigger sse observable teardown on disconnect