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
34 changes: 17 additions & 17 deletions .claude/cloud-bootstrap.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Canonical repo cloud bootstrap (SSOT). Materialized to each fleet repo's
# .claude/cloud-bootstrap.sh by distribution/sync-manifest.yml, so edits land
# here by pull request and fan out as reviewed sync PRs — never by patching a
# here by pull request and fan out as reviewed sync PRs; never by patching a
# repo's materialized copy. Repo-specific work does not belong here: a repo
# enriches through its own .claude/cloud-bootstrap.local.sh (run below,
# never synced), or takes the component locally-owned in the manifest to
Expand All @@ -12,7 +12,7 @@
# session process launches. Claude Code builds its plugin/command/skill
# registry at process start and never re-reads it, so this pre-launch
# call is the only path that gets plugins loaded at turn one.
# 2. The SessionStart hook (startup|resume), as drift repair — the
# 2. The SessionStart hook (startup|resume), as drift repair: the
# environment cache can be ~7 days stale. Plugins it installs go live
# at the next resume, not in the session that ran the hook.
# Outside cloud sessions this exits immediately: declaring a marketplace is
Expand All @@ -22,8 +22,8 @@
# Idempotent and best effort: a failed step costs a tool or a plugin, never
# the session.
#
# Everything below is data-driven from the repo's own manifests — .node-version,
# package-lock.json, global.json, .claude/settings.json — so this file carries
# Everything below is data-driven from the repo's own manifests (.node-version,
# package-lock.json, global.json, .claude/settings.json), so this file carries
# no repo names, no pinned versions, and no marketplace identifiers.
#
# Both callers run `bash <this script>`, so the interpreter is whatever `bash`
Expand Down Expand Up @@ -55,22 +55,22 @@ fi
# exit 0 when `claude` or `jq` is missing, and the toolchain must not be
# collateral damage of an unrelated CLI being absent. The cloud VM is a fresh
# Ubuntu image shipping Node 20/21/22 and no .NET, so without this a session
# builds and lints on the wrong toolchain — the failure a live cloud
# builds and lints on the wrong toolchain: the failure a live cloud
# verification run confirmed across the fleet. The shared environment's setup
# script pre-installs a warm cache of common pins; this stage is the
# correctness guarantee and must not assume the cache installed anything.
#
# Subshell with its own errexit posture: this file runs under `set -e`, and a
# failed optional install must cost a toolchain, never the session. The
# subshell ends in an explicit `exit 0` rather than being wrapped in
# `|| true` — wrapping would put every call inside it in an `||` context,
# `|| true`: wrapping would put every call inside it in an `||` context,
# which is what .shellcheckrc's check-set-e-suppressed (SC2310) exists to flag.
(
set +e

toolchain_warn() { printf 'cloud-bootstrap: %s\n' "$*" >&2; }

# env_line <export-line> — append to the session env file once. Dedup-guarded
# env_line <export-line>: append to the session env file once. Dedup-guarded
# because SessionStart fires again on resume.
env_line() {
[[ -n "${CLAUDE_ENV_FILE:-}" ]] || return 0
Expand Down Expand Up @@ -133,7 +133,7 @@ fi
bash "$installer" --version "$sdk" --install-dir .dotnet >/dev/null 2>&1; then
:
else
toolchain_warn "dotnet $sdk install failed — check the environment's network allowlist (dot.net, aka.ms, builds.dotnet.microsoft.com, download.visualstudio.microsoft.com)"
toolchain_warn "dotnet $sdk install failed: check the environment's network allowlist (dot.net, aka.ms, builds.dotnet.microsoft.com, download.visualstudio.microsoft.com)"
fi
rm -f "$installer"
fi
Expand All @@ -146,7 +146,7 @@ fi
fi

# Git history: base-ref diffs (several plugin suites use origin/main) break
# on the shallow single-branch cloud clone — deepen it and make origin/main
# on the shallow single-branch cloud clone; deepen it and make origin/main
# resolve. The explicit destination refspec matters: in a single-branch
# clone a bare `fetch origin main` only writes FETCH_HEAD and never creates
# refs/remotes/origin/main. `main` is the fleet's default branch.
Expand Down Expand Up @@ -179,8 +179,8 @@ fi
fi

# --- Repo extension (enrich seam) -----------------------------------------
# A repo appends its own setup — extra lockfiles, pinned hygiene binaries,
# symlinks — in this committed, never-synced sibling. Same contract as this
# A repo appends its own setup (extra lockfiles, pinned hygiene binaries,
# symlinks) in this committed, never-synced sibling. Same contract as this
# file: idempotent, best effort, bash-3.2-safe. Deliberately inside this
# subshell so it inherits the nvm-selected Node on PATH and the
# warn-never-fatal posture, plus this script's environment
Expand All @@ -199,16 +199,16 @@ fi
)

# --- Session-start hook output ----------------------------------------------
# When the SessionStart hook is the caller, stdout is parsed as hook output —
# that is why every summary in this script goes to stderr — and this line asks
# When the SessionStart hook is the caller, stdout is parsed as hook output
# (that is why every summary in this script goes to stderr), and this line asks
# for a skills re-scan for whatever the harness can pick up mid-session (the
# plugin registry itself is only rebuilt at the next process start). From the
# pre-launch caller it lands harmlessly in the setup log.
#
# Emitted here, before the plugin stage, because the toolchain subshell and
# the repo's own cloud-bootstrap.local.sh above may already have materialized
# skills worth rescanning, and every way the plugin stage can end early — no
# `claude`, no `jq`, no fleet list, or an unexpected failure under `set -e` —
# skills worth rescanning, and every way the plugin stage can end early (no
# `claude`, no `jq`, no fleet list, or an unexpected failure under `set -e`)
# would otherwise swallow the request along with the installs. Nothing below
# writes to stdout, so this stays the only line the harness parses.
printf '%s\n' '{"hookSpecificOutput":{"hookEventName":"SessionStart","reloadSkills":true}}'
Expand Down Expand Up @@ -243,7 +243,7 @@ fleet_plugins="${CLOUD_BOOTSTRAP_FLEET_LIST:-/opt/melodic-fleet-plugins.json}"
# JSON of the wrong shape (a bare array, enabledPlugins as an array) ends the
# plugin stage: every read below is a jq expression that expects the settings
# shape, and an existence check alone lets a wrong-shaped file through to fail
# there. Skipping is the whole answer — drift repair has no set to repair
# there. Skipping is the whole answer: drift repair has no set to repair
# against without the list, and the repo file declares deltas, not a set. The
# gate is a shape test, not a content test: an object carrying no
# enabledPlugins at all is a valid empty source and passes. Exiting here
Expand Down Expand Up @@ -336,7 +336,7 @@ install_plugins_from "$settings" "repo $settings"

# Catalog inventory line. Everything above installs strictly what the fleet
# list and the repo declare, so a plugin added to a marketplace after both
# were written is not installed and nothing says so — the gap surfaces only
# were written is not installed and nothing says so: the gap surfaces only
# when someone types a slash command that does not resolve, which is exactly
# how it has surfaced. Each registered marketplace is already cloned to disk
# by the `marketplace add` above, so naming the difference costs one jq pass
Expand Down
14 changes: 7 additions & 7 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf

# Markdown — trailing whitespace is significant (two trailing spaces = a hard
# Markdown: trailing whitespace is significant (two trailing spaces = a hard
# line break); indentation is variable per CommonMark.
[*.{md,markdown}]
trim_trailing_whitespace = false
Expand All @@ -28,13 +28,13 @@ indent_size = unset
[*.{json,jsonc,yml,yaml,toml}]
indent_size = 2

# JavaScript / TypeScript — 2-space, matching the shared Biome formatter policy
# JavaScript / TypeScript: 2-space, matching the shared Biome formatter policy
# (the single owner of JS/TS formatting). IndentSize is disabled in the checker,
# so this is an editor hint that keeps editors aligned with Biome.
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}]
indent_size = 2

# Go — gofmt is the sole formatter and indents with tabs, so the space default
# Go: gofmt is the sole formatter and indents with tabs, so the space default
# does not apply; indent enforcement is disabled here and deferred to gofmt
# (mirrors the JS/TS deferral to Biome).
[*.go]
Expand All @@ -45,19 +45,19 @@ indent_size = unset
[*.{sh,bash}]
indent_size = 2

# Windows batch — cmd.exe requires CRLF.
# Windows batch: cmd.exe requires CRLF.
[*.{cmd,bat}]
end_of_line = crlf

# Git config — git writes (and idiomatically uses) tab indentation under each
# Git config: git writes (and idiomatically uses) tab indentation under each
# section, so the space default does not apply. Covers the plain file, gitconfig
# includes, and chezmoi-style source forms (dot_gitconfig, dot_gitconfig.tmpl).
[{.gitconfig,*.gitconfig,dot_gitconfig*}]
indent_style = tab

# Lockfiles — generated; suppress formatting enforcement. packages.lock.json is
# Lockfiles: generated; suppress formatting enforcement. packages.lock.json is
# NuGet's lock file (written by restore with platform line endings and no final
# newline — hence end_of_line is unset too; .gitattributes still normalizes the
# newline, hence end_of_line is unset too; .gitattributes still normalizes the
# committed bytes to LF).
[{package-lock.json,packages.lock.json,*.lock}]
end_of_line = unset
Expand Down
2 changes: 1 addition & 1 deletion .editorconfig-checker.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"_comment": "Root-canonical editorconfig-checker policy (keys per editorconfig-checker 3.x). Validates files against the repo-root .editorconfig. Line endings are NOT checked here — .gitattributes is the single authority for EOL, so EndOfLine is disabled to avoid double-enforcement. IndentSize and MaxLineLength are disabled because indent width and line length are owned by per-language formatters and are IDE hints, not hard rules. Only deviations from the engine defaults are listed. Verbose, Debug, IgnoreDefaults, SpacesAfterTabs, NoColor, AllowedContentTypes, PassedFiles, and the Disable entries not named below already hold their engine defaults, so they are omitted deliberately rather than restated — do not add them back. Note AllowedContentTypes is omitted rather than left empty because the engine merges a non-empty value onto its defaults and skips an empty one, so `[]` was already a no-op. Exclude[] entries are universal regular expressions; managed consumers do not edit this file and pass repository-specific excludes with -exclude (which combines additively). Version is intentionally blank so the config adopts cleanly on any 3.x engine; consumers pin the engine in CI.",
"_comment": "Root-canonical editorconfig-checker policy (keys per editorconfig-checker 3.x). Validates files against the repo-root .editorconfig. Line endings are NOT checked here: .gitattributes is the single authority for EOL, so EndOfLine is disabled to avoid double-enforcement. IndentSize and MaxLineLength are disabled because indent width and line length are owned by per-language formatters and are IDE hints, not hard rules. Only deviations from the engine defaults are listed. Verbose, Debug, IgnoreDefaults, SpacesAfterTabs, NoColor, AllowedContentTypes, PassedFiles, and the Disable entries not named below already hold their engine defaults, so they are omitted deliberately rather than restated; do not add them back. Note AllowedContentTypes is omitted rather than left empty because the engine merges a non-empty value onto its defaults and skips an empty one, so `[]` was already a no-op. Exclude[] entries are universal regular expressions; managed consumers do not edit this file and pass repository-specific excludes with -exclude (which combines additively). Version is intentionally blank so the config adopts cleanly on any 3.x engine; consumers pin the engine in CI.",
"Version": "",
"Exclude": [
"bin/",
Expand Down
10 changes: 5 additions & 5 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*.bash diff=bash

###############################################################################
# PowerShell — LF is deliberate. Verified to run on both PowerShell 7 and
# PowerShell: LF is deliberate. Verified to run on both PowerShell 7 and
# Windows PowerShell 5.1. The PowerShell repo pins .ps1 to eol=lf; the popular
# community gitattributes template pins crlf — they target different eras. Listed
# community gitattributes template pins crlf, and they target different eras. Listed
# explicitly so it is not "corrected" to crlf without a requirement to round-trip
# pre-existing CRLF-signed scripts unchanged.
###############################################################################
Expand All @@ -27,22 +27,22 @@
*.psd1 text eol=lf

###############################################################################
# Windows-native — cmd.exe requires CRLF (overrides the LF default above).
# Windows-native: cmd.exe requires CRLF (overrides the LF default above).
###############################################################################

*.cmd text eol=crlf
*.bat text eol=crlf

###############################################################################
# Lockfiles — tracked, but suppress noisy diffs (regenerate to resolve).
# Lockfiles: tracked, but suppress noisy diffs (regenerate to resolve).
###############################################################################

package-lock.json -diff
packages.lock.json -diff
*.lock -diff

###############################################################################
# Binary — no line-ending conversion, no diff.
# Binary: no line-ending conversion, no diff.
###############################################################################

*.png binary
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/managed-files-guard.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: managed-files-guard

# SYNC-MANAGED FILE — DO NOT EDIT IN THE CONSUMING REPOSITORY.
# SYNC-MANAGED FILE: DO NOT EDIT IN THE CONSUMING REPOSITORY.
# Source of truth: melodic-software/standards,
# components/managed-files-guard/managed-files-guard.yml (the
# `managed-files-guard-caller` component in distribution/sync-manifest.yml).
Expand All @@ -14,8 +14,8 @@ name: managed-files-guard
# it is given and fails the pull request when the diff hand-edits one of them
# (ADR-0007: a managed file is byte-exact with its standards source; the fix
# path is a standards change, never a downstream edit). Pull requests opened
# by the sync itself — labeled `standards-sync`, or authored by
# `melodic-standards-sync[bot]` — are exempt inside the action.
# by the sync itself (labeled `standards-sync`, or authored by
# `melodic-standards-sync[bot]`) are exempt inside the action.
#
# ADVISORY during soak (standards#496): this check is NOT aggregated into
# `ci-status` and is not a required context. Promotion is a per-target
Expand Down
2 changes: 1 addition & 1 deletion .gitleaks.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# gitleaks — https://github.com/gitleaks/gitleaks
# gitleaks: https://github.com/gitleaks/gitleaks
# Config reference: https://github.com/gitleaks/gitleaks#configuration
#
# Root-canonical policy: inherit the upstream default ruleset and add nothing
Expand Down
6 changes: 3 additions & 3 deletions .markdownlint-cli2.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// GitHub Flavored Markdown (GFM) ruleset for markdownlint-cli2.
// The $schema URL pins to the markdownlint-cli2 devDependency of
// melodic-software/standards (its package.json), where this file is authored
// and synced into consumers from. Authoring-time validation only — it makes
// and synced into consumers from. Authoring-time validation only: it makes
// no claim about which markdownlint-cli2 version a consumer runs. In standards,
// bump it alongside that dependency; markdownlint-schema-pin.test.sh fails the
// standards build if the two drift apart.
Expand All @@ -11,7 +11,7 @@
// Globs are passed by the caller (CLI / CI), not declared here.
"$schema": "https://raw.githubusercontent.com/DavidAnson/markdownlint-cli2/v0.23.2/schema/markdownlint-cli2-config-schema.json",
"ignores": [
// Build, dependency, and cache trees — not authored markdown.
// Build, dependency, and cache trees: not authored markdown.
"**/node_modules/**",
"**/.venv/**",
"**/bin/**",
Expand All @@ -26,7 +26,7 @@
"MD046": { "style": "fenced" }, // Fenced (not indented) code blocks
"MD048": { "style": "backtick" }, // Backtick (not tilde) code fences
"MD024": { "siblings_only": true }, // Allow duplicate headings under different parents
"MD060": false, // Table column style — disabled; allows any pipe spacing (its default flags tables matching no supported style)
"MD060": false, // Table column style: disabled; allows any pipe spacing (its default flags tables matching no supported style)

// --- Relaxed for GFM / prose ---
"MD013": false, // No hard line-length limit (tables and code exceed 80)
Expand Down
Loading
Loading