IR-20261111: EXTDEL v2 — deliver the refocus pi extension by manifest (sbx-gits + sbx-lab); 2 commits, commit 2 droppable. NOT FOR LANDING #958

Open
pi-landing wants to merge 2 commits from plane/IR-20261111-extdel-v2 into live
Collaborator

NOT FOR LANDING

Build-only PR (EXTDEL v2, Lab-Run: IR-20261111-extdel). Opened so the diff is reviewable and CI runs; it must NOT be merged until the landing gate at the bottom is satisfied.

The problem

forgejo reaches sbx-lab and sbx-gits only through the EXTDEL ConfigMaps generated by scripts/gits-sbx-forgejo-ext-gen.sh. Two other extensions had no source in Git at all — pi-swarm-suite and refocus reached the pods only as a hand copy inside the one-time /home/ld/work/.seed/pi-agent drop, so the tree a sandbox actually runs could not be reviewed and no boot could reproduce it.

Re-scope (El Director, 11:30:54Z) — pi-swarm-suite is OUT

pi-swarm-suite cannot travel this way: it needs croner + nanoid at runtime (pi's jiti loader does not alias them, so they would have to ship as node_modules) and its rendered source set is 1,410,451 B, over the 1,048,576 B ConfigMap ceiling. It moves to spec 029. This PR therefore delivers refocus only.

refocus feasibility — all three conditions measured

At UPSTREAM_REF = c5ac96f548856dbc22c335d26f49aea88266e475 (unchanged by commit 1):

  1. Source-only at runtime. The runtime set's complete import list is typebox, @earendil-works/pi-coding-agent, @earendil-works/pi-ai, node:fs. The first three are aliased by pi's own jiti loader (getAliases() in dist/core/extensions/loader.js); node:fs is a builtin. There is no dynamic import() and no require() anywhere in the set, so nothing resolves from the volume and no node_modules travels.
  2. Fits one ConfigMap. 13 files, 78,009 B of source. Rendered, per object:
object bytes headroom under 1,048,576 B
sbx-gits-refocus-ext (sbx-gits/refocus-ext.yaml) 91,484 957,092
sbx-lab-refocus-ext (sbx-lab/refocus-ext.yaml) 91,562 957,014

The generator refuses to emit an object above the ceiling.
3. Every file matches pi-extensions main. All 13 runtime files hash-identical between c5ac96f5 and origin/main (cb0d8376): 13/13 SAME, 0 differing.

Commit 1 — 9db9b5c6 — deliver refocus at c5ac96f5

  • scripts/gits-sbx-forgejo-ext-gen.sh: extended to TWO packages with their own pinned FILE sets (per-package FILES/pins) emitting FOUR objects; --check covers all four. emit_data became one parameterised function over (package dir, source dir, file list). The two forgejo objects are byte-identical to what the script produced before this commit — git shows no change to either file, and --check is rc 0 on all four.
  • core/manifests/apps/sbx-gits/refocus-ext.yaml, core/manifests/apps/sbx-lab/refocus-ext.yaml: the generated ConfigMaps, flat refocus.<file> keys, directory layout restored by items[].path, source-ref annotated with the pin, defaultMode 288 (0440).
  • Both statefulsets change: sbx-gits AND sbx-lab. Each gets:
    • a SEED_REFOCUS_EXT env switch (declared before args:, which the epic test extracts by indentation);
    • a seed step (1c in sbx-lab, 1d in sbx-gits) using the same rm -rf + cp -a pattern as forgejo — Git wins on every boot, because cp -an would freeze the first version that ever landed forever;
    • OFF semantics deliberately differ from forgejo's: refocus is a shared extensions.list entry that sbx-sendrast also requires, so OFF means "do not copy" and never "remove it" — removing it would fail the seed's own list verification and take the pod down;
    • a 13-file guard (the generator's exact file set), so a tree that lost a key is caught at boot instead of failing to load at session start;
    • the volume, its mount, and the refocus sha in .seed-status.
  • The shared extensions.list is not touched: refocus stays in it (sbx-sendrast seeds it from its own .seed copy and carries neither generated object), and the seed's SEED-INVARIANT guard keeps not naming it.
  • scripts/gits-sbx-epic-test.sh: the new volumes/mounts/env are allowed in the sbx-lab template invariants; the two new ConfigMaps are allowed objects in H1b; the generated-source value-scan exclusion covers them; the H1b red mutation now removes the whole generated-source family (with two generated objects per namespace, dropping one had stopped biting); T7[diff]'s allowed set is re-measured for sbx-gits; the H11[gen] fixture copies all four committed objects.

Not touched: no .DS_Store and no herdr-agent-state.ts (EXTDEL does not manage them — the latter is herdr's own hook).

Commit 2 — 0c72e058 — DROPPABLE re-pin to cb0d8376

UPSTREAM_REF -> cb0d8376a3b0b9ad92d2e037c716564fd4421ded (#133) plus the four regenerated ConfigMaps. No hand edit of any generated file, and no other file at all.

Proof, both legs run: committed data == a fresh generator run (cmp IDENTICAL on all four objects) and scripts/gits-sbx-forgejo-ext-gen.sh --check <drop> exits 0 with "IN SYNC" for all four.

Droppable: dropping this commit (revert, or opening the PR at commit 1) restores the c5ac96f5 state exactly, byte for byte, because every generated byte is a pure function of (source drop, pin) and the pin is one literal in the generator. refocus/ is unchanged between the two refs, so its objects differ only in the source-ref annotation and the header pin line.

Size accounting (both namespaces, separately)

object commit 1 (c5ac96f5) commit 2 (cb0d8376)
sbx-gits/forgejo-ext.yaml 712,623 B (unchanged) 720,710 B
sbx-lab/forgejo-ext.yaml 712,969 B (unchanged) 721,056 B
sbx-gits/refocus-ext.yaml 91,484 B 91,484 B (annotation only)
sbx-lab/refocus-ext.yaml 91,562 B 91,562 B (annotation only)

All four are under the 1,048,576 B ConfigMap ceiling; the minimum headroom is 327,520 B (sbx-lab/forgejo-ext.yaml at commit 2).

CI

Epic suite: 706 checks, 16 failed — the identical 16 that fail on a clean origin/live worktree in this environment (verified side by side: baseline 16 of 700, this branch 16 of 706). Zero new failures; the 6 added checks are the new invariants.

Rollback

git revert of commit 2 alone returns the pin to c5ac96f5 (everything else untouched). git revert of commit 1 alone returns both sandboxes to the previous behaviour. Neither touches the work volume: the next boot's seed step is what changes the tree, and .seed remains untouched underneath.

Recreates and coupling

  • sbx-lab recreate — coordinated with 4a.
  • sbx-gits recreate — coordinated with homelab-33.
  • Both sandboxes pick the new tree up at their next recreate only (a ConfigMap edit never reaches a running session), and sbx-gits is OnDelete, so a template change restarts nothing by itself.

Landing gate (all of it, in order)

  1. a clean-loading pair of seats (CENSUS-FORMAT.md: 2 NO-READ seats, model: omniroute/deepseek-flash, full 40-hex head pin);
  2. SEATSID run by the overseer;
  3. El Director's GO;
  4. commit 2 only if #133-fresh approves — otherwise drop it and land commit 1 alone;
  5. ONE sbx-lab recreate together with 021's fleet-image pin bump (a single recreate, not two);
  6. the sbx-gits recreate separately, coordinated with homelab-33.

No landing, no apply, no pod change has been made by this PR's author.

Lab-Run: IR-20261111-extdel

## NOT FOR LANDING Build-only PR (EXTDEL v2, `Lab-Run: IR-20261111-extdel`). Opened so the diff is reviewable and CI runs; it must NOT be merged until the landing gate at the bottom is satisfied. ## The problem `forgejo` reaches `sbx-lab` and `sbx-gits` only through the EXTDEL ConfigMaps generated by `scripts/gits-sbx-forgejo-ext-gen.sh`. Two other extensions had **no source in Git at all** — `pi-swarm-suite` and `refocus` reached the pods only as a hand copy inside the one-time `/home/ld/work/.seed/pi-agent` drop, so the tree a sandbox actually runs could not be reviewed and no boot could reproduce it. ## Re-scope (El Director, 11:30:54Z) — `pi-swarm-suite` is OUT `pi-swarm-suite` cannot travel this way: it needs `croner` + `nanoid` **at runtime** (pi's jiti loader does not alias them, so they would have to ship as `node_modules`) and its rendered source set is **1,410,451 B**, over the 1,048,576 B ConfigMap ceiling. It moves to **spec 029**. This PR therefore delivers `refocus` only. ## `refocus` feasibility — all three conditions measured At `UPSTREAM_REF` = `c5ac96f548856dbc22c335d26f49aea88266e475` (unchanged by commit 1): 1. **Source-only at runtime.** The runtime set's complete import list is `typebox`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-ai`, `node:fs`. The first three are aliased by pi's own jiti loader (`getAliases()` in `dist/core/extensions/loader.js`); `node:fs` is a builtin. There is **no dynamic `import()` and no `require()`** anywhere in the set, so nothing resolves from the volume and no `node_modules` travels. 2. **Fits one ConfigMap.** 13 files, 78,009 B of source. Rendered, per object: | object | bytes | headroom under 1,048,576 B | |---|---|---| | `sbx-gits-refocus-ext` (`sbx-gits/refocus-ext.yaml`) | 91,484 | 957,092 | | `sbx-lab-refocus-ext` (`sbx-lab/refocus-ext.yaml`) | 91,562 | 957,014 | The generator refuses to emit an object above the ceiling. 3. **Every file matches pi-extensions `main`.** All 13 runtime files hash-identical between `c5ac96f5` and `origin/main` (`cb0d8376`): **13/13 SAME, 0 differing.** ## Commit 1 — `9db9b5c6` — deliver `refocus` at `c5ac96f5` * `scripts/gits-sbx-forgejo-ext-gen.sh`: extended to **TWO packages with their own pinned FILE sets** (per-package FILES/pins) emitting **FOUR objects**; `--check` covers all four. `emit_data` became one parameterised function over (package dir, source dir, file list). The two `forgejo` objects are **byte-identical** to what the script produced before this commit — `git` shows no change to either file, and `--check` is rc 0 on all four. * `core/manifests/apps/sbx-gits/refocus-ext.yaml`, `core/manifests/apps/sbx-lab/refocus-ext.yaml`: the generated ConfigMaps, flat `refocus.<file>` keys, directory layout restored by `items[].path`, `source-ref` annotated with the pin, `defaultMode 288` (0440). * **Both statefulsets change: `sbx-gits` AND `sbx-lab`.** Each gets: * a `SEED_REFOCUS_EXT` env switch (declared before `args:`, which the epic test extracts by indentation); * a seed step (`1c` in sbx-lab, `1d` in sbx-gits) using the **same `rm -rf` + `cp -a` pattern as `forgejo`** — Git wins on every boot, because `cp -an` would freeze the first version that ever landed forever; * **OFF semantics deliberately differ from `forgejo`'s**: `refocus` is a *shared* `extensions.list` entry that `sbx-sendrast` also requires, so OFF means "do not copy" and **never** "remove it" — removing it would fail the seed's own list verification and take the pod down; * a 13-file guard (the generator's exact file set), so a tree that lost a key is caught at boot instead of failing to load at session start; * the volume, its mount, and the refocus sha in `.seed-status`. * The shared `extensions.list` is **not touched**: `refocus` stays in it (`sbx-sendrast` seeds it from its own `.seed` copy and carries neither generated object), and the seed's SEED-INVARIANT guard keeps not naming it. * `scripts/gits-sbx-epic-test.sh`: the new volumes/mounts/env are allowed in the sbx-lab template invariants; the two new ConfigMaps are allowed objects in `H1b`; the generated-source value-scan exclusion covers them; the `H1b` red mutation now removes the whole generated-source family (with two generated objects per namespace, dropping one had stopped biting); `T7[diff]`'s allowed set is re-measured for sbx-gits; the `H11[gen]` fixture copies all four committed objects. **Not touched:** no `.DS_Store` and no `herdr-agent-state.ts` (EXTDEL does not manage them — the latter is herdr's own hook). ## Commit 2 — `0c72e058` — DROPPABLE re-pin to `cb0d8376` `UPSTREAM_REF` -> `cb0d8376a3b0b9ad92d2e037c716564fd4421ded` (#133) plus the four regenerated ConfigMaps. No hand edit of any generated file, and no other file at all. **Proof, both legs run:** committed `data` == a fresh generator run (`cmp` IDENTICAL on all four objects) and `scripts/gits-sbx-forgejo-ext-gen.sh --check <drop>` exits **0** with "IN SYNC" for all four. **Droppable:** dropping this commit (revert, or opening the PR at commit 1) restores the `c5ac96f5` state **exactly, byte for byte**, because every generated byte is a pure function of (source drop, pin) and the pin is one literal in the generator. `refocus/` is unchanged between the two refs, so its objects differ only in the `source-ref` annotation and the header pin line. ## Size accounting (both namespaces, separately) | object | commit 1 (`c5ac96f5`) | commit 2 (`cb0d8376`) | |---|---|---| | `sbx-gits/forgejo-ext.yaml` | 712,623 B (unchanged) | 720,710 B | | `sbx-lab/forgejo-ext.yaml` | 712,969 B (unchanged) | 721,056 B | | `sbx-gits/refocus-ext.yaml` | 91,484 B | 91,484 B (annotation only) | | `sbx-lab/refocus-ext.yaml` | 91,562 B | 91,562 B (annotation only) | All four are under the 1,048,576 B ConfigMap ceiling; the minimum headroom is 327,520 B (`sbx-lab/forgejo-ext.yaml` at commit 2). ## CI Epic suite: **706 checks, 16 failed — the identical 16 that fail on a clean `origin/live` worktree in this environment** (verified side by side: baseline 16 of 700, this branch 16 of 706). Zero new failures; the 6 added checks are the new invariants. ## Rollback `git revert` of commit 2 alone returns the pin to `c5ac96f5` (everything else untouched). `git revert` of commit 1 alone returns both sandboxes to the previous behaviour. Neither touches the work volume: the next boot's seed step is what changes the tree, and `.seed` remains untouched underneath. ## Recreates and coupling * **`sbx-lab` recreate** — coordinated with **4a**. * **`sbx-gits` recreate** — coordinated with **homelab-33**. * Both sandboxes pick the new tree up **at their next recreate only** (a ConfigMap edit never reaches a running session), and `sbx-gits` is `OnDelete`, so a template change restarts nothing by itself. ## Landing gate (all of it, in order) 1. a **clean-loading pair** of seats (CENSUS-FORMAT.md: 2 NO-READ seats, `model: omniroute/deepseek-flash`, full 40-hex head pin); 2. **SEATSID** run by the overseer; 3. **El Director's GO**; 4. **commit 2 only if #133-fresh approves** — otherwise drop it and land commit 1 alone; 5. **ONE `sbx-lab` recreate together with 021's fleet-image pin bump** (a single recreate, not two); 6. the `sbx-gits` recreate separately, coordinated with homelab-33. No landing, no apply, no pod change has been made by this PR's author. Lab-Run: IR-20261111-extdel
EXTDEL v2, commit 1 of 2 (El Director re-scope, 11:30:54Z). Scope: the pi
extension `refocus` (HOMELAB-1678, intent re-injection) has NO source in Git
today — it reaches sbx-lab and sbx-gits only as a hand copy inside the one-time
`/home/ld/work/.seed/pi-agent` drop, so the tree a sandbox runs cannot be
reviewed and cannot be reproduced. This delivers it the way `forgejo` is already
delivered: a GENERATED ConfigMap per namespace plus a boot-time seed step.

WHY NOT pi-swarm-suite (the scope this replaces): it is infeasible for the same
mechanism — it needs `croner` + `nanoid` AT RUNTIME (pi's loader does not alias
them) and its rendered source set is 1,410,451 B, over the 1,048,576 B ConfigMap
ceiling. It moves to spec 029. `forgejo` is untouched by this commit.

FEASIBILITY OF `refocus` (all three conditions measured, at UPSTREAM_REF
c5ac96f548856dbc22c335d26f49aea88266e475 — UNCHANGED by this commit):
 (a) SOURCE-ONLY AT RUNTIME. The runtime set's complete import list is
     `typebox`, `@earendil-works/pi-coding-agent`, `@earendil-works/pi-ai` and
     `node:fs`. The first three are aliased by pi's jiti loader
     (`getAliases()` in `dist/core/extensions/loader.js`); `node:fs` is a
     builtin. There is no dynamic `import()` and no `require()` anywhere in the
     set, so nothing is resolved from the volume and NO `node_modules` travels.
 (b) FITS ONE ConfigMap. 13 files, 78,009 B of source, rendered:
       core/manifests/apps/sbx-gits/refocus-ext.yaml   91,484 B  (headroom 957,092 B)
       core/manifests/apps/sbx-lab/refocus-ext.yaml    91,562 B  (headroom 957,014 B)
     Both are far under the 1,048,576 B ceiling, and the generator refuses to
     emit an object over it.
 (c) EVERY FILE MATCHES pi-extensions `main`. All 13 files hash-identical
     between c5ac96f5 and origin/main of Homelab/pi-extensions (cb0d8376):
     13/13 SAME, 0 differing.

WHAT CHANGES
 * `scripts/gits-sbx-forgejo-ext-gen.sh` now delivers TWO packages with their own
   pinned FILE sets (per-package FILES/pins) and emits FOUR objects; `--check`
   covers all four. `emit_data` became one parameterised function over
   (package dir, source dir, file list) — and the two `forgejo` objects are
   BYTE-IDENTICAL to what this script produced before this commit (git shows no
   change to either file; `--check` is rc 0 on all four).
 * `core/manifests/apps/sbx-{gits,lab}/refocus-ext.yaml`: the generated
   ConfigMaps `sbx-{gits,lab}-refocus-ext`. Flat `refocus.<file>` keys, the
   directory layout restored by `items[].path`, `source-ref` annotated with the
   pin, `defaultMode 288` (0440).
 * BOTH statefulsets change — `sbx-gits` AND `sbx-lab`:
   - a `SEED_REFOCUS_EXT` env switch (declared before `args:`, which the epic
     test extracts by indentation) defaulting to OFF;
   - seed step 1c (sbx-lab) / 1d (sbx-gits): the SAME `rm -rf` + `cp -a` pattern
     `forgejo` uses, so Git wins on every boot (a `cp -an` merge would freeze the
     first version that ever landed forever). OFF is NOT forgejo's OFF here:
     `refocus` is a SHARED `extensions.list` entry that sbx-sendrast also
     requires, so OFF means "do not copy" and NEVER "remove it" — a removal
     would fail the seed's own list verification and take the pod down;
   - a 13-file guard (the generator's exact file set), so a tree that lost a key
     is caught at boot instead of failing to load at session start;
   - the volume and its mount, and the refocus sha in `.seed-status`.
 * The shared `extensions.list` is NOT touched: `refocus` stays in it (sbx-
   sendrast seeds it from its own `.seed` copy and carries NEITHER generated
   object), and the seed's SEED-INVARIANT guard keeps NOT naming it.
 * `scripts/gits-sbx-epic-test.sh`: the two new volumes/mounts and the env switch
   are allowed in the sbx-lab template invariants; the two new ConfigMaps are
   allowed objects in H1b; the generated-source value-scan exclusion covers them;
   the H1b red mutation now removes the whole generated-source family (with two
   generated objects per namespace, dropping one stopped biting); T7[diff]'s
   allowed set is re-measured for sbx-gits; the H11[gen] fixture copies all four
   committed objects.

NOT REACHED BY THIS COMMIT: no `.DS_Store` and no `herdr-agent-state.ts` change
(EXTDEL does not manage them — herdr's own hook writes the latter).

ROLLBACK: `git revert` of this commit alone returns both sandboxes to the
previous behaviour; the merge tool and redactor are unaffected.

Lab-Run: IR-20261111-extdel
IR-20261111: chore(sbx-gits,sbx-lab): re-pin EXTDEL to pi-extensions cb0d8376
All checks were successful
CI Review / helm-validate (pull_request) Successful in 11s
CI Review / receiver-test (pull_request) Successful in 7s
CI Review / runner-manifest-test (pull_request) Successful in 13s
CI Review / alert-receiver-test (pull_request) Successful in 28s
Lint & Validate / shellcheck (pull_request) Successful in 10s
Lint & Validate / yaml-lint (pull_request) Successful in 29s
CI Review / record-sql-test (pull_request) Successful in 58s
Lint & Validate / terraform-validate (pull_request) Successful in 1m59s
CI Review / cockpit-e2e (pull_request) Successful in 2m21s
CI Review / cockpit-test (pull_request) Successful in 2m59s
CI Review / dispatcher-test (pull_request) Successful in 3m18s
0c72e05842
EXTDEL v2, commit 2 of 2 — DROPPABLE. It changes NOTHING but the pin and the four
regenerated ConfigMaps: dropping it (`git revert`, or opening the PR at the
previous commit) restores the c5ac96f5 state EXACTLY, byte for byte, because
every generated byte is a pure function of (source drop, pin) and the pin is a
single literal in the generator.

WHAT MOVES
  UPSTREAM_REF c5ac96f548856dbc22c335d26f49aea88266e475
            -> cb0d8376a3b0b9ad92d2e037c716564fd4421ded   (#133, the seat-posting
               helpers' credential pinned to the built-in origin, plus review-3c's
               S1/S3 follow-ups)
plus the four objects the generator writes from that ref:
  core/manifests/apps/sbx-gits/forgejo-ext.yaml  720,710 B
  core/manifests/apps/sbx-lab/forgejo-ext.yaml   721,056 B
  core/manifests/apps/sbx-gits/refocus-ext.yaml   91,484 B
  core/manifests/apps/sbx-lab/refocus-ext.yaml    91,562 B
No hand edit of any generated file, and no other file at all.

PROOF (both legs run, both green)
 * committed `data` == a FRESH generator run: `cmp` IDENTICAL on all four files.
 * `scripts/gits-sbx-forgejo-ext-gen.sh --check <drop>` exits 0 and says "IN
   SYNC" for all four.
 * `forgejo/` moved (#133 touched the landing/seat-posting paths); `refocus/` is
   byte-identical between the two refs, so its two objects change only in the
   `source-ref` annotation and the header's pin line — the tree the sandbox runs
   is the same.

WHY IT IS SEPARATE (the PIN HOLD): El Director has not cleared cb0d8376 for the
sandboxes, so the pin must be droppable without touching the delivery machinery
of commit 1. Commit 1 is complete and correct at c5ac96f5 on its own.

Landing note: this commit should not land until #133-fresh approves.

Lab-Run: IR-20261111-extdel
All checks were successful
CI Review / helm-validate (pull_request) Successful in 11s
Required
Details
CI Review / receiver-test (pull_request) Successful in 7s
CI Review / runner-manifest-test (pull_request) Successful in 13s
CI Review / alert-receiver-test (pull_request) Successful in 28s
Lint & Validate / shellcheck (pull_request) Successful in 10s
Required
Details
Lint & Validate / yaml-lint (pull_request) Successful in 29s
Required
Details
CI Review / record-sql-test (pull_request) Successful in 58s
Lint & Validate / terraform-validate (pull_request) Successful in 1m59s
Required
Details
CI Review / cockpit-e2e (pull_request) Successful in 2m21s
CI Review / cockpit-test (pull_request) Successful in 2m59s
CI Review / dispatcher-test (pull_request) Successful in 3m18s
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin plane/IR-20261111-extdel-v2:plane/IR-20261111-extdel-v2
git switch plane/IR-20261111-extdel-v2
Sign in to join this conversation.
No reviewers
No labels
operator-review
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Homelab/infra-core!958
No description provided.