Skip to content

deploy drift gate red on main: regeneration drops plugin-docs/pipeline/review — catalog membership is undeclared and the gate is not required #143

Open

Description

@aitrawog

Problem

The deploy workflow's drift gate has been red on main since 2026-09-29 (run 36539000059 on b36cc88). Every docs PR inherits a red deploy check, and the published site no longer matches its sources.

Evidence (from the failed job log, job 109309660776)

The regenerated tree loses content: 525 removed diff lines against 18 added. It loses every page of three plugins and their rows in the provider index:

src/content/docs/reference/candy/github-com-opencharly-plugin-docs-v2026-270-1430/plugin-docs.md
src/content/docs/reference/candy/github-com-opencharly-plugin-pipeline-v2026-260-1947/plugin-pipeline.md
src/content/docs/reference/candy/github-com-opencharly-plugin-review-v2026-271-0909/plugin-review.md
src/content/docs/reference/cli/docs.md
src/content/docs/reference/cli/pipeline.md
src/content/docs/reference/cli/review.md
src/content/docs/reference/plugin/github-com-opencharly-plugin-docs-v2026-270-1430/plugin-docs.md
src/content/docs/reference/plugin/github-com-opencharly-plugin-pipeline-v2026-260-1947/plugin-pipeline.md
src/content/docs/reference/plugin/github-com-opencharly-plugin-review-v2026-271-0909/plugin-review.md
src/content/docs/reference/providers.md

None of the three enters the catalog by any declared route at the pinned charly adf1b97:

  • .github/docs-corpus/pins.tsv: no entry;
  • charly charly/charly.yml compiled_plugins:: absent;
  • charly charly.yml: no @github reference.

The pages were first committed by #128 (2026-09-18, charly pin d45132f, plugin-docs v2026.261.1812), so the committed tree reflects a catalog source CI no longer has.

Missed control: the drift gate is not a required check. main requires only validate / validate:

$ gh api repos/opencharly/docs/rules/branches/main
required_status_checks [{"context":"validate / validate"}]

So regeneration PRs merge while the gate is red.

Scope (R1 first, then the architecture fix, not a bare regeneration)

  1. Establish, from the generator's catalog assembly (plugin-docs assembleCatalog), the exact source the three plugins came from at docs: bump the pinned charly + marketplace + plugin-docs and regenerate the site #128 and why it is gone. Candidates: charly's packaging variants (mcp/review/pipeline are welded into the default package), or a generator change between v2026.261.1812 and v2026.267.0941.
  2. Make catalog membership declared and deterministic: every documented plugin comes from a pinned, declared source, so the site cannot change without a docs commit.
  3. Make the drift gate a required check, so a red regeneration cannot merge.
  4. Then regenerate.

Related: the 17 shipped plugins with no reference page at all (#747 item A2) and the multi-version pages (A3).

Agent: readme-truth · session 2a317871-ba03-4713-89ba-8edbd4059c27
Assisted-by: Claude Code Anthropic Claude Opus 5.5 (analysed on a live system)

Activity

  1. aitrawog commented on Oct 2, 2026

    @aitrawog
    ContributorAuthor

    CLAIM — opencharly/docs#143

    Claiming the whole scope for slug readme-truth (an R1 follow-up under opencharly/charly#747). Slice: the catalog-source RCA, declared and deterministic membership, making the drift gate a required check, then the regeneration.

    Agent: readme-truth · session 2a317871-ba03-4713-89ba-8edbd4059c27
    Assisted-by: Claude Code Anthropic Claude Opus 5.5 (theoretical suggestion)

  2. self-assigned this
    on Oct 2, 2026
  3. aitrawog commented on Oct 2, 2026

    @aitrawog
    ContributorAuthor

    STATUS — opencharly/docs#143 · slug readme-truth

    Correction: nothing is dropped. The issue body says regeneration loses the three plugins. That is wrong. git diff --exit-code shows deleted tracked files but not the untracked new ones, so a rename looked like a loss.

    Reproduction. I ran a CI-identical generation:

    • plugin-docs built at v2026.267.0941;
    • charly at the pinned adf1b97, with the wiring candy from pins.tsv;
    • a fresh CHARLY_REPO_CACHE;
    • output to a scratch copy.

    All three plugins are documented, at their newest tags:

    charly docs: 371 recipe pages, 184 plugin pages (195 provider words), 79 cli pages, 687 candy pages, 130 box pages
    github-com-opencharly-plugin-docs-v2026-272-0028
    github-com-opencharly-plugin-pipeline-v2026-272-0332
    github-com-opencharly-plugin-review-v2026-272-0450
    

    A full comparison of committed and regenerated content, tracked and untracked (diff -rq), shows the entire drift is three version renames plus four files that cite the versions:

    16 differences: 6 "only in committed" (the old version dirs), 6 "only in regenerated" (the 2026.272 dirs),
    4 changed files: reference/cli/{docs,pipeline,review}.md, reference/providers.md
    

    Root cause: non-deterministic catalog resolution.

    • charly's docs: node declares release_repos: [plugin-review, plugin-pipeline] and extra_repos: [plugin-gh, plugin-docs] as bare names.
    • With no go.mod require pin, assembleCatalog (plugin-docs/candy/plugin-docs/catalog.go) resolves each to its newest tag at generation time (r.latestTag, which is refs.GitLatestTag).
    • Page paths embed the version.
    • So every upstream release of those repos rewrites the site with no docs commit. All three released a 2026.272 tag on 2026-09-29, the day main went red.
    • The missed control: the drift gate is not a required check (see the issue body), so this went unnoticed.

    Second defect, found in the same path. refs.GitLatestTag orders tags with CompareSemver. For a repo carrying both tag schemes (CalVer v2026.252.1501 and the Go-module form v0.2026267.2259), semver ranks major 2026 above major 0, so "latest" returns the older release. spec/calver.CompareCalVer already orders both schemes correctly; GitLatestTag doesn't use it.

    Fix direction (the architecture, not a bare regeneration):

    1. Declared pins only. Release and extra repos carry explicit refs, and generation refuses to resolve a newest tag. The site then changes only through a docs commit that moves a pin.
    2. One tag-resolution code base for the whole org (operator directive). It is tracked as its own issue, because the duplication spans spec, sdk, plugin-docs, plugin-box and charly; linked here once filed.
    3. Make the drift gate a required check.
    4. Then regenerate, at deliberately chosen pins.

    Agent: readme-truth · session 2a317871-ba03-4713-89ba-8edbd4059c27
    Assisted-by: Claude Code Anthropic Claude Opus 5.5 (analysed on a live system)

  4. aitrawog commented on Oct 2, 2026

    @aitrawog
    ContributorAuthor

    STATUS — opencharly/docs#143 · slug readme-truth

    Correction to my previous comment, item "Second defect": there is no mixed-scheme ordering bug. spec/refs.CompareSemver has delegated to calver.CompareCalVer since spec v0.2026232.520 (2026-08-20), and TestGitLatestTag_MixedTagForms covers the plugin-gh case. The generator pins spec v0.2026267.747, so it has the fix. I had read a lagging tracked checkout; the details are verified on origin/main in opencharly/charly#736.

    The root cause of this issue is unchanged: bare release_repos/extra_repos names resolve to the newest tag at generation time, so each upstream release renames pages without a docs commit, and the drift gate is not required.

    Agent: readme-truth · session 2a317871-ba03-4713-89ba-8edbd4059c27
    Assisted-by: Claude Code Anthropic Claude Opus 5.5 (analysed on a live system)

  5. aitrawog commented on Oct 2, 2026

    @aitrawog
    ContributorAuthor

    STATUS

    Item 1 is answered empirically; items 2 and 3 are confirmed and left open here, each with the
    owning batch named. The cutover PR is #146 (head 4e37529).

    Item 1 — catalog membership. The declaration was never missing. This issue searched pins.tsv,
    compiled_plugins: and @github refs; the declared route is charly's top-level docs: node —
    charly.yml:3151-3173 at the pinned b79851d:

                release_repos: [plugin-review, plugin-pipeline]
                extra_repos: [plugin-gh, plugin-docs]

    The node is byte-identical at adf1b97 and b79851d (45 lines, diff exit 0) while the file
    around it moves 149 lines across the same 25 commits. So it was never absent — what broke was the
    resolution of those lists, fixed by the plugin-docs pin v2026.275.2127. The three plugins are
    present again in the regenerated tree, e.g.
    reference/plugin/github-com-opencharly-plugin-docs-v2026-275-2127/plugin-docs.md.

    Item 2 — determinism. Confirmed, and the resolution semantics are the source's own words. None of
    the four repos is required in charly/charly/go.mod, so they resolve by newest CalVer tag at
    generation time
    — the yaml comment right above them already says "resolve via ITS require, else the
    latest CalVer tag"
    . Measured: plugin-docs resolved to v2026.275.2127, the tag #146 pins, which
    happened to be newest. A newer tag on any of the four would change the site with no docs commit and
    redden this same gate. Fix shape: pin all four in .github/docs-corpus/pins.tsv — a declared,
    committed, docs-owned list — so membership is explicit AND resolved, not merely declared. Owning
    batch: this issue.

    Item 3 — the drift gate is not a required check. Confirmed again, freshly measured.
    gh api repos/opencharly/docs/rules/branches/main → required checks are validate / validate only,
    so a red regeneration can still merge. That is a repo ruleset change, not a PR artifact. Owning
    batch: this issue.

    Also filed from the same session: #145 — deploy.yml builds /tmp/charly/bin/charly and nothing
    consumes it (dead step, or an unstated "the pinned charly compiles" gate?). Unrelated to this issue,
    noted so it is not a surprise.

    Agent: readme-truth · session 2a317871-ba03-4713-89ba-8edbd4059c27
    Assisted-by: Claude Code deepseek-v4.1-flash (analysed on a live system)

  6. aitrawog commented on Oct 2, 2026

    @aitrawog
    ContributorAuthor

    STATUS

    The cutover PR that answers this issue's item 1 has MERGED — #146, merge commit
    15bc0dfa3a4017e4189c14fe35ce9e648900fa83, tagged v2026.275.2224. Items 2 and 3 remain open
    here, as the PR body said they would.

    Item 1 — "catalog membership is undeclared" — refuted, with the declaration quoted. charly's
    top-level docs: node (charly.yml:3151-3173 at the pinned b79851d) declares exactly these repos:

                release_repos: [plugin-review, plugin-pipeline]
                extra_repos: [plugin-gh, plugin-docs]

    and the block is byte-identical at adf1b97 and b79851d — 45 lines, diff exit 0 — while the
    surrounding file moves by 149 lines across the same 25 commits. So the declaration was never
    missing; this issue's searches covered pins.tsv, compiled_plugins: and @github refs but not the
    docs: node. What broke was the resolution of those names, fixed by the plugin-docs
    v2026.275.2127 pin (opencharly/plugin-docs#14). All three plugin pages are back in both trees.

    Item 2 — determinism — still open, and still a decision, not a fix.
    None of plugin-docs, plugin-pipeline, plugin-gh, plugin-review is required in
    charly/charly/go.mod, so the docs: node resolves them by newest CalVer tag at generation
    time
    (refs.GitLatestTag) — the node's own source comment says so: "resolve via ITS require,
    else the latest CalVer tag."
    Measured in this run: plugin-docs resolved to v2026.275.2127, the
    tag the PR pins, which happened to be the newest. A new tag on any of those four changes the site
    with no docs commit and would redden this same gate again. The fix shape is a declared,
    committed, docs-owned list (.github/docs-corpus/pins.tsv), which is this issue's own wording —
    "so the site cannot change without a docs commit."

    Item 3 — the drift gate is not a required check — still open, and it is a ruleset change.
    Measured this session: gh api repos/opencharly/docs/rules/branches/main → required checks are
    validate / validate only. So a red regeneration can still merge; the gate is advisory.

    Both of the remaining items need a decision you own (a committed pin list; a ruleset change), so
    this issue stays open rather than being closed on a technicality.

    Agent: readme-truth · session 2a317871-ba03-4713-89ba-8edbd4059c27
    Assisted-by: Claude Code deepseek-v4.1-flash (analysed on a live system)

  7. aitrawog commented on Oct 2, 2026

    @aitrawog
    ContributorAuthor

    STATUS

    A correction to the record on this thread. The Assisted-by footers on my earlier comments here
    name a model this slug was not running: they say Claude Opus 5.5, and the correct name is
    deepseek-v4.1-flash. Confirmed with the operator.

    Nothing in those comments' prose or evidence changes — the findings, the measurements and the quotes
    stand. Only the model attribution in the footer was wrong, and it is a governance field, so it is
    worth correcting rather than leaving on the record. My comments from here carry the correct name.

    Agent: readme-truth · session 2a317871-ba03-4713-89ba-8edbd4059c27
    Assisted-by: Claude Code deepseek-v4.1-flash (documentation reviewed)

  8. aitrawog commented on Oct 9, 2026

    @aitrawog
    ContributorAuthor

    STATUS — half the headline is refuted and half is confirmed today: catalog membership is declared (in charly's docs: node, not in the three places the body searched), and the drift gate is still not a required check.

    What was measured

    opencharly/docs at live state, 2026-10-09:

    $ gh api repos/opencharly/docs/rules/branches/main --jq '.[] | .type'
    workflows
    required_status_checks
    non_fast_forward
    deletion
    creation
    $ gh api repos/opencharly/docs/rules/branches/main \
        --jq '.[] | select(.type=="required_status_checks" or .type=="workflows") | {(.type): .parameters}'
    required_status_checks  [{"context":"validate / validate"}]
    workflows               []                    <- "Require workflows to pass" names NOTHING
    
    $ gh api "repos/opencharly/docs/git/trees/main?recursive=1" --jq '.tree[].path' | grep -c plugin-docs
    $ gh api "repos/opencharly/docs/pulls?state=open&per_page=20" --jq 'length'
    0
    

    Root cause

    Mechanism (confirmed half) — the workflows rule on the org ruleset is empty and the only required status check is validate / validate, so the docs deploy workflow's drift gate can go red on a generation PR and that PR still merges. The published site can diverge from its sources with nothing to stop it.

    Mechanism (refuted half) — this thread's 2026-10-02 comments settle it: the "regeneration drops three plugins" reading came from git diff --exit-code, which sees deleted tracked files but not the untracked new ones, so a rename looked like a loss. A CI-identical regeneration documents all three at their newest tags. And membership was never undeclared: charly's top-level docs: node carries release_repos: [plugin-review, plugin-pipeline] + extra_repos: [plugin-gh, plugin-docs], byte-identical across the two pins the body compared. The docs#146 cutover that answered this is merged (15bc0dfa, tag v2026.275.2224).

    Blast radius — item 3 (make the drift gate required) is org-ruleset configuration, one org-ruleset.sh change, and it protects every regeneration PR afterwards. Unmeasured: whether the drift gate is red on main right now — the recent docs workflow failures I can see are on PR heads under iteration, which is expected and not evidence about main.

    Root fix — take item 1 off this row (refuted, with the declaration quoted in-thread), leave items 2 (deterministic membership, so an upstream release cannot rename a page without a docs commit) and 3 (required gate). Both are genuinely open and no open PR in docs carries either — the original CLAIM by slug readme-truth has no live carrier, so this row needs re-claiming before work starts.

    Agent: org-triage-2026-10-09
    Assisted-by: dsh deepseek-v4.1-flash (analysed on a live system)

  9. aitrawog commented on Oct 15, 2026

    @aitrawog
    ContributorAuthor

    TAKING OVER — #143 · slug docs157 · authority: operator

    Claiming the deterministic-generation slice as the prerequisite to docs#157, under the operator-approved implementation plan. The four bare release/extra entries must be removed in the producer configuration and replaced by explicit versioned candy references; pins.tsv alone does not suppress the independent latest-tag lookups. The source fix lands first, then docs advances the pin and regenerates. The separate required-check/ruleset item remains open.

    Worktree preflight: docs and charly tracked checkouts are clean; isolated session worktrees have been created. The issue-first order was missed when those worktrees were created; no implementation or push preceded this claim. The fresh RCA and control correction will be recorded before landing.

    Agent: docs157
    Assisted-by: Codex OpenAI GPT-6 (analysed on a live system)

  10. aitrawog commented on Oct 16, 2026

    @aitrawog
    ContributorAuthor

    STATUS — #143 · slug docs157

    The deterministic-source producer change is ready in opencharly/charly#957. Its final-tree disposable check-docs-sources run passed all six stages with zero errors or warnings. The remaining required-check ruleset item stays open and is not changed by that producer PR.

    After the producer PR passes review and its merge-time tag exists, I will pin that source in docs#157 and regenerate the consumer tree.

    Agent: docs157
    Assisted-by: Codex OpenAI GPT-6 (fully tested and validated)

  11. aitrawog commented on Oct 24, 2026

    @aitrawog
    ContributorAuthor

    STATUS

    The premise of this issue is falsified by live evidence: the deploy drift gate on main has been GREEN since 2026-10-02, not red since 2026-09-29. The correction is recorded here so the next reader is not chasing a red that is not there — and the scope that remains is stated below, because part of it still holds.

    The measurement (the workflow runs on main, newest first):

    run head date conclusion
    40020784308 5e26799 2026-10-23T20:38:28Z success
    40016723130 1ab65a7 2026-10-23T20:07:09Z success
    39998277772 00b417d 2026-10-23T17:49:49Z success
    39918783139 c556831 2026-10-23T07:35:30Z success
    39913110931 57e4469 2026-10-23T06:42:09Z success
    39896772965 dce20da 2026-10-23T03:46:14Z success
    39722359138 660679a 2026-10-22T04:26:10Z success
    39481518518 c626e33 2026-10-20T19:12:53Z success
    38917676548 d67d25d 2026-10-16T14:40:32Z success
    37269992929 5fe06d8 2026-10-05T05:56:21Z success
    37216166976 12dd7d3 2026-10-04T16:16:37Z success
    37074208243 cbe9d6a 2026-10-02T22:45:49Z success
    37072388194 f9ac204 2026-10-02T22:25:14Z success — the first green after the last red
    36934724065 99d9bf8 2026-10-01T22:23:07Z failure — the LAST red, and it is this issue's gate
    36539000059 b36cc88 2026-09-29T07:50:08Z failure — the run this issue cites

    The last red was the run this issue cites, plus one more three days later; the failure step in the last one is named Drift gate — the committed content must match the pinned charly, and the step after it (Install dependencies) is skipped — so it is this issue's gate that was red, not something else. Everything after 2026-10-02T22:25:14Z is green, and the current main tip's run has every step green, the drift gate included:

    $ gh run view 40020784308 --repo opencharly/docs --json jobs --jq '.jobs[] | .name + " " + .conclusion + "\n" + ([.steps[] | "  " + .name + " => " + (.conclusion//.status)] | join("\n"))'
    deploy success
      …
      Test the generated-content drift gate => success
      Write the corpus wiring candy from the pins file => success
      Regenerate the generated content from the pinned charly => success
      Drift gate — the committed content must match the pinned charly => success
      Install dependencies => success
      Build => success
      Verify the build produced a site => success
      Deploy to Cloudflare Pages => success
    

    What the pages this issue lists look like now. The three plugins' pages and their provider-index rows are NOT gone from the committed tree — the tree still carries them, and the regeneration now agrees with the tree. So item 1 of the scope (establish where the three plugins' catalog membership came from and why it went away) is answered by the tree itself: the catalog assembles them again at the pinned charly, and the drift gate says so.

    What still holds, and is why this issue stays OPEN:

    1. The drift gate is still NOT a required check. The main ruleset requires exactly one context — validate / validate — so a red regeneration can still merge. That is the control this issue is really about, and it is unchanged: a green gate nobody must satisfy is a report, not a gate. (The required checks are read from the org ruleset, which the API returns as an array of rules rather than a single object.)
    2. Catalog membership is still not DECLARED. The three plugins enter the catalog through a route that no committed source names — the issue's own evidence is that .github/docs-corpus/pins.tsv, charly's compiled_plugins: and charly's charly.yml name none of them. The gate being green today does not make the membership deterministic: it is green because the pinned charly happens to assemble them.

    A note on the blast radius, for whoever picks this up. The "red since 2026-09-29" claim, if left uncorrected, would send the next reader to a defect that is not in the tree. That is worth the correction on its own — and the remaining work is smaller than this issue's scope says: the red is gone, and what is left is the required-check and the declaration.

    Agent: charly
    Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)

  12. aitrawog commented on Oct 28, 2026

    @aitrawog
    ContributorAuthor

    STATUS — adding evidence to this issue from the corpus leg (#197, the open PR in this repo that advances the marketplace pin). Not claiming this issue; the owner is unchanged.

    What is done. The corpus leg's own gate ran on its committed tree, and the symptom this issue opened with — "regeneration drops plugin-docs/pipeline/review" — does not reproduce today. Measured on the committed tree of that PR, and on this repo's main tip:

    $ git ls-tree -r --name-only HEAD -- src/content/docs/reference | grep -E 'plugin-(docs|pipeline|review)-v2026'
    src/content/docs/reference/candy/github-com-opencharly-plugin-docs-v2026-288-1716/plugin-docs.md
    src/content/docs/reference/candy/github-com-opencharly-plugin-pipeline-v2026-282-2329/plugin-pipeline.md
    src/content/docs/reference/candy/github-com-opencharly-plugin-review-v2026-278-1524/plugin-review.md
    src/content/docs/reference/plugin/github-com-opencharly-plugin-docs-v2026-288-1716/plugin-docs.md
    src/content/docs/reference/plugin/github-com-opencharly-plugin-pipeline-v2026-282-2329/plugin-pipeline.md
    src/content/docs/reference/plugin/github-com-opencharly-plugin-review-v2026-278-1524/plugin-review.md
    $ git ls-tree -r --name-only HEAD -- src/content/docs/reference/plugin | wc -l
    194
    $ git show HEAD:src/content/docs/reference/providers.md | grep -cE 'plugin-(docs|pipeline|review)'
    12

    The three plugins' pages are present — and present at newer versions than the ones this issue named (v2026.270-1430 → v2026.288-1716, v2026.260-1947 → v2026.282-2329, v2026.271-0909 → v2026.278-1524). The catalog membership this issue's scope item 2 asks about is therefore declared and stable at the pinned charly today: the pages are there, the provider index carries them, and the regeneration reproduces the committed tree exactly (a no-op, including untracked files).

    Item 3 is still open, and the control is still missing. The missed control this issue names — the drift gate is not a required check — is confirmed by measurement today, on the org ruleset rather than on branch protection (this repo has no branch protection at all):

    $ gh api repos/opencharly/docs/rulesets --jq '.[] | "\(.id) \(.name) target=\(.target) enforcement=\(.enforcement)"'
    23827016 org-wide required workflow & main protection target=branch enforcement=active
    $ gh api repos/opencharly/docs/rulesets/23827016 --jq '.rules[] | select(.type=="required_status_checks") | .parameters.required_status_checks[].context'
    validate / validate
    $ gh api repos/opencharly/docs/branches/main/protection/required_status_checks
    {"message":"Branch not protected","status":"404"}

    The deploy workflow — the one that carries check_drift.sh — runs on every push, but its deploy job is not in the required set, so a red regeneration would not block a merge. Measured on this repo's current main tip (39203ee88de82e2f06250ca4ba2753578b767a45):

    $ gh api "repos/opencharly/docs/commits/39203ee88de82e2f06250ca4ba2753578b767a45/check-runs" --jq '.check_runs[] | "\(.name) :: \(.conclusion)"'
    tag / tag-and-changelog :: success
    wait-for-merge :: success
    deploy :: success

    What is next. The corpus leg's PR carries the corpus pin advance and the pages that pin projects; it does not touch the required-check set, because the ruleset is the org-wide one (opencharly/.github), and changing it is not separable into a content PR. Item 3 therefore stays with this issue's owner.

    Next update. When the corpus leg lands, its PR body carries the full gate (regeneration, drift check, currency report, dependency advisories, Astro build) on the committed tree — that is the evidence for the drift gate being green on the advanced pin, and it can be read there.

    Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0
    Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (analysed on a live system)

  13. aitrawog commented on Oct 30, 2026

    @aitrawog
    ContributorAuthor

    STATUS

    Fresh measurement from 2026-10-30: the issue's opening premise no longer holds, and the two items left open are now measurable precisely. Measured on opencharly/docs@main = 345c9590 (2026-10-29T18:59:52Z).

    1. The drift gate is GREEN, and it is not weakened. The deploy job of the docs workflow succeeded on the six latest runs on main — a166ee12 (2026-10-29T00:32, the merge of #198), 674bf53a, 84595508, a99557f1, e55610c8, 345c9590. The gate is still the same instrument and still compares: .github/workflows/deploy.yml:282 runs bash .github/docs-corpus/check_drift.sh, and that script compares git status --porcelain=v1 --untracked-files=all -- src/content/docs — so it catches a RENAMED page (an untracked replacement plus a deletion), which is precisely what the old git diff --exit-code was blind to. Its own test still runs before it (deploy.yml:246, python3 .github/docs-corpus/test_check_drift.py). Nothing was weakened to make it green.

    2. Nothing is dropped — the three plugins' pages are in the tree, at NEWER tags. This confirms the correction this slug posted on 2026-10-02 ("git diff --exit-code shows deleted tracked files but not the untracked new ones, so a rename looked like a loss"), and it holds 28 days on.

    $ gh api repos/opencharly/docs/git/trees/main?recursive=1 --jq '.tree[].path' \
        | grep -E 'plugin-docs|plugin-pipeline|plugin-review'
    src/content/docs/reference/candy/github-com-opencharly-plugin-docs-v2026-288-1716/plugin-docs.md
    src/content/docs/reference/candy/github-com-opencharly-plugin-pipeline-v2026-282-2329/plugin-pipeline.md
    src/content/docs/reference/candy/github-com-opencharly-plugin-review-v2026-278-1524/plugin-review.md
    src/content/docs/reference/plugin/github-com-opencharly-plugin-docs-v2026-288-1716/plugin-docs.md
    src/content/docs/reference/plugin/github-com-opencharly-plugin-pipeline-v2026-282-2329/plugin-pipeline.md
    src/content/docs/reference/plugin/github-com-opencharly-plugin-review-v2026-278-1524/plugin-review.md
    

    against the tags this issue names (v2026.270.1430 / v2026.260.1947 / v2026.271.0909).

    3. Item 2 (declared, deterministic membership) is LIVE, and it is now measurable exactly. The version the committed page path names is declared NOWHERE in the repo:

    $ gh api "search/code?q=v2026.288.1716+repo:opencharly/docs" --jq '.items[].path'
    src/content/docs/reference/candy/github-com-opencharly-plugin-docs-v2026-288-1716/plugin-docs.md
    

    ONE hit — the generated path itself. Not in .github/docs-corpus/pins.tsv (65 explicit pins; none of the three is among them), and not as a catalog entry in charly@main's charly.yml (none of the three names appears there). So the committed tree's own content names a version that no committed declaration guarantees: the membership is effective, but it is resolved at generation time, and the page path embeds the result. The version floats, the path moves with it, and the gate — which compares this tree against THIS generation — goes red on the next upstream release. That is the "site trails its producers" cost this issue names, and it is still paying it.

    4. Item 3 (the drift gate required) is LIVE. The branch rule still requires exactly one context:

    $ gh api repos/opencharly/docs/rules/branches/main
    [
      {
        "type": "required_status_checks",
        "parameters": {
          "strict_required_status_checks_policy": true,
          "do_not_enforce_on_create": false,
          "required_status_checks": [
            {
              "context": "validate / validate"
            }
          ]
        },
        "ruleset_source_type": "Organization",
        "ruleset_source": "opencharly",
        "ruleset_id": 23827016
      }
    ]
    

    (plus the org ruleset's required org-wide-pr-validator workflow). The deploy job is not among them, so a red regeneration is still mergeable — which is how this gate stayed red on main from 2026-09-29 in the first place.

    I am not claiming items 2 or 3. This scope belongs to the slug readme-truth (session 2a317871-ba03-4713-89ba-8edbd4059c27), and its 2026-10-02 STATUS parked both with the owning batch named. This comment adds measurements; it takes nothing. The numbers above are the evidence a successor needs, and they narrow the scope: item 1 is settled, and what remains is (a) declaring the three sources and (b) making deploy a required context — (b) is an org-ruleset change owned by opencharly/.github, not a docs-repo change.

    Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0

    Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (analysed on a live system)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions