Skip to content

feat(health): ask whether the GitHub Release exists - #868

Merged
developerz-ai[bot] merged 5 commits into
mainfrom
dz/add-github-release-existence-row-to-health-md--1ec4a653
Oct 25, 2026
Merged

developerz-ai[bot] merged 5 commits into
mainfrom
dz/add-github-release-existence-row-to-health-md--1ec4a653

Conversation

@developerz-ai

@developerz-ai developerz-ai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

What

A release-tag.yml cut can fail after the annotated tag exists: the tag lands,
then gh release create fails, and the tag is left with no Release. No health
row asked about the Release, so a half-cut release stayed invisible after
ordinary pushes.

Adds a ninth health row that reads gh release view v<tag> --json tagName,isDraft,publishedAt for the last tag — the command PUBLISHING.md
already documents — and judges it three ways: Release missing (unhealthy),
isDraft true (unhealthy), published (healthy). An answer it cannot read is
X_HEALTH_ROW_UNREADABLE, never a silent green.

The brief gains the matching row, and the guard page is regenerated because
scripts/health.ts's header states the row count.

Acceptance

  • bun run scripts/health.ts --json returns a ninth row in data.rows, in the same order as .dz/briefs/health.md's table, and data.healthy is true only when all nine read healthy
  • The new row's command is gh release view v<tag> --json tagName,isDraft,publishedAt for the last tag, the tag git describe --tags --abbrev=0 --match 'v[0-9]*' origin/main names
  • The row's verdict distinguishes the three states: Release missing (gh exits non-zero, no JSON document) is unhealthy; isDraft true is unhealthy; isDraft false with publishedAt non-null is healthy
  • An unreadable gh answer for the row refuses the whole result with X_HEALTH_ROW_UNREADABLE and no data, never a silent healthy
  • .dz/briefs/health.md carries the new row, cites PUBLISHING.md's documented command for the same fact, and its two 'eight rows' statements now say nine
  • bun run scripts/guards-doc.ts --check --json reports no drift: docs/architecture/guards.md matches the regenerated health.ts header
  • bun test scripts/health.ts.test.ts passes, and a new case proves the row can go unhealthy (a missing or draft Release) — the test fails if the row's verdict is forced back to healthy
  • No new X_* code is introduced, so wiki/Error-Codes.md and bun run scripts/gate-codes.ts stay as they are

Changes

  • scripts/lib/health-rule.ts (edit) — Add the ninth row: extend ROW_IDS with 'release-exists' (append at the end so the existing eight keep their order), add a releaseExistsVerdict(input) pure function returning one RowVerdict that distinguishes three states — Release missing (unhealthy: a tag with no Release is the half-cut release release-tag.yml leaves when its gh release create step fails), Release exists and is published (healthy), and Release exists but is a draft (unhealthy: isDraft: true is not a published Release). Add the fields the verdict needs to RowVerdict (e.g. tagName, isDraft, publishedAt) so the a [trimmed]
  • scripts/lib/health-narrow.ts (edit) — Add the narrowing for the new row's gh release view document: a function that reads a parsed unknown into a small shape carrying tagName (string), isDraft (boolean) and publishedAt (string|undefined). It must never throw and never invent a field: a document that is not an object, or one whose isDraft is not a boolean, comes back undefined so scripts/health.ts can refuse the row with X_HEALTH_ROW_UNREADABLE. Note the missing-Release case is signalled by gh exiting non-zero with no JSON document, NOT by a field — the reader must carry that distinction to the judge.
  • scripts/health.ts (edit) — Wire the ninth row: add its entry to the ROW_COMMANDS map (the command it runs, for the X_HEALTH_ROW_UNREADABLE cause), its read interface and reader in defaultReaders (resolve the last v* tag with git describe --tags --abbrev=0 --match 'v[0-9]*' origin/main — the same tag row 2 uses — then run gh release view <tag> --json tagName,isDraft,publishedAt through the existing gh() helper), its judge, and one judge() call in healthAt. The judge must treat a gh non-zero exit with no JSON document as Release-missing (the half-cut release), and an unreadable tag as an unreadable row, neve [trimmed]
  • docs/architecture/guards.md (edit) — Regenerate this page from the guard headers after scripts/health.ts's header changed — run bun run scripts/guards-doc.ts --write and commit the result, so the health.ts row reads 'nine rows' and X_GUARDS_DOC_DRIFT stays green (scripts/guards-doc.test.ts asserts the committed page matches). Do not hand-edit any other row: this page is generated, never hand-edited.
  • scripts/health.ts.test.ts (edit) — Pin the new row: add its reader to the healthyReaders fixture (a published Release: tagName present, isDraft false, publishedAt non-null) so the existing 'all rows read healthy' case still passes with nine rows; add cases proving the three states — Release missing is unhealthy, a draft Release is unhealthy, a published Release is healthy — and that an unreadable gh answer (no JSON document) is X_HEALTH_ROW_UNREADABLE with ok:false and no data, never healthy. Use expect.unreachable() for a verdict the test cannot see, and make sure each new case can FAIL (a test that cannot fail is a [trimmed]
  • .dz/briefs/health.md (edit) — Add the ninth row to the brief's check table, in the same order as ROW_IDS in scripts/lib/health-rule.ts: a signal like 'the GitHub Release exists', whose Command cell is gh release view v<tag> --json tagName,isDraft,publishedAt for the last tag (the tag git describe --tags --abbrev=0 --match 'v[0-9]*' origin/main names), and whose Healthy cell states the three readings — Release missing (unhealthy: the half-cut release release-tag.yml leaves when its Release step fails), isDraft true (unhealthy), published (healthy: isDraft false and publishedAt non-null). Cite PUBLISHING.md's d [trimmed]

Verification

bun run verify passed (exit 0) in 14m 17s.


🤖 Opened by developerz.ai for task tsk_1ec4a6537237ffa2e2f1824d37a335a1 on developerz-ai/ultimate.

Raised automatically by the raw_task_triage lane.

🤖 developerz.ai, an automated agent, not a human — this PR is one slice of a stacked plan.
Dispatched automatically by the raw_task_triage lane
Model MiniMax-M3 on router.ai.developerz.ai via native, funded by account_key
Ran on box sebastian-3
Cost unknown: no list price on record for MiniMax-M3 on router.ai.developerz.ai
Run timeline run_f08982fa06d84b60bc8c60802ef92293
Part 1/1 of plan rtk_9c45d54f5434426fb4b76a61b81a64b1

A release-tag.yml cut can fail after the annotated tag exists: the tag lands,
then `gh release create` fails, and the tag is left with no Release. No health
row asked about the Release, so a half-cut release stayed invisible after
ordinary pushes.

Adds a ninth health row that reads `gh release view v<tag> --json
tagName,isDraft,publishedAt` for the last tag — the command PUBLISHING.md
already documents — and judges it three ways: Release missing (unhealthy),
isDraft true (unhealthy), published (healthy). An answer it cannot read is
X_HEALTH_ROW_UNREADABLE, never a silent green.

The brief gains the matching row, and the guard page is regenerated because
scripts/health.ts's header states the row count.

Dz-Task-Id: tsk_1ec4a6537237ffa2e2f1824d37a335a1
@developerz-ai developerz-ai Bot added dz/fleet-pr Opened by developerz.ai, an automated agent, from a fleet run. dz/model:MiniMax-M3 developerz.ai: model that wrote this bot PR. dz/provider:router.ai.developerz.ai developerz.ai: provider that served this bot PR. labels Oct 23, 2026
@developerz-ai

developerz-ai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

Resolve merge conflict on #868

Work landed on #868 — watching it toward merge.

2h13m · 26 tool calls · 17 messages

Sessions: coding run · review 1


🤖 developerz.ai, an automated agent, not a human — hv-dedicated-1 (developerz-ai[bot]) · model glm-5.3-flash on api.z.ai

@developerz-ai

developerz-ai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

A fix round is resolving this pull request's merge conflict with main. Nothing is needed from you right now.

  • Red on this head: packages (1/2), gate (unit-1), gate (e2e), gate (unit-3), windows, verify
  • What was done: Fix round tsk_2f17d26f86c2d5239df07bc22899a8ce is running: this pull request conflicts with its base branch main, so GitHub cannot merge it until the conflict is resolved.
  • What happens next: It merges the base branch into this branch, resolves the conflicting files and pushes (no force-push); CI and the review then run on the new head. If the conflict cannot be settled within the attempt budget, a person is asked.

Status for head ceb206e2dd46. This comment is updated in place.

🤖 Posted by developerz.ai — an automated agent, not a human.

@developerz-ai

developerz-ai Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor Author

File fence widened for a merge conflict resolution. The resolve_conflict follow-up for this pull request needed to change file(s) the merge left auto-merged but not conflicted, to resolve the conflict correctly — reason given: typecheck:

  • scripts/lib/health-release.ts
  • scripts/lib/health-release.test.ts

Why: The merged scripts/health.ts imports './lib/health-release' (lines 22-23, context lines vs the branch tip — the PR's own module), but the merge never brought that file into the tree. Typecheck fails: "scripts/health.ts(22,40): error TS2307: Cannot find module './lib/health-release' or its corresponding type declarations." and the same at (23,55); the unit step reds on the same missing module. The module must be restored (it holds row 9's read/verdict; health.ts and health-rule.ts are both against the 500-line filesize ceiling that also failed), with its test beside it per the repo's tests-next-to-source rule.

The platform granted it under the same area lock a new task takes (no other in-flight task holds these files), after checking the path is not a secret, CI configuration or a human-merge path.

Posted automatically by the developerz bot (AI-authored).

@developerz-ai

developerz-ai Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor Author

🟡 Reviewed

2 actionable comment(s) · grounded on your code

⏱ 2m 13s wall clock · gpt-6.1-sol via router · 3 model call(s) · 872 output token(s)

🤖 developerz.ai — automated review, running on your model and your box.

@developerz-ai developerz-ai Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review summary — 6 file(s), 1 finding(s).

Critical 0 · Major 0 · Minor 1 · Nit 0

completed · reviewer[bot]: Adds a ninth health row for the last tag's GitHub Release. The required orchestrator regression test for an unhealthy Release is missing.

1 non-blocking finding (1 minor; not posted inline)
  • scripts/health.ts.test.ts:84 test reviewer[bot]: The only new Release fixture is published, so forcing the release-exists verdict to healthy still passes this suite, contrary to the acceptance criterion. Add missing-Release and draft-Release cases asserting an unhealthy row and data.healthy false, plus an unreadable-answer case ass…
  • CI checks were not shown to the reviewer — GitHub reported no checks on the commit under review, so this review judged the diff without a build result

🤖 developerz.ai review — automated, running on your model and your box. What is this? · Reviewed by router/gpt-6.1-sol on box hv-dedicated-5 — 175k in / 680 out over 3 calls; cost unknown: no price on record for router/gpt-6.1-sol.

@developerz-ai

developerz-ai Bot commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

File fence widened for a merge conflict resolution. The resolve_conflict follow-up for this pull request needed to change file(s) the merge left auto-merged but not conflicted, to resolve the conflict correctly — reason given: unit:

  • scripts/health-dependabot.test.ts

Why: Merged scripts/health.ts has nine rows (this PR adds 'release-exists'), but main's auto-merged scripts/health-dependabot.test.ts was written against main's eight-row health script: its healthyReaders fixture (lines 23-56) pins rows 1-8 only. Every healthAt-based test in it now runs the ninth row's DEFAULT reader (git describe + gh release view subprocesses); when gh refuses in CI the row is unreadable and healthAt returns ok:false with no data.rows — 14 tests fail with "UnreachableError: ok:true always carries data.rows" (health-dependabot.test.ts:136, :215, :238; verify unit step red, 14 failed). The fixture must agree with the merged file: adding the same 'release-exists' override the branch's health.ts.test.ts already pins (tag + found release). I cannot fix this from health.ts or health-release.ts without weakening the unreadable refusal the repo's own brief mandates.

The platform granted it under the same area lock a new task takes (no other in-flight task holds these files), after checking the path is not a secret, CI configuration or a human-merge path.

Posted automatically by the developerz bot (AI-authored).

…ithub-release-existence-row-to-health-md--1ec4a653

# Conflicts:
#	scripts/health.ts.test.ts
…ithub-release-existence-row-to-health-md--1ec4a653
Follow-up intent: Fix failing CI on #868

Dz-Task-Id: tsk_519faf3d2e84fdc95aa357e25ee65f42
@developerz-ai

developerz-ai Bot commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

File fence widened for a merge conflict resolution. The resolve_conflict follow-up for this pull request needed to change file(s) the merge left auto-merged but not conflicted, to resolve the conflict correctly — reason given: typecheck + unit (X_TYPECHECK_FAILED / X_TEST_FAILED):

  • scripts/lib/health-release.ts
  • scripts/lib/health-release.ts.test.ts
  • scripts/lib/health-readers.ts

Why: Resolving scripts/health.ts requires both files. (1) The ours side of the conflict imports ./lib/health-release (row 9's read/judge/command, per health-rule.ts's header), but that module was never committed to the PR branch — the gate now fails with scripts/health.ts(33,60): error TS2307: Cannot find module './lib/health-release', so it must be created. (2) Main's conflict side moved the default reader table into scripts/lib/health-readers.ts (its header: "The readers live in scripts/lib/health-readers.ts"), so row 9's reader must join THAT table — the gate fails with scripts/health.ts(287,33): error TS7053: '"release-exists"' can't be used to index type 'HealthReaders' and error TS2353: ''release-exists'' does not exist in type 'HealthOverrides' in scripts/health.ts.test.ts(86) and scripts/health-dependabot.test.ts(58), both of which are in my set and override that row. health-release.ts.test.ts is the module's tests-beside-source file (repo convention).

The platform granted it under the same area lock a new task takes (no other in-flight task holds these files), after checking the path is not a secret, CI configuration or a human-merge path.

Posted automatically by the developerz bot (AI-authored).

…ithub-release-existence-row-to-health-md--1ec4a653

# Conflicts:
#	scripts/health.ts

@developerz-ai developerz-ai Bot left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review summary — 7 file(s), 2 finding(s).

Critical 0 · Major 0 · Minor 2 · Nit 0

[bot] Completed review: adds a ninth health row for missing, draft, and published GitHub Releases. Malformed publication metadata is classified as unhealthy instead of refusing the unreadable result. [bot] completed: The missing-Release test does not exercise the required failing subprocess result.

2 non-blocking finding(s) below major (no thread on a re-review — only blocking findings open threads)
  • scripts/lib/health-release.ts:66 minor · bug [bot] A document with publishedAt: 42 becomes an unhealthy verdict rather than X_HEALTH_ROW_UNREADABLE because narrowRelease (scripts/lib/health-narrow.ts:216) converts invalid types to undefined. Validate publishedAt as string or null before accepting the document, preserving null as the unpubli…
  • scripts/lib/health-release.ts.test.ts:131 minor · test [bot] The missing-Release test uses stubRunner(), which returns ok:true and code:0, so it passes even if a non-zero gh exit is incorrectly refused before its output is classified. Make this stub return ok:false and code:1 with release not found, and retain the missing-lookup assertion.

🤖 developerz.ai review — automated, running on your model and your box. What is this? · Reviewed by router/gpt-6.1-sol on box hv-dedicated-ci-1 — 155.4k in / 872 out over 3 calls; cost unknown: no price on record for router/gpt-6.1-sol.

@developerz-ai
developerz-ai Bot merged commit 02e0c55 into main Oct 25, 2026
16 checks passed
@developerz-ai
developerz-ai Bot deleted the dz/add-github-release-existence-row-to-health-md--1ec4a653 branch October 25, 2026 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dz/fleet-pr Opened by developerz.ai, an automated agent, from a fleet run. dz/model:MiniMax-M3 developerz.ai: model that wrote this bot PR. dz/provider:router.ai.developerz.ai developerz.ai: provider that served this bot PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants