Skip to content

Commit f6bd5ef

Browse files
hyperpolymathclaude
andcommitted
feat(launcher): adopt machine-readable launcher standard
Relocate the canonical A2ML form of the launcher standard into the standards monorepo so that downstream consumers can reference it by path or $LAUNCH_SCAFFOLDER_STANDARD env var instead of vendoring it. - launcher/launcher-standard.a2ml — verbatim copy of the file currently vendored at launch-scaffolder/standards/launcher-standard.a2ml - launcher/README.adoc — explains the sync requirement with docs/UX-standards/launcher-standard.adoc and documents how launch-scaffolder consumes it (--standard / $LAUNCH_SCAFFOLDER_STANDARD) Follow-up: launch-scaffolder will drop its vendored copy and point its loader at this location in a separate commit in that repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5c5f23b commit f6bd5ef

2 files changed

Lines changed: 164 additions & 0 deletions

File tree

launcher/README.adoc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// SPDX-License-Identifier: PMPL-1.0-or-later
2+
= Launcher Standard (Machine-Readable)
3+
:toc:
4+
5+
This directory holds the canonical machine-readable companion to the prose
6+
specification at `docs/UX-standards/launcher-standard.adoc`.
7+
8+
== Files
9+
10+
`launcher-standard.a2ml`::
11+
The authoritative A2ML form of the launcher standard. All tooling that
12+
provisions, audits, or validates launchers MUST consume this file rather
13+
than re-parsing the prose spec or carrying its own vendored copy.
14+
15+
== Consumer: launch-scaffolder
16+
17+
`launch-scaffolder` (Rust/SPARK workspace at
18+
`/var/mnt/eclipse/repos/launch-scaffolder/`) is the minter / provisioner /
19+
configurator for launchers across the estate. It consumes this standard by
20+
reference:
21+
22+
* `--standard <path>` — explicit path to this file
23+
* `$LAUNCH_SCAFFOLDER_STANDARD` — environment-variable fallback
24+
25+
A follow-up change in `launch-scaffolder` will drop its vendored copy under
26+
`launch-scaffolder/standards/` and point its loader at this directory.
27+
28+
== Sync requirement
29+
30+
This file MUST stay in lock-step with `docs/UX-standards/launcher-standard.adoc`.
31+
Any edit to one REQUIRES a matching edit to the other in the same commit.
32+
Drift between prose and machine-readable forms is a standards-compliance bug.

launcher/launcher-standard.a2ml

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
3+
#
4+
# launcher-standard.a2ml — canonical declarative description of a
5+
# hyperpolymath-compliant desktop launcher.
6+
#
7+
# This file is the source of truth for what a compliant launcher looks like.
8+
# It is baked into the launch-scaffolder binary at build time via
9+
# include_str!(), and can be overridden at runtime via --standard <file> or
10+
# $LAUNCH_SCAFFOLDER_STANDARD.
11+
#
12+
# See also:
13+
# - standards/rhodium-standard-repositories/spec/LANGUAGE-POLICY.adoc
14+
# - standards/docs/UX-standards/launcher-standard.adoc (prose version)
15+
# - standards/docs/UX-standards/LM-LA-LIFECYCLE-STANDARD.adoc (install/uninstall)
16+
17+
[spec]
18+
version = "0.1.0"
19+
date = "2026-04-10"
20+
compliance = [
21+
"launcher-standard.adoc",
22+
"LM-LA-LIFECYCLE-STANDARD.adoc",
23+
"cross-platform-system-integration-modes",
24+
]
25+
26+
[required-modes]
27+
# These are the modes every compliant launcher MUST implement.
28+
runtime = ["--start", "--stop", "--status", "--auto", "--browser"]
29+
integration = ["--integ", "--disinteg"]
30+
meta = ["--help"]
31+
32+
[optional-modes]
33+
# Modes launchers MAY implement for extra functionality.
34+
developer = ["--debug", "--logs", "--tail"]
35+
36+
[default-mode]
37+
# Mode selected when the launcher is invoked with no arguments.
38+
mode = "--auto"
39+
40+
[runtime]
41+
# Required runtime behaviour.
42+
background = "nohup"
43+
pid-file-pattern = "/tmp/{app-name}-server.pid"
44+
log-file-pattern = "/tmp/{app-name}-server.log"
45+
wait-for-url-timeout-seconds = 15
46+
startup-command-search = [
47+
"{repo-dir}/scripts/run.sh",
48+
"{repo-dir}/dev.sh",
49+
]
50+
51+
[error-visibility]
52+
# When the launcher runs in a GUI context (no tty + DISPLAY/WAYLAND_DISPLAY set),
53+
# errors must be visible to the user via a GUI dialog, not only to stderr.
54+
gui-dialog-chain = ["kdialog", "zenity", "notify-send", "xmessage"]
55+
always-also-to-stderr = true
56+
57+
[integration.linux]
58+
apps-dir = "$HOME/.local/share/applications"
59+
icon-dir = "$HOME/.local/share/icons/hicolor/256x256/apps"
60+
desktop-shortcut-dir = "$HOME/Desktop"
61+
bin-dir = "$HOME/.local/bin"
62+
desktop-file-permissions = 444
63+
# If no custom icon is available, fall back to this freedesktop named icon.
64+
icon-fallback = "package-x-generic"
65+
refresh-command = "update-desktop-database"
66+
trust-command = "gio set {file} metadata::trusted true"
67+
68+
[integration.macos]
69+
apps-dir = "$HOME/Applications"
70+
desktop-shortcut-dir = "$HOME/Desktop"
71+
bin-dir = "$HOME/.local/bin"
72+
bundle-pattern = "{app-display}.app"
73+
shortcut-pattern = "{app-display}.command"
74+
75+
[integration.windows]
76+
start-menu-dir = "$APPDATA/Microsoft/Windows/Start Menu/Programs"
77+
desktop-shortcut-dir = "$HOME/Desktop"
78+
bin-dir = "$HOME/.local/bin"
79+
shortcut-pattern = "{app-display}.lnk"
80+
# Fallback when PowerShell is not reachable under Git Bash / WSL.
81+
bat-fallback = true
82+
83+
[integrity]
84+
# Per LM-LA-LIFECYCLE §LM/LA-INSTALL: after --integ completes, generate
85+
# integrity hashes via an external tool.
86+
verification-tool = "verify-desktop-integrity.sh"
87+
fallback-paths = [
88+
"/var/mnt/eclipse/repos/.desktop-tools/verify-desktop-integrity.sh",
89+
]
90+
fatal-on-failure = false # missing verifier is a log line, not an error
91+
92+
[disinteg]
93+
# What --disinteg removes and what it deliberately leaves alone.
94+
remove = [
95+
"desktop-file",
96+
"desktop-shortcut",
97+
"icon",
98+
"launcher-binary",
99+
"start-menu-entry",
100+
"bat-fallback-shortcuts",
101+
"pid-file",
102+
]
103+
preserve = [
104+
"$HOME/.config/{app-name}/",
105+
"/tmp/{app-name}-server.log",
106+
"{repo-dir}",
107+
]
108+
109+
[soft-attach]
110+
# Optional integrations — called if present, silently skipped if absent.
111+
tools = [
112+
{ name = "feedback-o-tron", event-on-failure = "launcher:start_failed" },
113+
{ name = "hypatia", command = "hypatia diagnose --app {app-name} --log {log-file}" },
114+
{ name = "panic-attack", command = "panic-attack assail {repo-dir}" },
115+
]
116+
117+
[a2ml-metadata-block]
118+
# Every generated launcher must carry this metadata block in its header so it
119+
# can be re-parsed by `launch-scaffolder config` and `realign`.
120+
required-fields = [
121+
"id",
122+
"type",
123+
"version",
124+
"app-name",
125+
"app-display",
126+
"app-url",
127+
"standards-compliance",
128+
"modes",
129+
"platforms",
130+
"lifecycle-phases-covered",
131+
"lifecycle-phases-deferred",
132+
]

0 commit comments

Comments
 (0)