Skip to content

CI: move required runners to Ubicloud standard (ubicloud-standard-16-arm) - #6107

Merged
briansrls merged 2 commits into
mainfrom
session/bright-cat-462-ubicloud
Jul 1, 2026
Merged

briansrls merged 2 commits into
mainfrom
session/bright-cat-462-ubicloud

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What

Switches required CI (ci.yml, all 3 jobs) off the self-hosted [self-hosted, linux, arm64] fleet onto Ubicloud ubicloud-standard-16-arm (16 vCPU / 48 GB) dedicated runner VMs.

Why (stabilize)

Per operator directive: take required CI off the self-hosted fleet "for now." The fleet is the source of the recurring pain — sccache flakes, OOM-kills, and the spawn-width budget mismatch. On Ubicloud each job gets its own VM, so the 10× oversubscription / memory-admission problem that motivated the whole fleet budget tree disappears by construction (no co-residence).

Modeled, not hand-hacked

  • gunbc_ci_runner_spec → RunsOnExpression { expression: gunbc_ci_ubicloud_runner_label }. New single-authority data decl gunbc_ci_ubicloud_runner_label = "ubicloud-standard-16-arm". (Used the existing RunsOnExpression variant rather than polluting GitHub's hosted RunnerLabel enum with a third-party label.)
  • ci_runner_seam_witness_test flipped to assert the runs-on is the Ubicloud hosted label (was: self-hosted arm64). Green by execution.
  • .github/workflows/ci.yml regenerated — byte-drift-gated against the model.

arm64 chosen to keep the current arch (zero arch-change risk); 48 GB clears the measured rust_tests ~37 GiB peak. One knob to resize: gunbc_ci_ubicloud_runner_label.

Scope — reliability now, speed as a clean follow-up

This is the reliability half. The ~9× floor speedup (spawn_width 1 → ~9 on a 48 GB VM) is deliberately not here: the floor width fold's cap gunbc_ci_runner_cgroup_memory_cap (8 GiB) is the load-bearing authority for the self-hosted fleet budget tree (fleet_host_budget, ci_runner_placement, ci_budget_tree + witnesses). It is genuinely two concepts now (dormant self-hosted cap vs active Ubicloud VM cap); a §3 de-conflation is the right move but shouldn't ride in a stabilization PR that touches the floor scheduler.

Merge coordination

Hold merge behind the in-flight re-revert of #6078's resurrected roster (adhoc-9575c77c) — this PR adds one self-tested data decl the resurrected roster would flag as unrostered.

🤖 Generated with Claude Code

…arm)

Stabilization move (operator directive): take required CI off the
self-hosted arm64 fleet, which is the source of the sccache flakes,
OOM-kills, and the spawn-width budget pain. Each Ubicloud job runs on
its OWN dedicated VM, so the 10x-oversubscription / admission problem
that motivated the whole fleet budget tree dissolves by construction.

Modeled, not hand-hacked:
- gunbc_ci_runner_spec -> RunsOnExpression "ubicloud-standard-16-arm"
  (16 vCPU / 48 GB, arm64 to keep the current arch — zero arch-change
  risk). New single-authority data decl gunbc_ci_ubicloud_runner_label.
- ci_runner_seam_witness flipped: asserts the runs-on is the Ubicloud
  hosted label (was: self-hosted arm64). Green by execution.
- ci.yml regenerated (byte-drift-gated) — runs-on on all 3 jobs.

Scope: this is the RELIABILITY half. The ~9x floor speedup (spawn_width
1 -> ~9 on a 48 GB VM) needs a separate §3 cap de-conflation: the floor
width fold's cap (gunbc_ci_runner_cgroup_memory_cap, 8 GiB) is the
load-bearing authority for the self-hosted fleet budget tree
(fleet_host_budget, ci_runner_placement, ci_budget_tree + witnesses), so
it is genuinely two concepts now (dormant self-hosted cap vs active
Ubicloud VM cap). Splitting it is deliberate follow-up, kept out of this
stabilization PR so it does not touch the floor scheduler.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 1, 2026
Scope-creep fix per review: the runner_spec_from_offer + ci_runner_seam
witness edits are unrelated to boundary-coverage; they live in #6107
(CI -> Ubicloud). Restore both files to main so this PR is boundary-coverage only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…n/cargo

The self-hosted fleet had cargo pre-baked at the isolated $CARGO_HOME/bin;
a fresh Ubicloud VM has cargo on PATH (via setup-rust-toolchain + the pinned
default toolchain in the isolated RUSTUP_HOME), not at that hardcoded path.
ci_release_build_line -> 'cargo build ...'; propagates to both jobs and all
eagain retries. ci.yml regenerated; drift + serializer witnesses green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@briansrls
briansrls merged commit 7d03d93 into main Jul 1, 2026
1 of 2 checks passed
@briansrls
briansrls deleted the session/bright-cat-462-ubicloud branch July 1, 2026 20:02
briansrls added a commit that referenced this pull request Jul 1, 2026
…dard-16-arm) (#6107)" (#6111)

Operator directive: put CI back on srv1/srv2. The ubicloud move bought no
wall-clock — the dominant cost is the serial batch-1 dsl_compile_clean_gate
(~47min, 1 node / 1 resolve-group, spawn_width-immune), so a dedicated
16-vCPU VM runs the same ~50min as the fleet. No use renting VMs for it;
the real levers (affected-set-scoped compile-clean, cross-run resolve
memoization, sharding the gate) are tracked on the roadmap (#6110 §2).

Full revert of the #6107 bundle (spec + seam witness + $CARGO_HOME cargo
path, ci.yml regenerated via main_wet; drift gate + ci_runner_seam_holds
PASS by execution). Also heals the pre-existing .gitignore drift (stale
srv3 dnsmasq row) — same one-line heal as #6110, merges cleanly either
order.

Known residual, accepted by operator: fleet sccache flakes / OOM exposure
return, and deploy_dashboard_srv1's LocalShell premise ("runner is ON
srv1") is only restored when srv1 claims the job — [self-hosted, linux,
arm64] can land on srv2 (wrong-host deploy risk; tracked as 2-cd-transport
+ G1 placement on the roadmap).

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Jul 11, 2026
Self-hosted fleet has no free slots (operator, 2026-07-11); route this
PR's iteration to ubicloud-standard-16-arm so the lens work is not
gated on fleet capacity. Same move as the #6107 -> #6111 precedent.

gunbc_ci_runner_spec() returns the ubicloud label; the fleet
derivation is preserved untouched as gunbc_ci_runner_spec_fleet_derived()
and ubicloud_iteration_routing_note carries the revert obligation.
Workflows regenerated from the authority via main_wet (drift gate
stays coherent): runs-on [ubicloud-standard-16-arm] at ci.yml
build_release/floor/emit-determinism and falsifier.yml.

Revert = git revert this single commit + regen (or just revert; the
regenerated ci.yml/falsifier.yml are included here).
briansrls pushed a commit that referenced this pull request Jul 12, 2026
… cost/routing work (#6489)

* witness-cost-locality lens v0: one typed verdict for the two ambient-coupling axes (receipt-only)

One law: witness cost must be denominated in its subject (the DESIGN 5
denomination law). Two detectable projections at module grain:
DataBreadth (closure reaches an ambient-read carrier: filesystem_read
callers + the decl_facts reflection home) and LayerDepth (closure spans
>=2 compiler pipeline stages - the round-trip shape). Verdict algebra +
census receipt + precision-frontier disclosures as data; six fixture
witnesses incl. the single-stage boundary and a red control (law
perturbed to >=1 flips single_stage_closure_stays_local red - receipted).

Census 2026-07-11 over the 732-entry roster: Local 483 / LayerDepth 229 /
DataBreadth 9 / both 11; derives the operator-ruled-offline enforcement
rows and the execution/ exclusions; falsified two naive laws (decl_facts
reflection invisible to filesystem_read grep; hermetic fixture rows
over-flagged - the declared InputEnvelope is the override authority).
LayerDepth is receipt-only until fn-grain call-graph reachability lands
(ci_yaml counter-receipt: stage-type imports are not stage execution).

Dissolve-on: fn-grain reachability + InputEnvelope declarations wired
into floor admission; the witness_exclusion hand-rows and this v0
roster retire together.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Add the required construction_justification row (cursor review)

WallAfterGrounding dissolving to SingleAuthority: the verdict is
validation-tier until fn-grain reachability + InputEnvelope declarations
let floor admission consume it, at which point non-Local rows are
structurally absent from the per-PR plan (the single authority) and the
lens dissolves per its precision-frontier note.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* [ITERATION-ONLY - REVERT BEFORE MERGE] Route CI to ubicloud runners

Self-hosted fleet has no free slots (operator, 2026-07-11); route this
PR's iteration to ubicloud-standard-16-arm so the lens work is not
gated on fleet capacity. Same move as the #6107 -> #6111 precedent.

gunbc_ci_runner_spec() returns the ubicloud label; the fleet
derivation is preserved untouched as gunbc_ci_runner_spec_fleet_derived()
and ubicloud_iteration_routing_note carries the revert obligation.
Workflows regenerated from the authority via main_wet (drift gate
stays coherent): runs-on [ubicloud-standard-16-arm] at ci.yml
build_release/floor/emit-determinism and falsifier.yml.

Revert = git revert this single commit + regen (or just revert; the
regenerated ci.yml/falsifier.yml are included here).

* Closure facts + per-PR admission law: the transitive-carrier case becomes provable, and verdict x envelope decides the lane

Extends the v0 lens with the fact half its census note promised:

- ModuleImportFact + import_closure: module-grain closure over declared
  import facts, the |E|-sweeps fixpoint shape sanctioned by
  v2.lens.affected_set (pass + frontier-stability + doubled-facts fuel,
  early-stable). Terminates on cyclic FACT rows - the substrate refuses
  cyclic imports, but the fold must not trust its input.
- witness_cost_locality_from_facts: closes over the facts so the
  transitive carrier (the enforcement_live falsification - the corpus
  read two hops away) is provable in fixtures, not just prose.
- WitnessInputEnvelope + per_pr_admission: the admission matrix
  (verdict x declared envelope), fail-closed with
  declaration-wins-when-stricter. DeclaredCorpusInput always routes to
  the scheduled lane; DeclaredBoundedFixture is the hermetic override
  (reachability over-approximates; the scheduled falsifier lane is its
  audit); EnvelopeUndeclared admits only Local - the
  refused_undeclared_when_envelope_unknown shape from InputEnvelope P0.
  RouteScheduledLane is a typed routing verdict, never a silent drop.

Witnesses (7 new, 13 total, all green by execution; the suite itself
stays Local-class: 393ms resolve, 0ms eval, fixture-only):
- two-hop transitive carrier couples on DataBreadth; severing the mid
  hop flips it Local (the discriminating pair)
- cyclic facts terminate and still reach the carrier
- admission matrix cells incl. the RED control: undeclared + coupled
  never rides the continuous floor

* Resolve the cargo binary at toolchain-pin time; stop baking the fleet's shim path into the build line

The build line invoked "$CARGO_HOME/bin/cargo" - a fleet fact fused
into the job model. On a runner image whose rustup pre-exists (ubicloud,
GitHub-hosted), setup-rust-toolchain never runs rustup-init, so no shim
lands under the isolated $CARGO_HOME and the build dies with "No such
file or directory" (run 29161556017). The isolated RUSTUP_HOME/CARGO_HOME
env still governs whichever shim exists - only the shim's LOCATION is
realization-specific.

Fix: the pin step (already the "make the isolated toolchain invocable"
step, name unchanged so the cost-floor roster keeps resolving; no new
run-step so the raw-script count pin holds) resolves CARGO_BIN once -
isolated shim if present, else PATH - and refuses loudly when neither
exists (fail-closed, DESIGN 5). ci_release_build_line invokes
"$CARGO_BIN"; the retry escalations' env-prefix composition is
unchanged since it stays one word. Falsifier inherits via the shared
prelude. Workflows regenerated via main_wet.

witness_rustup_run_plain_not_quoted repinned as
witness_rustup_run_block_scalar_not_quoted: the pin step is now
multi-line so its run correctly serializes as a block scalar; the
property the witness guards (quote-laden content never YAML-escaped,
negative control kept) is unchanged. ci_yaml_serializer_keystone_holds
green by execution; 18-entry consumer sweep green except 3 witnesses
red on unedited baseline too (pre-existing/environmental).

* [ITERATION-ONLY - REVERT BEFORE MERGE] Reconcile the runner seam witness with the ubicloud override

Cursor catch (review on the folded #6490, restated on #6489): the
routing override left ci_runner_seam_holds red - it pinned
gunbc_ci_runner_spec() to the fleet derivation and the yaml to
[self-hosted, linux, arm64].

Reconciliation, discriminating in both directions during the window:
the fleet-derivation witnesses repoint to
gunbc_ci_runner_spec_fleet_derived() (the derivation authority stays
proven and un-drifted), the live-spec witnesses pin the override label
exactly (drift of the override itself is caught), and the
workflow==live-spec seam witness is unchanged. ci_runner_seam_iteration_note
carries the revert obligation; this commit reverts together with the
routing commit (3f203d8). ci_runner_seam_holds green by execution.

* Revert the iteration-only ubicloud routing (operator go 2026-07-11: iteration window closed, focus on merge)

Restores gunbc_ci_runner_spec() to the fleet derivation as the single
runner authority and the seam witnesses to pinning it (reverts
3f203d8 + 36e4cd3 as one motion); workflows regenerated via
main_wet back to [self-hosted, linux, arm64]. The CARGO_BIN
resolution (a03142d) stays - fleet-neutral portability fix, proven
by execution on both runner classes (fleet floors unchanged; ubicloud
build green run 29162064482). ci_runner_seam_holds and the serializer
keystone green by execution on the reverted head.

What the iteration window bought, for the record: the CARGO_BIN
portability bug (fixed), the 12.5-min full floor + 13.5GiB-uncapped
counterfactual receipt that pinned the fleet wedge on the memory.high
throttle (now fixed at the budget edge in #6495), and the surfacing of
the #6459 batch-2 panic (fixed in #6493).

* Runner offers modeled + one selection authority: labels, memory regime, and budgets project from the selected target

Operator asks 2026-07-11: model the runner rows (github, ubicloud;
fleet existed) and make the mappings clear - then "stay on ubicloud
for this change; self host runners are still contended."

extdeps (cited, zero fabrication):
- extdeps.cloud.ubicloud: the 10 documented runner shapes
  (runner-types.md anchor; arm 3GB/vCPU, x64 4GB/vCPU kept as vendor
  facts; the standard-16-arm observed MemTotal receipt recorded
  SEPARATELY from the catalog claim, discrepancy noted not reconciled)
- extdeps.github.hosted_runners: the Ubuntu family with repository
  VISIBILITY as a first-class axis (public 4vCPU/16GB vs private
  2vCPU/8GB for the same label - folding it away would be a
  state-space conflation); version-pinned labels, ubuntu-latest alias
  deliberately not a row

gunbc.ci_runner_target (the missing edge the iteration window proved):
- CiRunnerTarget = FleetSelfHosted | UbicloudRunner{row} |
  GithubHostedRunner{row}; selected_ci_runner_target() is THE switch
- projections: runs-on spec (fleet stays DERIVED from the fleet offer;
  cloud rows carry the provider's cited token), memory regime
  (SlotCarved{desired} with the 15GiB throttle line vs
  WholeMachine{ram}), RAM-speed budget (fleet -> slot ceiling;
  cloud -> catalog ram)
- ci_workflow, falsifier_workflow, floor budget, falsifier width all
  read the projections: flipping the selection row moved runs-on AND
  CARGO_BUILD_JOBS (4 -> 11, from the 48GB row) AND floor width in one
  regen - the propagation the label-only model could not do
- selection = ubicloud-standard-16-arm (operator routing, fleet
  contended); flip back = FleetSelfHosted + regen, nothing else moves
- falsifier now rides the selected shape too: its pinned fleet-slot
  capacity deficit witness stays parameterized on the FLEET ceiling
  (the deficit is a slot fact), while on 48GB its envelope fits with
  3x headroom - the nightly's dissolve-on path

Witnesses: ci_runner_target_witnesses (fleet-derivation identity,
ubicloud/github label projections, both regimes, cited arm ratio held
across the family, visibility-axis discrimination) + seam witnesses
repinned to the selection authority with the fleet derivation kept
live for the flip back.

* Width-fit witness measures against the machine the plan runs on (the selected target budget), not the fleet slot unconditionally

* Regen after folding the runner-offer selection into this branch (ubicloud labels + JOBS=11 + CARGO_BIN compose)

* Resolve the cargo binary at toolchain-pin time; stop baking the fleet's shim path into the build line

The build line invoked "$CARGO_HOME/bin/cargo" - a fleet fact fused
into the job model. On a runner image whose rustup pre-exists (ubicloud,
GitHub-hosted), setup-rust-toolchain never runs rustup-init, so no shim
lands under the isolated $CARGO_HOME and the build dies with "No such
file or directory" (run 29161556017). The isolated RUSTUP_HOME/CARGO_HOME
env still governs whichever shim exists - only the shim's LOCATION is
realization-specific.

Fix: the pin step (already the "make the isolated toolchain invocable"
step, name unchanged so the cost-floor roster keeps resolving; no new
run-step so the raw-script count pin holds) resolves CARGO_BIN once -
isolated shim if present, else PATH - and refuses loudly when neither
exists (fail-closed, DESIGN 5). ci_release_build_line invokes
"$CARGO_BIN"; the retry escalations' env-prefix composition is
unchanged since it stays one word. Falsifier inherits via the shared
prelude. Workflows regenerated via main_wet.

witness_rustup_run_plain_not_quoted repinned as
witness_rustup_run_block_scalar_not_quoted: the pin step is now
multi-line so its run correctly serializes as a block scalar; the
property the witness guards (quote-laden content never YAML-escaped,
negative control kept) is unchanged. ci_yaml_serializer_keystone_holds
green by execution; 18-entry consumer sweep green except 3 witnesses
red on unedited baseline too (pre-existing/environmental).

* Unbreak the post-merge-wave floor: absent declared roots skip loudly, the split-spanning gate universe, and the disposition-marker adjacency pin

Three content reds every completed floor now hits, all proven on clean
main (the 60m-timeout and batch-2-panic masks are gone, so the content
layer behind them is finally visible):

1. anchor_source_root panicked mid-floor on "dag/compiler" (run for
   PR #6497, cli_run.rs:365) - a DECLARED root from the
   medium-structure roster that does not exist on disk yet
   (modeled-before-implemented). The layer walk's own is_dir guard
   proves absence is a legitimate skip state there, but the anchorer
   panicked before the guard could run. New non-panicking
   try_anchor_source_root for declared-root walks: absence skips with
   a counted [layer-import] line (loud, never silent); CLI-provided
   roots keep the strict panicking contract.

2. affected_set_universe_gate_processes_match_declared_gates compared
   the Gate coproduct's 10 arms against gunbc_ci_gates - the ci JOB's
   slice (7) since the #6472 job split. The witness now unions
   floor+regen+emit_determinism (the same union its sibling
   witness_gate_roster_matches_coproduct_arms already used); probe
   receipt: the three slices partition the 10 arms exactly.

3. witness_floor_disposition_marker_initialized_before_docs_only_branch
   (landed in today's wave) pinned the stamp DIRECTLY adjacent to the
   docs-only branch, but the emitted script has a blank line between
   them - red on clean main from its first run. The pin now matches
   the emitted adjacency (stamp, blank, _ci_changed) and still proves
   the ordering it exists for.

Receipts: ci_spec_witnesses, all 4 affected_set_universe witnesses,
and the layering clean-tree witness green by execution with the fixed
binary. Remaining known main reds (predate today, tracked separately):
s1_closure_parses_holds (#6459 wrapper-retained diagnostic arm),
ci_deploy_witnesses.

* GithubHostedRunner projects the hosted scalar form (cursor catch)

Ground GithubHostedRunnerCatalogRow.runs_on_label in the actions grammar's
RunnerLabel closed vocabulary (extended with the cited ubuntu-24.04-arm /
ubuntu-slim spellings; runner_label_string stays the single spelling
authority) and route the GithubHostedRunner target through HostedRunner,
whose serialization is the scalar runs-on form GitHub uses for hosted
labels. A labels-list projection would have emitted the self-hosted
label-matching form. Witness repinned to the HostedRunner variant plus a
by-execution runner_yaml discrimination (scalar hosted vs flow-list
label-routed). Ubicloud stays SelfHosted label routing (provider tokens,
proven live 2026-07-11).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* ci_deploy witness: repin deploy invoke to the rooted source-root spelling

witness_deploy_run_script_invokes_gunbc_wet pinned the unrooted
'--source-root dag' while gunbc_ci_deploy_invoke emits the rooted
'--source-root "$ROOT/dag"' (witness_layer_source_flags_rooted, #6453)
- red on clean main, the third masked layer of the rooted-argv family
(#6493 repinned the scheduler-argv pair). Proven by execution: suite
false -> true on the repin, conjunct-bisected first.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* try_anchor_source_root: seed-retained scaffold receipt (cursor #6489 catch)

Hand-Rust expansion now carries the DESIGN §7 shape the same file
requires: authority rows (cli_run_source_root_anchor_scaffold sibling of
the workspace-root scaffold, bind to the declaration), named dissolve-on
(roots walk GENERATED via cli-run-reconcile-defork Chunk F, absence a
typed roster-layer diagnostic; or 5-dissolve-patches), checkable receipt
anchor + counted loc delta, scaffold witnesses green by execution, and a
discriminating unit pair (declared-present -> Some, declared-absent ->
None).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* s1_closure floor panic: wrapper-retained diagnostics must inhabit the Diagnostics coproduct

body_lower_wrapper_retained_shell constructed Accepted with a RAW
NonEmptyDiagnostics in the diagnostics field where the Diagnostics
coproduct (None | Some) is declared - the first downstream match over
Diagnostics (diagnostics_merge in the normalize child fold) panicked
non-exhaustive on every file with a wrapper-retained fn body, killing
the s1_closure witness whenever the affected set selected it. Fix wraps
the singleton in Some. Reproduced red (exact CI panic) and green by
execution via s1_file_parses on dag/std/error_primitives.dag; new
witness pins the shape and returns false (no panic) on the raw form.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Post-merge regen: plan docs re-derive the Lane D links from the merged authorities

This branch's earlier regen ran while the .dag plan authorities lacked
the link rows (pre-#6503), so it had written the docs linkless; the
merge kept that side while main brought the link rows. main_wet now
re-derives the linked docs - pair consistent, drift gate green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Two latent fleet-lane witness reds, first executed by this head's wider selection

Both red on clean main by direct execution, latent behind affected-set
skips and the batch-2 red era:

host_standup_spine: the spine gained the P0:host-identity-converge step
in #6253 (11 steps) while spine_step_tag matched exactly 10 phases with
no catchall - non-exhaustive panic on Assimilation{HostIdentityConverge}
whenever executed. Witness now describes the 11-step spine (tag arm +
ordinal shift + length/ledger pins 10->11, gap count 4 unchanged,
fn renamed ten->eleven to keep the name truthful).

fleet_show_effective_read: declared_runner_count() derives from
pool_budget / slot cap, so the #6495 re-carve (24->16GiB) moved it
10->5 and the 2026-07-03 width fixtures went stale. The parse-typing
witness now pins the literal it parses (a parse fixture must not depend
on a live-derived count - that fusion is how this went latent-red); the
srv1 convergence witness flips to assert the REAL fact, drift (the hosts
still run pre-carve width - the same oversubscription the falsifier
exit-137 receipts located), with a dissolve-on for a post-re-carve
readback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant