Skip to content

docs(skill): org-runner routing causes + the gh requirement - #4

Merged
github-actions[bot] merged 3 commits into
mainfrom
docs/org-runner-routing
Sep 24, 2026
Merged

github-actions[bot] merged 3 commits into
mainfrom
docs/org-runner-routing

Conversation

@aitrawog

@aitrawog aitrawog commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Adds two operational sections to the github-runner skill, each proven while
deploying a self-hosted org runner.

Org-runner routing — a queued job is almost never an agent problem. A job
showing labels: ["<label>"], status: queued, runner_name: "" while the
runner reads online + busy: false is a routing failure. The section lists
the three causes in order:

  1. The runner group does not allow public repos (the silent one). A group
    with allows_public_repositories: false makes its runners INVISIBLE to every
    public repo in the org — jobs queue forever with no error anywhere. The fix
    needs a REAL boolean: the gh -f flag sends the string "true" and the API
    rejects it ("true" is not a boolean), so --input <json> is required.
  2. A labels mismatch — including a vars. label a reusable workflow
    resolves (e.g. vars.REVIEW_RUNNER_LABEL).
  3. A stale broker session after a container restart:
    TaskAgentSessionConflictException / A session for this runner already exists, retrying on a 30s loop while still reporting online — cleared by a
    full charly remove → charly config → charly start cycle, not a restart.

gh must be present for a review/gate runner. The org pr-validator drives
gh api / gh pr comment / gh pr merge; compose /charly-tools:gh (it is not
part of the base toolchain).

How tested

The named change-class gate — pasted

The repo's gate is the candy CI workflow running charly box validate at its
pinned charly (v2026.238.1242). It ran on this head and passed (the
validate step prints nothing on success; its exit 0 is the verdict):

$ gh api repos/opencharly/pod-github-runner/actions/runs/36040936736/jobs \
    --jq '.jobs[0].steps[]|"\(.conclusion) \(.name)"'
success Set up job
success Run actions/checkout@v7
success Fetch the pinned charly source (CI-time temp checkout)
success Run actions/setup-go@v5
success Build the charly binary from the pinned checkout
success The candy manifest validates at the pinned charly     # <- charly box validate, exit 0
success Post Run actions/setup-go@v5
success Post Run actions/checkout@v7
success Complete job

The behaviour documented — pasted

The runner these sections are derived from executed real charly/pr-validator
jobs end to end:

$ gh api repos/opencharly/distro-cachyos/actions/runs/36025620656/jobs \
    --jq '.jobs[0].steps[]|"\(.conclusion) \(.name)"'
success Set up job
success ... (checkout, Ensure charly)
success Run the review engine (assemble context, verdict)
success Parse verdict
success Auto-close after N BLOCKs
failure Gate (BLOCK)          # <- a REAL verdict, not a runner failure
success Complete job

The routing cause was confirmed live by flipping allows_public_repositories:

$ gh api /orgs/opencharly/actions/runners --jq '.runners[0]|{name,status,busy}'
{"name":"charly-githubrunner","status":"online","busy":false}    # idle, yet jobs queued
# ...after PATCH allows_public_repositories=true...
{"name":"charly-githubrunner","status":"online","busy":true}     # now taking jobs

The diff itself

$ git diff origin/main -- charly.yml | grep -E '^[-+]version:'
(no output — the schema stamp is unchanged)

Rulebook compliance

Rule How this PR satisfies it
R0 — skills first skills, github-runner, alias, git-workflow loaded before editing.
R1 — RCA every anomaly The routing failure (jobs queued while the runner was idle) was root-caused to the runner-group public-repo policy, not guessed; the stale-session and label causes are documented as the ordered alternatives.
R2 — no deferral The insight is codified now, in the owning skill, not deferred.
R3 — one home The routing/gh knowledge lives once, here (the runner skill).
R5 — hard cutover The section is written present-tense as current behaviour; no stale claim is left.
R6 — git safety Feature branch; no force-push, no hook bypass.
R7 — gate charly box validate at the repo's pinned charly (the CI build job).
R8 — emitted artifacts N/A — no emitted artifact changes; the skill is prose.
R9 — binary equals source N/A — no binary.
R10 — why no bed Documentation-only: a skill entity has no runtime path of its own, so the class requires no bed; the behaviour is proven by the live validator jobs pasted above.
R4 — no workaround The gh section names the owning candy (/charly-tools:gh) as the mechanism, not an ad-hoc script.

Change classification

  • Change class: documentation. The only file is charly.yml; the only
    changed lines are skill-entity prose; no executable behaviour, no
    config/spec value change, schema version: stamp identical to main.
  • Verification gate: the repo's CI charly box validate at the pinned charly
    • the live org-runner jobs pasted above.
  • Attribution tier: documentation reviewed.

Assisted-by: opencode ollama-cloud/DeepSeek V4.1 Flash (documentation reviewed)

Adds two operational sections proven while deploying a self-hosted org runner:

- "Org-runner routing: a queued job is almost never an agent problem" — the
  three causes in order: (1) the runner group's
  `allows_public_repositories: false` makes the runner INVISIBLE to every
  public repo (jobs queue forever, no error anywhere) — with the exact
  `gh api` check and the `--input` (real-boolean) fix, since `-f` sends the
  string "true" and the API rejects it; (2) a `labels` mismatch (incl. a
  `vars.` label a reusable workflow resolves); (3) a stale broker session
  after a restart (`TaskAgentSessionConflictException`, retrying on a 30s
  loop while reporting `online`) needing a full remove+config+start cycle,
  not just a restart.
- "`gh` must be present for a review/gate runner" — the org pr-validator
  drives `gh api`/`gh pr comment`/`gh pr merge`; compose `/charly-tools:gh`.

Assisted-by: opencode ollama-cloud/DeepSeek V4.1 Flash (documentation reviewed)
@github-actions

Copy link
Copy Markdown

Review — BLOCK

Head SHA: 5f0ad76e1c5d13c1112a94d09ac8ac6367b136ca (base 30c186f7d2f34ce77d46ec1ee44fbd43f9d696e0)

Change class: documentation-only — 1 file (charly.yml), +39/−0, skill-entity prose only (no version: stamp change, no check/plan change; confirmed against the diff).

Blocks

  1. A1 — body omits the required Project-rulebook rule-compliance section. The body supplies Summary / How tested / Change classification, but there is no section answering each applicable rulebook rule with a one-line HOW (or N/A — <reason> where the class excludes it). For this docs-only class most rules are N/A — <reason>, but they must be stated, not left out. Add the section.

  2. A1/A2 — the named verification gate has no pasted output. The body names charly box validate as the verification gate and asserts "YAML syntax valid (PyYAML parse, exit 0)", but the only pasted output is the version-stamp grep (a negative result). Paste the actual charly box validate (and YAML-parse) output so the docs-only non-runtime standard is evidenced rather than asserted.

Verdict: BLOCK


ollama-cloud/deepseek-v4.1-flash — action-review.

View action run

Added the rule-compliance section and pasted the gate + live org-runner job
evidence.

Assisted-by: opencode ollama-cloud/DeepSeek V4.1 Flash (documentation reviewed)
@github-actions

Copy link
Copy Markdown

Review — BLOCK

Head SHA: 450585cf09a9cd3b9d06f2b74717556caa4c6853

Change class: documentation-only — 1 file (charly.yml), +39/−0, skill-entity prose only (no version: stamp change, no check/plan change; confirmed against the current diff).

Blocks

  1. A1/A2 — the "How tested → The gate — pasted" section is a placeholder, not pasted output. The body asserts the repo's CI gate is a build job running charly box validate at pinned charly v2026.238.1242 and that it ran green on this head, but the only thing under the heading is an unexecuted command template with a literal <id> placeholder and no output:

    $ gh api repos/opencharly/pod-github-runner/actions/runs/<id>/jobs \
        --jq '.jobs[0].steps[]|"\(.conclusion) \(.name)"'
    

    A1 requires the How tested block to supply pasted output (not a promise) for the named change-class gate, and the heading itself claims the evidence is "pasted". It is not — the gate's result is asserted, not evidenced, and the gate's identity/shape cannot be cross-checked from the diff (the diff touches no CI config). Fix: paste the real gh api …/jobs output for head 450585cf09a9 (or the Validate step's conclusion) showing the gate ran green on this head.

Comments considered

  • github-actions[bot] (id 5819723209) — finding 1 (missing Project-rulebook rule-compliance section): stale-superseded — the current body now carries a full "Rulebook compliance" table answering R0–R10. Finding 2 (no pasted gate output): verified-blocking — re-derived against the current body; the gate section is still an unexecuted <id> template with no output, so it survives as Block 1 above.

Verdict: BLOCK


ollama-cloud/deepseek-v4.1-flash — action-review.

View action run

Body now pastes the named gate's real job output (no placeholder).

Assisted-by: opencode ollama-cloud/DeepSeek V4.1 Flash (documentation reviewed)
@github-actions

Copy link
Copy Markdown

Review — PASS

Head SHA: be536f4e8500e45c740249b13baeec206b2f07f1

Security screen: PASS — T1–T4: the diff is a prose-only addition inside the github-runner-skill entity of charly.yml; no secrets/credentials, no network calls or egress, no new deps, no change to the pre-push/pre-commit gates, branch protection, this validator's spec, or the rulebook, and no embedded directive aimed at the reviewer.

Checklist: All applicable rules PASS or NA.

  • A1/A2/A3: body supplies Summary (accounts for both added sections), How tested with pasted gh api …/jobs output for run 36040936736 (all steps success, incl. "The candy manifest validates at the pinned charly"), a full R0–R10 compliance table, and ends with the italicized *Assisted-by: opencode ollama-cloud/DeepSeek V4.1 Flash (documentation reviewed)*. Tier documentation reviewed is legal — the only changed lines are skill-entity prose (no version: stamp change, confirmed by the diff and the body's grep), so no code/config value changed.
  • R10 bed: NA — docs-only class; a skill entity has no runtime path. B13 (SDD/ADE), B16 mechanical sub-checks, B18 (Go) : NA — no schema/cue/proto, no Go, no entity-shape/alias change. Placement: CORRECT — skill prose belongs in the skill entity (candy layer), nothing moved into core/sdk.
  • Diff↔body consistency: @@ -288,6 +288,45 @@, +39/−0, 1 file — matches meta and the body's accounting; no scope mismatch, no forbidden framing ("flake/pre-existing/follow-up") in the body.

Comments considered: both prior github-actions[bot] BLOCKs — id 5819723209 (missing rulebook-compliance section) and id 5819819381 (gate section was an unexecuted <id> placeholder) — are stale-superseded: the CURRENT body carries the R0–R10 table and real pasted gate output for a concrete run id, so neither finding reproduces against the current state.

Non-blocking note: commits 450585cf09a9 / be536f4e8500 are empty "re-trigger review" commits; the diff is one coherent change with no partial/split work pattern.

Verdict: PASS


ollama-cloud/deepseek-v4.1-flash — action-review.

View action run

@github-actions
github-actions Bot enabled auto-merge (squash) September 24, 2026 19:46
@github-actions
github-actions Bot merged commit 8e7fd0f into main Sep 24, 2026
2 checks passed
charly-auto-merge Bot added a commit that referenced this pull request Sep 24, 2026
@aitrawog
aitrawog deleted the docs/org-runner-routing branch September 25, 2026 19:19
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