Skip to content

chore: bootstrap Level.io sidecars (179 scripts)#46

Draft
limehawk wants to merge 33 commits into
mainfrom
level-sync-bootstrap
Draft

chore: bootstrap Level.io sidecars (179 scripts)#46
limehawk wants to merge 33 commits into
mainfrom
level-sync-bootstrap

Conversation

@limehawk

@limehawk limehawk commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Bootstraps level-script-sync against this repo. Adds one <stem>.level.yaml sidecar per script — 179 new files, no existing file modified.

Each platform's sync tool owns its own sidecar namespace (*.level.yaml here) and touches no other. level-script-sync reads and writes only *.level.yaml.

Level.io side

  • 179 scripts created, all in a Limehawk script group (Level went 13 → 192).
  • The 13 pre-existing scripts were not touched — no repo script name-collided, so nothing linked or overwrote.
  • Every synced script's command is byte-identical to the repo blob; a follow-up drift run reports no drift; a second push is a clean no-op.
  • Sidecars carry each script's real description and timeout (not tool defaults).

Not synced

  • scripts/workstation_info.vbs — Level has no VBScript shell. The tool now warns rather than skipping silently.
  • tools/lint/check_strictmode_ordering.ps1 — outside scriptsPath.

⚠️ Follow-up: 47 scripts need input plumbing before they will run on Level

Level's script variables are output capture slots, not inputs — per Level's docs: "Script variables are for capturing output, not supplying input." A script writes to a slot with {{name=value}}; data is passed into a script via system variables / custom fields interpolated in the body with the {x} picker.

So the input placeholders these scripts rely on do not carry over automatically:

  • 43 scripts take runtime inputs (e.g. cloudflared_install.ps1 needs CloudflaredTunnelToken).
  • 4 scripts additionally use asset-field placeholders (assetId, client.name) with no Level analogue: workstation_rename_{auto,manual}{,_macos}.

These are ported by editing the script bodies, not by the sync tool. Until then they are present in Level but will not receive their inputs.

Merging

Merge this before syncing from main, otherwise main has no sidecars and a sync there would create 179 duplicate scripts in Level.

limehawk and others added 11 commits July 10, 2026 01:31
…runtime variables

The initial bootstrap generated each .level.yaml from the filename plus config
defaults, so description was empty, timeout fell back to 60, and the runtime
variables 43 scripts declare were never carried across.

One-time migration: seeds each Level sidecar from the platform metadata already
in the repo. 179 sidecars gain a description and their real timeout; 43 gain
their runtime variables (by name only — this repo is public, so no defaultValue).

placeholderVariables are intentionally NOT mapped: they are asset-field bindings
(assetId, client.name), not user inputs, and Level has no analogue. The four
scripts using them need porting: workstation_rename_{auto,manual}{,_macos}.

lastPushedMetaChecksum is left stale on purpose so the next sync detects the
metadata change and reconciles Level.
Level script variables are OUTPUT capture slots, not inputs — per Level's docs:
'Script variables are for capturing output, not supplying input.' Data is passed
INTO a script via system variables / custom fields interpolated in the body.

The previous commit mapped this repo's input placeholders onto those output
slots, which created 43 meaningless empty slots and did nothing to supply the
scripts their inputs. Reverting that mapping; description, timeout and readme
backfills are correct and stay.

The 43 scripts that take inputs still need porting to Level's {{...}} custom
field / system variable syntax. Also drops the temporary variable smoke script.
@limehawk

Copy link
Copy Markdown
Owner Author

Heads-up on a limitation this PR exposes: the 179 scripts are synced, but 43 of them take runtime inputs that Level cannot supply. SuperOps substitutes $snake_case placeholders; Level has no per-run input prompt — values must come from custom fields ({{cf_*}}), system variables ({{level_*}}), or automation variables.

They fail safe (the existing guard catches the unsubstituted placeholder and exits), so nothing misbehaves — they just don't do their job until ported.

Full mapping, verified API facts, and the secrets problem: #47

This PR is still correct to merge — the sidecars accurately describe what's in Level today.

limehawk added 17 commits July 22, 2026 15:37
KB5054156 enablement package (24H2 → 25H2) with x64/ARM64 catalog
MSUs. Level System run, 60m timeout, no SuperOps dependencies.
Level timeout is in seconds (UI: "Timeout (in seconds)"). Prior value
60 was only one minute of wall time — too short for MSU download/install.
…econds

Level UI timeout is seconds. Sidecars were backfilled from SuperOps-style
minute values (mostly 15). Multiply those by 60. Leave values already
>= 1000s alone (e.g. windows11_25h2_install at 7200).
Detect source OS and choose path: eKB for 24H2 (KB5054156), full
feature upgrade via WU then Installation Assistant for Win10 and
pre-24H2 Win11. Timeout 14400s (4h). Fixes Win10 22H2 hard-fail.
…t true

Upgrade is incomplete without restart. Schedule a 60s reboot after eKB
or full feature-upgrade success. Set $rebootAfterInstall = $false for
maintenance windows.
…2.0.4)

Healthy DISM output "No component store corruption detected." matched
corruption.*detected and forced a needless RestoreHealth run. Match only
"component store is repairable".
…v2.0.0)

Replaces the Level-only bitlocker_enable.ps1 (never lived in this repo)
which reported success while leaving Protection Status: Off — OOBE
pre-provisioned volumes (FullyEncrypted + clear key) never got their
protectors enabled, so Level scored the disk unencrypted.

- Converge every state: decrypted -> start encryption; encrypted with
  protection suspended -> manage-bde -protectors -enable
- Check manage-bde exit codes; show its output in the Level log
- Final status fails (exit 1) unless Protection is On or encryption is
  in progress with protectors active — no more false success
- Require ready TPM; ensure exactly one RecoveryPassword protector

Closes #57 steps 1-2. Framework validated (script-framework-engine, PASS).

Claude-Session: https://claude.ai/code/session_01TtVS51os6EjjAmxLXjitL8
…ruption

Bring DISM found-and-fixed reboot behavior onto the Level sync branch and
update the Level sidecar readme. Other main-only scripts also land via merge.
limehawk added 5 commits July 22, 2026 21:57
Drop SuperOps module, placeholders, and GraphQL asset sync. Client code
comes from Level {{level_group_name}} (auto = 3-char abbr; manual =
optional hardcoded override). Emit DesiredHostname/RenameStatus output
slots. Replace SuperOps sidecars with *.level.yaml for level-script-sync.
Keep existing Level scriptIds/groupIds; update bodies to use
{{level_group_name}}, drop SuperOps sidecars/API, add output slots.
Resolve add/add conflicts by taking main script/framework yaml and keeping
Level scriptId/groupId from bootstrap so sync updates the existing Level script.
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