Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!--
SPDX-License-Identifier: CC-BY-SA-4.0
Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
-->
# Code of Conduct

This project follows the [Contributor Covenant, version 2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/), with the project-specific reporting and enforcement process described in [`../CODE_OF_CONDUCT.adoc`](../CODE_OF_CONDUCT.adoc).

Participation is expected to be respectful, inclusive, and free of harassment. Unacceptable conduct includes personal attacks, discriminatory language, intimidation, doxxing, unwanted sexual attention, and retaliation against someone who reports a concern.

## Reporting

Report conduct concerns privately to **j.d.a.jewell@open.ac.uk**. Do not use a public issue for a sensitive report. The maintainer will review reports discreetly and may remove content, restrict participation, or take other appropriate action. The full policy is in [`../CODE_OF_CONDUCT.adoc`](../CODE_OF_CONDUCT.adoc).
3 changes: 3 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# SPDX-License-Identifier: CC-BY-SA-4.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>

# Contributing

Contributions are welcome! Please:
Expand Down
40 changes: 40 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# SPDX-License-Identifier: CC-BY-SA-4.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
name: Bug report
description: Report a reproducible defect.
labels: ["bug", "needs-triage"]
body:
- type: markdown
attributes:
value: For security vulnerabilities, use the private reporting path in `.github/SECURITY.md`; do not open a public issue.
- type: textarea
id: observed
attributes:
label: Observed behavior
description: Include the exact command and output.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behavior
validations:
required: true
- type: textarea
id: reproduction
attributes:
label: Minimal reproduction
validations:
required: true
- type: input
id: version
attributes:
label: Version or commit
validations:
required: true
- type: input
id: environment
attributes:
label: OS and Rust version
validations:
required: true
6 changes: 6 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# SPDX-License-Identifier: CC-BY-SA-4.0
blank_issues_enabled: true
contact_links:
- name: Security vulnerability
url: https://github.com/hyperpolymath/launch-scaffolder/security/advisories/new
about: Report vulnerabilities privately; do not use a public issue.
24 changes: 24 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# SPDX-License-Identifier: CC-BY-SA-4.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
name: Feature request
description: Propose a scoped improvement.
labels: ["enhancement", "needs-triage"]
body:
- type: textarea
id: problem
attributes:
label: Problem to solve
validations:
required: true
- type: textarea
id: proposal
attributes:
label: Proposed behavior
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives and compatibility impact
validations:
required: false
19 changes: 19 additions & 0 deletions .github/SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!--
SPDX-License-Identifier: CC-BY-SA-4.0
Copyright (c) 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
-->
# Security Policy

## Reporting a vulnerability

Please report security vulnerabilities privately through [GitHub Security Advisories](https://github.com/hyperpolymath/launch-scaffolder/security/advisories/new). Do not open a public issue or pull request for an undisclosed vulnerability.

If GitHub Advisories are unavailable, email **j.d.a.jewell@open.ac.uk** with the subject `Security report: launch-scaffolder`. Include the affected version or commit, impact, and reproducible steps. Please do not include secrets belonging to other people.

## Response

The maintainer aims to acknowledge reports within 48 hours and provide an initial triage within seven days. Fix and disclosure timing will be coordinated with the reporter; these are targets, not guarantees.

## Supported versions

Security fixes target the latest code on `main`. Older generated launchers are not automatically updated; re-mint them with a current `launch-scaffolder` release.
26 changes: 1 addition & 25 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: MPL-2.0
# Dependabot configuration for RSR-compliant repositories
# Covers common ecosystems - remove unused ones for your project
# Only ecosystems used by this Rust/SPARK repository are configured.

version: 2
updates:
Expand All @@ -25,27 +25,3 @@ updates:
# current Dependabot behaviour. See rsr-template-repo commit 78b050e
# and 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md.
open-pull-requests-limit: 0

# Elixir/Mix
- package-ecosystem: "mix"
directory: "/"
schedule:
interval: "weekly"

# Node.js/npm
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"

# Python/pip
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"

# Nix flakes
- package-ecosystem: "nix"
directory: "/"
schedule:
interval: "weekly"
9 changes: 7 additions & 2 deletions .github/workflows/launcher-artefacts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ jobs:
if [ -s "$RUNNER_TEMP/fmt.diff" ]; then
echo "rustfmt wants changes ($(wc -l < "$RUNNER_TEMP/fmt.diff") line(s)):"
cat "$RUNNER_TEMP/fmt.diff"
annotate "cargo fmt --check drift" "$RUNNER_TEMP/fmt.diff" 80
# GitHub truncates large annotations. Split the diff so every
# rustfmt hunk remains actionable even when log archives are unavailable.
split -l 35 "$RUNNER_TEMP/fmt.diff" "$RUNNER_TEMP/fmt-part-"
for part in "$RUNNER_TEMP"/fmt-part-*; do
annotate "cargo fmt --check drift ${part##*-}" "$part" 35
done
else
echo "✓ cargo fmt --all -- --check is clean"
fi
Expand Down Expand Up @@ -191,7 +196,7 @@ jobs:
# absolute path of the config that produced the script, which is
# checkout-location-specific by design and not a template property.
./target/debug/launch-scaffolder mint "$FIXTURE_CONFIG" --stdout \
| sed -E 's|^CONFIG_FILE=.*|CONFIG_FILE=""|' \
| sed -E "s|^CONFIG_FILE=.*|CONFIG_FILE=''|" \
> "$OUT/stapeln-launcher.sh"
STATUS="${PIPESTATUS[0]}"
if [ "$STATUS" -ne 0 ]; then
Expand Down
2 changes: 2 additions & 0 deletions .machine_readable/6a2/0-AI-MANIFEST.a2ml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: CC-BY-SA-4.0
# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell <j.d.a.jewell@open.ac.uk>
# AI Manifest for 6a2 Directory

## Purpose
Expand Down
49 changes: 18 additions & 31 deletions .machine_readable/6a2/AGENTIC.a2ml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# AGENTIC.a2ml — AI agent constraints and capabilities
# Defines what AI agents can and cannot do in this repository.
# AGENTIC.a2ml — AI agent constraints and capabilities for launch-scaffolder.

[metadata]
version = "0.1.0"
last-updated = "2026-04-11"
format = "a2ml"
schema = "agentic"
schema-version = "0.1"
last-updated = "2026-09-26"

[agent-permissions]
can-edit-source = true
Expand All @@ -16,17 +17,14 @@ can-edit-config = true
can-create-files = true

[agent-constraints]
# What AI agents must NOT do:
# - Never use banned language patterns (believe_me, unsafeCoerce, etc.)
# - Never commit secrets or credentials
# - Never use banned languages (TypeScript, Python, Go, etc.)
# - Never place state files in repository root (must be in .machine_readable/)
# - Never relicense an existing file, and never run an automated licence
# sweep (LICENCE-POLICY.adoc A2). New files get correct SPDX from birth.
# - Never assume a licence. Read standards/LICENCE-POLICY.adoc: Rule 1
# defaults to MPL-2.0 (code) / CC-BY-SA-4.0 (prose), but Rule 3
# (co-developed), Rule 4 (network-deployed services) and Rule 5
# (games) are AGPL-3.0-or-later, and Rule 2 names the PMPL register.
# - Never commit secrets, credentials, or private user data.
# - Keep repository code in Rust; generated launchers are Bash via Tera.
# - Do not add Python, TypeScript, or Go source to this Rust-primary repository.
# - Never switch from the session's fixed Arena branch or rewrite .git state.
# - Preserve existing licenses; new files require an appropriate SPDX header.
# - Read .github/SECURITY.md and keep undisclosed vulnerability reports private.
# - Treat unmarked desktop entries, launcher binaries, and icons as user-owned.
# - Do not describe macOS/Windows native provisioning or placeholder APIs as done.

[maintenance-integrity]
fail-closed = true
Expand All @@ -35,22 +33,11 @@ allow-silent-skip = false
require-rerun-after-fix = true
release-claim-requires-hard-pass = true

# ============================================================================
# METHODOLOGY (ADR-002)
# ============================================================================
# Detailed methodology configuration lives in:
# .machine_readable/bot_directives/methodology.a2ml
# .machine_readable/bot_directives/coverage.a2ml
# .machine_readable/bot_directives/debt.a2ml
#
# AGENTIC.a2ml declares WHAT agents can do (permissions, gating).
# bot_directives/ declares HOW agents should work (methodology).

[methodology]
instructions-dir = ".machine_readable/bot_directives/"
default-mode = "hybrid"
instructions-dir = ".machine_readable/contractiles/"
default-mode = "inspect, implement, validate, document"

[automation-hooks]
# on-enter: Read 0-AI-MANIFEST.a2ml, then STATE.a2ml, then bot_directives/
# on-exit: Update STATE.a2ml, coverage.a2ml, and debt.a2ml with session outcomes
# on-commit: Run just validate-rsr
# on-enter: Read root 0-AI-MANIFEST.a2ml, then this directory's STATE.a2ml.
# on-exit: Update STATE.a2ml and relevant repository documentation with outcomes.
# on-validation: Run `just validate` and the launcher-artifact workflow when possible.
25 changes: 12 additions & 13 deletions .machine_readable/6a2/ECOSYSTEM.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,19 @@ format = "a2ml"
schema = "ecosystem"
schema-version = "0.1"
# ISO 8601 UTC timestamp (see STATE.a2ml for convention).
updated = "2026-04-10T20:00:00Z"
updated = "2026-09-26T00:00:00Z"

[ecosystem]
version = "0.1"
name = "launch-scaffolder"
type = "cross-cutting-tool"
purpose = "Generate/install/maintain cross-platform desktop launchers for every hyperpolymath project from a single declarative spec."
purpose = "Generate and maintain portable launcher scripts from a shared standard, with native Linux desktop provisioning."

position-in-ecosystem = """
launch-scaffolder is estate-wide tooling. It sits between the launcher
*standard* (lives in standards/ monorepo) and every project that needs a
desktop launcher. It is a *producer* of launcher scripts, not a runtime
library — its output is consumed by desktop environments, not by other
hyperpolymath tools at runtime.
*standard* (maintained in the standards monorepo) and projects that need a
launcher. It produces scripts and manages Linux desktop entries; it is not a
runtime library. Native macOS and Windows provisioning remain unsupported.
"""

[[related-projects]]
Expand Down Expand Up @@ -75,7 +74,7 @@ detail = "Process-kind launcher."
[[related-projects]]
name = "hyperpolymath-ecosystem"
relationship = "umbrella"
detail = "Every hyperpolymath repo that ships a desktop launcher is a potential consumer. The 5 declared exceptions in docs/launcher-exceptions-2026-04-10.md are the current non-consumers and have explicit migration triggers."
detail = "Every hyperpolymath repo that ships a desktop launcher is a potential consumer. The 5 declared exceptions in docs/launcher-exceptions-2026-04-10.adoc are the current non-consumers and have explicit migration triggers."

[[related-projects]]
name = "invariant-path"
Expand All @@ -90,9 +89,9 @@ relationship = "declared-exception"
detail = "Stays hand-written — remote web app with gossamer fallback and bespoke modes."

[integration-points]
input-config-format = "A2ML (TOML-compatible today) at <repo-root>/<app>.launcher.a2ml"
input-standard = "praxis DEED (DEED v1.0.0), launcher-standard_praxis.deed, located via the :priority search ladder the deed declares for itself under (resolution) -> standard-search"
output-launcher = "POSIX bash script at <repo-root>/<app>-launcher.sh (chmod 755)"
output-desktop-entry = "Freedesktop .desktop file written by the generated script's --integ mode"
output-bundle-macos = ".app bundle written by the generated script's --integ mode"
output-shortcut-win = ".lnk or .bat written by the generated script's --integ mode"
input-config-format = "TOML content under the legacy <repo-root>/<app>.launcher.a2ml filename; DEED migration is tracked with standards#960"
input-standard = "Praxis DEED v1.0.0, launcher-standard_praxis.deed, located via the :priority search ladder declared under (resolution) -> standard-search"
output-launcher = "Bash script at <repo-root>/<app>-launcher.sh (mode 0755 unless --no-chmod)"
output-desktop-entry = "Freedesktop .desktop files installed by the native Linux provisioner or generated-shell fallback"
output-bundle-macos = "Not implemented; native macOS integration is planned"
output-shortcut-win = "Not implemented; native Windows integration is planned"
35 changes: 16 additions & 19 deletions .machine_readable/6a2/META.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ schema = "meta"
schema-version = "0.1"
# ISO 8601 UTC with `Z` suffix — same-day intermittent writes stay
# distinguishable in git history. See STATE.a2ml for the same convention.
updated = "2026-04-10T20:00:00Z"
updated = "2026-09-26T00:00:00Z"

[project]
name = "launch-scaffolder"
Expand Down Expand Up @@ -129,7 +129,7 @@ present for each kind.
consequences = """
Most launchers fit one of the three shapes cleanly. 5 outliers are
declared exceptions and stay hand-written until the scaffolder grows a
custom-modes hook (see docs/launcher-exceptions-2026-04-10.md).
custom-modes hook (see docs/launcher-exceptions-2026-04-10.adoc).
"""

[[architecture-decisions]]
Expand All @@ -155,13 +155,13 @@ build/dev noise (`target/`, `.git/`, `node_modules/`, `_exploratory/`,
`.archive*/`) — never directories that might hold real work.
The scaffolder's own `examples/stapeln.launcher.a2ml` was renamed to
`examples/stapeln.launcher.fixture.a2ml` as the first consumer of the
new rule, and the convention is documented in `examples/README.md`.
new rule, and the convention is documented in `examples/README.adoc`.
"""
consequences = """
Fixtures can live anywhere, including inside consumer repos, without
interfering with estate walks. Contributors must name new fixtures
with the `.fixture.` infix — there is no directory-based safety net.
The `examples/README.md` is the single contributor-facing source of
The `examples/README.adoc` is the single contributor-facing source of
truth for the rule.
"""

Expand Down Expand Up @@ -231,12 +231,11 @@ title = "Hand-rolled metadata-block parser, not coerced TOML"
status = "accepted"
date = "2026-04-10T20:00:00Z"
context = """
cmd_config needs to get/set/validate fields inside the
Historically, cmd_config needed to get/set/validate fields inside the
`# @a2ml-metadata begin ... # @a2ml-metadata end` block embedded at the
top of every generated launcher. The format is `#`-prefixed lines,
wrapped in `(` / `)`, with scalar values in double quotes and list
values on their own lines inside `[ ... ]`. It is neither standard
TOML nor any other off-the-shelf format.
top of generated launchers. The legacy format is `#`-prefixed lines, wrapped in `(` / `)`, with
scalar values in double quotes and list values on their own lines inside
`[ ... ]`. Current launchers emit a DEED `@launcher-deed` block instead.
"""
decision = """
Write a small hand-rolled scanner in
Expand All @@ -249,24 +248,22 @@ of the target line, preserving column alignment and surrounding
whitespace.
"""
consequences = """
The format is 100% controlled by `launcher.sh.tera`, so brittleness is
bounded. `REQUIRED_SCALAR_KEYS` is a module-level const — the single
source of truth for what `config validate` enforces. List keys are
read-only via `config get`; `config set` on a list key returns a
structured error. Round-trip (parse → rewrite → reparse) is covered
by tests.
The legacy format is retained for reads and safe scalar edits, while
current DEED blocks are parsed and validated but not edited by `config set`.
List keys remain read-only, and round-trip behavior is covered by tests.
"""

# ---------------------------------------------------------------------------
# DEVELOPMENT PRACTICES
# ---------------------------------------------------------------------------

[development-practices]
build = "cargo build --release"
test = "cargo test --release"
lint = "cargo clippy --workspace --all-targets -- -D warnings"
build = "cargo build --locked --workspace"
test = "cargo test --locked --workspace"
lint = "cargo clippy --locked --workspace --all-targets -- -D warnings"
format = "cargo fmt --all"
pre-commit = "just pre-commit (fmt-check + lint + test)"
pre-commit = "just pre-commit (fmt-check + check + lint + test)"
validate = "just validate (fmt-check + check + lint + test + standard validation)"
license-header = "SPDX-License-Identifier: MPL-2.0 on every .rs, .tera, .a2ml, .adoc, .sh file"
author = "Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com>"

Expand Down
Loading
Loading