Repository navigation
Description
What
The 2026-11-04 bitácora rollout PRs got the first reviews of the canonical add-to-project.yml and bitacora-status.yml (PR-Agent and CodeRabbit on hive#564). The findings are about the canonical copies, so they are handled here once, not in each consumer.
To fix (canonical copies):
-
add-to-project.yml:connect: connection refusedis classified permanent, so the job goes red without a retry, though the header calls network failures transient. -
add-to-project.yml: a secondary rate limit gets 15 s of total backoff (attempt * 5, three attempts). GitHub asks for at least one minute. -
bitacora-status.yml: the status read has no retry, so one transient error leaves the assigned issue where it was. -
bitacora-status.yml: the guard readsfieldValueByName(name: "Status")and compares the option name withBacklog. A rename of either makes the guard wrong: a renamed Status field reads as unset and can move a Blocked issue to In Progress. Compare by field and option id, as the In Progress constant already does. -
add-to-project.yml: the rate-limit warning saysbitacora-reconcile.ymlheals the drop. That workflow lives in dotfiles (daily, every repository), not in the consumer, so name it asmlorentedev/dotfilesbitacora-reconcile.yml. -
bitacora-status.yml: "Full reference: vault 00_meta/runbooks/..." points at a path a contributor to the consumer cannot open. -
CI (from the review of fix(ci): silence the GraphQL-variable shellcheck note in add-to-project #3159): the canonical-workflow actionlint test skips in dotfiles CI, which does not install actionlint. Install a pinned, checksummed actionlint in the job that runs the bats suite.
-
bitacora-status.yml(CodeRabbit on kubelab#3097): the job gates ongithub.event.issue.state, the state at assignment time. An issue that closes while the run is queued is still moved. Re-read the live state before the mutation. -
bitacora-rollout.sh: each re-run resetsci/bitacora-workflowsto the base, which closes the open PR and leaves its reviews and triage on a closed PR (kubelab#3077 → fix(harness): refresh the insights and vault-doctor records from the vault #3097 → refactor(doctor): split checkHandoffThreads under the function limits #3100). Add commits to an open PR's branch instead. -
add-to-project.yml(PR-Agent on hive#566, REAL): the retry notice goes to stdout, andPROJECT_ID=$(gh_graphql ...)captures it, so a recovered transient error fails the mutation. -
add-to-project.yml(REAL):--jqprintsnullfor a missing project, which passes the non-empty guard. -
add-to-project.yml(THEORETICAL): GraphQL reportsRATE_LIMITEDand permission errors with HTTP 200, so they take the success path. Check.errorsin the body.
Fixed by: #3166 (10, 11), #3167 (3, 4, 6, 8), #3168 (7, 9). Still open: 1, 2, 5, 12, after #3166 lands (same file).
Declined, with reason:
- Failing the job on the primary rate limit (CodeRabbit): green-on-purpose is the design (OPS-023, OPS-023: add-to-project silently drops issues from the bitácora on any API failure #809). The reconciler heals the drop, and failing would only add a red run on an
issues: openedevent nobody watches. - The "project id resolved empty" branch is dead (PR-Agent, low impact): the jq output on a
nullproject is the stringnull, so the guard is not reached. Folded into 4 as "check fornulltoo" rather than removed.
Acceptance criteria
- Items 1–12 fixed in the canonical copies, with tests in
tests/bitacora-*.batsfor 1, 2 and 4. - The rollout re-run so the open consumer PRs carry the fix.
Activity
mlorentedev commentedon Nov 5, 2026
Item 7, from the review of #3159:
tests/bitacora-canonical-consumer-rules.batstest 4 (actionlint with no ignores) skips in CI, because dotfiles CI does not install actionlint. Install a pinned, checksummed actionlint in the job that runs the bats suite, asci.ymlalready does for shellcheck, so a canonical-workflow drift fails dotfiles CI rather than only a local pre-commit.mlorentedev commentedon Nov 5, 2026
Two more, from the reviews of the re-rolled PRs:
bitacora-status.yml(CodeRabbit, Major, on kubelab#3097): the job gates ongithub.event.issue.state, which is the state at assignment time. If the issue closes while the run is queued, the run can still add it to the board and move it to In Progress. Re-read the live state before the mutation.bitacora-rollout.sh: each re-run resetsci/bitacora-workflowsto the base, which closes the open PR and opens a new one (kubelab#3077 → fix(harness): refresh the insights and vault-doctor records from the vault #3097 → refactor(doctor): split checkHandoffThreads under the function limits #3100, ts-bridge#583 → feat(secrets): strip backend unlock credentials from the run child env #610 → chore(main): release 0.23.0 #614, hive#564 → feat(mem): Claude session-start injectors (CLI-025) #566). Each consumer's review history and## Review triageare left on a closed PR. Update the branch with a new commit so the PR survives a re-run.mlorentedev commentedon Nov 5, 2026
From PR-Agent on hive#566 (current canonical, 944e6f5):
add-to-project.yml:107:gh_graphqlprints its retry notice (::warning::transient failure ...) to stdout, and the project lookup captures stdout:PROJECT_ID=$(gh_graphql ... --jq ...). One transient error followed by a successful retry leaves the notice insidePROJECT_ID, and the mutation then fails on a malformed id: a recovered error becomes a red run. Send the notice to stderr (the runner reads workflow commands from both streams) and add a test that runs the function against a stub that fails once.--jqprints the stringnullfor a missing project, so the mutation is sent withproject="null". Treatnullas empty.gh api's exit status, but GraphQL reportsRATE_LIMITEDand permission errors with HTTP 200, so those take the success path. Check.errorsin the body.test(bitacora): satisfy the dbracket and stub-pairing guards
test(bitacora): end bare [[ ]] assertions in || false
fix(bitacora): read every field value and honour the primary reset
fix(bitacora): fail the repo when the open-PR lookup fails
fix(ci): keep the bitácora retry notice out of the captured project id (
fix(bitacora): guard the status move by id, live state and retry (#3167)
fix(bitacora): keep the rollout PR open and lint canonical copies in …
fix(ci): retry refused connections and wait a minute on a secondary l…
mlorentedev commentedon Nov 5, 2026
All twelve items are merged:
The rollout ran once from main at 3550b98 (
scripts/bitacora-rollout.sh, 16 changes applied, exit 0). It opened one PR per consumer, for the owner to review and merge: mlorentedev/kubelab#3123, mlorentedev/ts-bridge#640, mlorentedev/hive#568, mlorentedev/iris#59, mlorentedev/pdf-modifier#233, mlorentedev/pollex#123, mlorentedev/yt-metrics-cli#111, mlorentedev/web#605.None of the eight repos had an open PR on
ci/bitacora-workflows, so item 9's open-PR path (commits added to the open PR, no reset) did not run live this time. Tests 18 to 21 oftests/bitacora-rollout.batscover it; the next rollout over an open PR is its first live run.mlorentedev commentedon Nov 5, 2026
Item 9's first live run: the rollout re-ran from main at 8104969 (after #3187) over the eight open consumer PRs. Each one is still open with the same number, and the compare API shows its head 2 commits ahead of the previous head and 0 behind: no reset, so no PR closed.
The same run's dry-run listed 617 open items in mlorentedev/kubelab. Before #3187, the reconciler listed at most 200 issues and 200 PRs per repository, silently, so part of kubelab was never reconciled.