Skip to content

[M057] Core Handler & Webhook Test Backfill #96

@keithah

Description

@keithah

Roadmap source: kodiai-roadmap.md

  • Phase: Phase 3 — Code Safety Net
  • Milestone: M057

Slice M057/S01 — Webhook layer tests

What this is

src/webhook/ is the entry point for every GitHub event Kodiai sees. It has five source files and zero test files:

  • src/webhook/verify.ts — wraps @octokit/webhooks-methods.verify() for signature validation.
  • src/webhook/dedup.ts — deduplicates deliveries.
  • src/webhook/router.ts — dispatches events to handlers.
  • src/webhook/filters.ts — drops app-originated events (self-event filter invariant called out in PROJECT.md).
  • src/webhook/types.ts — type definitions.

The self-event filter is explicitly referenced as a truthfulness invariant in PROJECT.md ("self-generated reviewer/team requests cannot be used as proof for human manual rereview behavior"). That invariant has no test.

Acceptance criteria

  • src/webhook/verify.test.ts covers: valid signature, invalid signature, missing header, wrong algorithm prefix, timing-safe failure, @octokit/webhooks-methods throw path.
  • src/webhook/dedup.test.ts covers: first-seen delivery accepted, duplicate rejected, race condition (concurrent deliveries with same id).
  • src/webhook/router.test.ts covers: known event types routed to correct handlers, unknown event types dropped with log tag, handler exceptions surfaced (not silently swallowed).
  • src/webhook/filters.test.ts covers: app-originated event filter (the self-event invariant), bot-originated event handling, human-originated event pass-through, the specific pull_request.review_requested with team-only target case (must produce skipReason=team-only-request per M051 contract).
  • All four test files pass in CI.

Files to touch

  • src/webhook/verify.test.ts, src/webhook/dedup.test.ts, src/webhook/router.test.ts, src/webhook/filters.test.ts — create.

Verify contract

  • Command: bun run verify:m057:s01
  • Script: scripts/verify-m057-s01.ts
  • Check IDs: webhook_verify_test_present, self_event_filter_invariant_tested, team_only_skip_reason_tested, tests_pass.
  • Status codes: m057_s01_ok, m057_s01_missing_test, m057_s01_invariant_not_covered.

Slice M057/S02 — ci-failure.ts handler tests

What this is

src/handlers/ci-failure.ts is a 341-LOC handler that processes check_suite.completed events, classifies CI failures, tracks flakiness, and upserts CI analysis comments. It has no .test.ts sibling. Every other handler in src/handlers/ that has comparable complexity has tests.

Acceptance criteria

  • src/handlers/ci-failure.test.ts covers: check_suite.completed payload parsing, missing base-ref handling, failure classification categories (each path), flakiness stat integration, comment upsert (create vs. update), error handling when GitHub API is unreachable.
  • Test uses fixtures under fixtures/webhooks/check_suite/ (create if missing).
  • bun test src/handlers/ci-failure.test.ts passes.

Files to touch

  • src/handlers/ci-failure.test.ts — create.
  • fixtures/webhooks/check_suite/ — add fixtures if missing.

Verify contract

  • Command: bun run verify:m057:s02
  • Script: scripts/verify-m057-s02.ts
  • Check IDs: ci_failure_test_present, fixture_corpus_present, all_classification_paths_covered.
  • Status codes: m057_s02_ok, m057_s02_missing_test, m057_s02_path_uncovered.

Slice M057/S03 — fork-manager.ts + gist-publisher.ts tests

What this is

Every other file in src/jobs/ has a .test.ts sibling (aca-launcher.test.ts, queue.test.ts, review-work-coordinator.test.ts, workspace.test.ts). Only src/jobs/fork-manager.ts and src/jobs/gist-publisher.ts are missing tests. Fork management deals with GitHub fork operations; gist publishing is a write-mode output path.

Acceptance criteria

  • src/jobs/fork-manager.test.ts covers: fork creation happy path, fork-already-exists idempotency, auth failure, rate-limit handling.
  • src/jobs/gist-publisher.test.ts covers: gist creation with expected filename and visibility, update vs. create flow, failure handling, any secret-scrub behavior (important for publish-path secret scanning called out in M031).
  • Both tests pass.

Files to touch

  • src/jobs/fork-manager.test.ts, src/jobs/gist-publisher.test.ts — create.

Verify contract

  • Command: bun run verify:m057:s03
  • Script: scripts/verify-m057-s03.ts
  • Check IDs: fork_manager_test_present, gist_publisher_test_present, publish_path_secret_scrub_covered.
  • Status codes: m057_s03_ok, m057_s03_missing_test.

Slice M057/S04 — Resolve prepare-agent-workspace.test.ts orphan + audit for other orphans

What this is

src/execution/prepare-agent-workspace.test.ts exists but src/execution/prepare-agent-workspace.ts does not. The test is testing nothing real. Possible paths:

  1. Source was deleted and test was left behind → delete test.
  2. Source was never written and test was committed prematurely → write source to satisfy test, or delete test.
  3. Functionality moved into another file → rename test or update to point at new source.

While we're in there, audit src/**/*.test.ts for any other orphans.

Acceptance criteria

  • The prepare-agent-workspace.test.ts ambiguity is resolved with an explicit decision: delete, write source, or rename + point at new source.
  • Repo-wide scan confirms every .test.ts has a sibling source (or justified via an allowlist).
  • bun test still passes.

Files to touch

  • src/execution/prepare-agent-workspace.test.ts — delete, rename, or keep and add missing source.
  • scripts/check-orphaned-tests.ts — new sibling-check script, wired into CI under M058/S03.

Verify contract

  • Command: bun run verify:m057:s04
  • Script: scripts/verify-m057-s04.ts
  • Check IDs: prepare_agent_workspace_resolved, no_orphaned_tests, ci_step_registered.
  • Status codes: m057_s04_ok, m057_s04_orphan_remaining.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions