Test Suite Consolidation Deep Dive

Audience: maintainers planning the test-consolidation effort — deciding which suites become PR-blocking, nightly, release-gating, or remain report-only.

Snapshot date: 2026-05-22 UTC.

This report extends TEST_PROJECT_CI_INVENTORY.mdwith a consolidation-grade static inventory of runnable suites and fixture/corpus ownership. It is intended to support consolidation planning — it reports structure and CI mapping, not behavioral correctness.

Generated appendices:

Follow-up consolidation plan: TEST_FRAMEWORK_CONSOLIDATION_PLAN.md.

Method

The inventory was generated from repository-local files only. It excludes bin, obj, node_modules, dist, generated artifacts, Playwright reports, coverage output, and test result directories.

For .NET projects, estimated_test_methods_or_spec_files is a static count of [Fact] plus [Theory] methods, not expanded data rows. Data-driven breadth is captured separately through InlineData, MemberData, and ClassData counts in the CSV. For frontend, Playwright, and Go rows, the same field counts spec/test files.

Headline Findings

FindingCountConsolidation impact
Runnable suite rows inventoried597Includes .NET, frontend, Playwright, Go, tooling, and docs sample/template runners.
Test/spec files indexed7,557Static source files after generated/build output pruning.
Estimated methods/spec files41,954Useful for relative suite size, not exact test-case expansion.
Fixture/corpus roots198Fixture ownership needs its own manifest, not ad hoc project-local conventions.
High-value suites not currently blocking368Integration, E2E, security, golden, determinism, offline, connector, performance, and contract layers are mostly manual/report-only today.
Runnable rows with no active CI mapping23Includes 20 product/test-surface rows plus 3 docs sample/template rows.
.NET suites missing Category traits147Filter-based consolidation is unsafe until trait taxonomy is normalized.
Suites with skipped tests10These contain 34 static Skip = attributes and need an explicit skip audit.

CI State

CI stateRowsMeaning
manual-report-only567Generic .NET sweep / fanout mapping exists, but current workflow state is manual and report-only.
no-active-ci23No direct active workflow mapping was found.
automatic-pr-or-push3Current workflow mapping includes automatic PR/push execution without a report-only marker.
report-only3Automatic or mixed workflow exists, but the mapped row is explicitly report-only.

The three automatic rows are the OpenAPI conformance pack, the Air-gap Federation integration pack, and root docs/API parity tooling. Frontend is intentionally conservative in this table because its current single row mixes Vitest PR drift, default Playwright, and Air-gap E2E mappings; the manifest work should split those into separate runner rows.

Suite Layers

Layer counts are non-exclusive because a single suite can be both integration and security, or golden and determinism.

Suite layerRows
unit/component188
integration181
connector/feed/plugin130
determinism/replay/time52
security/identity/crypto48
golden/corpus44
analyzer/static-analysis42
e2e31
contract/conformance30
performance/benchmark23
offline/airgap16
chaos6
browser-e2e2
go-unit2
frontend-unit1
operator-live1

Scenario Families

Scenario familyRows
advisory-feed-connectors105
scanner/reachability/vex100
__Libraries57
evidence/attestation/signing53
policy/risk/verdict38
release-workflow38
binary/symbols/ground-truth33
__Tests31
notification/connectors28
identity/authority26
web/ui23
airgap/offline16

The highest fragmentation is in advisory-feed connector fixtures and Scanner reachability/VEX coverage. These should be manifest-owned first because they combine fixture corpuses, external-format contracts, and high-value regression coverage.

Consolidation Buckets

BucketRowsMeaning
high-value-not-blocking368Suite layer looks release-relevant but current CI state is manual/report-only or unmapped.
fixture-owned216Suite has local fixtures, embedded/content resources, or fixture roots nearby.
trait-missing147.NET suite has no static Category trait detected.
standardize-in-manifest135No immediate exception, but should still be registered in the manifest.
ci-gap23No direct active CI mapping.
skip-audit10Suite has static skipped tests.

CI Gap Rows

ModuleSuiteLayerEstimatePath
src/__Tests/playwrightoperator-trust-playwrightbrowser-e2e;e2e;operator-live16src/__Tests/playwright/package.json
__TestsStellaOps.Testing.Determinism.Propertiesdeterminism/replay/time15src/__Tests/__Libraries/StellaOps.Testing.Determinism.Properties/StellaOps.Testing.Determinism.Properties.csproj
__TestsStellaOps.E2E.AnomalyV2Pipelinee2e1src/__Tests/e2e/AnomalyV2Pipeline/StellaOps.E2E.AnomalyV2Pipeline.csproj
__TestsStellaOps.E2E.GoldenSetDiffe2e;golden/corpus7src/__Tests/e2e/GoldenSetDiff/StellaOps.E2E.GoldenSetDiff.csproj
__TestsStellaOps.Integration.E2E.Integrationsdeterminism/replay/time;e2e;integration;offline/airgap111src/__Tests/e2e/Integrations/StellaOps.Integration.E2E.Integrations.csproj
__TestsStellaOps.E2E.ReplayableVerdictdeterminism/replay/time;e2e12src/__Tests/e2e/ReplayableVerdict/StellaOps.E2E.ReplayableVerdict.csproj
__TestsStellaOps.E2E.RuntimeLinkagee2e;integration5src/__Tests/e2e/RuntimeLinkage/StellaOps.E2E.RuntimeLinkage.csproj
__TestsStellaOps.Integration.GoldenSetDiffgolden/corpus;integration20src/__Tests/Integration/GoldenSetDiff/StellaOps.Integration.GoldenSetDiff.csproj
__TestsStellaOps.Integration.AirGape2e;integration;offline/airgap19src/__Tests/Integration/StellaOps.Integration.AirGap/StellaOps.Integration.AirGap.csproj
__TestsStellaOps.Integration.ClockSkewdeterminism/replay/time;integration12src/__Tests/Integration/StellaOps.Integration.ClockSkew/StellaOps.Integration.ClockSkew.csproj
__TestsStellaOps.Integration.Determinismdeterminism/replay/time;integration182src/__Tests/Integration/StellaOps.Integration.Determinism/StellaOps.Integration.Determinism.csproj
__TestsStellaOps.Integration.E2Ee2e;integration28src/__Tests/Integration/StellaOps.Integration.E2E/StellaOps.Integration.E2E.csproj
__TestsStellaOps.Integration.HLCchaos;determinism/replay/time;integration18src/__Tests/Integration/StellaOps.Integration.HLC/StellaOps.Integration.HLC.csproj
__TestsStellaOps.Integration.Immutabilitydeterminism/replay/time;integration19src/__Tests/Integration/StellaOps.Integration.Immutability/StellaOps.Integration.Immutability.csproj
__TestsStellaOps.Integration.Performanceintegration;performance/benchmark41src/__Tests/Integration/StellaOps.Integration.Performance/StellaOps.Integration.Performance.csproj
__TestsStellaOps.Integration.Platformintegration8src/__Tests/Integration/StellaOps.Integration.Platform/StellaOps.Integration.Platform.csproj
__TestsStellaOps.Integration.ProofChainintegration6src/__Tests/Integration/StellaOps.Integration.ProofChain/StellaOps.Integration.ProofChain.csproj
__TestsStellaOps.Integration.Reachabilityintegration9src/__Tests/Integration/StellaOps.Integration.Reachability/StellaOps.Integration.Reachability.csproj
__TestsStellaOps.Integration.Unknownsintegration12src/__Tests/Integration/StellaOps.Integration.Unknowns/StellaOps.Integration.Unknowns.csproj
BinaryIndexStellaOps.BinaryIndex.Benchmarksperformance/benchmark0src/BinaryIndex/__Tests/StellaOps.BinaryIndex.Benchmarks/StellaOps.BinaryIndex.Benchmarks.csproj
DoctorStellaOps.Doctor.Plugin.Storage.Testsconnector/feed/plugin;integration7src/Doctor/__Tests/StellaOps.Doctor.Plugin.Storage.Tests/StellaOps.Doctor.Plugin.Storage.Tests.csproj
docs-sample/templateStellaOps.Plugin.MyConnector.Testsconnector/feed/plugin0docs/dev/sdks/plugin-templates/stellaops-plugin-connector/__Tests/StellaOps.Plugin.MyConnector.Tests/StellaOps.Plugin.MyConnector.Tests.csproj
docs-sample/templateStellaOps.Plugin.MyJob.Testsconnector/feed/plugin0docs/dev/sdks/plugin-templates/stellaops-plugin-scheduler/__Tests/StellaOps.Plugin.MyJob.Tests/StellaOps.Plugin.MyJob.Tests.csproj
docs-sample/templateExamples.Integration.Testsintegration0docs/modules/router/samples/tests/Examples.Integration.Tests/Examples.Integration.Tests.csproj

Largest Suites

ModuleSuiteLayerEstimateCI state
CliStellaOps.Cli.Testsdeterminism/replay/time;golden/corpus;integration1,687manual-report-only
PolicyStellaOps.Policy.Engine.Testsdeterminism/replay/time;integration;performance/benchmark1,204manual-report-only
Webstellaops-webbrowser-e2e;e2e;frontend-unit968report-only
ScannerStellaOps.Scanner.WebService.Testscontract/conformance;integration;security/identity/crypto935manual-report-only
ExportCenterStellaOps.ExportCenter.Testsintegration895manual-report-only
AdvisoryAIStellaOps.AdvisoryAI.Testsdeterminism/replay/time;integration;performance/benchmark;security/identity/crypto868manual-report-only
SignalsStellaOps.Signals.Testsdeterminism/replay/time;integration758manual-report-only
AttestorStellaOps.Attestor.ProofChain.Testsdeterminism/replay/time;golden/corpus;integration735manual-report-only
NotifierStellaOps.Notifier.Testsintegration671manual-report-only
PolicyStellaOps.Policy.Testsintegration648manual-report-only
ScannerStellaOps.Scanner.Reachability.Testscontract/conformance;determinism/replay/time;golden/corpus;integration;performance/benchmark601manual-report-only
ConcelierStellaOps.Concelier.Core.Testsdeterminism/replay/time;integration;performance/benchmark514manual-report-only

These suites should not be moved casually. They are the best candidates for a manifest-driven split into fast deterministic slices, fixture-backed golden slices, and slower infra/live slices.

Fixture and Corpus Ownership

Top fixture roots by file count:

OwnerFixture rootTypeFiles
src/__Tests/e2esrc/__Tests/e2e/scanner-analyzer-corpus/fixturesfixture880
__Testssrc/__Tests/reachability/fixturesfixture523
testssrc/tests/reachability/fixturesfixture385
Scannersrc/Scanner/__Tests/StellaOps.Scanner.Analyzers.OS.Tests/Fixturesfixture359
Scannersrc/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Python.Tests/Fixturesfixture102
Scannersrc/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Tests/Fixturesfixture81
Scannersrc/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Bun.Tests/Fixturesfixture62
Scannersrc/Scanner/__Tests/StellaOps.Scanner.Analyzers.Lang.Node.Tests/Fixturesfixture60
Cryptographysrc/Cryptography/__Tests/StellaOps.Cryptography.Tests/Eidas/Fixturesfixture58
__Testssrc/__Tests/fixturesfixture57

Fixture root counts by owner are concentrated in Concelier (57), Scanner (38), cross-cutting __Tests (17), Policy (9), docs/qa (9), Attestor (8), and Authority (7). Consolidation should add ownership, refresh command, offline status, and determinism policy for each root.

Skip Audit

The deep inventory found 10 suites with static Skip = attributes, totaling 34 skipped declarations. The affected modules include __Tests, AdvisoryAI, Cli, Concelier, Platform, ReleaseOrchestrator, Router, and Scanner. These should be reviewed before using suite green status as release evidence.

Consolidation Recommendations

  1. Create a versioned test manifest and make CI consume it. Each row should name the runner, layer, owner, fixture roots, infra, trigger, and gating state.
  2. Resolve ci-gap rows first. Product/test-surface priorities are production Playwright, src/__Tests/e2e/**, src/__Tests/Integration/**, module-owned Doctor plugin tests, and BinaryIndex benchmarks.
  3. Split mixed rows before changing gates. The Web row currently combines Vitest specs, default Playwright, live/search Playwright, and Air-gap federation UI specs. Those should become separate manifest entries.
  4. Normalize Category / Lane traits before relying on filter-based consolidation. There are 147 .NET rows with no static Category trait.
  5. Promote high-value report-only suites in stages: first make them explicit non-blocking lanes with stable artifacts, then decide which slices become PR blocking, nightly blocking, release blocking, or permanently report-only.
  6. Give fixture corpuses first-class ownership. The Scanner SCM corpus, reachability fixtures, Concelier connector fixtures, and docs/QA fixtures should have refresh commands, offline rules, and expected deterministic outputs.
  7. Keep expensive, live, hardware, OS-confinement, and Docker-heavy tests out of generic PR fanout unless they have fast slices. They still need manifest rows so consolidation does not hide them.

Decisions Needed Later