Skip to content

fix(harnessd): bind matrix readiness to the listener actually acquired #1140

Description

@dennisonbertram

Work type

Bug

Problem

Parallel TestMatrix_ cases reserve an ephemeral address with freeLocalAddr, close it, then later accept any /healthz response at that recycled address. A sibling harness can acquire the same port, causing the custom-global-skill case to query the wrong server and intermittently receive an empty registry.

Evidence: hosted race run 30848795397 logged two harnesses on 127.0.0.1:44987; the intended runtime logged loaded 1 skill(s) but TestMatrix_SkillsEnabledWithCustomGlobalDir queried {"skills":[]}. Harness source and tests are byte-identical on origin/main 68a82ddf and the failing #1138 ancestor, so this is a baseline race.

Scope

  • Add optional listener injection to runDeps (default net.Listen).
  • Have runMatrixTest request 127.0.0.1:0 and record the actual acquired listener address through the injected wrapper.
  • Await that exact listener (or early runWithSignals failure) before /healthz and assertions.
  • Remove freeLocalAddr from matrix cases.

Out of scope

  • Production skill loading behavior.
  • Serializing matrix tests or increasing arbitrary timeouts.

Acceptance criteria

  • A deterministic regression proves runMatrixTest uses the address actually bound by its server.
  • Custom-global-skill endpoint test passes through the corrected helper.
  • Focused custom-skill normal/race stress and full TestMatrix_ normal/race stress pass.
  • cmd/harnessd normal/race and ./scripts/test-regression.sh pass.

Impact and rollout

Test-harness-only dependency injection; production defaults remain net.Listen. No API, persistence, deployment, or rollback change.

Test plan

TDD: add deterministic red listener-identity regression, implement injected listener handoff, then run focused/race/full regression.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions