Skip to content

fix: base-id membership at remaining exact-id check sites (#234) - #235

Open
ranxianglei wants to merge 2 commits into
masterfrom
2026-09-09_subid-membership-sites
Open

fix: base-id membership at remaining exact-id check sites (#234)#235
ranxianglei wants to merge 2 commits into
masterfrom
2026-09-09_subid-membership-sites

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

What

Fixes #234. PR #233 normalized prune.ts + sync.ts to compare block coverage by base id so sub-id projections (base#r0, base#call1) stay covered by blocks that recorded the plain base (and vice versa). This PR applies the same baseIdOf / base-set normalization to every remaining same-class site in the kernel.

Stacked on #233 — this branch contains #233's commit (ad78b45, cherry-pick of ed232f5) so baseIdOf is available. Whichever PR merges first, the other auto-resolves. Merge #233 first if you prefer a clean single-PR history; otherwise this PR can merge directly.

Sites fixed

Listed in #234's table:

Site Check Fix
src/recommend.ts isSyntheticOrPruned block.effectiveMessageIds.includes(message.id) precomputed activeBlockCoveredBases(state) set, tested via baseIdOf(message.id); built once per pass in computeProtectedRefs + buildCompressibleRanges
src/decompress.ts findBlocksOverlappingMessages messageIds.has(id) messageBases set from the param, tested via baseIdOf(id)
src/decompress.ts buildRestoredContentPreview b.effectiveMessageIds.includes(message.id) precomputed covered-bases set
src/compress.ts danglingMessageRefs block.effectiveMessageIds.includes(rawId) visible + covered base sets; ref-map form divergence handled
src/compress.ts collectCoverage + directMessageIds filter coverage set vs range ids coverage stored as base ids; filter tests baseIdOf(id) — livelock guard now fires across forms
src/boundaries.ts activeOwnerAnchor inherited.has(id) owned + inherited sets both base-normalized
src/report.ts collectVisible coveredIds.has(message.id) covered set + lookup base-normalized

Found during verification (same class, not in the table):

Site Check Fix
src/decompress.ts collectBlockContent targetIds.has(m.id) + nestedCovered.has(m.id) base sets for target and nested-fold (already flagged in #231 triage, floor 3)
src/boundaries.ts message-ref lookup indexByMessageId.get(rawId) exact first, then baseIndexById.get(baseIdOf(rawId)) fallback — stale refs from an older projection form still anchor to the visible message
src/boundaries.ts visibleBlockAnchor / blockVisibleInRange / earliestIndexOfIds block ids vs view index map base→earliest-index map built in resolveBoundaries + applySingleRange; exported fns gained an optional trailing baseIndexById? param (backward-compatible, no API break; derived from the exact map when omitted)

Report-only (not fixed here): src/wire/compress-detect.ts:180 boundaryRawCore compares block.effectiveMessageIds (via ref map) against current core-message ids with exact equality — same class, but it's in the wire subpath (replay-guard, #91 lineage) with its own test suite; left out to keep this PR focused on the kernel path. Happy to fold it in or file a follow-up — your call.

Tests

New tests/subid-membership.test.ts — 19 regression tests covering every fixed site, both projection directions (base block / sub-id view and sub-id block / base view) plus prefix-safety controls (h_abcde is NOT covered by base h_abc — no accidental prefix matching). Verified against the pre-fix code: 17/19 fail, the 2 passing are the prefix-safety controls (correct in both states).

Full suite: 651/651 pass, tsc --noEmit clean, build OK.

Minor note

package-lock.json on master is one version behind package.json (0.0.58 vs 0.0.59 — the release commit only bumps package.json). npm install rewrites it locally; I reverted that to keep this PR focused. Can be synced in a housekeeping commit if you want.

ework-agent added 2 commits September 9, 2026 14:48
#233 normalized prune.ts and sync.ts to compare block coverage by base id so sub-id projections (base#r0) stay covered by blocks that recorded the plain base. The same exact-string membership class remained at:

- recommend.ts: isSyntheticOrPruned (protected refs + compressible ranges)
- decompress.ts: findBlocksOverlappingMessages, buildRestoredContentPreview, collectBlockContent (target + nested-fold sets)
- compress.ts: danglingMessageRefs, collectCoverage/preExistingCoverage (livelock guard), applySingleRange nested re-scan
- boundaries.ts: message-ref lookup (base fallback), activeOwnerAnchor (owned/inherited sets), visibleBlockAnchor/blockVisibleInRange/earliestIndexOfIds (base index map, optional param - API-compatible)
- report.ts: collectVisible covered set

19 regression tests (tests/subid-membership.test.ts), both projection directions plus prefix-safety controls (h_abcde not covered by h_abc). 17 fail on the pre-fix code; the 2 passing controls guard against over-matching.

Stacked on PR #233 (contains its commit).
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

📦 Built Package Artifact

Branch: 2026-09-09_subid-membership-sites (14a3f60)

Option A — Install from npm PR tag (recommended)

In your adapter project:

npm install acp-kernel@pr-235

Each push to this PR publishes a new version under the pr-235 npm tag.

Option B — Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf acp-kernel-pr235.tgz
npm install ./package

This comment is automatically updated on each push.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

exact-id membership vs block.effectiveMessageIds: remaining same-class sites (latent until sub-id projections ship)

1 participant