Skip to content

The operator owns the Lazurio version: ~/.local/bin/lazurio, hosted manual allows lazurio update, Folder refresh needed (F17 addendum) - #58

Merged
immakermatty merged 3 commits into
mainfrom
claude/DEV-6626-operator-update
Sep 28, 2026
Merged

immakermatty merged 3 commits into
mainfrom
claude/DEV-6626-operator-update

Conversation

@immakermatty

@immakermatty immakermatty commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Why

Decisions of the Principal on 2026-09-28: there is one updater, lazurio update; the operator of an Environment may update Lazurio without a rollout, on a hosted Machine as well; a rollout may still raise a Machine that fell behind, because operators sometimes forget to update; nothing ever lowers a version. Until now the generated manual of hosted Machines forbade lazurio update, and nothing created the standard command ~/.local/bin/lazurio that root decision 0161 names. The pilot of 0.1.7 on a work VM confirmed it on 2026-09-28: lazurio is not on the operator's PATH there.

What changes

A. lazurio install creates ~/.local/bin/lazurio, a link to the selector of the install base, placed by an atomic rename.

At ~/.local/bin/lazurio Result Written
nothing created yes
link to this selector present no
link to the selector of a Lazurio install base (another base, or one that is gone) replaced yes
dangling link of any other shape conflict never
~/.local or ~/.local/bin is a link or not a directory conflict (parent) never; nothing is written through it
regular file, link to anything else, directory conflict never; install still succeeds and says what to do
cannot be written failed no; install still succeeds

Shell profiles are never edited. Whether ~/.local/bin is on PATH and whether another program named lazurio resolves first is reported with both paths, not changed.

B. The generated manual allows lazurio update on hosted Machines (Czech and English). The operator owns the version; an agent runs the update on the operator's instruction; update status is free to use; the provider's pin is a minimum. Template revision base-instructions-8 → 9 (8 shipped in v0.1.7). A test checks for every preset and both languages that no output forbids the update.

C. "Folder refresh needed". When the product renders a newer template revision than the Folder records, lazurio update, lazurio update status and the update section of the Launchpad say so with the exact command. Read-only: no automatic refresh, no button.

D. F17 addendum and the contract for the Machines role in docs/machine-handover.md: install when absent, raise when below the pin, never lower, never run lazurio update, verify the PATH entry from install --json.

What does not change

  • No new rollback machinery; update rollback stays as it is.
  • Machines itself and the root decision register are not edited here; root 0161 is amended by its own pull request.
  • No Windows work.

Known gaps, stated plainly

  1. install of the same version does not repair a dangling selector or a damaged active executable.
  2. The first update from v0.1.7 or older runs the old updater, which does not report the refresh; update status of the new version does.
  3. On a workstation without a service unit, lazurio update needs --folder to know the Folder.
  4. No warning on a shared Team Environment that an update affects every operator there.

Verification

bun run check on this head, run independently by the delegating agent: see the comment below. No test touches the real home directory.

Refs #50

🤖 Generated with Claude Code

immakermatty and others added 2 commits September 28, 2026 11:17
…l allows lazurio update, "Folder refresh needed"

- lazurio install (first install and offline update) links ~/.local/bin/lazurio
  to <base>/bin/lazurio atomically; creates ~/.local/bin 0755; replaces only a
  dangling link or a link into another Lazurio install base; never overwrites a
  file or a foreign link (reported as conflict with what to do); reports whether
  ~/.local/bin is on PATH and another lazurio that resolves first.
- Generated manual and AGENTS.md: the operator owns the version of Lazurio, an
  agent runs lazurio update on the operator's request, the pin is a minimum and
  a rollout never lowers a version, the refresh command follows an update.
  Template revision base-instructions-9 (8 shipped in v0.1.7).
- lazurio update, update status (--folder, the supervised unit's Folder or the
  hosted operator's) and the installed Launchpad pill say "Folder refresh
  needed" with the exact command; read-only. The self-check report states the
  template revision an executable renders.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…in is a minimum; Machines role contract

Records the Principal's decisions of 2026-09-28 (one updater, pin as a minimum,
forward repair, Linux first), the standard entry ~/.local/bin/lazurio and the
"Folder refresh needed" report; updates docs/update.md, environment-tools.md and
machine-handover.md, which now holds the contract for the Machines role.

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

Copy link
Copy Markdown
Contributor Author

Independent bun run check on 1d7287d (macOS arm64): 724 pass, 4 skip (systemd tests), 0 fail; public guard PASS; standalone smoke PASS.

@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.

Exact-head review of 1d7287d — CHANGES_REQUESTED.

  1. [P1] src/update/path-entry.ts:146-161: refuse symlinked ancestors before touching the standard entry. lstat(path) follows symlinks in ~/.local / ~/.local/bin, and ensureDirectory accepts EEXIST without checking that the existing component is a real directory. Reproduced with a temporary HOME whose .local/bin is a symlink to another directory: ensurePathEntry returned created and wrote lazurio in that other directory. If that directory already holds a replaceable link, the rename can replace it there too. This escapes the promised ~/.local/bin custody boundary. Check each existing parent with lstat (and fail/report rather than following a symlink); add a regression with symlinked bin/.local.

  2. [P1] src/update/path-entry.ts:73-78: a dangling symlink is not proof of Lazurio ownership. Reproduced with ~/.local/bin/lazurio -> <missing foreign-tool>: the function returned replaced and changed that link to the Lazurio selector. A broken link can be someone else's intentionally installed entry; it may point to a temporarily unmounted target. This contradicts the requirement not to replace entries that are not Lazurio's. Keep a foreign dangling link as conflict, or accept only a verifiably Lazurio-owned selector shape/path. Update the documented blanket 'dangling link' replacement rule and test the foreign case.

The existing focused suite passed locally after bun install --frozen-lockfile: 56 passed, 0 failed across path-entry, Folder-refresh, generated-manual and offline-install tests. Both required exact-head checks, check (macos-14) and check (ubuntu-24.04), are green. The Czech/English update instructions are aligned in the inspected generated templates; the offline install below-floor and high-water gates are intact. These two filesystem-custody findings block approval despite green checks. No merge requested.

…bin; a dangling link stays unless it has the shape of a Lazurio selector

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

@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 re-review of 6bcf037 — APPROVED. The two previously blocking findings are fixed: ~/.local and ~/.local/bin are lstat-checked as plain directories before creating/replacing the PATH entry, and a foreign dangling link stays untouched while only a Lazurio-selector-shaped missing-base link can be replaced. The linked-parent and three foreign-dangling regression cases pass. Independent disposable-clone validation: focused tests 58 pass, 0 fail; bun run check 726 pass, 4 skip, 0 fail, plus lint, typecheck, check:public, build:proof and smoke:proof; git diff --check passes on the frozen PR diff. Both exact-head required checks, check (macos-14) and check (ubuntu-24.04), are SUCCESS; no unresolved review threads. No merge performed.

@immakermatty
immakermatty merged commit fdf2336 into main Sep 28, 2026
3 checks passed
@immakermatty
immakermatty deleted the claude/DEV-6626-operator-update branch September 28, 2026 09:49
immakermatty added a commit that referenced this pull request Sep 28, 2026
Brings in PR #58 (the operator owns the Lazurio version; "Folder refresh
needed" in the update section) and PR #61 (the gh sign-in links the
Machine's SSH key) and places both in the Settings layout.

Conflicts:
- src/launchpad/tools-panel.ts: main added "Link SSH key" to the card's
  action row, this branch had turned the card into a settings row. The
  row keeps main's control (data-control="link-ssh", openLogin(tool,
  "ssh"), the named label) and shows it as the row's primary action
  before "Sign out". The gh status line reads "version · signed in as X
  · SSH key linked|not linked|not verified" with the SSH part its own
  span, in the warning colour when not linked; main's signInLine,
  messages and the login flow are unchanged.
- docs/launchpad-development.md: the row description of this branch
  with main's SSH wording and the Link SSH key action.

Folder refresh: main's #update-folder-refresh replaces the empty
#folder-refresh slot above the update pill in the sidebar footer (one
element), a subdued notice whose command stands in its own selectable
monospace line; the sentence still comes from main's message.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
agentrozjedemeai pushed a commit that referenced this pull request Oct 6, 2026
…hem (Anička, DEV-6645) (#226)

* Shell: the design system re-vendored at fdcc9b4 (three radii, one floating shadow)

src/shell/vendor/lazurio/tokens.css is copied byte for byte from
HumanAndMachine-ai/design-system-lazurio fdcc9b4 (#62). Since the previous
pin 5bbc1f7 (#54) only this file of the vendored ones changed, in #58 and
#59 (Anička, 2026-10-04): the comment on the radii now names three radii,
one per kind of thing, and --lz-shadow-float (0 8px 24px, ink at 10 %) is
new, the one shadow of a layer floating above the page. The logo symbol,
the stones and Iconoir's licence are byte for byte as before.

src/shell/vendor/README.md names the new source commit, what changed and
the new SHA-256; tests/apps-view.test.ts ("every vendored file has the hash
its README records") passes against it. Nothing reads the new token yet;
the shell's styles take it in the next commit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Shell: the rail and the Environment picker as Anička revised the wireframe (DEV-6645)

The elements follow the shell wireframe at prototypes-lazurio 1acd615 and
the design system at fdcc9b4 (prototypes-lazurio #11, #14, #15, #17;
design-system-lazurio #57, #58, #59, #62).

The rail is one grid step, 64 px instead of 72, and sets
--lazurio-rail-width to 64px: 40 px items with radius-md around 32 px marks
with radius-sm, concentric corners, an item under the pointer brings the
quiet surface without changing its shape, smaller icons (16 px), "+" a
32 px dashed square, the account's photo 28 px, dividers 24 px. The active
space keeps B3; its spread shadows now fill exactly the 40 px item. Your
personal monogram is a mark on the raised colour with a hairline, never an
ink block, in the rail and in the picker. Without roles the rail stands on
paper like the app's column.

Every radius is one of the three tokens; the list under the picker, the
⌘⇧E dialog and the rail's label carry --lz-shadow-float with a hairline,
and the switch's active tab a hairline instead of its drop shadow.

The picker's list is one line per Environment of the space (switcherList in
view.ts): no Organization head and no title, a search field only past seven
Environments, only "Všechny Organizace" at its foot; widened, the field and
every space by its title, still without heads and without a foot. The
current row has the check, and "tady jsi" is for screen readers only.
⌘⇧E keeps the Organization's heads above the same rows and its key hints.
The keys (switcherKey) work with or without the field: arrows wrap, Home
and End outside the field, Enter, Escape; without the field the focus lands
on the current Environment, else the first, and moves with the keys and
the pointer. The Launchpad page's fallbacks of --lazurio-rail-width are
64px.

Tests: tests/shell-picker.test.ts pins the list, the threshold, the foot,
the jump's heads, the keys and the rail's width; the suites that asserted
the head in the picker now assert it in the jump only.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Launchpad: the Organization's name in the Apps head opens its Dashboard (DEV-6645)

The picker no longer leads to an Organization's Dashboard (prototypes-lazurio
#17, design-system-lazurio #62): the Organization's name in the page's head
does, as the wireframe's .lp-head__link. appsHeading in apps-view.ts makes
the name a link to the Organization's page as the shell document names it
(the same lookup "Přístup k modulu" uses), titled "Dashboard Organizace" /
"Organization Dashboard", in the same window. The personal space ("Osobní"),
the home without a group and an Organization the document does not name
stay plain text. The link has the heading's colour and no underline, and is
underlined 2 px with a 4 px offset under the pointer.

Tested in tests/apps-view.test.ts: an Organization, one the shell document
does not name, one the Folder cannot read, the personal space and the home.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Docs: F36 addendum, the rail and the picker as the wireframe revised them (DEV-6645)

docs/decisions.md records the addendum of 2026-10-06, decided by Anička and
confirmed by Matěj: the 64 px rail with one corner family and the personal
monogram as a mark, three radii, one shadow for a floating layer, the
compact picker without the Organization's head, the keys with or without
the search field, ⌘⇧E keeping its heads, the Organization's name in the
Apps head opening its Dashboard, what the colour roles now colour, and that
no v1 document or interface name changes. It names what it supersedes in
the Organization-rail addendum (point 2), the colour addendum (point 1) and
the addendum of 2026-10-05 (point 6), which carry dated notes; what is left
as it is (the picker's button and gear, the icons' stroke) and where the
shell keeps its own rule; the alternatives; and how it was verified, with
the measurements against the wireframe at prototypes-lazurio 1acd615.

docs/launchpad-development.md describes the same in the target shell (the
rail, the picker, the selection, the Apps header), in the shell as built
("The look", the column head on an Organization's Dashboard, a space
without an Environment), in the colour roles table and the test list.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Shell: the picker and its gear as the design system draws them; icons at the wireframe's stroke of 1.6 (DEV-6645)

Matěj asked that the Environments and the Dashboard follow the wireframe as
it stands, so the column head now takes the design system's values
(design-system-lazurio fdcc9b4) as the wireframe draws it since
prototypes-lazurio #8, still its state at 1acd615:

- The picker is lz-picker: at least --lz-space-48 tall, --lz-space-8
  around, --lz-space-12 between its parts, radius-md; 52 px with its two
  lines (was 47). Its glyph is lz-picker__mark, --lz-space-32 with
  radius-sm, an Organization's mark or your monogram 24 px inside, the
  kind's icon filling it; the name --lz-size-nav, the line --lz-size-meta.
  The row is lz-picker-row, --lz-space-4 apart.
- The gear is lz-button--icon: a --lz-space-48 square with radius-sm in
  the picker's ink (was 40 px wide and muted). Under the pointer it keeps
  the quiet surface of the column's other controls: the design system's
  quiet button takes paper, which does not show on the paper column; under
  a host's roles both are --lazurio-hover.
- In a narrow host (@container max-width 160px) the picker and the gear
  stand as 48 px squares, one above the other; the 40 px override is gone.
- The glyph takes the picker's ink, so on a dark host without roles a
  kind's icon is light instead of near-black (issue #169).
- The switch's tabs take line-height normal, 49 px as the wireframe.

Every interface icon, src/shell/icons.ts and the Launchpad page's 32
inlined symbols, is drawn at stroke 1.6, as the wireframe's Icon.tsx has
done since before 1cbad15 (the provenance notes said 1.5); the notes now
cite 1acd615.

The F36 addendum gains point 5 (the picker and its gear) and loses the two
items it left as they were; its verification and colour-roles point say
what changed. No test pinned the old sizes.

Checked: bun run check (1463 pass, 7 skip, 0 fail). In Chrome against
the wireframe: the column head 191 x 52 beside the 48 px gear, the 32 px
glyph, 15 and 14 px text, the switch 49 px, icons at 1.6, all equal; in
T3 Code's dark sidebar at 208 and 264 px, its light one, MausBot's
Midnight, a dark host without roles and a 64 px host, nothing overflows.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Docs: the F36 addendum's verification says the column head, not the page, was drawn narrow (DEV-6645)

The verification of the addendum on the rail and the picker said that
narrow widths were not exercised, while the column head was drawn in a
64 px host and at the 160 px limit. It now says that the column head was
checked in the Launchpad's preview too, and that the page at narrow window
widths was not exercised. The paragraph is rewrapped; nothing else changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <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.

2 participants