Skip to content

test: Phase 5 — 24 tests for filterEdited, filterEphemeral, ContextEdit validation#29

Merged
e6qu merged 1 commit intodevfrom
phase5/remaining-tests
Mar 22, 2026
Merged

test: Phase 5 — 24 tests for filterEdited, filterEphemeral, ContextEdit validation#29
e6qu merged 1 commit intodevfrom
phase5/remaining-tests

Conversation

@e6qu
Copy link
Owner

@e6qu e6qu commented Mar 22, 2026

Phase 5: Remaining Tests

24 new tests covering the core message filtering and context edit validation logic. These test Frankencode-specific features — none of these systems exist in upstream OpenCode.

Origin and Attribution

The features being tested were designed and built entirely for Frankencode. They are not backports — upstream OpenCode has no equivalent context editing, lifecycle markers, or ephemeral command system.

Original design and implementation:

  • Adrian Mârza (@e6qu) — designed the context editing architecture (CAS, edit graph, 6 operations, lifecycle markers, deterministic sweeper, ephemeral commands, side threads, focus agents)
  • Implementation assistance by Claude (Anthropic) across Phases 0-5 of the Frankencode roadmap

Upstream contributions that informed the design:

  • The message pipeline structure (toModelMessages, convertToModelMessages) was designed by the upstream OpenCode team (Dax Raad, Kit Langton) — our filterEdited and filterEphemeral plug into this existing pipeline
  • The permission system (PermissionNext) used by ContextEdit validation was originally by Jason Quense (anomalyco/opencode#17064) — we extended it with ownership, budget, and recency rules
  • The AsyncLocalStorage context propagation pattern (InstanceALS) used in test fixtures was refactored by Kit Langton (anomalyco/opencode#17544) — we further refactored it into InstanceALS + InstanceLifecycle + InstanceContext

Bug fixes found during implementation (by Frankencode):

  • B3: unhide/annotate missing transaction — found and fixed in code review
  • B7: filterEdited breaks message alternation — fixed with synthetic placeholder (the exact behavior tested here)
  • B15: Ephemeral commands crash (schema validation) — fixed by replacing sweep with filterEphemeral() (tested here)
  • B16: Ephemeral sweep leaks content into LLM turn — fixed by upstream filter via filterEphemeral() (tested here)
  • B49: context-edit mark() not in transaction — found and fixed in PR fix: bug fixes (B47-B52), type safety audit, architecture docs #22

filterEdited (8 tests) — test/session/filter-edited.test.ts

Tests for MessageV2.filterEdited() (source).

Pure function tests (no DB):

  • No-edit passthrough (identity optimization)
  • Hidden part removal (edit.hidden === true)
  • Superseded part removal (edit.supersededBy set)
  • Parts with edit.hidden === false kept
  • Mixed hidden/visible filtering
  • Synthetic placeholder on all-hidden message ("[Content edited out]", synthetic: true)
  • Message alternation preserved with placeholder (B7 fix)
  • Object identity preserved when no filtering needed

filterEphemeral (6 tests) — test/session/filter-ephemeral.test.ts

Tests for MessageV2.filterEphemeral() (source).

Pure function tests (no DB):

  • No-ephemeral passthrough
  • All-ephemeral message removal
  • Partial ephemeral kept (some parts ephemeral, others not)
  • Paired assistant removal via parentID link
  • User message kept when only assistant is ephemeral
  • Multiple ephemeral messages filtered correctly

ContextEdit validation (10 tests) — test/context-edit/validation.test.ts

Tests for validation logic in ContextEdit (source).

Integration tests (DB-backed via Instance.provide):

  • Ownership: privileged agent bypass, user message protection, cross-agent block, self-edit
  • Budget: under/over 70% hidden ratio
  • Recency: last 2 turns protected, older messages editable
  • Tool protection: "skill" tool parts blocked
  • General: successful hide() returns CAS hash

See docs/context-editing.md for full architecture documentation.

Test plan

  • bun run typecheck (tsgo) — 0 errors
  • bun test — 1512 pass, 0 fail (24 new)

…it validation

filterEdited tests (8):
- No-edit passthrough, hidden removal, superseded removal, hidden=false kept
- Mixed visibility filtering, synthetic placeholder on all-hidden
- Message alternation preservation, identity optimization

filterEphemeral tests (6):
- No-ephemeral passthrough, all-ephemeral removal, partial-ephemeral kept
- Paired assistant removal via parentID, user kept when only assistant ephemeral
- Multiple ephemeral messages filtered

ContextEdit validation tests (10):
- Ownership: privileged bypass, user protection, cross-agent block, self-edit
- Budget: under 70% allowed, over 70% blocked
- Recency: last 2 turns protected, older messages editable
- Tool protection: skill tool parts blocked
- General: successful hide returns CAS hash

1512 tests passing (up from 1488), 0 tsgo errors.
@e6qu e6qu merged commit df60a47 into dev Mar 22, 2026
1 check passed
@e6qu e6qu deleted the phase5/remaining-tests branch March 22, 2026 00:20
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.

1 participant