Skip to content

Extract /statusline install logic into a tested script - #12

Merged
gering merged 3 commits into
mainfrom
task/refactor-statusline-to-script
Jun 18, 2026
Merged

Extract /statusline install logic into a tested script#12
gering merged 3 commits into
mainfrom
task/refactor-statusline-to-script

Conversation

@gering

@gering gering commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Summary

  • Move the /statusline install/enable/disable/uninstall/status logic out of 24 KB of SKILL.md prose into a deterministic, locally-testable shell script.
  • The skill becomes a thin wrapper: parse the argument, invoke the script, relay its output.
  • Closes the "render half is a script, install half is prose" gap from the architecture review (Prio 5). The render half (statusline-cks.sh) was already a script; now the install half is too.

Changes

  • New plugins/knowledge-system/scripts/statusline-install.sh (518 lines): marker-block injection/removal, # {{cks}} placement priority (placeholder → auto-detect → guided abort), version-gated renderer copy, per-project sentinel management, atomic python3 mutation with session backup + post-write verify (non-empty / marker-pair / bash -n / executable-bit), restore-on-failure.
  • SKILL.md shrunk 24 KB → 4.6 KB: argument parsing + script invocation + result presentation; user-facing docs (output format, custom placement, third-party tools) retained.
  • Version bump knowledge-system 1.7.0 → 1.8.0 (plugin.json + marketplace.json, in sync).

Readiness

  • ✅ README — verified current (behavior unchanged; pure refactor)
  • ✅ Version — bumped to 1.8.0 (both files in sync)
  • ➖ Changelog — N/A (repo has none)
  • ➖ Knowledge — N/A (no .claude/knowledge; applies the established prose→script pattern from /define, /rebase)
  • ✅ Tests — scripts/check-structure.py 0 errors; 16/16 functional sandbox tests pass
  • ➖ Lint/Build — N/A (declarative markdown/JSON; bash -n covered by the structure check)

Test plan

  • python3 scripts/check-structure.py → 0 errors
  • bash -n plugins/knowledge-system/scripts/statusline-install.sh
  • /statusline status in a project with .claude/knowledge or .claude/rules
  • /statusline install against a custom ~/.claude/statusline.sh (placeholder + auto-detect paths), then uninstall — confirm clean round-trip and backup

🤖 Generated with Claude Code

gering and others added 3 commits June 17, 2026 12:23
Move install/enable/disable/uninstall/status out of 24 KB of SKILL.md
prose into scripts/statusline-install.sh; the skill becomes a thin
wrapper (parse argument, invoke script, relay output).

- New statusline-install.sh: marker-block injection/removal, # {{cks}}
  placement priority, version-gated renderer copy, per-project sentinel,
  atomic python3 mutation with backup + post-write verify
- Shrink SKILL.md from 24 KB to 4.6 KB
- Bump knowledge-system to 1.8.0 (plugin.json + marketplace.json)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Address findings from a multi-angle review of statusline-install.sh:

- restore_and_die: report a failed restore truthfully instead of a false
  "Restored from backup" when the cp itself fails
- mutate_file: read/write bytes so CRLF and non-ASCII host files survive
  untouched (text mode normalized newlines and choked under a C locale)
- inspect_markers: single marker-pair classifier shared by install,
  uninstall, and status — status now applies the BEGIN<END check and
  reports INVALID consistently instead of "installed and current"
- project_dir helper: per-project sentinel ops mirror the renderer's
  DIR-first precedence so disable/enable/status agree with render time
- validate START_LINE/END_LINE before mutation (grep-misfire failsafe)
- backup via mktemp (no same-second collision); post-write chmod warns
  instead of failing a correct install; status distinguishes an unreadable
  target from an absent marker; empty argument token defaults to status

Covered by a 22-case sandbox suite (all green); check-structure clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Second review-round findings on statusline-install.sh:

- mutate_file split on \n only (matching grep -n) instead of
  bytes.splitlines(), which also breaks on a lone \r and desynced the
  Python line indices from the bash-computed ones — a lone-CR line above
  the marker would splice the block at the wrong offset
- preserve the host file's permission bits across os.replace (copy the
  original mode onto the temp file), so install no longer drops group/other
  bits (e.g. 0770 -> 0644) or print a spurious "was dropped during write"
  on every run
- project_dir back to CLAUDE_PROJECT_DIR-first: a stray $DIR in the
  environment must not redirect the per-project sentinel (and this matches
  the SKILL.md contract)

Sandbox suite extended to 24 cases (lone-CR placement, mode preservation,
stray-$DIR sentinel); all green; check-structure clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gering
gering merged commit adf9dcb into main Jun 18, 2026
1 check passed
@gering
gering deleted the task/refactor-statusline-to-script branch June 18, 2026 07:01
gering added a commit that referenced this pull request Jul 16, 2026
First dogfooding run: /swarm:review --fix over its own diff (4 cluster
finders + codex + grok-4.5 + composer; 13 findings, 5 cross-family
consensus). Fixes the agreed findings:

- Keep validly tagged off-cluster lens prefixes: validate against the
  global lens set, not the finder's subset — coercion could flip kind
  and route a real defect through the applicability verifier (#1, consensus critical)
- Verify design clusters even with cross-family consensus: agreement
  attests agreement, not repo-grounded applicability (externals cannot
  open repo files); defect consensus stays auto-accepted (#2)
- Untagged external findings ('unspecified' lens) no longer vote in the
  cluster-kind derivation (#3)
- Derive CANDIDATE_LENSES from LENS_CLUSTERS — one list, no unchecked
  mirror; DRIFT WARNING on the SKILL.md external-prompt copy (#4, #9)
- Finder prompt: "issue (defect or substantive improvement)" + all lens
  prefixes; external prompt lead covers design improvements too (#5, #6)
- pr-post.py owns design-row ordering + [lens] prefixing via optional
  kind/lens row fields, unit-tested; SKILL.md step 5 passes rows through
  verbatim (#13)
- Doc sync: balance-spec finder count, README canonical cluster names +
  preset teaser wording, knowledge-index line trimmed (#8, #10, #11, #12)

Declined: #7 (per-cluster dilutes per-lens depth) — deliberate,
documented cost/coverage trade-off; --max is the depth profile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 16, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
Swarm loop round 3 — 3 findings, all in the probe. Rather than patch a probe
that had a security jail bolted on (rounds 1-3 all fixed jail-adjacent bugs),
this removes the jail: a readiness check passes no untrusted diff, so it never
needed one — the sibling `codex login status` in ready_check is unjailed too.

- Run `grok models` directly, not through sandboxed(). This roots out the
  round-3 CRITICAL (#18): the jail's `_init_sandbox` builds its deny profile
  with python3, so routing the probe through it made python3 a hard dependency
  of the formerly-local `ready`/`list` paths — and a missing python3 then
  misreported as "grok models failed (rc=65)". No jail, no python3 dep, honest
  reasons.
- Bound with `timeout -k 3` (#17): plain `timeout` only SIGTERMs, so a grok
  that ignores SIGTERM (or forks a stdout-inheriting child) kept the command
  substitution blocking past the deadline — the "must never hang" hole. `-k`
  SIGKILLs after a grace period. rc 124 (SIGTERM at the deadline) reports as
  "timed out"; rc 137 (SIGKILL) reports as "killed" — almost always our own
  `-k`, but an OOM/external kill shares the code, so the message doesn't assert
  a timeout that may not have happened.
- Take only the FIRST id per bullet line (#19): scanning the whole line also
  matched a grok-4.5 mentioned in prose on another model's line
  ("* grok-5 (successor to grok-4.5)"), reporting a retired model as offered.
- Fold _build_jail back into sandboxed(). It existed ONLY to share the jail
  with the probe; with the probe unjailed, the split — and the shared-warning
  (#12) and per-backend-memo (#15) fixes it forced last round — are moot.
  sandboxed() is back to its pre-split shape; _init_sandbox keeps the backend
  key (harmless, strictly more correct).
- Fix a stale swarm-review.js input-contract comment ("subset of the three" →
  codex, grok).
- Docs (header/README/CHANGELOG/knowledge) drop the jail claim. The knowledge
  entry records the real lesson: five rounds of patching a jailed probe ended
  the moment the jail was deleted — a feature added to be safe that generates
  every round's bugs is a shape problem; cut it, don't harden it. The composer
  removal (the PR's subject) drew zero findings across all five rounds.

Verified: live grok ready; SIGTERM-ignoring grok bounded by -k in ~5s, reported
as killed; SIGTERM-obeying grok reported as timed out; model-gone → honest hint,
no warning; probe rc=1 → warn + trust-auth; NO python3 invoked on the ready
path; review path still fully jailed (sandbox-exec + AWS/GH secret stripping);
end-to-end review returns a schema-valid finding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gering added a commit that referenced this pull request Jul 17, 2026
First dogfooding run: /swarm:review --fix over its own diff (4 cluster
finders + codex + grok-4.5 + composer; 13 findings, 5 cross-family
consensus). Fixes the agreed findings:

- Keep validly tagged off-cluster lens prefixes: validate against the
  global lens set, not the finder's subset — coercion could flip kind
  and route a real defect through the applicability verifier (#1, consensus critical)
- Verify design clusters even with cross-family consensus: agreement
  attests agreement, not repo-grounded applicability (externals cannot
  open repo files); defect consensus stays auto-accepted (#2)
- Untagged external findings ('unspecified' lens) no longer vote in the
  cluster-kind derivation (#3)
- Derive CANDIDATE_LENSES from LENS_CLUSTERS — one list, no unchecked
  mirror; DRIFT WARNING on the SKILL.md external-prompt copy (#4, #9)
- Finder prompt: "issue (defect or substantive improvement)" + all lens
  prefixes; external prompt lead covers design improvements too (#5, #6)
- pr-post.py owns design-row ordering + [lens] prefixing via optional
  kind/lens row fields, unit-tested; SKILL.md step 5 passes rows through
  verbatim (#13)
- Doc sync: balance-spec finder count, README canonical cluster names +
  preset teaser wording, knowledge-index line trimmed (#8, #10, #11, #12)

Declined: #7 (per-cluster dilutes per-lens depth) — deliberate,
documented cost/coverage trade-off; --max is the depth profile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
First dogfooding run: /swarm:review --fix over its own diff (4 cluster
finders + codex + grok-4.5 + composer; 13 findings, 5 cross-family
consensus). Fixes the agreed findings:

- Keep validly tagged off-cluster lens prefixes: validate against the
  global lens set, not the finder's subset — coercion could flip kind
  and route a real defect through the applicability verifier (#1, consensus critical)
- Verify design clusters even with cross-family consensus: agreement
  attests agreement, not repo-grounded applicability (externals cannot
  open repo files); defect consensus stays auto-accepted (#2)
- Untagged external findings ('unspecified' lens) no longer vote in the
  cluster-kind derivation (#3)
- Derive CANDIDATE_LENSES from LENS_CLUSTERS — one list, no unchecked
  mirror; DRIFT WARNING on the SKILL.md external-prompt copy (#4, #9)
- Finder prompt: "issue (defect or substantive improvement)" + all lens
  prefixes; external prompt lead covers design improvements too (#5, #6)
- pr-post.py owns design-row ordering + [lens] prefixing via optional
  kind/lens row fields, unit-tested; SKILL.md step 5 passes rows through
  verbatim (#13)
- Doc sync: balance-spec finder count, README canonical cluster names +
  preset teaser wording, knowledge-index line trimmed (#8, #10, #11, #12)

Declined: #7 (per-cluster dilutes per-lens depth) — deliberate,
documented cost/coverage trade-off; --max is the depth profile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 17, 2026
Second dogfooding round at the deepest profile (/swarm:review --max --fix:
per-lens split live — gate pruned style, 10 xhigh finders + codex
gpt-5.6-sol@xhigh + grok-4.5 + composer; 24 findings, 10 consensus).
Fixes the agreed findings:

- Never auto-accept an all-untagged consensus cluster: no tagged lens
  backs it, so it is verified like a solo. Verify/auto-accept now derive
  from ONE needsVerify predicate (structural exactly-once partition);
  kind vote in clearer every-form (#1, consensus critical; #21, #22)
- Design verifier sees the finding's recommendation — the proposal the
  applicability rubric actually tests — and carries an escape hatch:
  a genuine defect mis-filed under a design lens is not refuted away
  (#12, #3); "solo" dropped from verifier prompts (#4)
- Untagged findings from multi-lens cluster finders fall back to
  'unspecified' (safe defect bucket), not lenses[0] (#7); merge-agent
  free-text lens validated, majority-member fallback (#9)
- Improvement invitation scoped to design finder units — defect-lens
  finders stay defect-only (#8); merge prompt clusters by issue, not
  only defect (#13); schema descriptions generalized for design
  findings (#14)
- LENS_BRIEF startup assertion (#6); gate prompt interpolates
  LENS_CLUSTERS.design (#19); new test_lens_sync.py guards all lens
  mirrors: SKILL HDR prompt, LENS_BRIEF, pr-post DESIGN_LENSES (#5)
- Workflow assigns stable finding num (defects first, shared sequence);
  presenter/pr-post render it verbatim (#20)
- pr-post.py: design lens is the backup kind signal when the handoff
  drops kind (explicit defect still wins); single-pass partition (#17, #24)
- Balance: REFUTED is its own segment (refuted ⊄ solo since design
  consensus can be refuted) (#2); LOCKED design-table column precedence
  in --loop rounds clarified (#11); "verifies solos" doc sweep across
  manifests/README/knowledge (#4); cluster failure-isolation trade-off
  documented (#10); knowledge index line trimmed (#15)

Declined: #16 (JS test harness for sandbox code; lens-sync test covers
the drift class), #18 (gate-fail under --max runs all lenses — the
documented never-silently-narrower degrade), #23 (micro-opt vs readability).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126cGxsBYxqgEFH4AcpriNk
gering added a commit that referenced this pull request Jul 23, 2026
External-only swarm review (codex + grok) on PR #42. Apply the agreed
findings to the decision record:

- AMQ send vs single-sequencer: workers send only to the Manager handle;
  Manager relays. `amq send --to <peer>` bypasses the sequencer (#1).
- Broadcast: reuse AMQ fan-out/presence/federation instead of hand-rolled
  multi-writer global.jsonl (the model Maildir superseded) (#2).
- Lane lifecycle: drain-on-/close + stale-mail guard so a reused path never
  reconsumes a prior occupant's undrained message (#3).
- Soften the "RESOLVES" overclaim: this ADR supersedes the herdr docs' enum;
  their refresh is pending (#4).
- Canonicalize the lane key via git rev-parse --show-toplevel, not raw cwd (#7).
- Fix ws-statusline states flag order: `states [--cached] <dir>` (#10).
- _index.md blurb: central ~/.agent-mail/ mailbox, not the superseded
  .mailbox/ protocol (always-loaded surface) (#11).
- Note the spike is decided, no open task file (#12).
- Trust-model residuals (convention-based identity, home-dir readable store)
  as accepted for a single-user local tool (#5, #6).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LTZx9DqrXPXQFoTrCvcJmD
gering added a commit that referenced this pull request Jul 25, 2026
Apply the agreed findings from a local swarm review (11 ✅ + 1 🟨; the 3 ❌ —
a feature version bump, a README inventory line, and a per-subcommand python3
guard — were deliberately left, see the PR discussion).

herdr-agent.sh:
- Bound herdr list/get/read with a wall-clock timeout (_ha_bounded: timeout →
  gtimeout → perl alarm), honouring the header's "never a hang" promise. wait
  stays governed by its own --timeout. (#6)
- ha_wait now detects the --timeout=MS form too, so a caller's explicit bound in
  either spelling is honoured and no duplicate flag is appended. (#7)
- A missing <target> returns usage code 2, not 4 (server-unreachable), so a
  programmer error is not mistaken for a transient outage. (#12)
- set -u is enabled only on the executed-CLI path, never at source time, so
  sourcing for the prelude/helpers no longer mutates the caller's shell. (#13)
- classify_cwd returns the resolved path as a third tuple element, so a caller
  keying by full path reuses it instead of a second realpath. (#14)

lanes.sh:
- Scrub tab/CR/LF from every TSV cell: agent-derived fields are untrusted, and an
  embedded tab/newline would forge columns/rows. Mirrors herdr-tab-glyph. (#1)
- Guard the agent loop against non-dict (null) elements → never crash, always
  exit 0. (#2)
- flush() now calls the shared classify_cwd instead of re-open-coding the task
  rule, so the classification can't drift between the two consumers. (#15)
- Resolve SCRIPT_DIR via BASH_SOURCE (robust to bare-name invocation). (#5)
- Header wording: exit-0 scope clarified; --json emits [] when no lanes. (#3, #8)

herdr-tab-glyph.sh: consume classify_cwd's new 3-tuple; same BASH_SOURCE fix (#5).
herdr-tab-glyphs.md: point at $HERDR_MATCH_PRELUDE as the shared match SoT. (#10)
Tests extended: null-element + TSV-injection (lanes); --timeout= + missing-target
exit 2 (herdr-agent). Regression: herdr-tab-glyph output byte-identical vs a live
snapshot.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01R8crYp6tzRKMiwW63Zt3GG
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