Context
During the 2026-08-06 GitHub Actions incident, with no CI reporting on any branch, the operator asked whether integration-parity could be disabled as a required check — reasoning that it looked like leftover debt now that local Agent OS dockerization is mostly done.
It is not debt, and checking that took reading the suite rather than the name. But the question is the finding: a live safety gate is named for a transition that is over, so it reads as retirable to anyone who has not opened it. It nearly was.
The Problem
integration-parity sounds like local versus dockerized parity — a comparison that would indeed be obsolete once the dockerized plane is canonical.
What it actually does is boot a second, isolated dockerized plane and assert the two coexist without contaminating each other:
- separate Compose project (
neo-parity-ci) over docker-compose.dev.yml + docker-compose.parity-ci.yml
- separate data root —
/app/.neo-ai-data-parity against the canonical /app/.neo-ai-data
- internal network separation, with a documented trap: addressing the same project through the base file alone replaces the live internal network and severs the MCP server's Chroma connection
- environment-backed provider secrets, including a negative arm proving a developer
.env cannot silently supply a credential after explicit process-env deletion
That is multi-plane isolation. Its relevance grows rather than shrinks: a second deployment is by definition a second plane, and the 2026-08-06 corpus incident had a plane move (#16556) as its root cause — an artifact that was present on one plane and absent on the other, undetected until it had corrupted every framework-class chunk.
The suite's own source shows the confusion is not the reader's fault. test.yml:238 reasons about the path subset in terms of integration coverage crossing into src/state/Provider and src/core/Base — integration language, under a parity name.
The Architectural Reality
A rename is not cosmetic here — the name is a consumed contract. The workflow job name becomes the check context, and that string is encoded in code:
test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjs:316
required_status_checks: [{context: 'integration-parity', integration_id: 15368}]
:322 name = 'integration-parity'
:441 {context: 'integration-parity', integrationId: 15368}Branch protection (operator-owned) references the same context. Rename the job without updating protection first and the renaming PR blocks forever, waiting on a check that can no longer report. That ordering is the whole risk in this ticket.
Surfaces carrying the name:
| surface |
file |
workflow job, matrix entry, isParityRelevantPath, run_parity, skip reason |
.github/workflows/test.yml |
| two further workflows referencing it |
check-agentos-theme.yml, config-template-ssot-lint.yml |
| Playwright config |
test/playwright/playwright.config.integration-parity.mjs |
| suite directory + spec + fixture |
test/playwright/integration-parity/, ParityTopology.integration.spec.mjs, fixtures/parityProbe.mjs |
| chained config |
test/playwright/playwright.config.update-chain.mjs |
| unit spec |
test/playwright/unit/ai/deploy/ParityPlaneVolumeScoping.spec.mjs |
| npm script |
package.json:124 test-integration-parity |
| compose files |
ai/deploy/docker-compose.parity-ci.yml, docker-compose.parity-capture.yml, docker-compose.dev.yml |
| env vars |
NEO_PARITY_COMPOSE_PROJECT, NEO_PARITY_READY_URL |
| required-check contract |
PullRequestService.spec.mjs (three sites) |
The Fix
Proposed name: plane-isolation. It matches vocabulary already load-bearing in this codebase — PLANE_ID, PLANE_DATA_ROOT, ADR-0014's host-edge / container-plane authority projection, ParityPlaneVolumeScoping — and it states the invariant rather than a historical comparison. Alternatives worth a moment before committing: multi-plane-isolation (more explicit, longer check context) or leaving the suite named and only fixing the comment (cheapest, but leaves the retirement risk intact).
Ordering is the deliverable, not the rename. Suggested sequence, and the ticket should record whichever is chosen:
- Add the new check context to branch protection alongside the old one (operator-owned; both required, or new one non-required initially).
- Land the rename PR — its own run reports under the new context, which already exists.
- Update
PullRequestService.spec.mjs's three encoded sites and its integration_id if it changes.
- Remove the old context from protection once no open PR still references it.
A single-step rename is the trap; a PR that renames the check it must pass cannot pass it.
Contract Ledger Matrix
| Target Surface |
Source of Authority |
Proposed Behavior |
Fallback |
Docs |
Evidence |
| workflow job / check context |
.github/workflows/test.yml |
Renamed; both contexts live during transition |
Old context retained until step 4 |
job-level comment |
PullRequestService.spec.mjs:316 encodes it |
required_status_checks contract |
PullRequestService.spec.mjs:316/:322/:441 |
Updated to the new context |
— |
spec comments |
three encoded sites |
| npm script |
package.json:124 |
Renamed |
— |
— |
— |
| suite dir + config + fixture |
test/playwright/integration-parity/ |
Renamed; path predicates updated |
— |
— |
isParityRelevantPath at test.yml:240 |
| compose project / env vars |
docker-compose.parity-ci.yml, NEO_PARITY_* |
Renamed consistently |
Defaults preserved |
inline |
ParityTopology.integration.spec.mjs:11-16 |
Decision Record impact
none. A naming and sequencing correction; no runtime behaviour, no authority, no coverage change. The suite's assertions are unchanged.
Acceptance Criteria
Out of Scope
- Any change to what the suite asserts. This ticket renames; it does not touch isolation coverage. If the coverage is wrong that is a separate ticket with its own evidence.
- Retiring or disabling the suite. The investigation that produced this ticket concluded the opposite.
- CodeQL, or any other required check's status.
- The path-gating logic itself (
isParityRelevantPath behaviour) beyond following the rename.
Avoided Traps
"It is just a rename, do it in one PR." The job name is the required-check context, encoded in three code sites and in operator-owned branch protection. A one-step rename produces a PR that can never satisfy its own gate. The sequencing is the actual work.
"Rename the comment only, leave the suite alone." Cheapest and it does fix the immediate confusion — but it leaves a safety gate labelled for an obsolete transition, which is the condition that produced this ticket. Listed as a live alternative rather than dismissed; if chosen, record why.
"Parity is fine, everyone here knows what it means." Empirically not: the question that produced this ticket came from the operator, and the suite's own path-predicate comment uses integration language under the parity name.
Related
- #16556 — the plane move whose carried artifact caused the 2026-08-06 corpus incident; the concrete case for why plane isolation matters more, not less.
- #16600 / #16601 — the artifact that was present on one plane and absent on the other.
- #16569 — the plane-id default valid for exactly one deployment; adjacent plane-identity debt.
Handoff Retrieval Hints
query_raw_memories: "integration-parity rename plane isolation required status check context branch protection"
- Source anchors:
.github/workflows/test.yml:238-259 (path predicates), test/playwright/integration-parity/ParityTopology.integration.spec.mjs:11-31 (plane constants + compose graph), test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjs:316/:322/:441 (encoded check context).
- Live latest-open sweep: checked the latest 20 open issues 2026-08-06;
resources/content/issues/ keyword hits are historical records (#15252, #15798, #15800), not duplicates.
Origin Session ID: 8921d480-6087-4bfa-abe0-4f47873e06c4
Authored by @neo-opus-grace (Claude Opus 5).
Context
During the 2026-08-06 GitHub Actions incident, with no CI reporting on any branch, the operator asked whether
integration-paritycould be disabled as a required check — reasoning that it looked like leftover debt now that local Agent OS dockerization is mostly done.It is not debt, and checking that took reading the suite rather than the name. But the question is the finding: a live safety gate is named for a transition that is over, so it reads as retirable to anyone who has not opened it. It nearly was.
The Problem
integration-paritysounds like local versus dockerized parity — a comparison that would indeed be obsolete once the dockerized plane is canonical.What it actually does is boot a second, isolated dockerized plane and assert the two coexist without contaminating each other:
neo-parity-ci) overdocker-compose.dev.yml+docker-compose.parity-ci.yml/app/.neo-ai-data-parityagainst the canonical/app/.neo-ai-data.envcannot silently supply a credential after explicit process-env deletionThat is multi-plane isolation. Its relevance grows rather than shrinks: a second deployment is by definition a second plane, and the 2026-08-06 corpus incident had a plane move (#16556) as its root cause — an artifact that was present on one plane and absent on the other, undetected until it had corrupted every framework-class chunk.
The suite's own source shows the confusion is not the reader's fault.
test.yml:238reasons about the path subset in terms of integration coverage crossing intosrc/state/Providerandsrc/core/Base— integration language, under a parity name.The Architectural Reality
A rename is not cosmetic here — the name is a consumed contract. The workflow job name becomes the check context, and that string is encoded in code:
test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjs:316 required_status_checks: [{context: 'integration-parity', integration_id: 15368}] :322 name = 'integration-parity' :441 {context: 'integration-parity', integrationId: 15368}Branch protection (operator-owned) references the same context. Rename the job without updating protection first and the renaming PR blocks forever, waiting on a check that can no longer report. That ordering is the whole risk in this ticket.
Surfaces carrying the name:
isParityRelevantPath,run_parity, skip reason.github/workflows/test.ymlcheck-agentos-theme.yml,config-template-ssot-lint.ymltest/playwright/playwright.config.integration-parity.mjstest/playwright/integration-parity/,ParityTopology.integration.spec.mjs,fixtures/parityProbe.mjstest/playwright/playwright.config.update-chain.mjstest/playwright/unit/ai/deploy/ParityPlaneVolumeScoping.spec.mjspackage.json:124test-integration-parityai/deploy/docker-compose.parity-ci.yml,docker-compose.parity-capture.yml,docker-compose.dev.ymlNEO_PARITY_COMPOSE_PROJECT,NEO_PARITY_READY_URLPullRequestService.spec.mjs(three sites)The Fix
Proposed name:
plane-isolation. It matches vocabulary already load-bearing in this codebase —PLANE_ID,PLANE_DATA_ROOT, ADR-0014's host-edge / container-plane authority projection,ParityPlaneVolumeScoping— and it states the invariant rather than a historical comparison. Alternatives worth a moment before committing:multi-plane-isolation(more explicit, longer check context) or leaving the suite named and only fixing the comment (cheapest, but leaves the retirement risk intact).Ordering is the deliverable, not the rename. Suggested sequence, and the ticket should record whichever is chosen:
PullRequestService.spec.mjs's three encoded sites and itsintegration_idif it changes.A single-step rename is the trap; a PR that renames the check it must pass cannot pass it.
Contract Ledger Matrix
.github/workflows/test.ymlPullRequestService.spec.mjs:316encodes itrequired_status_checkscontractPullRequestService.spec.mjs:316/:322/:441package.json:124test/playwright/integration-parity/isParityRelevantPathattest.yml:240docker-compose.parity-ci.yml,NEO_PARITY_*ParityTopology.integration.spec.mjs:11-16Decision Record impact
none. A naming and sequencing correction; no runtime behaviour, no authority, no coverage change. The suite's assertions are unchanged.Acceptance Criteria
NEO_*env vars carry a name describing plane isolation rather than parity.grep -rn "integration-parity"returns zero hits outside historicalresources/content/records.required_status_checkssites inPullRequestService.spec.mjsreference the new context, and its spec passes.test.yml's path-predicate comment (:238) describes what the suite guards; the integration-versus-parity conflation in that comment is resolved.Out of Scope
isParityRelevantPathbehaviour) beyond following the rename.Avoided Traps
"It is just a rename, do it in one PR." The job name is the required-check context, encoded in three code sites and in operator-owned branch protection. A one-step rename produces a PR that can never satisfy its own gate. The sequencing is the actual work.
"Rename the comment only, leave the suite alone." Cheapest and it does fix the immediate confusion — but it leaves a safety gate labelled for an obsolete transition, which is the condition that produced this ticket. Listed as a live alternative rather than dismissed; if chosen, record why.
"Parity is fine, everyone here knows what it means." Empirically not: the question that produced this ticket came from the operator, and the suite's own path-predicate comment uses integration language under the parity name.
Related
Handoff Retrieval Hints
query_raw_memories: "integration-parity rename plane isolation required status check context branch protection".github/workflows/test.yml:238-259(path predicates),test/playwright/integration-parity/ParityTopology.integration.spec.mjs:11-31(plane constants + compose graph),test/playwright/unit/ai/services/github-workflow/PullRequestService.spec.mjs:316/:322/:441(encoded check context).resources/content/issues/keyword hits are historical records (#15252, #15798, #15800), not duplicates.Origin Session ID: 8921d480-6087-4bfa-abe0-4f47873e06c4
Authored by @neo-opus-grace (Claude Opus 5).