LearnNewsExamplesServices
Frontmatter
id10939
titleRe-add unit matrix row to test.yml — gated on TestLifecycleHelper substrate stabilization
stateClosed
labels
enhancementaitestingmodel-experience
assigneesneo-gpt
createdAtMay 8, 2026, 9:02 AM
updatedAtMay 12, 2026, 4:09 AM
githubUrlhttps://github.com/neomjs/neo/issues/10939
authorneo-opus-4-7
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 8, 2026, 2:43 PM

Re-add unit matrix row to test.yml — gated on TestLifecycleHelper substrate stabilization

Closedenhancementaitestingmodel-experience
neo-opus-4-7
neo-opus-4-7 commented on May 8, 2026, 9:02 AM

Context

Successor to closed PR #10933 (Phase 3 unit-row re-add). The 1-line workflow change (suite: [integration]suite: [unit, integration] in .github/workflows/test.yml) is mechanical, but the unit suite's pre-existing instability under workers:1 substrate makes re-enabling it premature.

PR #10933 went through 5 commit cycles trying to converge:

  • 7e19cd354 — workflow-line change (initial)
  • 8e6c3fd78 — test-body skip-guards (fired too late vs beforeAll/beforeEach)
  • 746fa8aea — beforeEach + Database describe-scope guards (partial)
  • 42522ec08 — FileSystemIngestor describe-scope guard (1 flake-set swapped for another)
  • 2e23dcaf7 — Path B: removed close+null from FileSystemIngestor.afterAll (root-cause fix at one producer)
  • 5cf8e99ac — Path B extended to Server.spec + GraphService.spec afterAlls

Each push surfaced new failures from the same root-cause class: spec files that close+null the singleton SQLite cascade into init failures across every consumer under workers:1. The c.5cf8e99ac extension broke GraphService.spec's own tests because line 642 inside a test also nulls the singleton, and the afterAll's clear-only no longer compensates.

The Problem

The unit suite has structural state-pollution under workers:1 substrate. Multiple specs (Server.spec, GraphService.spec, WakeSubscriptionService.spec, FileSystemIngestor.spec, plus probably more) intentionally close+null the GraphService singleton for their own test isolation. The SDK's lazy re-init breaks once the singleton is null. Sibling consumers fail.

Skip-guarding consumers is whack-a-mole. Producer-side close-removal cascades into the producer's own tests (because they rely on close+immediate-re-init for fresh state). Neither approach converges.

The Architectural Reality

@neo-gemini-3-1-pro is independently working on TestLifecycleHelper in branch agent/sqlite-hardening (per A2A 2026-05-08 06:51) — a unified cleanup substrate for SQLite/singleton lifecycle that addresses the destroy-without-re-init pattern at the helper layer rather than per-spec. That's the proper scope for the structural fix.

The Fix

Three-stage handoff:

  1. Substrate stabilization (Gemini's lane): complete TestLifecycleHelper on agent/sqlite-hardening — unified spec lifecycle helper that handles destroy+re-init paired correctly under workers:1.

  2. Migrate the close-singleton specs to TestLifecycleHelper (one PR per spec OR bundled): Server.spec, GraphService.spec, WakeSubscriptionService.spec, FileSystemIngestor.spec. Each gets its lifecycle migrated to use the helper's destroy+re-init contract.

  3. Re-add unit matrix row (this ticket's deliverable): once the unit suite is structurally stable, re-file the workflow-line change as a clean single-commit PR. Should be exit-code-0 on first run.

Acceptance Criteria

  • (AC1) TestLifecycleHelper lands via Gemini's agent/sqlite-hardening branch
  • (AC2) All 4 close-singleton specs migrated to TestLifecycleHelper lifecycle
  • (AC3) Unit suite passes locally with WORKERS=1 npm run test-unit (matches CI substrate)
  • (AC4) Workflow-line change re-filed as clean single-commit PR
  • (AC5) PR's own unit GitHub Actions check passes on first run
  • (AC6) Successor PR resolves both #10897 (Lane C followup) and any remaining Bucket G items

Out of Scope

  • Re-attempting the workflow-line change with skip-guards-only (whack-a-mole approach already proven non-convergent across 5 commits)
  • Migrating to workers: undefined for unit suite (would mask the underlying state-pollution bugs; substrate gate exists for a reason)
  • Per-test database instances (architectural change beyond AC scope)

Avoided Traps

  • Skip-guard whack-a-mole: rejected because every push surfaces new flake from the same root cause; doesn't converge
  • Producer-side close-removal alone: rejected because producer specs rely on close+immediate-re-init for their own test isolation
  • Closing PR #10933 without filing successor: rejected because the work needs visible tracking; this ticket IS the tracker
  • Reusing PR #10933 branch for v2: rejected per @tobiu's "fragmented intermediate insecure states" framing in feedback_quality_over_speed; new PR cleaner once substrate stabilizes

Related

  • Predecessor PR (closed): #10933 (5 commits of attempted convergence; lessons captured in PR body iteration retro)
  • Substrate dependency: @neo-gemini-3-1-pro's agent/sqlite-hardening branch (TestLifecycleHelper)
  • Lane C scaffolding: #10897 (Phase 3 still owed; this ticket completes it)
  • Sibling sub-tickets (stay open under #10924): #10934 (FileSystemIngestor), #10935 (TransportService residual), #10936 (KBRecorderService), #10937 (PermissionService AGENT:* pollution), #10938 (Database.spec G6)
  • Bucket G epic: #10924 (close ledger amended to include this ticket)

MX Lessons captured (substrate-discipline retro)

PR #10933's iteration cycle produced two saved feedback memories:

  • feedback_lead_role_decision_thresholds: when operator delegates lead, EXECUTE on options I myself recommended; don't loop back with another A/B/C menu
  • (forthcoming) feedback_substrate_scope_restraint: when iterative skip-guards or producer-fixes don't converge after 2-3 cycles, the substrate work is bigger than the originating PR's scope; choose Drop+Supersede over continued iteration

The 8h cost @tobiu flagged this morning was the empirical anchor for the lead-role memory; this ticket's filing IS the empirical application of the scope-restraint memory.

Origin Session ID: 7e897a0b-33ce-4d6c-b1a9-a1ff93e4e571

Retrieval Hint: query_raw_memories(query="unit matrix row workers 1 TestLifecycleHelper Phase 3 #10897 PR 10933 successor scope-restraint")

tobiu referenced in commit d14bac5 - "test(memory-core): migrate to non-destructive clear strategy (#10939) (#10940) on May 8, 2026, 9:32 AM
tobiu referenced in commit 98897fc - "feat(ci): re-add unit suite to matrix post-Bucket-G substrate (#10939) (#10953) on May 8, 2026, 2:43 PM
tobiu closed this issue on May 8, 2026, 2:43 PM
tobiu assigned to @neo-gpt on May 9, 2026, 1:09 PM