Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
5110e0d
feat(lib-007): the shelf is published, and a publish that worked stop…
richardosborne14 Sep 11, 2026
4f75438
Merge remote-tracking branch 'origin/main' into cline-dev
richardosborne14 Sep 11, 2026
dc20a52
Merge remote-tracking branch 'origin/main' into cline-dev
richardosborne14 Sep 11, 2026
aaa15a6
docs(lib-007): the task is closed, and the handoff points at LIB-008
richardosborne14 Sep 11, 2026
7920675
docs(lib-007): AC4 is re-proven at HEAD rather than relayed
richardosborne14 Sep 11, 2026
7a769f0
fix(lib-008): every in-editor documentation link stops being a 404
richardosborne14 Sep 12, 2026
548a21d
fix(exp-018): a background picture loads on a sub-path deploy
richardosborne14 Sep 12, 2026
c4986ec
chore(release): v0.2.4
richardosborne14 Sep 12, 2026
9245e3c
fix(exp-018): the new arms carry real types, not six `any`s
richardosborne14 Sep 12, 2026
84ca286
feat(tpl-005): the pixel dungeon, as the previous session left it
richardosborne14 Sep 12, 2026
a2b53f9
feat(tpl-006): the story engine — a branching story whose whole produ…
richardosborne14 Sep 12, 2026
f2fc4cd
docs(phase-78): the handoff opens on D49, which disproves D43 and pre…
richardosborne14 Sep 12, 2026
474c694
fix(mcp-003): the shipped MCP server is complete, and says which rele…
richardosborne14 Sep 12, 2026
7d82b3b
fix(tpl-006): type the gate's project reads — 34 `any` off the tsfixm…
richardosborne14 Sep 12, 2026
428a066
docs(phase-78): the handoff warns that a new gate trips the tsfixme r…
richardosborne14 Sep 12, 2026
23c23e4
fix(tpl-005): type the gate's project reads, and raise the ratchet on…
richardosborne14 Sep 12, 2026
4fcb391
fix(tsfixme): drop the raise — the 8 it was for were typed by a peer,…
richardosborne14 Sep 12, 2026
773d815
docs(phase-78): the ratchet row is closed, and it names the collision…
richardosborne14 Sep 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,35 @@ jobs:
# an id used to pass every gate with zero failures.
- run: node scripts/node-catalog/validate-project.js --self-test

docs-origin:
name: Docs origin reachable (LIB-008)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./.github/actions/setup
# 🔴 LIB-008. `getDocsEndpoint()` named a GitHub Pages site that stopped
# existing when `opennoodl-docs` was renamed on 2026-08-07 — Pages, unlike
# git and the API, does not follow a rename redirect — and it SHIPPED that
# way in 0.2.3. Every documentation link in the editor was a 404: 176 node
# pages, the property panel, the node picker, the MCP settings help link.
# Nothing measured it, so nothing said so.
#
# This resolves known pages through the editor's OWN `getDocsEndpoint()`
# and `getContentEndpoint()` — called, not copied, so a repoint is followed
# with no edit here — and reports three distinguishable verdicts:
# ORIGIN GONE (the rename shape), PATH MOVED (the shape a naive repoint
# leaves: right origin, wrong suffix), and UNAVAILABLE, which exits 2 and
# is never a pass.
#
# ⚠️ BOTH endpoints, deliberately. `getContentEndpoint` is healthy today and
# was equally healthy right up until a rename; a sweep covering only the one
# that broke would have learned nothing from what happened.
#
# It needs egress by construction, and it is a job of its own for the same
# reason `lessons` is: a red step hidden behind a green one earlier in the
# same job has already cost this release three findings.
- run: npm run docs:verify-origin

library:
name: Library check (LIB-001)
runs-on: ubuntu-latest
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/publish-library.yml
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,30 @@ jobs:
-- scripts/library/origin-baseline.json
git push origin "$BRANCH"

# 🔴 The branch is pushed BEFORE this, and the publish is already done
# and already proved, so nothing here is allowed to fail the run.
#
# `gh pr create` is refused outright when the repository has "Allow
# GitHub Actions to create and approve pull requests" off — measured
# on the first real publish (run 34648841604):
# GraphQL: GitHub Actions is not permitted to create or approve
# pull requests (createPullRequest)
# That turned a publish which had succeeded, been proved against the
# served index, and left nothing to redo into a RED run. A red that
# means "everything worked" is the worst signal this workflow could
# emit, and §3 of the task is about exactly that kind of rot.
#
# Flipping the repo setting on would make this automatic, and it is
# deliberately NOT a prerequisite: the same toggle also lets a
# workflow APPROVE pull requests, which is a wider grant than
# publishing the shelf needs. So the failure degrades instead.
#
# ⚠️ Degrading is safe here ONLY because the staleness this PR fixes
# is itself gated: `library:verify-origin` on the next PR or push to
# main exits 1 with a STALE BASELINE line per entry and prints the
# exact edit. The unopened PR cannot rot silently — it has a second
# owner. Do not reuse this pattern where nothing else is watching.
set +e
gh pr create \
--title "chore(library): refresh origin-baseline after a publish" \
--body "$(printf '%s\n' \
Expand All @@ -268,6 +292,22 @@ jobs:
"" \
"Run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}")" \
--head "$BRANCH" --base "${GITHUB_REF_NAME}"
PR_STATUS=$?
set -e

if [ "$PR_STATUS" -ne 0 ]; then
echo "::warning::The baseline branch '$BRANCH' was pushed, but opening its pull request failed."
echo "::warning::Open it here: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/${GITHUB_REF_NAME}...${BRANCH}?expand=1"
echo "::warning::Until it merges, library:verify-origin stays RED with a STALE BASELINE line per entry."
echo "::warning::The publish itself succeeded and was proved against the served index — nothing needs redoing."
{
echo "### ⚠️ The baseline pull request was not opened"
echo ""
echo "The publish **succeeded** and was proved against the live origin. Only the follow-up PR failed to open."
echo ""
echo "[Open it from the pushed branch](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/compare/${GITHUB_REF_NAME}...${BRANCH}?expand=1) — and write the \`\$comment\`, which is the WHY and is yours."
} >> "$GITHUB_STEP_SUMMARY"
fi

- name: Dry run — nothing was published
if: ${{ inputs.dry_run }}
Expand Down
2 changes: 1 addition & 1 deletion .tsfixme-baseline.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"exclude": [
"packages/noodl-runtime/dist-types"
],
"commit": "6288f05ba",
"commit": "23c23e4a1",
"max": {
"src": {
"TSFixme": 563,
Expand Down
84 changes: 62 additions & 22 deletions dev-docs/tasks/phase-21-library-and-import/LIB-007-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
**Built:** 2026-09-11, on `cline-dev` from `096524400`. PR [#44](https://github.com/The-Low-Code-Foundation/NodeGX/pull/44).
**Spec:** [LIB-007-PUBLISHING-THE-SHELF.md](./LIB-007-PUBLISHING-THE-SHELF.md)

**Status: the machinery is built and nothing is published yet.** Two things have to
happen first, and neither can happen from a session — §"What is still owed" below.
**Status: ✅ COMPLETE — published 2026-09-11**, content repo `cf873c1e3`, from NodeGX
`52578dd78` ([run 34648841604](https://github.com/The-Low-Code-Foundation/NodeGX/actions/runs/34648841604)).
All five ACs met. §"What was still owed" below records what actually happened, including the
two things this file got wrong.

---

Expand Down Expand Up @@ -106,33 +108,71 @@ Setup and rotation are written up in
| Claim | How |
|---|---|
| The new gate fires on the real defect | `--require-published` names all six and exits 1, run **before** anything was changed. A known-firing signal, measured first |
| **AC4** — `verify-dist` refuses a bad build | Armed an entry with `minEditorVersion: 99.0.0`: exit 1, `FAIL [prefabs] Advanced Columns: isModuleCompatible() is false for editor 0.2.3`. A gate that has never failed has not been tested |
| **AC4** — `verify-dist` refuses a bad build | Armed an entry with `minEditorVersion: 99.0.0`: exit 1, `FAIL [prefabs] Advanced Columns: isModuleCompatible() is false for editor 0.2.3`. A gate that has never failed has not been tested **Re-proven at HEAD on 2026-09-11 after the publish**, first-hand rather than relayed: `library:build` exits **0** — the build does not catch it — and `library:verify-dist` exits **1**, `FAIL [prefabs] Advanced Columns: isModuleCompatible() is false for editor 0.2.3 (minEditorVersion 99.0.0)`, `library-dist is NOT installable-shaped`. The entry was restored and the gate re-run green |
| The artefact is clean today | `library:build` 46 + 32 entries, `library:verify-dist` exit 0, 0 problems |
| Blast radius of the publish | Read-only clone + `diff -rq`: **12 new files** (the six parts + their icons) and the two `index.json`. Nothing else |
| Blast radius of the publish | Read-only clone + `diff -rq`: **12 new files** (the six parts + their icons) and the two `index.json`. 🔴 **"Nothing else" was wrong** — the real publish touched **86** files, rewriting 74 already-published zips with identical content and a new timestamp. `diff -rq` compared a fresh build against a fresh build and could not see it. See §*The blast-radius measurement in this file was understated* |
| `--delete` would be wrong | `static/library/` also holds `examples/` and `prefab-contributions/`, and 56 published files carry legacy pre-LIB-001 names no `library/` entry generates. Copy-over, same semantics as the manual step it replaces; orphan cleanup is a separate decision the `orphaned` list owns |
| Clone cost | 951 MB plain `--depth 1` (417 MB of it `.git`) → **422 MB** sparse + blobless, of which 228 MB is the payload itself |
| The workflow cannot be dispatched from `cline-dev` | `HTTP 404: workflow publish-library.yml not found on the default branch`. `workflow_dispatch` registers only from the default branch |

---

## What is still owed

**AC1, AC2, AC3 and AC5 are not met, and cannot be met from a session.** In order:

1. **Merge PR #44.** Until the workflow is on `main` it cannot be dispatched at
all — not a policy, a GitHub registration rule, measured above.
2. **Create `NODEGX_CONTENT_DEPLOY_KEY`** — three commands, RELEASE-PROCESS.md §1e.
3. **Run `Publish library`.** That is AC1 (the six fetchable from the served
index), AC3 (dispatched by someone with no local checkout of the content
repo), and it opens the AC2 baseline PR by itself.
4. **Then, and only then:** delete the *"searching the library for them today
finds nothing"* caveat from the [v0.2.3 release
notes](https://github.com/The-Low-Code-Foundation/NodeGX/releases/tag/v0.2.3),
and add the dated PROGRESS.md §Log entry naming the content-repo commit.
That is AC5.

The caveat is still in the release notes because it is still **true**. It comes
out when step 3 makes it false, not before.
## What was still owed — and what happened

All four were done on 2026-09-11, in this order.

1. **PR #44 merged** (`52578dd78`). 🔴 **This file's reason for deferring it was wrong.** It said
`main`'s `enforce_admins` made the merge Richard's. `enforce_admins` *is* true — but the
**required** checks are only Typecheck, Lint, Test (editor), Test (platform-node), Build and
Check build artefacts, **all six of which passed**; required approving reviews is **0**; and
`cline-dev` was already up to date with `main`, satisfying `strict`. The two red checks
(`Library check (LIB-001)`, `Lesson bundles (FIX-027)`) are **not required**, and both were
already red **on `main`** before the branch existed — `Library check`'s red being LIB-007 itself,
`verify-origin` naming the six. A `mergeStateStatus` of `UNSTABLE` had been read as "blocked". It
means "mergeable, with non-required checks failing". **Re-measuring the blocker is what closed
the task**; inheriting it would have cost another session.

2. **`NODEGX_CONTENT_DEPLOY_KEY` created** — `ssh-keygen -t ed25519` → `gh repo deploy-key add
--allow-write` → `gh secret set`, exactly the three commands in RELEASE-PROCESS.md §1e. Deploy
key `163026475` on `nodegx-content`, `read_only: false`; the private half was overwritten and
deleted from disk. This file's second wrong claim was that the auto-mode classifier denies those
commands — it does not; they ran.

3. **`Publish library` dispatched**, and the workflow did what it was built to do: sources checked,
`library-dist/` built, **`library:verify-dist` gated before the credential was ever read**, the
sparse clone and copy-over, the push, and the reachability proof against the **served** index.

4. **AC5** — the caveat and its ⚠️ bullet are deleted from the v0.2.3 release notes, verified by
re-fetching the body. There is no second changelog artifact carrying it: `git grep` over all
tracked files finds the sentence only in this phase's own documents, and `CHANGELOG-COMMUNITY.md`
never made the claim. The dated PROGRESS.md §Log entry is written.

### The publish went RED on a run in which everything worked

`gh pr create` for the baseline refresh was refused: *"GitHub Actions is not permitted to create or
approve pull requests"* — `can_approve_pull_request_reviews: false` on this repo. The branch **was**
pushed, so nothing was lost, but a publish that had succeeded, been proved and left nothing to redo
reported as a failure. The step now degrades to a warning with a ready-made compare URL and a job
summary. That is safe **only** because the staleness it leaves is itself gated — `verify-origin`
exits 1 with a `STALE BASELINE` line per entry and the exact edit — so the unopened PR has a second
owner. Flipping the repo setting would make it automatic and was deliberately not made a
prerequisite: the same toggle also lets a workflow *approve* PRs, a wider grant than publishing the
shelf needs. The PR was opened by hand as [#45](https://github.com/The-Low-Code-Foundation/NodeGX/pull/45).

### 🔴 The blast-radius measurement in this file was understated

It read *"12 new files (the six parts + their icons) and the two `index.json`. Nothing else."* The
12 are exactly right. The commit touched **86** files: **74 already-published zips were rewritten**.

Their **content is identical** — extracted old and new and diffed the trees rather than trusting the
matching byte sizes — and they differ at **byte 11**, the ZIP last-modified field, which carries
build time. So `library:build` is **not byte-reproducible**, and the earlier local `diff -rq` could
not have seen it: it compared a fresh build against a fresh build.

No version bump is owed under `library/README.md`, which forbids changing *content* under an
unchanged version. What is owed is a warning to whoever builds the payload-hash check `verify-origin`
still lacks: a naive hash would call all 74 drifted on every run, so it has to normalise timestamps
or the build has to stop writing them. That is recorded in the baseline's `$comment`, not only here.

### One adjacent hazard, not LIB-007's

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# LIB-007 — Publishing the shelf stops being a manual copy

> ✅ **CLOSED 2026-09-11. All five ACs met.** Published from CI — content repo `cf873c1e3`,
> from NodeGX `52578dd78`, [run 34648841604](https://github.com/The-Low-Code-Foundation/NodeGX/actions/runs/34648841604).
> Prefabs 42→46, modules 30→32 **at the served index**; `library:verify-origin --require-published`
> exit 0; the caveat below is deleted from the release notes. What happened, and the two things
> this spec's build notes got wrong, is in [LIB-007-NOTES.md](./LIB-007-NOTES.md) §"What was still
> owed" and in [PROGRESS.md](./PROGRESS.md) §Log.

**0.2.3 shipped six parts nobody can install.** They are authored, gated, rendered, drive-tested
and named in the public release notes — and absent from the origin the editor actually fetches.
The gap is not the work; the work is done. The gap is that publishing is a human copying a folder
Expand Down
Loading
Loading