Frontmatter
| title | fix(ci): scope-classifier triggers integration only on relevant paths (#12980) |
| author | neo-opus-vega |
| state | Merged |
| createdAt | Jun 12, 2026, 11:53 AM |
| updatedAt | Jun 12, 2026, 12:08 PM |
| closedAt | Jun 12, 2026, 12:08 PM |
| mergedAt | Jun 12, 2026, 12:08 PM |
| branches | dev ← fix/12980-integration-ci-whitelist |
| url | https://github.com/neomjs/neo/pull/12982 |

PR Review Summary
Status: Approved
Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: The diff directly fixes the over-triggering integration classifier while keeping the safer false-negative boundaries covered. The remaining observable "next unit-only PR skips integration" check is post-merge validation of the CI surface, not an unimplemented code path in this PR.
Peer-Review Opening: Reviewed #12982 at exact head a831cbdba1b6f02a834778cd657e95a8dc4b1a5a; the classifier whitelist is narrow enough to skip the reported unit-only shape and complete enough to avoid obvious integration false-negatives.
Patch-Blind Premise Snapshot
- Inputs Read Before Patch: Target issue #12980, current
dev.github/workflows/test.yml, live PR metadata, close-target labels, exact branch commit message, REST check-runs fora831cbd, and the integration config/import surfaces (test/playwright/playwright.config.integration.mjs, integration fixtures/util imports, sharedfixtures.mjs, andai/deploy/docker-compose.test.ymlpath). - Expected Solution Shape: A correct fix should replace the old "integration unless docs-only" blacklist with an integration-relevance whitelist, while not hardcoding only
src/+ai/and accidentally skipping dependency, integration-spec, shared-infra, or workflow changes. Test isolation should prove the reported#12976-shape skips integration and the false-negative guard paths still run it. - Patch Verdict: Matches. The patch introduces
isIntegrationRelevantPath, includessrc/,ai/, integration specs, shared Playwright infra, dependency manifests, and.github/workflows/test.yml, and leavesrun_unitunchanged.
Context & Graph Linking
- Target Epic / Issue ID: Resolves #12980
- Related Graph Nodes:
#12976observed friction shape, GitHub Actions scope classifier, post-v13 CI-efficiency backlog.
Depth Floor
Documented search: I actively looked for false-negative gaps in the integration config/import graph, branch commit close-target hazards, and protected-branch missing-check risk, and found no blocking concerns.
Rhetorical-Drift Audit:
- PR description: framing matches the diff; it calls out the old over-triggering default and the new whitelist boundary.
- Anchor & Echo summaries: N/A; no JS class/method JSDoc changed.
-
[RETROSPECTIVE]tag: N/A; none added. - Linked anchors: #12980 establishes the classifier whitelist target;
#12976is used descriptively as the observed friction.
Findings: Pass.
Graph Ingestion Notes
[KB_GAP]: N/A.[TOOLING_GAP]:gh pr checks 12982timed out through GraphQL in this harness; I used the REST check-runs endpoint for exact heada831cbdinstead.[RETROSPECTIVE]: CI classifier whitelists are safer when reviewed as false-negative surfaces, not just as cost-saving skips; the complete path set matters more than the one reported skip case.
N/A Audits - Contract / MCP / Wire Format / Turn-Memory
N/A across listed dimensions: this PR changes an existing GitHub Actions classifier and does not alter public APIs, MCP tool descriptions, JSON/wire contracts, or turn-loaded instruction substrate.
Close-Target Audit
For every issue named as close-target, verify it does NOT carry the epic label:
- Close-targets identified: #12980
- #12980 labels are
enhancement,ai,build; noepiclabel. - Branch commit message checked; no hidden
Closes/Fixes/ staleResolvesbody hazard beyond the PR body's validResolves #12980.
Findings: Pass.
Evidence Audit
- PR body contains an
Evidence:declaration line. - Achieved evidence covers the implementable classifier behavior: local predicate verification over representative path sets plus GitHub check-runs on this workflow-changing PR.
- Post-merge validation is correctly scoped to observing the next real PR's check presentation; the workflow shape keeps the matrix job present and gates inner steps, so protected-branch checks are not removed.
Findings: Pass.
Cross-Skill Integration Audit
- Existing workflow behavior changes, but no new agent workflow primitive is introduced.
- No
AGENTS_STARTUP.md, skill, MCP, or wire-format documentation needs updating for this internal classifier adjustment.
Findings: All checks pass — no integration gaps.
Test-Execution & Location Audit
- Branch checked out locally at
a831cbdba1b6f02a834778cd657e95a8dc4b1a5a. - Canonical Location: no new/moved test files.
- Workflow syntax:
ruby -ryaml -e 'YAML.load_file(".github/workflows/test.yml")'->workflow yaml ok. - Predicate cases: local Node classifier check passed for the reported
#12976shape,src/,ai/, package manifests, integration specs, shared util, workflow changes, docs-only, and portal generated data content. - CI: REST check-runs for exact head show
CodeQL,unit,integration-unified,Classify test scope,Analyze (javascript), andlint-pr-bodyall succeeded.
Findings: Pass.
Required Actions
No required actions — eligible for human merge.
Evaluation Metrics
[ARCH_ALIGNMENT]: 95 - 5 points deducted only because the broaderrun_unitsymmetry remains out of scope; the integration side itself follows the repo's existing present-but-skipped check pattern.[CONTENT_COMPLETENESS]: 95 - 5 points deducted because the post-merge observable skip remains a validation checkbox, but the PR body otherwise has clear evidence, deltas, close-target, and follow-up framing.[EXECUTION_QUALITY]: 95 - 5 points deducted for static/predicate verification ceiling on a CI-behavior change; exact-head CI is green and local predicate/YAML checks passed.[PRODUCTIVITY]: 100 - The PR achieves the#12980goal: the reported unit-only shape skips integration while integration-relevant paths still run it.[IMPACT]: 45 - Routine but meaningful CI-efficiency fix; it reduces unnecessary heavy integration runs without changing runtime product behavior.[COMPLEXITY]: 35 - Low-to-moderate: one workflow classifier function, but correctness depends on remembering the integration stack's dependency surface.[EFFORT_PROFILE]: Quick Win - Small diff with direct CI-cost payoff and bounded verification surface.
No required actions from my side.
Resolves #12980
Replaces
test.yml's "run integration unless docs-only" blacklist with a whitelist: the integration suite now runs only when a change can actually affect the integration stack. Fixes the operator-flagged friction where a unit-test-only PR (#12976 — a unit spec + a.mdfixture) triggered the heavy integration suite for no reason.Authored by Claude Opus 4.8 (Claude Code). Session 3e808a22-50ef-484b-83c9-477ad47e9087.
Evidence: L2 (predicate-logic verification over 9 representative changed-path sets +
ruby -ryamlparse of the workflow) → L1 required (the AC is the classifier's static path→suite mapping). Residual: observable suite-gating on a real follow-up PR (Post-Merge).The change
run_integrationflips fromsome(file => !isDocsOnlyPath(file))(trigger unless docs-only — so every non-docs path-type defaults to triggering) tosome(isIntegrationRelevantPath), where a path is integration-relevant iff it is under:src/— the engine the Agent-OS stack runs onai/— the Agent OS the integration suite exercises (incl.ai/deploy/docker-compose.test.yml, the integration Chroma stack)test/playwright/integration/— the integration specs + fixtures themselvestest/playwright/util/+fixtures.mjs/setup.mjs/playwright.config.integration.mjs— shared test infra integration usespackage.json/package-lock.json— dep changes can break the integration stack.github/workflows/test.yml— CI-logic changes run the full suite to validaterun_unitis unchanged.Why a complete whitelist (not a tight
src/+ai/list)The prior blacklist over-triggers — wasteful but safe (it never misses). A whitelist's failure mode is the opposite and worse: skip-when-it-was-needed → an integration regression merges green. So the membership is deliberately complete (deps, the integration tests themselves, shared infra, CI-logic) to avoid false-negatives. Source-scope verified: the integration suite is Agent-OS/cloud integration (KB tenant-isolation, MCP transport, OIDC, heartbeat, backup/restore, multi-tenant ingestion, daemon safety) under
ai/, and it runs the engine —BackupRestoreWipe.integration.spec.mjsimportssrc/Neo.mjs+src/core/_export.mjs.Deltas from ticket
None — implements the whitelist exactly as specified in #12980.
Test Evidence
Predicate logic verified over 9 representative path-sets:
#12976shape (unit spec +.mdfixture) → SKIP integration ✓ (the fix)src/,ai/,ai/deploy/...compose,package.json, an integration spec, this workflow → RUN ✓ (no false-negative)resources/content/→ SKIP ✓ruby -ryamlparse of.github/workflows/test.yml→ valid. And this PR changestest.ymlitself, so by the new rule it runs the full suite (unit + integration) — self-validating.Post-Merge Validation
integration-unifiedcheck (reports present-but-skipped, not missing — protected-branch gating preserved).src/orai/PR still runsintegration-unified.Follow-up (out of scope)
The symmetric
run_unitper-suite whitelist (so an integration-only/e2e-only change doesn't drag in the unit suite) is the broader root-fix — deferred to bound this PR to the reported integration friction. Worth a follow-up ticket;run_unitover-triggers too, but unit is cheap and over-running it is safe.Commits
a831cbdba— whitelistrun_integration+ accurateskip_reason.