Skip to content

Make a blocked regen reach a human instead of an inbox nobody reads - #32

Merged
kev1n merged 1 commit into
mainfrom
regen-blocked-issue
Sep 6, 2026
Merged

Make a blocked regen reach a human instead of an inbox nobody reads#32
kev1n merged 1 commit into
mainfrom
regen-blocked-issue

Conversation

@kev1n

@kev1n kev1n commented Sep 6, 2026

Copy link
Copy Markdown
Member

regen.yml fails closed on a blocked classification, uploads its evidence artifact, and then notifies nobody - there is no failure step in the workflow at all. It failed on every run from 2026-09-01T06:55Z; the only signal was GitHub's default Actions email. Five days passed with the SDKs stale at v0.36.0 while the blocked batch grew from one item to seven. (PR #31 is the acceptance of that batch.)

What this adds

A failing run opens a GitHub issue assigned to kev1n; the next healthy run closes it.

blocked / any other failure  ->  no open issue   ->  create, assign kev1n
                             ->  open, same set  ->  rewrite body only (no notification)
                             ->  open, new set   ->  comment the delta
patch / minor / none (job green) ->  open issue  ->  comment + CLOSE

Closing is the requirement, not a nicety. The upsert deduplicates by exact title, so a stale open incident would turn the next real failure into another silent comment on a thread nobody watches - the lesson recorded in the monorepo's upsert-production-incident.mjs, and the reason if: success() resolves.

if: failure() catches every path, including a failure before the classifier ever ran (that files under a single stable item so the run link still reaches a human).

The issue alone is enough to decide

Composed locally from the real blocked artifact (run 34009542245):

`regen` stopped and did not publish. The SDKs stay at the last released version until this is resolved.

## What is blocking

- company_enrichment.crustdata_v3: output required fields changed
- tiktok.video: input required fields changed
- tiktok.video_transcript_full: output.segments[].words[].confidence numeric bounds changed
- yelp.search: input.limit default changed
- youtube.channel_shorts: output.shorts[] required fields changed
- twitter.search: input.lang field removed
- youtube.search_hashtag: input.type enum member "shorts" removed

[Failing run](...)

[Evidence artifact](...) - old/new IR, release notes, and the generated diff.

## Full classifier output
...

Why the classifier CLI changed

renderSummary drops the slug, so the release notes say "output required fields changed" with no way to tell which SKU - useless as an issue. classify-cli gains --json-out, which writes the classification it already computes, and release-notes.sh threads a third path through so there is still exactly one classification run per regen.

The classification itself is untouched. generator/src/classify.ts has no diff; nothing here makes a blocked run easier to pass.

Rejected

  • Vendoring upsert-production-incident.mjs whole: its sentinel/--source production half and its sentinel-report.mjs dependency have no meaning here. Only the probe shape (fingerprint in the body, recovery closes) is reimplemented.
  • Checkly / PagerDuty wiring: out of scope, lives in third-party consoles.

Gate

pnpm check                exit 0
  dash guard              pass
  release:test            27 pass  (12 registry-version + 15 new; the script now
                                    globs scripts/*.test.mjs so the new suite gates)
  generate:check          No drift
  @anyapi/generator       160 pass (158 + 2 new classify-cli)
  @getanyapi/sdk          471 pass, tsup build, consumer-typecheck OK

Both gh paths were exercised end to end against a stub binary: issue create --assignee kev1n on the create path, issue comment + issue close on the recovery path.

🤖 Generated with Claude Code

`regen` fails closed on a blocked classification, uploads its evidence artifact,
and then notifies nobody: the workflow has no failure step at all. It failed
every run from 2026-09-01T06:55Z, and the only signal was GitHub's default
Actions email. Five days passed with the published SDKs stale at v0.36.0 while
the blocked batch grew from one item to seven.

A failing run now opens a GitHub issue assigned to kev1n, and the next healthy
run closes it. Closing is the requirement, not a nicety: the upsert reuses an
open issue by exact title, so a stale open incident turns the next real failure
into comment 17 on a thread nobody watches. Between those two states a repeat
rewrites the body (no notification for news that has not changed) and a changed
block adds one comment naming what is newly blocking and what cleared.

The issue alone is enough to decide. Its body names each blocked and removed
item WITH ITS SKU SLUG, links the failing run and the evidence artifact, and
carries the full classifier output. `if: failure()` catches every path, so a
failure before the classifier ever ran still files, under a stable single item.

The slug is the reason for the one classifier-adjacent change: `renderSummary`
drops it, so the release notes say "output required fields changed" with no way
to tell which SKU. `classify-cli` gains `--json-out`, which writes the same
classification it already computes as JSON, and `release-notes.sh` threads a
third path through. The classification itself is untouched - nothing here makes
a blocked run any easier to pass.

`scripts/upsert-regen-issue.mjs` reimplements the minimum of the AnyAPI
monorepo's `upsert-production-incident.mjs` probe shape rather than vendoring
it; `pnpm release:test` now runs every `scripts/*.test.mjs` so its 15 tests and
the registry-version suite both gate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@kev1n
kev1n merged commit 4287f35 into main Sep 6, 2026
4 checks passed
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.

1 participant