Skip to content

main - release#365

Merged
saadqbal merged 3 commits into
mainfrom
develop
Jul 21, 2026
Merged

main - release#365
saadqbal merged 3 commits into
mainfrom
develop

Conversation

@saadqbal

@saadqbal saadqbal commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Related

Type of change

  • Feature
  • Bug fix
  • Tech-debt / refactor
  • Docs
  • Security / hardening
  • Breaking change

Test plan

Screenshots / recordings

Deployment notes

Checklist

  • Tests added / updated and passing locally
  • Docs updated if behavior or config changed
  • No secrets / credentials in the diff
  • For security-sensitive paths: appropriate reviewer requested

Note

Low Risk
Mostly installer UX, docs, and CI linting; credential/name sanitization is improved via shared paste stripping with limited blast radius.

Overview
Introduces a shared terminal style system for bash and PowerShell installers, documented in STYLE.md and enforced in CI by scripts/check-style.sh (no hardcoded brand hex outside common.sh, no traffic-light emoji, no user-facing “workspace”).

scripts/lib/common.sh becomes the bash colour engine (TB_* tones, truecolor/NO_COLOR handling); summaries and helpers switch to those roles (cyan headings, lime commands, lime instead of 🟢). Windows install-k8s.ps1 gets matching role colours and copy tweaks (“Environment”, green commands).

Terminology / UX: prompts say secure environment; _strip_paste_garbage is centralized in common.sh and applied to the client-name prompt in provision.sh (plain read to avoid tee/readline echo issues). CLI install uses a soft spinner, one-line success (tb vs tracebloc, up to date / updated), and tests were updated. manifest.sha256, CODEOWNERS, and the PR checklist reflect the new guard.

Reviewed by Cursor Bugbot for commit 41be7a1. Bugbot is set up for automated code reviews on this repo. Configure here.

LukasWodka and others added 3 commits July 21, 2026 10:38
* Installer: clean setup output + fix name-prompt escape garble

Two related installer polish items on the macOS/Linux install path.

1. Setup output copy (matches the agreed spec)
   The password/Docker/tools/CLI lines were noisy and off-guideline
   (stray "Homebrew", "(k3d, helm, kubectl)", tool-version dumps, and a
   "verified on your PATH" claim). Collapse to the intended sequence:

     tracebloc needs your password once to set up Docker and a few tools.
     Password:
     ✔ Docker ready
     ✔ System tools ready
     ✔ tracebloc CLI updated (v0.9.2 → v0.9.3) — run `tb` to use it

   - common.sh: password hint "install" → "set up".
   - setup-macos.sh: Homebrew lines → log() (hidden); drop the
     "(k3d, helm, kubectl)" parenthetical from "System tools ready".
   - install-cli.sh: collapse the already-present / re-running / installing /
     ready pileup into ONE ✔ line with an old→new version delta when the
     CLI was upgraded ("updated (vX → vY)"), else "up to date" / "ready";
     capture the prior version before the installer runs. Edge-case lines
     (installed-but-not-yet-on-PATH) keep the actionable PATH-fix hints.
   - install-k8s.ps1: Windows parity for the same three changes.

2. Name-prompt escape garble (customer-reported 2026-07-20)
   Typing arrow keys at the "Name this client" prompt injected raw
   ESC[D/ESC[A bytes that slug-ified into a garbage name ("d-d-d-a-a-a")
   when passed to `client create`. The credential prompt already stripped
   these; the name prompt did not.
   - provision.sh: `read -e` (readline line-editing so arrows move the
     cursor instead of emitting escapes) + strip any sequence that still
     slips through, using the same helper the credential path uses.
   - Reword the prompt to "Name your secure environment" (terminology SoT).
   - Move _strip_paste_garbage from install-client-helm.sh to common.sh so
     both the credential path and the name prompt share one sanitizer
     (removes a fragile cross-file dependency; fixes bats isolation).

Tests: install-cli.bats assertions updated for the new ✔ copy; ps1 Pester
assertions likewise. Full bats suite green except two failures that
pre-date this change and reproduce on clean develop (validate_config /
_extract_yaml_value — local bash/locale artifacts, unrelated).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address Bugbot: drop read -e (breaks echo under tee) + guard false "updated"

Two Bugbot findings on #362.

1. provision.sh (Medium) — "Readline echo breaks under tee".
   setup_log_file redirects this process's stdout+stderr through
   `exec > >(tee …) 2>&1`. `read -e` (readline) echoes typed characters to
   stderr, so under the tee pipe the live echo is delayed/garbled on exactly
   the interactive name-prompt path this change targets. Revert to plain
   `read -r` — kernel-tty echo is immune to the redirection — and keep relying
   on _strip_paste_garbage (the actual escape-garble fix) for the captured
   value. No behavioural loss: the strip already neutralizes arrow-key bytes.

2. install-cli.sh (Low) — "False CLI updated verdict".
   The upgrade branch fired on any non-empty TB_CLI_OLD_VER != "$ver",
   including when $ver was empty after a failed post-install version probe —
   printing "tracebloc CLI updated" with no version to back it up. Gate the
   branch on `-n "$ver"` too, so an unconfirmed version falls through to the
   neutral "up to date".

Tests: install-cli.bats + provision.bats green; the two pre-existing failures
(validate_config / _extract_yaml_value) are unchanged and unrelated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address Bugbot: prefer `tb`, fall back to `tracebloc` in CLI success copy

Bugbot "wrong CLI command in success copy" (Medium) on #362.

The new ✔ verdict lines hardcoded "run `tb`", but the CLI installer only
symlinks `tb` when that name is free — when it's already taken it skips the
alias, leaving only `tracebloc`. In that case the copy pointed the user at a
command that doesn't exist (command-not-found right after a clean install).

Detect the usable command once (`tb` when it resolves, else `tracebloc`) and
use it in all four verdict lines. The short alias is still preferred — and
still what the copy shows in the common case — so the agreed
"… — run `tb` to use it" output is unchanged where `tb` exists.

- install-cli.sh: `local cli_cmd="tracebloc"; has tb && cli_cmd="tb"`, used in
  the updated / up-to-date / ready / installed lines.
- install-k8s.ps1: same, `$cli = if (Has "tb") { "tb" } else { "tracebloc" }`.
- install-cli.bats: strengthen the verified-verdict test to assert the `tb`
  preference, and add a test that the copy names `tracebloc` when `tb` is absent.

(The round-1 "false updated verdict" thread is already resolved by the earlier
`-n "$ver"` guard; Bugbot did not re-raise it on this HEAD.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address Bugbot: keep the non-fatal CLI install failure soft (drive spin directly)

Bugbot "fatal-looking CLI install failure UX" (Medium) on #362.

Collapsing the CLI-install step onto spin_cmd (earlier in this PR) meant a
failed install now prints spin_cmd's hard red "✖ Installing the tracebloc CLI…"
+ a 10-line log dump BEFORE the soft "your client is set up fine" warn. This
step is non-fatal by design (the client is already connected), so that reads as
a hard failure and reintroduces exactly the noisy output this PR removes.

Drive `spin` directly instead — same transient spinner, but no hard-failure
banner — and let the existing soft warn + "install it later" hint own the
failure path.

Strengthened the non-fatal-failure bats test to assert the hard "✖ …" line and
"Last 10 lines" log dump are absent (they'd be present with spin_cmd).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Regenerate installer manifest (supply-chain R8) for the changed scripts

scripts/gen-manifest.sh — updates the SHA256 entries for the six installer
files touched in this PR (common.sh, setup-macos.sh, install-client-helm.sh,
install-cli.sh, provision.sh, install-k8s.ps1). Fixes the 'Installer manifest
is current' static-analysis gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* installer: mirror the brand terminal style system (surface 2)

Ports the Go CLI's style system (cli #367) to the bash installer + the
Windows ps1, so both surfaces read identically. Same organising idea from
the homepage gradient: cyan orients (structure), lime moves (action).

common.sh — a colour engine mirroring internal/ui:
- Decides mode {none,16,true} + background {dark,light} ONCE at source time
  (before setup_log_file redirects stdout through tee, so `-t 1` sees the real
  terminal): NO_COLOR / non-TTY / TERM=dumb / TB_PLAIN=1 → none;
  COLORTERM=truecolor|24bit → 24-bit; else ANSI-16. COLORFGBG picks the bg.
  This ALSO adds the colour-off gating the installer never had.
- A tone table (_sgr) maps each role to its exact 24-bit hex on dark AND light
  (primary/secondary ramps) + the nearest ANSI-16 fallback — the same values
  the Go engine emits (cyan #01a5cc, lime #91e947, soft lime #a7ed6c, …).
- Re-points the helpers: success ✔ → lime, warn ⚠ → amber, error ✖ → bold red,
  step / step_header → cyan headings, labels → dim. Legacy CYAN/GREEN/… kept as
  tone aliases so untouched call sites stay on-brand and honour the off switch.

summary.sh — the connected / starting / error screens: cyan headings, lime
commands (`tracebloc data ingest`), cyan-underline links, soft-lime descriptions,
lime ● online (replacing the 🟢 emoji), dim label:value rows.

install-k8s.ps1 — Windows parity at the 16-colour tier (Write-Host can't do
truecolor): summary commands Cyan → Green, the "next" heading → Cyan, metadata
labels dim with plain values. Text unchanged (Pester assertions unaffected).

scripts/manifest.sha256 regenerated (R8 supply-chain gate) for the three
changed installer files.

Tests: full bats suite green except the two pre-existing local failures
(validate_config / _extract_yaml_value); bash -n + shellcheck clean on the
changed libs. No bats test asserts on colour codes, so the new gating is safe.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* test(summary): assert the live-status heading, not the removed 🟢 emoji

The style retheme replaced the 🟢 emoji with a lime ● (design decision: no
emoji). summary.bats:68 still asserted *"live 🟢"*, which passed on the local
bash/bats but failed in CI (multibyte-glob matching differs across versions —
same reason the validate_config / _extract_yaml_value baseline failures invert
locally vs CI). Assert the ASCII heading "Your secure environment is live"
instead — robust across locale, colour on/off, and bash version.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
* Enforce the terminal style system + terminology (installer)

Guards the style system (STYLE.md, shipped in #363) against regressions from
other contributors, layered strongest-first:

- scripts/check-style.sh — a CI gate (blocking, in the "Static analysis" job)
  with three MECHANICAL checks: no hardcoded brand colour outside the tone
  engine (common.sh), no status/traffic-light emoji, and no "workspace" in
  user-facing text (→ "secure environment"). Internal identifiers (the DNS-1123
  sanitisers), comments, and scripts/tests/ are exempt; a line can opt out with
  a trailing `# style-guard: allow`. Semantic calls (role misuse, softer wording)
  stay with review — a grep can't police those.
- STYLE.md — the reference: cyan=structure / lime=action, the role→tone table,
  where the engine lives, and the terminology glossary (SoT = docs TERMINOLOGY.md).
- CODEOWNERS — the guard + STYLE.md are code-owned, so the rules themselves
  can't be quietly weakened. (The engine files under scripts/lib/ + the ps1 are
  already owned via the R8 trust root.)
- PR template — a checklist line pointing at STYLE.md + the guard.

Cleaned the two pre-existing violations the guard surfaced so it ships blocking
with develop clean:
- common.sh --help: "Namespace / workspace label" → "Secure-environment name".
- install-k8s.ps1 summary: "Workspace :" → "Environment :" (aligns with the bash
  summary; re-padded the Version/Mode labels to match). No Pester assertion keys
  on the label text.

Manifest regenerated (R8) for the common.sh + ps1 edits. Guard passes; bash -n +
shellcheck clean; the 3 local bats failures are pre-existing on develop
(confirmed with the change stashed), unrelated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address Bugbot: make the brand-colour check case-insensitive

The hex scan matched only lowercase (01a5cc), so an uppercase #01A5CC would
slip past. Add -i to check 1. (Same fix applied to the cli guard.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address Bugbot: guard fails closed, anchored comment filter, shellcheck the guard

Three findings on #364.

1. Fails open on errors (Medium). scan swallowed grep stderr and read empty as
   clean, so a scan failure (bad regex/flags, missing tree) passed the blocking
   gate silently. Now: a missing scripts/ tree exits 2 up front, and grep exit
   ≥2 sets guard_error → the guard exits 2 (fail closed), never a silent pass.
2. Comment filter matched mid-line (Low). ':[0-9]+: *#' could exempt a
   user-facing string that merely embeds that shape (e.g. a URL port + fragment).
   Anchored to the file:line: prefix: '^[^:]+:[0-9]+:[[:space:]]*#'.
3. Guard omitted from ShellCheck (Low). Added scripts/check-style.sh to the
   Static-analysis ShellCheck step so regressions in the guard itself are caught.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Address Bugbot: make fail-closed actually reachable (parent-shell scan)

Follow-up to the previous fail-closed attempt, which didn't work: guard_error
was set inside scan, but scan was invoked via $(scan …) — a command-substitution
subshell — so the flag never reached the parent and the `exit 2` path was
unreachable (Bugbot: "fail-closed path never triggers"). A grep error could
still print ok / exit 0.

Fix: call scan in the PARENT shell (scan …, not $(scan …)); it now sets a global
`hits` plus guard_error directly, and the per-check display filtering moves to
the report() argument. Verified: a forced grep error (invalid regex) now
propagates guard_error and exits 2.

(The other two re-flags — guard omitted from ShellCheck, and the make-ci gap on
the cli side — were already fixed in earlier commits; confirmed present.)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* check-style: surface grep errors instead of suppressing (still fail-closed)

Drop 2>/dev/null on the scan grep so a real internal error prints to stderr;
rc>=2 already turns it into a fail-closed exit 2 (verified). Also removes the
pattern that kept tripping Bugbot's (now-inaccurate) 'fails open' heuristic —
the rc check on the very next line is the actual fail-closed path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
Contributor

👋 Heads-up — Code review queue is at 33 / 30

Above the WIP limit. The team convention is to review existing PRs before opening new work.

Open PRs currently in Code review (oldest first):

Pull from review before opening new work. (This is a nudge from the kanban WIP check, not a block.)

@saadqbal saadqbal self-assigned this Jul 21, 2026
@saadqbal
saadqbal merged commit e5fe41a into main Jul 21, 2026
65 of 66 checks passed
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.

3 participants