Skip to content

Content: personalspace install runs the template's own bootstrap (#377) - #412

Merged
immakermatty merged 2 commits into
mainfrom
agent/LP-377-install-bootstrap
Oct 14, 2026
Merged

immakermatty merged 2 commits into
mainfrom
agent/LP-377-install-bootstrap

Conversation

@immakermatty

@immakermatty immakermatty commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #377. Merge Lazurio/PersonalspaceTemplate_GEN3#4 first.

Why

lazurio personalspace install created the person's private <login>/<login>_GEN3 from the template but never ran the template's bootstrap. Its placeholders (owner-github-username, Owner Display Name) therefore stayed in personal.gen3.json and modules.manifest.json. Two things followed: the template's CI checked the instance as the template, and its live doctor took the placeholder for the owner. The doctor then reported the real owner as a forbidden collaborator of the Personalspace and of every personal module (#359 M2).

Matěj decided on 2026-10-14 ("S gbrainem, podle šablony"): the install runs the template's own bootstrap. It names the owner and creates and clones the private <login>/<login>-gbrain (root decision 0046). It does not install the gbrain CLI. The manual and the automatic install follow one rule, and the template keeps its identity logic.

What changes

These steps apply only to a Personalspace that this run has just created:

  • Asked before anything is created, in step create:
    • Bun, at ~/.local/bin/bun as the module lifecycle uses it, else on the PATH. Otherwise personalspace-toolchain-missing.
    • An identity to commit with: the operator's Git identity, else the person's GitHub noreply identity (see Verification). git-identity-missing only when neither is known.
    • A predictable cause therefore never leaves a created repository behind.
  • New step bootstrap.
    • First it checks that the fresh clone is clean and carries the template's marker personalspace.template.json. Otherwise personalspace-template-unexpected.
    • Then it runs bun run --cwd <checkout> bootstrap -- --login <login> --display-name <name> --apply with the operator's gh and git. The name is the GitHub profile's (name of GET /user, newly read by parseViewer), else the login. --install-gbrain is not passed.
    • The template's own doctor-outcome rule decides acceptance, so a doctor that is incomplete only because of gbrain.cli passes.
    • The Platform writes neither declaration. It reads what the template wrote and requires it to name the signed-in account with a gbrain repository.
  • New step push. It commits exactly the files the template's manual names (step 7), with its commit messages:
    • personal.gen3.json and modules.manifest.json, to main of the new Personalspace;
    • gbrain/.gitignore, to main of the new gbrain repository.
    • Failure codes: personalspace-commit-failed, personalspace-push-failed, gbrain-commit-failed, gbrain-push-failed.
  • A failed bootstrap (personalspace-bootstrap-failed):
    • The detail gives the template's own reason, what exists (the repository is created and cloned), and that nothing was committed, pushed or removed.
    • It names the next step: fix the cause, run the same command in the checkout (it reuses the gbrain repository and clone it already made), then commit and push as the template's manual says.
  • An existing Personalspace, found on GitHub or already in the Folder, is never bootstrapped. bootstrap is reported skipped with what it found.
    • When it still holds the placeholders, the item succeeds with warnings: ["personalspace-placeholders"].
    • The step's detail names the next step: run the template's bootstrap in a task worktree (personalspace/.worktrees/<task>), commit the two files and open a pull request into the Personalspace. The template PR adds the worktree support this needs.
  • The new code sits behind one injectable seam, ContentHost.personalspace (src/content/personalspace-bootstrap.ts).
  • The CLI help and the final line name the warning.
  • The Launchpad shows "Nastavuji" and "Ukládám na GitHub" only where the Personalspace is created, with failure sentences in cs and en.
  • Docs: docs/content-sync.md (The Personalspace) and decision F9's addendum of 2026-10-14, with alternatives and risks.

Why a re-run stays report-only

Re-running lazurio personalspace install on an existing Personalspace does not bootstrap it and does not open the pull request itself, for three reasons:

  1. Its main is the person's Publication.
  2. Bootstrapping would execute code of a repository that this run did not create. The resident root's create-personalspace.mjs refuses that too ("nikdy nespouští kód z předem existujícího repa").
  3. It would create a gbrain repository and a branch nobody asked for.

The warning carries the exact next step, so an agent can do it in a task worktree with a pull request the person merges.

What deliberately does not change

  • The gbrain CLI is not installed.
  • No repository is ever removed.
  • Existing Personalspaces are left as they are.
  • Organization install is unchanged.
  • The template's identity builders are not duplicated: the Platform only reads the two files and knows the placeholder string, to report it.

Verification

  • bun run check:static passes: lint, typecheck, check:public, proof build and smoke.
  • bun test --parallel=4 on the first head gave 2 load timeouts (tests/folder-tools.test.ts, tests/frozen-install-process.test.ts, Flaky under a loaded full run: frozen-install-process "real install stops when its hook changes .bunfig.toml" hits the 5 s test timeout #381); both pass alone. The current head is fully green (below).
  • New and changed tests, with a stub GitHub and real git over local bare repositories. The fixture template's bootstrap does to the two files what the template's own does.
    • tests/content-install.test.ts:
      • A fresh install names the owner with the profile's name, creates and pushes gbrain, and leaves both checkouts clean.
      • A failed bootstrap leaves the repository created and unpushed, with the template's reason and the next step.
      • Nothing is created without Bun or a Git identity.
      • An unmarked repository is never bootstrapped.
      • An existing Personalspace with placeholders, both just cloned and already present, is reported with the warning and never touched.
    • tests/personalspace-bootstrap.test.ts: the exact command line and environment (no stray variables, no --install-gbrain), the reason line, ready, and publish, which commits only the named files and reports a refused push as stage push.
    • tests/content-github.test.ts: the profile's name.
    • tests/content-view.test.ts: the new steps appear only on creation.
    • tests/content-routes.test.ts: the job's steps now include the skipped bootstrap.
  • Cross-repo E2E (manual, scratch outside the repo): the install core with the real template bootstrap from Bootstrap: run under a Lazurio Folder and from a task worktree (LazurioPlatform#377) PersonalspaceTemplate_GEN3#4, in a Folder made by initializeFolder (not a Git repository), with a fake gh for the template.
    • Result: find, create, clone, bootstrap, push, check all done. main names example / "Ex Ample", and gbrain's .gitignore is pushed.
    • The template's doctor afterwards is INCOMPLETE only on gbrain.cli, and root.* is N/A ("Lazurio Folder mimo Git").
  • Rebased onto main, which now includes the M2 stack (Modules: one module generator in the Platform, with the personal form (M2 1/3, #359) #394, Modules: lazurio module create personalspace/<slug> --dry-run, and module prepare dispatched (M2 2/3, #359) #396, Modules: lazurio module create personalspace/<slug> --confirm creates the confirmed plan (M2 3/3, #359) #399).
  • Commit identity (review follow-up). A Remote Environment sets no user.name or user.email, so Lazurio's commits on the person's behalf use the operator's own Git identity where it is set. Otherwise they use the person's GitHub identity: the profile's name (else the login) and <id>+<login>@users.noreply.github.com. It is given per commit with git -c, only for the missing fields, and is never written into any Git configuration. This covers the install's Personalspace and gbrain commits and the first commit of lazurio module create (module-create-run.ts). git-identity-missing and commit-failed remain only when neither identity is known. Tests: with an identity set, it is the author and committer; without one, the noreply identity is, and no .gitconfig or local user.* appears.
  • After the rebase and identity change: bun run check:static passes, and bun test --parallel=4 gives 3458 pass, 7 skip, 0 fail. GitHub CI on the head is green.

Risks and open points

🤖 Generated with Claude Code

Note

Run the template's own bootstrap during personalspace install

  • Newly created Personalspaces now run the template's bootstrap after cloning, then commit and push the generated owner files and gbrain .gitignore via install.ts and the new bootstrap service in personalspace-bootstrap.ts
  • Preflight checks for a usable Bun executable and a commit identity run before the GitHub repository is created. Missing toolchain or identity fails with new stable codes in model.ts
  • Commits use the operator's Git identity when configured; otherwise the signed-in viewer's GitHub noreply identity is supplied per commit, without writing Git configuration. Applies to module creation too via module-create-run.ts
  • Existing Personalspaces are never bootstrapped. One containing template placeholders now succeeds with a personalspace-placeholders warning and manual worktree guidance
  • Risk: ModuleCreateRunHost now requires GitHub viewer access; hosts without it will not compile. Failed bootstraps leave the created checkout in place but uncommitted and unpushed

Macroscope summarized 4782fa2.

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@immakermatty Exact-head QA on 207ff03 (base 2727629): CHANGES_REQUESTED.

Blocking regression: this PR silently reverts the already-merged #411 (its merge commit IS this PR’s base). In src/launchpad/apps-view.ts, appsHomeParts no longer accepts the verified personal holder or offers new-personal-module; an empty Personalspace Workspace disappears, and the personal section is renamed back to Osobní. src/launchpad/catalog-panel.ts drops the personal "+ Nový modul" tile; src/launchpad/prompts.ts and server.ts remove the holder-gated new-personal-module route; ui.ts removes the holder refresh. docs/decisions.md also deletes #411’s accepted 2026-10-13 addendum and its evidence. Thus the holder cannot found their first personal module from the Apps home even though #411 and #399 are merged. The PR description says Organization install is unchanged and does not disclose this product removal. Restore #411 behavior, decision text and its regression tests; keep the #377 bootstrap changes separate. Then rerun checks and request review on the new head.

Evidence: diff against base #411; isolated checkout bun run check:static PASS, four focused suites 62 PASS/0 FAIL; git diff --check PASS; CI 38553794061 green on this head; zero review threads. Green tests cannot cover behavior whose tests this PR deleted. Template #4 is separately approved but remains the merge-order dependency. No merge performed.

immakermatty and others added 2 commits October 14, 2026 13:18
A Personalspace created by lazurio personalspace install kept the template's
placeholders (owner-github-username, Owner Display Name): the install never
ran the template's bootstrap, so its CI checked the instance as the template
and its live doctor reported the real owner as a forbidden collaborator.

Matěj's decision of 2026-10-14 ("S gbrainem, podle šablony"), decision F9's
addendum of 2026-10-14: for a Personalspace this run has just created, the
install runs the template's own `bun run bootstrap -- --login <login>
--display-name <profile name, else login> --apply` in the fresh, clean,
marked checkout. The template names the owner and creates and clones the
private <login>/<login>-gbrain (root decision 0046); the gbrain CLI is not
installed. The new push step commits exactly the files the template's manual
names and pushes them to main of both new repositories. Bun and the
operator's Git identity are checked before anything is created. A failed
bootstrap leaves the repository created and unpushed, with the template's
reason and the next step. An existing Personalspace is never bootstrapped:
one that still holds the placeholders succeeds with the warning
personalspace-placeholders and the next step (the bootstrap in a task
worktree and a pull request).

The Platform writes neither declaration; the template's bootstrap is behind
one injectable seam (src/content/personalspace-bootstrap.ts). The Launchpad
shows the two new steps only where the Personalspace is created.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…has none

Nothing on a Remote Environment sets git's user.name or user.email, so the
Personalspace install stopped at git-identity-missing on a fresh personal
Environment (a regression of the first run's "Připravit"), and the first
commit of lazurio module create personalspace/<slug> failed (commit-failed).

Commits Lazurio makes on the person's behalf (the Personalspace's and
gbrain's after the template's bootstrap, a personal module's first) now use
the operator's own Git identity where it is set, and otherwise the person's
GitHub identity from the viewer gh already returns: the profile's name, else
the login, and <id>+<login>@users.noreply.github.com. It is given per commit
(git -c user.name=… -c user.email=…, only for the missing fields) and never
written into any Git configuration. git-identity-missing and commit-failed
remain only when neither is known.

Tests: with an identity set it is the commits' author and committer; without
one GitHub's noreply identity is, for both install commits and the module's
first commit, and neither the home nor the checkouts gain a Git
configuration; without either nothing is created.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@immakermatty
immakermatty force-pushed the agent/LP-377-install-bootstrap branch from 207ff03 to 4782fa2 Compare October 14, 2026 11:20

@agentrozjedemeai agentrozjedemeai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@immakermatty Exact-head QA on 4782fa2 (base 2727629): APPROVED. My prior #411 removal finding on 207ff03 was a two-dot comparison artifact after main advanced; the old branch’s merge-base patch did not remove #411. This rebase removes that ambiguity: the exact-base diff changes only src/launchpad/content-view.ts and messages.ts under src/launchpad; #411 apps home, tile, route, holder refresh and decision remain unchanged. Isolated detached checkout: check:static PASS; seven focused suites 98 pass / 0 fail, content-github 8 pass / 0 fail; git diff --check PASS. Live CI: required scope, static, test shards and Ubuntu check SUCCESS; 0 review threads; Template #4 merged. Remaining documented limitation: a real GitHub Remote Environment install was not exercised locally. Review only; no merge.

@immakermatty
immakermatty merged commit 12c18a3 into main Oct 14, 2026
7 checks passed
@immakermatty
immakermatty deleted the agent/LP-377-install-bootstrap branch October 14, 2026 11:30
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.

personalspace install leaves the template's placeholders in the person's Personalspace

2 participants