Problem
Pester (execution only) still behaves like a monolith even after the service-model split. It currently mixes:
- repo/control-plane context
- host/runtime preflight
- test selection and dispatcher shaping
- actual execution
- post-execution classification and receipts
The standing-priority false negative observed during the self-hosted execution path proves the leak: a repo-control-plane concern can still surface as an execution-seam failure.
Current evidence:
- direct operator proof run
23806250860 admitted the trusted router and cleared readiness
- the active long pole is
pilot / pester-run / Pester (execution only) on GHOST-comparevi-capability-ingress
- standing-priority discovery is correct in the repo itself (
#2069 is open and labeled standing-priority), so this defect class is about execution-layer coupling, not actual queue state
Objective
Break Pester (execution only) into coherent layers so each failure class is attributable to one contract boundary.
Target layers:
pester-context
pester-runtime-preflight
pester-selection
pester-execute
pester-post
Implementation Plan
1. Add a context layer and receipt
Create an explicit pester-context stage ahead of readiness/execution.
Responsibilities:
- resolve repository slug deterministically
- validate workflow token presence/usability for issue discovery
- run standing-priority sync or emit an explicit non-blocking context classification
- validate worktree/helper-root assumptions if they are needed by downstream scripts
- emit
pester-context-receipt@v1
Outputs:
context_status: ready | blocked | warning
repository
standing_priority_issue
standing_priority_reason
receipt artifact
2. Make runtime preflight consume context, not discover context
Refactor self-hosted readiness to assume repo/control-plane context is already settled.
Responsibilities:
- validate session-lock health
- validate
.NET toolchain and runtime dependencies
- validate Windows Docker runtime
- validate LVCompare and idle LabVIEW state
- prepare fixture prerequisites only
- emit
pester-selfhosted-readiness-receipt@v1
Non-goal:
- no standing-priority or issue discovery here
3. Add a selection layer
Create a pester-selection contract between readiness and execution.
Responsibilities:
- normalize integration mode
- resolve include/exclude patterns
- materialize dispatcher profile
- resolve the concrete test pack/file selection
- emit
pester-selection-receipt@v1
This separates test-shaping defects from dispatcher/runtime defects.
4. Shrink execution to execution only
Reduce pester-execute to one job: run the dispatcher against a prepared environment.
Responsibilities:
- consume context, readiness, and selection receipts
- acquire/release execution lock
- run
Invoke-PesterTests.ps1
- emit raw execution outputs and a minimal execution exit contract
Non-goals:
- no standing-priority sync
- no repo slug resolution
- no readiness probing
- no test-pack shaping
5. Move classification into post-processing
Create pester-post as the only place that turns raw execution into operator meaning.
Responsibilities:
- release lock defensively
- write execution receipt
- upload raw artifacts
- classify terminal status as one of:
completed
test-failures
context-blocked
readiness-blocked
selection-blocked
seam-defect
6. Remove context ownership from Invoke-PesterTests.ps1
Invoke-PesterTests.ps1 should become context-agnostic.
Required outcome:
- it must not own standing-priority lookup or repository-priority decisions
- it must assume context/readiness/selection were already proven upstream
- it may still own dispatcher/runtime/test orchestration
7. Add contract tests per layer
Add workflow and receipt tests for:
- context-ready path
- context-blocked path
- readiness-ready path
- readiness-blocked path
- selection receipt generation
- execution-only path with mocked dispatcher
- post-processing classification for missing summary / skipped / blocked / failures
8. Promote only after additive proof
Rollout sequence:
- land the layer split additively
- prove it on direct operator dispatch
- prove it on same-owner trusted PR routing
- prove it on
integration/** mounted upstream proof
- only then recast the current monolith as legacy/fallback
Acceptance Criteria
- standing-priority lookup failures surface in
pester-context, not pester-execute
- readiness failures surface in
pester-runtime-preflight, not as generic execution stalls
- test selection is represented by an explicit receipt
- execution can run without performing repo/control-plane discovery
- post-processing can classify failures without guessing their layer
- at least one end-to-end proof passes on the service-model rail after the split
Risks / Notes
- this is a follow-up slice under
#2069, not a replacement for it
- the issue should remain out of standing auto-selection while
#2069 stays the epic
- the current run
23806250860 should be preserved as pre-split evidence of the remaining execution-layer ambiguity
Problem
Pester (execution only)still behaves like a monolith even after the service-model split. It currently mixes:The standing-priority false negative observed during the self-hosted execution path proves the leak: a repo-control-plane concern can still surface as an execution-seam failure.
Current evidence:
23806250860admitted the trusted router and cleared readinesspilot / pester-run / Pester (execution only)onGHOST-comparevi-capability-ingress#2069is open and labeledstanding-priority), so this defect class is about execution-layer coupling, not actual queue stateObjective
Break
Pester (execution only)into coherent layers so each failure class is attributable to one contract boundary.Target layers:
pester-contextpester-runtime-preflightpester-selectionpester-executepester-postImplementation Plan
1. Add a context layer and receipt
Create an explicit
pester-contextstage ahead of readiness/execution.Responsibilities:
pester-context-receipt@v1Outputs:
context_status:ready | blocked | warningrepositorystanding_priority_issuestanding_priority_reasonreceipt artifact2. Make runtime preflight consume context, not discover context
Refactor self-hosted readiness to assume repo/control-plane context is already settled.
Responsibilities:
.NETtoolchain and runtime dependenciespester-selfhosted-readiness-receipt@v1Non-goal:
3. Add a selection layer
Create a
pester-selectioncontract between readiness and execution.Responsibilities:
pester-selection-receipt@v1This separates test-shaping defects from dispatcher/runtime defects.
4. Shrink execution to execution only
Reduce
pester-executeto one job: run the dispatcher against a prepared environment.Responsibilities:
Invoke-PesterTests.ps1Non-goals:
5. Move classification into post-processing
Create
pester-postas the only place that turns raw execution into operator meaning.Responsibilities:
completedtest-failurescontext-blockedreadiness-blockedselection-blockedseam-defect6. Remove context ownership from
Invoke-PesterTests.ps1Invoke-PesterTests.ps1should become context-agnostic.Required outcome:
7. Add contract tests per layer
Add workflow and receipt tests for:
8. Promote only after additive proof
Rollout sequence:
integration/**mounted upstream proofAcceptance Criteria
pester-context, notpester-executepester-runtime-preflight, not as generic execution stallsRisks / Notes
#2069, not a replacement for it#2069stays the epic23806250860should be preserved as pre-split evidence of the remaining execution-layer ambiguity