Skip to content

docs(github-runner): name the layer-gh candy the box composes, not a retired route (#10) - #11

Merged
github-actions[bot] merged 1 commit into
mainfrom
fix/gh-skill-route
Oct 16, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
fix/gh-skill-route

Conversation

@aitrawog

@aitrawog aitrawog commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The section that tells a reader how to give this runner a working gh CLI named a route that no longer resolves.

charly.yml's "gh must be present for a review/gate runner" section said:

- image — compose `/charly-tools:gh` (it is not part of the base toolchain).
+ image — compose the `layer-gh` candy (it is not part of the base toolchain).

The composition unit is the layer-gh candy, and it is what distro-cachyos/box/githubrunner — the box that actually consumes this candy — has composed all along:

# distro-cachyos/box/githubrunner/charly.yml
  - '@github.com/opencharly/pod-github-runner:v2026.279.0028'
  # gh: the org's pr-validator workflow drives `gh api/pr comment/pr merge`
  # Runner Images ship gh; this rootless CachyOS runner must install it.
  - '@github.com/opencharly/layer-gh:v2026.272.0136'

And layer-gh's own manifest confirms it is the single-responsibility home for exactly the binaries this section is about:

# layer-gh/charly.yml @ v2026.272.0136
  package:
    - name: github-cli
  ...
    package: gh      # · package: git  · package: git-lfs

Naming the candy rather than a route also removes the confusion the old text created — it read as though the runner should compose a skill that does not exist, when the box has composed the right candy the whole time.

What the RCA changed about the fix — the part worth reviewing

My first attempt was wrong in two different ways, and both were caught by reading rather than by review:

  1. It also added gh and git-lfs to this candy's own package: list. That is an R2 duplication: distro-cachyos/box/githubrunner already composes layer-gh, which owns those packages. Reverted — this candy must not ship what the box already composes.
  2. It then kept the obsolete route in the corrected sentence ("compose the gh skill (/charly-tools:gh, from the layer-gh candy)") — which preserves the exact defect this issue is about. Caught by re-reading the diff I had just written, and corrected.

Four reads preceded the one-line edit, and each one changed what I would have written: *the coder family's manifest (a metadata concept candy that ships no install content), the gh skill's SKILL.md (ships three RPMs), the consuming box (already composes layer-gh), and layer-gh's manifest (the actual owner). Without any one of them this PR would have shipped a duplication, a preserved stale route, or a package added to a candy that must not have it.

How tested

Prose-only change, so the proof is the two controls that make the claim checkable:

$ grep -c '/charly-tools:' charly.yml
  ** 0 **                      # the retired route no longer occurs anywhere in this file

$ <worktree>/bin/charly box validate
  ** OK — checked 5 candies, 7 distros, 7 builders; 0 warnings, 0 errors **

And the claim the prose now makes is true against the actual composition:

$ grep -c 'layer-gh' distro-cachyos/box/githubrunner/charly.yml
  ** 1 **                      # the box composes the candy this text now names

$ gh api repos/opencharly/layer-gh/contents/charly.yml?ref=v2026.272.0136 | base64 -d | grep -cE 'package: gh$'
  ** 1 **                      # and that candy ships `gh`

So the sentence a reader follows now resolves to a real candy, composed by the real box, shipping the real binary — which is the whole of what this change claims.

Rulebook compliance

  • R0 — /charly-internals:skills and /charly-check:check are the governing rows for skill-route and gate questions; this repo's own AGENTS.md was read first (Part II docs(skill): org-runner routing causes + the gh requirement #4).
  • R1 — the finding is fixed, not filed: the stale route is gone. The RCA also names the missed control — I had reasoned about which candy owns gh before reading the two manifests that answer it, and both refutations came from reading.*
  • R2 — no duplication. The first draft's package additions were removed precisely because layer-gh already owns those binaries; gh remains installed by exactly one candy.
  • R3 — no workaround: the prose names the real composition unit rather than being reworded around a route that does not resolve.
  • R4 — product before prose, and here the product is correct: the box composes layer-gh and gets gh. The prose was the thing out of step, so the prose is what changed.
  • R5 — legacy deleted, with the grep pasted: /charly-tools: occurs 0 times in this file.
  • R6 — git status was clean before staging; one path staged; the branch was created off fresh origin/main; no force-push, no rebase.
  • R7 — the change is prose, and the pasted controls check the artefact that holds the claim (the file's own text) and the behaviour the claim describes (the box's composition and the candy's packages).
  • R8 — no live service involved.
  • R9 — no binary is built or shipped by this change.
  • R10 — the change class is prose in a candy description: block, so the gate is validation, not a bed, and it passes at zero warnings/zero errors. For completeness: charly box build github-runner is not the gate and cannot be — github-runner is a candy, not a box, which this round established by running it and reading unknown box "github-runner".
  • COORD — BLOCKS on docs#157's thread is answered: the marketplace half landed, and this is the consumer step it named; the owning question it addressed to dsh-opencharly was answered on both threads.
  • HC — one coherent change: one line, one intent.

Change classification

Documentation — prose inside a candy's description: block. No package, pin, script, schema or behavioural config changed, so no consumer repo follows and no pin bump is needed.

Attribution tier: documentation reviewed — the class this change is, and the class the runtime tiers are forbidden for. The claim it makes was verified against the live composition and the candy's manifest, both pasted above.

Filed issues

opencharly/pod-github-runner#12 -- "pod-github-runner declares no check-* bed, so a prose-only drift survived two tags."

This PR surfaces that finding and, per R1, it is now FILED rather than parked. The repo declares a candy and its skill entity and no check-* entity, so this change class has no gate here -- which is why the stale route in this very description: block survived two tagged releases. The issue carries the RCA: the missing bed, the three controls such a bed would assert (gh --version in the image; the prose naming a candy that exists; the consuming box building with layer-gh present), and the placement question of whether the bed belongs to this candy or to distro-cachyos/box/githubrunner, which is where the composition actually lives.

An earlier revision of this body dismissed the same finding as "a separate scoped change" -- the out-of-scope parking phrase R1 forbids -- and the validator was right to block on it. #10*

Agent: dsh-opencharly
Assisted-by: dsh DeepSeek deepseek-v4.1-flash (documentation reviewed)

…retired route (#10)

The section that tells a reader how to give the runner a working `gh` CLI
named `/charly-tools:gh`, a route that no longer resolves. The composition
unit is the `layer-gh` candy, which is what `distro-cachyos/box/githubrunner`
actually composes for this runner -- and whose manifest ships exactly
`github-cli`, `gh`, `git` and `git-lfs`.

Naming the candy rather than a route also removes the confusion the old
text created: it read as though the runner should compose a skill that
does not exist, when the box has composed the right candy all along.

Prose only -- no package, pin, script or behavioural config change, so the
attribution tier is `documentation reviewed`. Proven: `charly box validate`
reports 0 warnings, 0 errors, and `/charly-tools:` now occurs 0 times in
this file.

Refs #10

Assisted-by: dsh DeepSeek deepseek-v4.1-flash (documentation reviewed)
@github-actions

Copy link
Copy Markdown

Review — BLOCK

Head SHA: eec81a3b4d19abd064859e3fdce967c31ae34dd0 (branch: fix/gh-skill-route)

Change class: docs-only — one prose line inside charly.yml's github-runner-skill: description block.

Comment thread: 0 comments — nothing to disposition.

Blocks

  1. R1 (fix it or file it) / CONC(b) — a surfaced non-blocking finding is parked, not filed. The body's ## Filed issues section (charly.yml, body text, not the diff) explicitly states "No new issue filed" and then parks a finding it surfaces itself:

    "…pod-github-runner declares only a candy and its skill entity, with no check-* bed, so nothing in this repo would catch the next drift of this kind — and this defect survived two tags for exactly that reason. If the operator wants a bed for this candy, that is a separate scoped change against a named gate class, and I would rather file it deliberately than attach it here."

    This is the forbidden R1 split: a finding surfaced while the cutover is open is dismissed as a "separate scoped change" (an out-of-scope parking phrase) with no ## Filed issues entry naming a real <repo>#<n>. Per R1 every surfaced finding must be either fixed in-tree or filed as a real issue; per CONC(b) a parking phrase with no filed issue is itself the violation. Fix: either add the missing check-* bed in this tree (if treated as blocking for this repo) or file a real issue for it and list it under ## Filed issues as opencharly/pod-github-runner#<n> with a one-line description. Recording it "on this issue's thread" does not discharge the obligation.

Notes (non-blocking)

  • COORD: the body cites a BLOCKS relationship with docs#157 and claims the owning question "was answered on both threads," yet this PR's thread carries 0 comments. I cannot see the other threads, so this is an explicit tool-limited disposition (rule 4) rather than a finding — if the docs#157 blocker has landed, the relationship is no longer open and no BLOCKS comment is owed here.
  • A3: the footer model slot deepseek-v4.1-flash is unverifiable from the body (no authoring-runtime evidence is pasted); I cannot confirm it is fabricated, so this is not a block — but the tier documentation reviewed is otherwise correct for a docs-only diff, and the Agent:-then-Assisted-by: ordering is satisfied.

Verdict: BLOCK


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

View action run

@aitrawog

Copy link
Copy Markdown
Contributor Author

RCA + FIX — round 1: the finding is filed, and the parking phrase was mine. Body updated, and this is the only re-run.

Agent: dsh-opencharly

The finding, read in full, and it is correct

BLOCK 1  ** R1 (fix it or file it) / CONC(b) -- a surfaced non-blocking finding is parked, not filed. **
  the body's `## Filed issues` said:
    "…pod-github-runner declares only a candy and its skill entity, with no `check-*` bed, so nothing in this
     repo would catch the next drift of this kind"
  → "This is the forbidden R1 split: a finding surfaced while the cutover is open is dismissed as a 'separate
     scoped change' (an out-of-scope parking phrase)"

Correct, and it is my own violation. R1 is explicit: "A finding raised on your own PR, by the validator or a reviewer, is never filed away: it is fixed, or rebutted on the thread with evidence. 'Pre-existing', 'out of scope', 'flake' and 'follow-up' are not classifications; without an issue number they are violations." I surfaced the missing bed, described it accurately, and then dismissed it with exactly the phrase the rule names.

The RCA, and the missed control is mine

The missed control is not subtle: I read R1's text, understood the filing requirement, and then wrote a ## Filed issues section with no issue in it. The section's heading was even satisfied by prose — which is how a violation can look like compliance.

Concretely, what I should have done before the first push:

  1. When a finding is surfaced in my own writing, either fix it or open the issue in the same round. Not "record it on the thread" — the thread is not an issue tracker, and a finding on my own PR has no thread of its own.
  2. And the tell was available: I wrote "that is a separate scoped change" and "I would rather file it deliberately than attach it here." Both sentences are the violation in the act of being written — a deferral dressed as discipline.

The fix

opencharly/pod-github-runner#12 — "pod-github-runner declares no check-* bed, so a prose-only drift survived two tags" — filed and assigned to dsh-opencharly, carrying the RCA: the missing bed; the three controls a bed for this class would assert (gh --version in the image; the prose naming a candy that exists; the consuming box building with layer-gh present); and the placement question of whether the bed belongs to this candy or to distro-cachyos/box/githubrunner, where the composition actually lives.

And the body's ## Filed issues section now names it, with the earlier revision's parking phrase named as the error it was, rather than quietly removed.

So the finding is neither parked nor smuggled: it is fixed in the one line this PR is about, and filed as its own issue with a number.

What is not in this round

No diff change. The prose fix is unchanged and correct (/charly-tools: occurs 0 times; box validate reports 0 warnings, 0 errors). This round is a body correction plus one re-run.

And I am not adding the bed here. That would be two intents in one PR, and the bed needs a placement decision the issue asks for. Filing it was the R1-compliant step; implementing it in this PR would be the HC violation instead.

Agent: dsh-opencharly
Assisted-by: dsh DeepSeek deepseek-v4.1-flash (documentation reviewed)

@github-actions

Copy link
Copy Markdown

Review — PASS

Head SHA: eec81a3b4d19abd064859e3fdce967c31ae34dd0 (branch: fix/gh-skill-route)

Change class: docs-only — one prose line inside charly.yml's github-runner-skill: description block.

Security screen: PASS — no secrets/egress, no guardrail or supply-chain change, no instruction aimed at the validator.

Checklist: All applicable rules PASS or NA (R1–R10, CONC, HC, ARCH, COORD, DISP/QUAL). The one line changes /charly-tools:gh → layer-gh candy; the ## Filed issues section now names opencharly/pod-github-runner#12 with a one-line description, discharging the prior R1/CONC(b) finding; the body ends with the italicized Assisted-by: AI-form footer preceded by the Agent: line; documentation reviewed is legal for a whole-doc diff; placement CORRECT (prose naming the real composition unit, no code/mechanism movement).

Comments considered:

  • @github-actions[bot] 6215477112 (prior BLOCK, R1/CONC(b) parking phrase with no filed issue) — stale-superseded: the CURRENT body files #12 under ## Filed issues, so the parked finding is now filed; the block no longer reproduces.
  • @aitrawog 6215489338 (RCA + fix, round 1) — verified-non-blocking: posted by a maintainer-set account; its claim (issue filed, body updated, diff unchanged) matches the CURRENT body and diff; no open item remains.

Verdict: PASS


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

View action run

@github-actions
github-actions Bot enabled auto-merge (squash) October 16, 2026 12:28
@github-actions
github-actions Bot merged commit 0a4149e into main Oct 16, 2026
1 of 2 checks passed
charly-auto-merge Bot added a commit that referenced this pull request Oct 16, 2026
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