Repository navigation
Workspace presets: three hosted Machine profiles, derived from the handover, adopting an existing Folder - #13
Conversation
…o branches)
The upstream identity schema now has a oneOf with a personal branch:
machine.kind "personal-vm", owner {kind "principal", github_login, github_id},
host {kind "provider-estate", estate_id, custody_repository, record_path} and
a required tailnet identity. Vendored byte-for-byte from tag v0.12.59
(commit dd0dbfaab4807f197f5f65f102fc74bd22496499); MachineContext is a union
of the two branches and conformance tests cover both with real-shaped
synthetic fixtures, including every cross-branch mix the schema refuses.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…dover
Presets are data in src/folder/presets.ts: local, hosted-personal,
hosted-organization-personal and hosted-organization-team, each a whole
composition (fixed access/purpose axes, communication defaults, Personalspace
policy, provider identity mode, surfaces, supervision). The preset is derived
from the typed handover fields only: personal-vm -> hosted-personal,
workspace-vm with owner.team -> hosted-organization-team, without ->
hosted-organization-personal; a workstation is local. A handover allows
exactly the presets of its Machine kind; a personal VM never takes an
Organization preset and vice versa.
Preferences schema 2 stores the preset reference (name, version 1, whether it
was derived or an explicit choice) and the immutable Machine binding projected
from the handover (null on a workstation). The whole composition is validated
on every parse. The profile-change request is now {preset?, profile} on the
same preview -> apply path for CLI and Launchpad; a disallowed preset or a
profile whose fixed axes disagree with the preset is a blocked plan, never a
write. `lazurio machine folder-init` derives the preset by default, accepts
--preset within the allow-list and takes the preset's communication defaults.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…mpty layout folder-init no longer demands an empty organizations/ and personalspace/. The Folder owns exactly AGENTS.md and .lazurio/ at the top level; the two work directories may hold content and are never traversed, listed beyond existence, moved or written; launchpad.gen3.json and launchpad.gen3.local.json are tolerated by name; any other top-level entry fails closed naming it. An Organization preset (Personalspace never present) accepts the empty personalspace/ that Machines precreates and refuses a used one without deleting anything. A re-run on an adopted Folder reports already-adopted and changes nothing; a different handover or unrecognized state is refused by name. Refusals surface from `lazurio machine folder-init` as blocked results with reason, entry and a next step. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ding The generated document is short context for every agent starting inside the Folder: which Machine this is and whose (owner, team, tailnet node, host), who the Principal is here (owner of a personal VM, the assigned operator of a work VM, the connected Team member on a shared team VM), the Personalspace boundary (present and intimate / never present), where Organization repositories live, the provider identity mode, and how work is done (Draft in a worktree and PR, the Organization's AGENTS.md and the Lazurio root rules). A relationships section renders only when the recorded binding carries one; upstream has no such field yet. Template revision base-instructions-2; snapshots per preset and locale. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… one flow
/api/profile returns the preset reference, the presets the recorded handover
allows, the immutable Machine binding and the profile. The panel renders the
binding as text only, offers the preset from the allow-list and the three
communication axes; access and purpose are no longer controls, they belong to
the preset. Preview and apply take {expectedRevision, preset?, profile} on
the same core use case as the CLI; a preset outside the allow-list is a 409
blocked plan and a request carrying a Machine binding is refused.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e-pin v0.12.59 workspace-presets.md records the implemented local preset model (names, derivation and allow-list, immutable/mutable split, storage, adoption) next to the typed-request direction that stays unimplemented. machine-handover.md records the byte-for-byte re-pin to Machines v0.12.59 (commit dd0dbfa), both schema branches, adoption instead of the empty layout, and the exact command a Machines resident role calls after handover with its JSON result shapes. Decision F10 is amended (2026-09-22, accepted by the Principal); F2, acceptance, ARCHITECTURE and the remaining references use the new names. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ptions as usage errors
Found on the native Linux ARM64 run of 2026-09-22 (docs/evidence). Ubuntu's
default umask 0002 leaves a hand-created ~/Lazurio and its children 0775; the
ownership rule refused correctly but reported only the generic "Folder
operation failed" with exit 1. folder-init now refuses before any mutation
with {"kind":"blocked","reason":"folder-directory-shared","entry":…} and exit 2
for the Folder root, organizations/ and personalspace/, and the resident
precondition (mode 0755 or 0700) is documented. An unknown or malformed
option is a MachineUsageError: the machine help on stderr and exit 2, not a
failed Folder operation. The evidence file records the setting, the verbatim
log and both defects as found-and-fixed.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
agentrozjedemeai
left a comment
There was a problem hiding this comment.
Exact-head QA: APPROVED
Reviewed SHA: 41f04611f0cbe4791d7f303e90f2ffeecedfbf8b
Evidence:
- The requested decision contract matches the implementation: handover-only derivation, the personal/workstation versus Organization allow-list boundary, explicit Organization-preset selection, and whole-composition validation are enforced in the state and shared profile-change path.
- Folder adoption treats only
AGENTS.mdand.lazurio/as owned. The implementation and focused tests preserve existing work inorganizations/andpersonalspace/, tolerate the two named legacy launchpad files, and refuse foreign, used-Personalspace, symlink, changed-layout and shared-directory cases before mutation. - Schema 1 preferences are refused; schema 2 stores a validated preset reference, immutable Machine binding and profile. The Launchpad exposes the binding read-only and sends only
{expectedRevision, preset?, profile}through preview then apply. Local browser smoke exercised an allowed Organization preset change plus all three communication axes; revision advanced from 1 to 2 while the binding stayed unchanged and access/purpose remained absent from the controls. - The vendored schema is byte-identical to
HumanAndMachine-ai/Machinescommitdd0dbfaab4807f197f5f65f102fc74bd22496499; its SHA-256 is2dc6dd3dd3b62c35e2ece4d6b48f4ea65d6e2f9f838db1e684a7628a9b7e9da1. GitHub Releasev0.12.59targets that same commit. - Local focused gate: 79 pass / 0 fail across handover, preset, state, change-profile, Launchpad and Machine-context suites. Full
bun run check: 496 pass / 4 platform skips / 0 fail; lint, TypeScript, public-policy guard, proof build and proof smoke passed. - CI was rechecked on this exact SHA:
check (ubuntu-24.04)andcheck (macos-14)are SUCCESS. No active review threads. - The native Ubuntu ARM64 evidence accurately distinguishes its fixture-handover scope from unproven real-Machines, native-Launchpad and post-log reporting-fix claims.
Conclusion: the requested local preset-model and existing-Folder adoption scope is coherent with F10 and has reproducible exact-head evidence.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
agentrozjedemeai
left a comment
There was a problem hiding this comment.
P1 — handover recovery přijme nový cizí top-level vstup
resumeInitialization u handoveru ověří pouze zaznamenané identity root / organizations / případně personalspace přes verifyHandoverLayout (src/folder/resume-initialization.ts:102–103, src/folder/handover-layout.ts:129–136). Nevolá však znovu requireAdoptableLayout a tedy před dalším zápisem nevynutí top-level allow-list.
Reprodukce na tomto exact headu:
- vytvořím validní organizační handover Folder;
initializeHandoverFolderpřeruším na checkpointujournal;- do rootu Folderu zapíšu
stray.txt; resumeInitializationvrátí{ "kind": "recovered", "revision": 1 }, vytvoříAGENTS.mdastray.txtponechá.
To odporuje explicitnímu kontraktu, že jakýkoli jiný top-level vstup Folderu initialization zastaví a pojmenuje. Zde recovery dále zapisuje do Folderu, který by fresh handover odmítl.
Prosím doplňte při handover recovery před jakýmkoli doplněním výstupu/archivací stejnou claimed allow-list kontrolu jako při initializaci — s Personalspace policy odvozenou z již validovaných preferences — a kontraktní test pro přerušení po journalu + nově přidaný stray.txt. Očekávání: named foreign-entry, žádný nový AGENTS.md ani jiný recovery zápis.
Lokálně jinak prošlo bun run check, focused handover/recovery 35/35, plná sériová sada 496 pass / 4 explicitní platformní skip / 0 fail a git diff --check; právě proto je třeba přidat chybějící regresní scénář.
…l help states the data mount, the candidate smoke runs again (#487) * Release: the candidate smoke accepts the preset a new Folder states `scripts/smoke-candidate.ts`, the documented check of a locally built candidate (docs/release-cycle.md, Build), expected `folder-init` to answer exactly `{kind, revision}`. Since the workspace presets (#13) the answer also names the preset, so the smoke failed on every candidate before it reached the Launchpad. It now checks the kind, the revision and that a preset is named; the rest of the smoke is unchanged and passes on a candidate built from main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Content: install help and the parity table say a module's data mount follows it Since #476 (B7 amendment of 2026-10-17) `lazurio organization install` clones a module's declared data mount (repository_db_mount) on its declared branch when the module is there after the install. Its help still said repository databases are left out, and the parity table's row 15 said the same. Both now state the shipped behavior: the data mount follows its module, other database slots and infra stay out. Text only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Launchpad: a tile whose Open was refused shows the reason on the overview Opening a workstation module from its tile starts it first. When the start was refused (data-mount-denied, required-slot-missing, a missing secret, …) the page said "<name> could not be opened. Its overview says why." and showed the overview, but the overview only read the status (Stopped) and never said why: the reason appeared only after pressing Start there. With #476 a missing data mount is now the most common such refusal. The refused start's sentence is now handed to the overview it navigates to and shown there exactly as after Start, and a refused start ends at once instead of polling the status first. Nothing changes for a start that succeeds, is pending or for a hosted Environment's tiles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Launchpad: a refused Open from the overview itself shows its reason there too Pablo's review of #487: the refusal reached the overview only when another module's overview was shown before; an Open from the same overview (its Open button or its favourite) left "Stopped" while the notice promised the overview says why. The reason is now put into the matching lifecycle whether it is fresh or already shown (lifecycleShown), taken once; another module's refusal stays for that module. Covered by tests/catalog-panel-lifecycle.test.ts (home tile, same overview, unrelated refusal). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tests: a recorded duration for the new catalog-panel lifecycle test Without an entry the time-balanced shard split moved files between the two CI shards and exposed the known background-GitHub-peek flakiness (#425) three runs in a row on shard 1. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Launchpad: the overview's lifecycle state in a module of its own The test of lifecycleShown imported catalog-panel.ts, the whole Apps panel, into a parallel test worker; since then CI shard 1 failed on unrelated Launchpad tests each run (port in use, settings peeks). The pure state function now lives in src/launchpad/module-lifecycle-state.ts with type-only imports, and the test imports only that. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Launchpad: the overview's lifecycle state in a module of its own (rest of the move) Completes 507ef1a, which committed only the test's rename: lifecycleShown and its types leave catalog-panel.ts for src/launchpad/module-lifecycle-state.ts (type-only imports), the test imports that module, and tests/timings.json names the renamed test file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ermes-agent#17 The fork change that marks a collected sign-in session cancelled under its lock is now a real pull request, approved for the release with #11, #13 and #14; F63 named it only generically. The rule itself is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Motivation
Real Machines are being handed over with
/etc/lazurio/lazurio.machine.json, and the Principal decided (2026-09-22) how the Lazurio Folder on them is configured: three hosted workspace presets with exact names, derived from the handover instead of chosen from a free list, an immutable/mutable split in the Launchpad, andfolder-initthat adopts the Folder real Machines already have instead of demanding an empty layout. Nothing was implemented under the earlier names (hosted-private,hosted-team), so they are renamed without compatibility.What changes
src/machine/lazurio-machine.v1.schema.jsonis byte-for-byte Machines v0.12.59 (commitdd0dbfaab4807f197f5f65f102fc74bd22496499): aoneOfwith the Organization workspace-VM branch and the new personal-VM branch (machine.kind "personal-vm",owner {kind "principal", github_login, github_id},host {kind "provider-estate", …}, required tailnet).MachineContextis the union; conformance tests cover both branches and every cross-branch mix.src/folder/presets.ts):local,hosted-personal,hosted-organization-personal,hosted-organization-team— name, version 1, fixed axes, communication defaults, Personalspace policy, provider identity mode, surfaces, supervision. Validated as a whole; unknown name/version/combination fails before any mutation.personal-vm→hosted-personal;workspace-vmwithowner.team→hosted-organization-team; without →hosted-organization-personal; workstation →local. A personal VM never takes an Organization preset and vice versa.lazurio machine folder-init [--preset]records the derived preset by default and an allowed override as an explicit choice.name,version,selection: derived|explicit) + immutable Machine binding projected from the handover (nullon a workstation) + profile, under the existing revision discipline — the local state a future "set preset reference" typed request needs.profile-preview/profile-update --presetand the Launchpad send{expectedRevision, preset?, profile}to the same preview → apply use case.preset-not-allowedandpreset-compositionare blocked plans, never writes.AGENTS.mdand.lazurio/;organizations/andpersonalspace/may be non-empty and are never traversed, listed beyond existence, moved or written;launchpad.gen3.json/launchpad.gen3.local.jsontolerated by name; any other top-level entry fails closed naming it. Organization presets accept the emptypersonalspace/that Machines'workspace_baselineprecreates and refuse a used one without deleting anything. Re-run →already-adopted, nothing changed.AGENTS.md: short and factual, from preset + binding + profile — which Machine, whose, who the Principal is here, Personalspace boundary, where Organization repos live, identity mode, how work is done, pointer to OrganizationAGENTS.mdand the Lazurio root rules. A relationships section renders only when the binding carries one.locale/detail/coordinationchangeable;access/purposeare no longer controls.~/Lazurio,organizations/orpersonalspace/(Ubuntu's default umask 0002) is refused before any mutation as{"kind":"blocked","reason":"folder-directory-shared","entry":…}with exit 2 instead of the generic failure; a wrongmachineinvocation (--json, duplicate/invalid choice, unknown preset) is a usage error printing themachinehelp on stderr with exit 2.workspace-presets.md,machine-handover.md(re-pin, adoption, the exact resident command, JSON shapes, the mode 0755/0700 precondition), F10 amended 2026-09-22, acceptance and references renamed,docs/evidence/presets-linux-arm64-2026-09-22.md.What deliberately does not change
relationshipsfield in the vendored schema (upstream has none); the renderer path exists and is tested with a synthetic binding.purposeaxis keeps its values until that sweep.personalspace/presence for Organization presets is judged by existence and emptiness only (oneopendirread, names never returned) — the minimum that makes the Principal's rule operable on the layout Machines delivers.Verification
bun run checkat head41f0461under a temporaryHOME/XDG_*: biome clean, tsc clean, 496 pass / 4 skip / 0 fail (500 tests, 69 files), public-policy guard, proof build and smoke pass. No new dependencies.AGENTS.mdsnapshots per preset × locale, Launchpad immutable section / preset change / disallowed preset (409), machine usage errors (exit 2 + help).6481a4c, root-owned fixture handovers of all three kinds): derived presets, explicit allowed override with cs/technical, adoption of non-emptyorganizations/+personalspace/withlaunchpad.gen3.jsonpresent,already-adoptedre-run withAGENTS.mdbyte-identical andpersonalspace/untouched,preset-not-allowed,folder-foreign-entry,folder-personalspace-conflictwith nothing deleted — verbatim log indocs/evidence/presets-linux-arm64-2026-09-22.md.Not proven
🤖 Generated with Claude Code
Note
Add hosted workspace presets, Machine binding, and existing-Folder adoption
local,hosted-personal,hosted-organization-personal,hosted-organization-team) with fixed access/purpose axes, personalspace policy, and provider identity, derived from the typed Machine handover context.FolderPreferencesstate to schema version 2, adding a validated preset reference and immutable nullableMachineBinding; schema-1 state is now rejected.base-instructions-2with a newInstructionSource(preset + Machine + profile), adds localized Machine sections, and replaces the Launchpad access/purpose controls with machine details and a preset selector.folder-initentrypoint to derive and authorize presets from observed handover, apply preset defaults with optional overrides, and report structured adoption refusals.retireIncompletePreparationin retire-preparation.ts andvalidatePreparationin validate-preparation.ts pass a two-field preview object missingmachine, which the updatedpreviewFolderparser rejects; these calls throw a validation error instead of producing output.Macroscope summarized 41f0461.