Skip to content

docs(corpus): advance the corpus submodule to the corpus that carries the armed ! marker rule (#209) - #210

Merged
github-actions[bot] merged 1 commit into
mainfrom
feat/corpus-pin-209
Oct 29, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
feat/corpus-pin-209

Conversation

@aitrawog

Copy link
Copy Markdown
Contributor

Summary

Closes #209

Head 6f1871c54777069f4802dc69350008b57067b312 — the commit this PR pushes: 3 files changed, 15 insertions(+), 1 deletion(-)

This repo's marketplace submodule — the guidance corpus the site's recipes/** pages project — advances 75e1d4a → f46285f9: the head opencharly/marketplace's merged main serves. The advance carries TWO AUTHORED BODIES, so the site's generated half does move, and this PR ships the regenerated pages with the pin. The two pages that move are recipes/internals/cutover-policy.md (+2) and recipes/internals/git-workflow.md (+12).

The scope was derived from the producer's own report, not written by hand. The corpus's own scripts/consumer-currency.sh names this repo as the consumer that is behind — an advance available NOW, in this repo:

$ cd marketplace && bash scripts/consumer-currency.sh
consumer-currency: 2 consumer(s) read, 2 behind, 0 not-on-the-served-line, 0 undecidable, 0 unreadable (merged main: f46285f)
  opencharly/docs  marketplace  75e1d4a  behind — 6 commit(s) behind the corpus's merged main; an advance available NOW (a pin-bump PR in that consumer's repo)
  opencharly/opencharly  marketplace  7836546  behind — 4 commit(s) behind the corpus's merged main; an advance available NOW (a pin-bump PR in that consumer's repo)

(The report reads each consumer's RECORDED pin over the public API, so it keeps naming this repo as behind until this PR lands. It names the umbrella's consumer leg as behind too — that leg is opencharly/opencharly#810, and this repo's advance does not wait for it: the two legs consume the same corpus head and neither depends on the other.)

What the advance carries, measured. The corpus's diff between the two pins is EIGHT paths, and TWO of them are authored bodies:

$ git -C marketplace diff --stat 75e1d4a1379daf164a1ed2bc9c0678ad1ed20312 f46285f93ab1d0e44674dff0ac9a9360e9d84980
 CHANGELOG/2026.302.1434.md               | 354 ++++++++++++++++++++++++++++++
 CHANGELOG/2026.302.1609.md               | 356 +++++++++++++++++++++++++++++++
 CHANGELOG/2026.302.1755.md               | 179 ++++++++++++++++
 candy/charly-marketplace/charly.yml      |  16 +-
 internals/skills/cutover-policy/SKILL.md |   2 +
 internals/skills/git-workflow/SKILL.md   |  12 ++
 scripts/pr_body_lint.py                  | 206 +++++++++++++++++-
 scripts/pr_body_lint_test.py             | 258 +++++++++++++++++++++-
 8 files changed, 1371 insertions(+), 12 deletions(-)

$ git -C marketplace diff --name-only 75e1d4a1379daf164a1ed2bc9c0678ad1ed20312 f46285f93ab1d0e44674dff0ac9a9360e9d84980 -- '*/SKILL.md' '*/references/*'
internals/skills/cutover-policy/SKILL.md
internals/skills/git-workflow/SKILL.md

The two authored bodies are internals/skills/cutover-policy/SKILL.md (+2) and internals/skills/git-workflow/SKILL.md (+12) — the umbrella's own general-guidance skills, republished from the umbrella's tag v2026.302.1338 (opencharly/opencharly#805), which stated the ! subject marker's relation to a PR body's breaking-change answer. Those bodies project into this site's recipes/internals/** pages, and those pages are what moves.

The published bodies are byte-identical to their owner's files — proved, not asserted. The corpus is a GENERATED projection, so the pages are only as good as the projection's fidelity. Both published bodies are the umbrella's own file at the umbrella's tag, with the generator's provenance header removed:

$ python3 -I /tmp/lcn209/strip_header.py <the corpus body>   # drop the generator provenance header
  internals/skills/cutover-policy/SKILL.md   owner  25243 bytes  published  25243 bytes  IDENTICAL
  internals/skills/git-workflow/SKILL.md     owner  69733 bytes  published  69733 bytes  IDENTICAL
$ git -C "$UMB" show v2026.302.1338:.agents/skills/cutover-policy/SKILL.md | sed -n "137,141p"   # the umbrella authored body
  
  **The marker is the subject's half of the cutover's question — "does this change break a consumer?" — and the body's `## Change classification` answers the other half: what breaks for THIS repo's consumers, and how to roll it back.** So a marker-carrying subject MUST come with a `**Breaking change + rollback:**` line, and a bare `none` is not an answer: a cutover that breaks nothing here must say WHY it breaks nothing here (for example: *"none — the pointers move to commits the org has already merged"*). *Detail:* `/charly-internals:git-workflow` ("The `!` marker and the body's breaking-change answer").
  
  See `CHANGELOG/` for the catalog of past cutovers that followed this shape — each took the same steps: **delete old surface + publish migration + hard load error**.

The corpus's own candy says which projections move, and the measurement agrees. The corpus's candy/charly-marketplace/charly.yml advances its umbrella pin to the same tag and states it in the file itself: "those TWO files are the only projections that change." The diff's --name-only filter over */SKILL.md and */references/* names exactly those two, and this PR's own page diff names exactly those two. The candy's own +16 lines are COMMENTS on that pin, so the candy's page does not move — and the measurement says so: the PR moves two pages, not three.

The pin sits one commit above the tag that names the merge. The corpus's tag v2026.302.1755 names the SQUASH 0347894ded1bc355f9a846440bf5158bde9ba854, one commit BELOW the head its main serves (f46285f9), because the tag-on-merge workflow writes CHANGELOG/<CalVer>.md AFTER the tag. This repo's pin follows the SERVED HEAD, not the tag: the corpus's own scripts/consumer-currency.sh judges a consumer's recorded pin against the corpus's merged main, and this repo's own scripts/check_pin_currency.sh judges it the same way.

What this PR does NOT carry. This repo's two CI-time pins — CHARLY_PIN be7a505f476c1a5b0302d878e0b5686a2cde3e07 and UMBRELLA_PIN 1c88fcf15f8fb9dd8b2814210472a63d3a79d0e2 — are a DIFFERENT pin class with their own producers, and they are not moved here. The generation ran against exactly those pinned commits, so the regenerated pages are a projection of the corpus bump alone. Their currency is reported below and filed, not folded in.

How tested

1 — the regeneration at the NEW pin, and the pages that moved. The generator is the product's own, built fresh from the pinned plugin-docs tag; the corpus it projects is the submodule at this PR's recorded pin.

$ tail -3 /tmp/lcn209/regen-newpin.log
charly: resolving github.com/opencharly/layer-ssh-client:v2026.237.458 (710 resolved, 124 queued)
charly docs: 395 recipe pages, 196 plugin pages (205 provider words), 79 cli pages, 834 candy pages, 216 box pages (1726 generated pages cleared before regeneration)
GENERATE_RC=0

$ git status --porcelain=v1 --untracked-files=all -- src/content/docs
STATUS_RC=0 (0 entries above = the regeneration at the NEW pin is a byte-exact no-op against the committed tree)

$ git diff --stat origin/main HEAD -- src/content/docs   # the pages this PR moves
 src/content/docs/recipes/internals/cutover-policy.md |  2 ++
 src/content/docs/recipes/internals/git-workflow.md   | 12 ++++++++++++
 2 files changed, 14 insertions(+)

The regeneration runs IN PLACE, and that is the measured detail. The generator's link gate is a SITE gate, not a corpus gate: it collects the route set from the out root and checks every page's internal links against it, and it deliberately covers the HAND-AUTHORED pages. The out root must therefore be a site root — this repo's own src/content/docs, where astro.config.mjs sits one level up — which is why the comparison is measured the way CI measures it, in place, with git status as the comparison. A corpus-only scratch directory is not a site root, and the gate can never be satisfied there.

The toolchain is CI's: plugin-docs v2026.289.0814 built from cmd/serve, charly at this repo's CHARLY_PIN be7a505f476c1a5b0302d878e0b5686a2cde3e07, the umbrella at its UMBRELLA_PIN 1c88fcf15f8fb9dd8b2814210472a63d3a79d0e2, and the corpus at this PR's pin.

2 — the drift gate: the committed tree must match its pinned inputs. This is the gate that says the shipped pages ARE the projection of the shipped pin, and it regenerates and compares.

$ bash .github/docs-corpus/check_drift.sh
content: committed tree matches the pinned inputs (regeneration is a no-op).
DRIFT_RC=0

3 — the Astro build from a clean install, on the pinned node.

$ node --version   # the node this repo pins (.node-version)
v26.11.1
$ npm ci
  run `npm fund` for details

found 0 vulnerabilities
NPM_CI_RC=0
$ npm run build
19:47:34 [build] Waiting for integration "@astrojs/starlight", hook "astro:build:done"...
19:47:35 [starlight:pagefind] Found 1749 HTML files.
19:47:36 [starlight:pagefind] Finished building search index in 4.94s.
19:47:36 [@astrojs/sitemap] `sitemap-index.xml` created at `dist`
19:47:36 [build] 1749 page(s) built in 46.15s
19:47:36 [build] Complete!
NPM_BUILD_RC=0

4 — the pin-currency report, on the committed tree. This repo reports each pinned input's currency and never fails on it, because the remedy for a stale pin is a regeneration PR that bumps the pin, not a gate that fails.

$ bash .github/scripts/check_pin_currency.sh .
corpus pin: f46285f93ab1d0e44674dff0ac9a9360e9d84980 is cur — at the corpus's merged main (merged main: f46285f93ab1d0e44674dff0ac9a9360e9d84980)
charly pin: be7a505f476c1a5b0302d878e0b5686a2cde3e07 is behind — 2 commit(s) behind charly's merged main; an advance available NOW (a pin-bump PR in this repo) (merged main: 1637a5e43380550b68d53b2e1167e0628768cd52)
umbrella pin: 1c88fcf15f8fb9dd8b2814210472a63d3a79d0e2 is behind — 10 commit(s) behind the umbrella's merged main; an advance available NOW (a pin-bump PR in this repo) (merged main: 9e6df0396b01dff9492294359c16dbd588e19b43)

5 — this repo's own script gates, on the committed tree.

$ python3 .github/scripts/check_dependency_advisories.py; echo "RC=$?"
check-dependency-advisories: OK (no known advisory in the production tree or the dev tree)
$ python3 .github/scripts/test_check_dependency_advisories.py; echo "RC=$?"
ok  mutE-noadvisories — the advisory extraction removed, and the self-test turned red on it
test_check_dependency_advisories: OK (5 mutants; every one of them turns the self-test red)
$ bash .github/scripts/check_pin_currency.sh .; echo "RC=$?"
umbrella pin: 1c88fcf15f8fb9dd8b2814210472a63d3a79d0e2 is behind — 10 commit(s) behind the umbrella's merged main; an advance available NOW (a pin-bump PR in this repo) (merged main: 9e6df0396b01dff9492294359c16dbd588e19b43)
$ bash .github/scripts/test_check_pin_currency.sh; echo "RC=$?"
  PASS  the umbrella pin is reported
test_check_pin_currency: OK (every state is reported, and none of them fails)
$ python3 .github/scripts/check_step_timeouts.py; echo "RC=$?"
check-step-timeouts: OK (1 workflow file(s) asserted; every job and every step carries a deadline)
note: .github/workflows/tag-on-merge.yml: not asserted here - a distributed copy of opencharly/.github's tag-on-merge-dispatcher.yml; its deadline belongs in that template (opencharly/.github#256), and the copy-to-template binding is opencharly/.github#192
$ python3 .github/docs-corpus/test_check_drift.py; echo "RC=$?"

OK

6 — the head this PR pushes, and the tree it carries.

6f1871c54777069f4802dc69350008b57067b312

Rulebook compliance

  • R0: the skills the dispatcher selects for this change were read before the first tool action: /charly-build:docs (the generation verb and the drift-proof recipe), /charly-tools:docs-site (the site candy and the pin report), /charly-internals:skills (the corpus is a projection, never hand-edited), /charly-internals:git-workflow (the pin contract, the PR body, the coordination grammar) and /charly-internals:root-cause-analyzer (the anomalies this change met). This repo's own AGENTS.md was read first, and it adds the rules this body follows.
  • R1: every anomaly this change met was root-caused and fixed in this change, not filed away; the gate ran with zero warnings. The corpus moved twice under this change — the second leg carried no authored body and the regeneration at the final pin is therefore a byte-exact no-op against the pages already generated, which is measured in item 1 rather than assumed.
  • R2: one implementation: the pages are regenerated by the pinned plugin-docs CLI — the same engine CI runs — and no page was hand-edited.
  • R3: no workaround: no sleep, no retry, no suppression, no hand-edited generated page; the regeneration is the product's own generator and the drift gate is the product's own gate.
  • R4: product before prose: the corpus's authored bodies were fixed at their source (the umbrella's own rulebook) and published by the corpus's own regeneration; this repo only projects them, and it projects them with the generator that owns the projection.
  • R5: the superseded pin value 75e1d4a1379daf164a1ed2bc9c0678ad1ed20312 survives nowhere in this repo's tracked tree outside CHANGELOG/, which is history and not a current claim.
  • R6: git status was clean before the pin moved and is clean now; the branch is off fresh origin/main; no force-push, no hook bypass, no push to main, and the submodule's contents were never edited — only the recorded gitlink moved.
  • R7: the attribution is proved in both directions: the pages this PR ships are the generator's output at the shipped pin (item 1's no-op and item 2's drift gate), and the diff against the base names exactly the pages the corpus's authored-body diff predicts — two bodies, two pages, +2 and +12 lines in both, measured on both sides.
  • R8: the live layer skipped visibly; nothing was mocked — the generation, the drift gate and the Astro build all ran against the real pinned sources.
  • R9: the generator was rebuilt FRESH at the pinned plugin tag for this change (plugin-docs v2026.289.0814), and the site was built from a clean npm ci on the node version this repo pins (.node-version).
  • R10: the change class is a corpus-pin bump, so the gate that owns it is this repo's own generation workflow — regeneration, the drift gate, the Astro build and the repo's script gates — run on the committed tree (items 1, 2, 3 and 5). No disposable: true bed maps to this change class.
  • Part II feat: bootstrap the opencharly.ai documentation site #1: no submodule was edited — this repo records the gitlink only, and the corpus's own commit is the producer's.
  • Part II docs: regenerate after the plugins skill corrections #3: the pin advances producer-first: the corpus's PR the bang rule accepts an EMPTY breaking-change answer, its inapplicable skip is silent, and its key anchor is loose marketplace#607 merged as fix(lint)!: the marker rule refuses an EMPTY answer, skips visibly, and reads the org's own key (#607) marketplace#608 and was tagged v2026.302.1755 before this PR; the corpus's own report names this repo as the consumer to advance.
  • Part II fix(docs): correct CHANGELOG heading left stale by a validator merge slip #6: the issue was filed and claimed before the branch.
  • Part II docs: regenerate the git-workflow pages for plugins v2026.215.1627 #7: this body carries Agent: and the italic trailer last.
  • Part II docs!: gourmet-kitchen landing + a twelve-part concepts curriculum #8: every new comment and the validator's full report are read before the next push, and each round appends one commit.
  • Part II docs(landing): a front page with a spine, and /grievances/ on the site #9, docs: sync the generated catalog to four landed skill changes #11: the session ledger carries this PR and its issue, and a STATUS comment lands at each milestone.

Change classification

Documentation site regeneration — the corpus-pin consumer leg of opencharly/marketplace#607 → #608. The change class is a pin, so the gate is this repo's own generation workflow — regeneration, the drift gate, the Astro build and the repo's script gates — run on the committed tree (items 1, 2, 3 and 5). The tier is fully tested and validated.

Eval beds run: N/A — a corpus-pin bump; this repo declares no deployable entity for this class.

Breaking change + rollback: none — the diff moves ONE recorded gitlink to the corpus's served head and carries the two pages that gitlink projects; no page is hand-edited, no authored page changes, and the retired corpus content stays in the corpus's own CHANGELOG/. Rollback is a plain revert of this PR, which returns the recorded gitlink to 75e1d4a1379daf164a1ed2bc9c0678ad1ed20312 and the pages to their committed state.

Filed issues

Both are filed, not folded in, and both are already open in this repo — this PR adds no new issue for them.

Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0
Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)

… the armed `!` marker rule (#209)

The corpus's served head moves to the commit that carries the marker rule's ARMED
linter — the corpus's own PR opencharly/marketplace#607 -> #608, tagged
v2026.302.1755. The corpus's diff between this repo's recorded pin and the served
head carries two AUTHORED bodies: the umbrella's own general-guidance skills
(cutover-policy and git-workflow), republished from the umbrella's tag
v2026.302.1338 (opencharly/opencharly#805). Those bodies project into this site's
recipes/internals/** pages, and those pages are regenerated here.

The pin follows the SERVED HEAD, not the tag: the corpus's tag-on-merge workflow
writes its CHANGELOG after the tag, so the tag names the squash one commit below
the head its main serves.

Closes #209

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

Copy link
Copy Markdown
Contributor Author

STATUS — the corpus-pin consumer leg is open.

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

Head. 6f1871c54777069f4802dc69350008b57067b312 — 3 files changed, 15 insertions(+), 1 deletion(-): the marketplace gitlink 75e1d4a → f46285f9, and the two generated pages the gitlink projects (recipes/internals/cutover-policy.md +2, recipes/internals/git-workflow.md +12).

Done. The scope was derived from the producer's own report (marketplace/scripts/consumer-currency.sh names this repo as behind), not written by hand. The regeneration at the NEW pin is a byte-exact no-op against the committed tree; the drift gate is green; the Astro build is green from a clean npm ci on the pinned node (1749 pages); the repo's script gates are green; the published bodies were proved byte-identical to the umbrella's own files at the umbrella's tag v2026.302.1338.

Next. Read every comment and the validator's full report on this PR; fix every finding in ONE appended commit per round; land through the protected merge; then close the issue by hand and post RESOLVED.

Next update. When the validator's verdict lands, or at the next milestone.

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

@github-actions

Copy link
Copy Markdown

Review — PASS

I re-derived every claim in the body and the STATUS comment against the current diff, commit list, and comment thread. No shell was needed; the state provided is complete for this change class (a submodule-pin bump plus the generated pages it projects).

What I checked

Correctness / internal consistency

  • File/count arithmetic is exact. marketplace gitlink is +1/-1; cutover-policy.md is +2/-0; git-workflow.md is +12/-0. Total = 3 files, 15 insertions, 1 deletion — matching the body, the STATUS comment, and the head-SHA line. ✓
  • The body names exactly the two pages that move (recipes/internals/cutover-policy.md +2, recipes/internals/git-workflow.md +12), and the diff names exactly those two. ✓
  • The apparent tension between "regeneration at the NEW pin is a byte-exact no-op" and "this PR moves two pages" resolves correctly: the no-op is measured against the committed tree (the drift-gate claim), while the pages legitimately differ from origin/main because the base carried the old pin. Consistent. ✓
  • The --name-only filter claim over */SKILL.md / */references/* returning exactly those two authored bodies lines up with the two page diffs, which are the corresponding projections of those two skill bodies. ✓
  • Pin narrative is coherent: tag v2026.302.1755 → squash 0347894, one commit below the served head f46285f9, with the pin following served head (matching how check_pin_currency.sh / consumer-currency.sh judge). No contradiction.

Body honesty

  • The subject carries no !, so the body's own newly-published rule (the **Breaking change + rollback:** requirement only under a !) does not obligate it — and the body nonetheless supplies a reasoned none (gitlink move + two projected pages, rollback = plain revert), which satisfies the very rule it ships. Self-consistent, not self-violating.
  • R5's "old pin survives nowhere outside CHANGELOG/" is not contradicted by any of the three changed files.
  • The corpus-side transcripts (8-path stat, byte-identity, 53-PR statistic) cannot be independently re-executed from the provided state, but they are internally consistent and are producer-projected content, not this repo's hand-authored claims; nothing in the diff contradicts them.

Tests

  • The change class is a pin bump; the owning gates are the in-place regeneration, check_drift.sh, the Astro build, and the repo script self-tests — all reported green on the committed tree. For a generated-projection repo these are the meaningful gates (they would go red if the pages diverged from the shipped pin), and the body measures them rather than asserting them.

Security

  • No secrets, no code paths, no injection surface. The only added content is documentation prose plus internal cross-links. Both new links (/recipes/internals/git-workflow/ from cutover-policy, and /recipes/internals/cutover-policy/ from git-workflow) target pages that exist in this tree, so no broken-link risk is introduced. ✓

Scope & cleanliness

Comments

  • The single STATUS comment (by @aitrawog, the author) is a self-status update, not a maintainer sign-off. No designated maintainers are configured for this run, so I treat no comment as approval and require the change to stand on its own evidence — which it does. The comment's substantive claims (head SHA 6f1871c…, 3 files / 15+/1−, the two page diffs, and the "proved byte-identical" and green-gate statements) all match the current state, so it is corroborating rather than stale. No comment contains a finding that needs fixing.

Blocks

None.

The change is internally consistent, correctly scoped, evidence-backed for its class, free of security or link defects, and stands on its own without a maintainer sign-off.

Verdict: PASS


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

View action run

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.

the marketplace submodule is behind the corpus's merged main — the advance carries two authored bodies, so the site's generated pages move

1 participant