Skip to content

feat(workflows): watchdog test-mode dispatch, classifier fixes, v0.15.0 re-pin - #416

Merged
kyle-sexton merged 4 commits into
mainfrom
feat/watchdog-test-dispatch
Aug 17, 2026
Merged

feat(workflows): watchdog test-mode dispatch, classifier fixes, v0.15.0 re-pin#416
kyle-sexton merged 4 commits into
mainfrom
feat/watchdog-test-dispatch

Conversation

@kyle-sexton

Copy link
Copy Markdown
Contributor

Summary

Phase 1.2+1.3 of the standards-sync audit: the watchdog caller gains the test-mode dispatch surface, three latent classifier defects are fixed, and the caller re-pins to v0.15.0 (the test-mode release). The full tracking-issue lifecycle proof ALREADY RAN against this branch — evidence below and in the plan.

Fix

  • classify-alert-failure: job-name match by suffix (the jobs API returns reusable jobs prefixed alert / … — the exact match had never hit); job-level actions: read (the jobs API 404s under contents:read-only); step conclusions read from the jobs listing (the previously targeted /actions/jobs/<id>/steps endpoint does not exist). Each was latent — this job had never executed before the proof dispatches.
  • workflow_dispatch gains test-mode + test-synthetic-candidates (string; '0' survives the explicit empty-string fallback), passed with schedule-safe defaulted expressions; concurrency group added so a dispatched proof and the hourly poll cannot race the rolling issue.
  • Re-pin to v0.15.0 (01c3295…); policy.json contract entry at the new SHA with the two new inputs (same-PR lockstep); runner-policy README rollout paragraph; stale rollout-window comment re-cut; Phase 1 plan + proof artifact ride this branch.

Verification

Pre-merge proof (branch-ref dispatches; full detail in docs/topics/standards-sync-audit/PLAN.md Phase 1.3): medley#1856 created (2 SYNTHETIC rows, run 32044893913) → updated (1 row, run 32045258184; deliberate failure classified infrastructure-failure=false, liveness SKIPPED) → closed completed (run 32045329964). node --test components/runner-policy/runner-policy.test.mjs 272/272; manifest validator green; lefthook green. The hourly cron shape is exercised by the next scheduled tick post-merge (expressions resolve to false/'1' on schedule events).

Related

Closes #415. Related: #406 (audit umbrella), melodic-software/ci-workflows#492 (the reusable's test mode).

🤖 Generated with Claude Code

https://claude.ai/code/session_013NhxMDn7vZdbs7Cq32m56M

kyle-sexton and others added 4 commits August 17, 2026 12:15
… re-pin

Standards-sync audit Phase 1.2 (plan: docs/topics/standards-sync-audit/PLAN.md,
Phase 1 sections added on this branch):

- classify-alert-failure now matches the alert job by SUFFIX: the jobs API
  returns reusable-workflow jobs prefixed with the caller job id ("alert /
  Detect ..."), verified live — the exact-equality match had never hit, so
  every deliberate post-filing failure would have misrouted to a false
  "watchdog is dark" liveness alarm.
- workflow_dispatch gains test-mode + test-synthetic-candidates (string, so
  the legal '0' close-path count survives the empty-string fallback); both
  are passed to the reusable on every run with schedule-safe defaulted
  expressions (with: keys cannot be conditionally omitted).
- concurrency group added: a dispatched proof run and the hourly poll must
  not race the rolling issue — the reusable's lookup fails closed forever
  on a duplicate-marker ambiguity.
- Caller re-pinned to v0.15.0 (the watchdog test-mode release); policy.json
  gains the contract entry at the new SHA with the two new inputs
  (same-PR lockstep rule); runner-policy README rollout paragraph appended.
- Stale rollout-window comment re-cut; Phase 1 plan + design addendum ride
  this branch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013NhxMDn7vZdbs7Cq32m56M
@kyle-sexton
kyle-sexton enabled auto-merge (squash) August 17, 2026 16:24
@claude

claude Bot commented Aug 17, 2026

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 3m 10s —— View job


Claude finished reviewing this PR

  • Gather context (PR description, changed files)
  • Read diff (origin/main...HEAD)
  • Review workflow YAML changes (classifier fixes, dispatch inputs, concurrency)
  • Review policy.json / README / plan doc changes
  • Post findings (inline + summary)

Summary

The three classifier fixes are correct and each is well-substantiated by the proof-run evidence in PLAN.md:

  • Suffix match (endswith) on the alert job name — correct; reusable-workflow jobs are returned by the jobs API prefixed with the caller job id ("alert / …"), so the prior exact-equality match could never have hit.
  • Job-level actions: read — required, since job-level permissions: fully replaces (not merges with) the workflow-level default, and the jobs listing endpoint 404s under contents:read-only.
  • Reading step conclusions from the jobs listing (.jobs[].steps[]) rather than a separate /actions/jobs/<id>/steps endpoint — correct; that endpoint doesn't exist, and the jobs API embeds steps inline.

The workflow_dispatch input threading holds up under the schedule-event edge case: github.event.inputs is null on a schedule trigger, but GitHub Actions coerces null to '' for string comparison, so test-mode correctly resolves to false and test-synthetic-candidates correctly resolves to '1' on a cron tick — matching the inline comment's claim. The explicit empty-string fallback (rather than ||) is necessary and correctly implemented, since a bare || would swallow the legal '0' that drives the close-path proof.

The new concurrency: group and the policy.json contract entry (allowlist superset, consistent with how prior contract entries already list unused-but-allowed inputs like manifest/standards-ref) both look correct.

Finding (posted inline)

One doc-drift issue in docs/topics/standards-sync-audit/design/design-resolution.md — the new Phase 1 addendum documents test-synthetic-candidates as number, but everywhere else touched by this same PR (the actual workflow_dispatch input at standards-sync-stuck-automerge-alert.yml:41-46, PLAN.md Phase 1.1 item 1, and runner-policy/README.md:766) says string, with an explicit rationale for why number was rejected (it would coerce to an empty string on cron runs). Looks like the design doc records a decision that was later reversed without being updated. See inline comment for details and a fix link.

Not verified

I don't have shell access to run node --test, actionlint, or the manifest validator in this lane, so I read the YAML/JSON/JS by hand rather than executing the test suites the PR description cites (272/272, manifest validator, lefthook). Nothing in the diff itself looked inconsistent with those claims.

@kyle-sexton
kyle-sexton merged commit 967ef48 into main Aug 17, 2026
46 checks passed
@kyle-sexton
kyle-sexton deleted the feat/watchdog-test-dispatch branch August 17, 2026 16:25
Comment thread docs/topics/standards-sync-audit/design/design-resolution.md

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7bd818ed7e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/topics/standards-sync-audit/design/design-resolution.md
@github-actions

Copy link
Copy Markdown

Claude has reviewed this PR 1 time. The lane skips further automatic reviews after 5; deleting this comment resets the count.

kyle-sexton added a commit that referenced this pull request Aug 17, 2026
## Summary

Phase 1.4 of the standards-sync audit: the watchdog lifecycle proof
passed (create/update/close/fail via dispatched test-mode runs — proof
artifact in the plan, PR #416), so the `.github` canary arms.

## Fix

`automerge: false` removed from the `melodic-software/.github` target
(absent key = armed default, schema-optional — engine treats absent as
true); the fleet-automerge header comment re-cut to the in-progress
restore state. Design addendum type nit from #416's post-merge threads
folded in.

## Verification

`bash distribution/sync-manifest.sh validate` → 38 components, 8
targets; `yq`: `.github` has no automerge key, exactly 7 targets still
carry the explicit opt-out. Merge-path safety (verified 2026-08-17,
evidence in plan 1.4): four required contexts fire on every `.github`
PR, `strict_required_status_checks_policy: false`, squash
triple-aligned, arming mutation + Workflows grant proven live under the
current pin.

**Canary trigger note:** `.github` is byte-in-sync — this flip opens no
PR by itself. The canary fires on the next organic canonical change to
one of its 7 components (recent cadence ~5/week), time-boxed 7 days
before Phase 1.5 proceeds on the proof alone. No manufactured canonical
change (it would fan PRs fleet-wide).

## Related

Closes #417. Related: #406 (audit umbrella), #416 (proof + caller).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_013NhxMDn7vZdbs7Cq32m56M

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 1.2: watchdog caller — classifier fix, test-mode dispatch, v0.15.0 re-pin

1 participant