"Homebrew tap: update cyberos-cli.rb for the cs rename"
TASK-IMP-133: Homebrew tap: update cyberos-cli.rb for the cs rename
Summary
Once TASK-IMP-130 ships an npm release with the renamed cs bin, the separate cyberskill-official/homebrew-tap repo's Formula/cyberos-cli.rb needs its pinned version bumped to that release and its test do assertion updated from bin/"cyberos" to bin/"cs" — done together, since bumping one without the other makes brew test fail.
Problem
Formula/cyberos-cli.rb (cyberskill-official/homebrew-tap, re-fetched fresh 2026-07-22) pins url "https://registry.npmjs.org/@cyberskill/cyberos/-/cyberos-1.0.9.tgz" and asserts bin/"cyberos" exists and is executable (lines 15-16, 26-32). bin.install_symlink Dir["#{libexec}/bin/*"] (line 23) itself needs no code change — it will pick up whatever bin name a newly-pinned npm tarball declares, automatically. But the Formula is pinned to a SPECIFIC already-released tarball (1.0.9), which still ships the old cyberos bin (TASK-IMP-130 has not shipped yet as of this task's authoring). Updating only the test do block's string to bin/"cs" while leaving url/sha256 pointed at 1.0.9 would make brew test fail every time — the installed payload would still only contain a cyberos bin, and the test would assert for a cs bin that isn't there. The plan (§7) already flagged that this Formula "will silently start asserting against a binary that no longer exists," but the specific mechanism — that the fix requires bumping the pinned release, not just editing a string — is a fact this task's authoring surfaced by reading the Formula directly, not something the plan itself stated.
Proposed Solution
Once an npm release carrying the cs bin (TASK-IMP-130) is published, update Formula/cyberos-cli.rb in the SAME commit: (1) url to that release's tarball URL, (2) sha256 to that tarball's actual digest (re-derived via the Formula's own documented method, line 11: curl -sL -o t.tgz "$(npm view @cyberskill/cyberos dist.tarball)" && sha256sum t.tgz), (3) the test do block's two assertions from bin/"cyberos" to bin/"cs", and (4) the header comment's "They share the name 'cyberos' upstream" sentence, which becomes inaccurate once the upstream bin is cs — reworded to describe the current state accurately. The Formula's own name (cyberos-cli, brew install cyberos-cli) does NOT change — that identifier disambiguates this Formula from the tap's separate cyberos GUI Cask (line 4-8) and is independent of the wrapped CLI's own bin name.
Alternatives Considered
- Update the Formula's test assertion immediately, ahead of TASK-IMP-130 shipping. Rejected: there would be nothing yet to test against —
brew testwould fail deterministically until a realcs-bin release exists, for no benefit over waiting. - Rename the Formula itself (e.g. to
cs-cli) to match the new bin name. Rejected: out of scope per the plan, and the Formula's name was already a deliberate disambiguation choice (TASK-APP-006, cited in the file's own header) independent of the wrapped tool's bin name; renaming it would be a second breaking change (brew install cyberos-clistops resolving) layered onto the one this plan already accepts. - Leave the header comment as-is since it's "just a comment." Rejected: the comment specifically explains a naming decision by asserting a fact (upstream shares the name "cyberos") that this very task makes false; leaving it uncorrected actively misleads the next person who reads it to understand why the Formula is named the way it is.
Success Metrics
- Primary: after this change,
brew install cyberos-cli(orbrew test cyberos-cliin CI) installs a workingcsbinary and the Formula's own test passes. Baseline today: the Formula assertsbin/"cyberos", which will stop existing the moment acs-bin npm release ships, with nothing in this Formula ready for that day. - Guardrail:
url/sha256and thetest doassertions are bumped in the SAME commit — never a state where one has moved to the new bin name and the other has not, which is exactly the deterministic-brew test-failure window this task exists to avoid ever existing.
Scope
In scope: Formula/cyberos-cli.rb's url, sha256, test do block, and header comment, in cyberskill-official/homebrew-tap.
Out of scope / Non-Goals
- Renaming the Formula itself away from
cyberos-cli. - The tap's separate
cyberosGUI Cask — a different product, unaffected by this rename (Formula header comment lines 4-6 already establish this distinction). depends_on "node"or theinstallmethod'snpm installinvocation — neither references the bin name and neither needs to change.- Publishing the actual npm release this task depends on — that is TASK-IMP-135's job (the gap TASK-IMP-133's own audit ISS-005 named); this task only reacts once that release exists on the registry.
Dependencies
Depends on TASK-IMP-130 (code that emits bin.cs) and TASK-IMP-135 (the owned operational cut that publishes that bin to the npm registry). Specifically, this task needs a PUBLISHED npm release carrying the cs bin — TASK-IMP-135's done criterion — not merely TASK-IMP-130's code being merged. This task cannot land (in the sense of passing brew test) until that release exists, even though its diff could technically be drafted earlier. This task is a soft (non-status-gating) prerequisite for TASK-IMP-134's manual release-time checklist, which the plan (§6 item 7) states must include "a fresh Homebrew install once the tap is updated" — TASK-IMP-134's own depends_on deliberately excludes this task so its fully-automated offline portion isn't blocked on this task's externally-gated completion (see TASK-IMP-134's Dependencies section).
Cross-repo note. This task's spec, audit, and backlog row live in cyberskill-official/cyberos's docs/tasks/ (this repo's .cyberos/ machine is what generated it), but its actual code change lands in the separate cyberskill-official/homebrew-tap repository, which has no .cyberos/ machine of its own. /ship-tasks driving this task will need to operate against a checkout of homebrew-tap, not this repo — flagged explicitly since every other task in this batch is a same-repo change and this one is not.
AI Authorship Disclosure
- Tools used: Claude (Fable 5) running the CyberOS
task-authorskill inside Cowork. - Scope:
Formula/cyberos-cli.rb's content was re-fetched via a fresh shallow clone ofcyberskill-official/homebrew-tapduring this authoring session, not carried over from an earlier read in the same conversation without re-verification, per the anti-fabrication discipline for cross-repo evidence. - Human review: task decomposition and cross-repo placement approved at the 2026-07-22 PLAN gate.
1. Description (normative)
- 1.1
Formula/cyberos-cli.rb'surlandsha256MUST be updated together, in the same commit, to point at the first published npm release of@cyberskill/cyberosthat ships thecsbin. - 1.2 In that same commit, the
test doblock's twobin/"cyberos"assertions MUST becomebin/"cs". - 1.3 The header comment's sentence asserting the CLI and the Cask "share the name 'cyberos' upstream" MUST be reworded to state the current, accurate naming (the CLI's public bin is
cs; the GUI Cask remains a separate product namedcyberos). - 1.4 The Formula's own name (
cyberos-cli, i.e.brew install cyberos-cli) MUST NOT change. - 1.5 This task MUST NOT be merged before a real npm release containing the
csbin exists — the commit may be prepared in advance, but landing it early would deterministically breakbrew test(traced by AC 2: a passing localbrew testrun is only possible once such a release genuinely exists at the pinnedurl, so AC 2 discharges this clause directly rather than needing a separate procedural check).
2. Acceptance criteria
- [x] AC 1 (traces_to: #1.1) -
Formula/cyberos-cli.rb'surlreferences a version string matching a real published@cyberskill/cyberosrelease that contains a"cs"key in that release'spackage.jsonbinfield,sha256matches that exact tarball's digest, andgit log -pfor the landing commit shows both fields changed together in one commit (not staged across two) - test: manual, ops flow (homebrew-taphas no CI workflow at all, confirmed by directory listing, so no automated check can run against the live npm registry from either repo) - the release engineer re-runs the Formula's own documented derivation command (line 11), diffs the result against what's committed, and confirms viagit logthat url+sha256 landed in the same commit as this task's other changes, as part of the release checklist - [x] AC 2 (traces_to: #1.2, #1.5) -
brew install --build-from-source cyberos-cli && brew test cyberos-cli, run locally by the implementer before opening the PR (there is no CI inhomebrew-tapto run this automatically — confirmed no.github/workflows/exists in this repo), passes against the updated Formula - test: documented in the PR description as a local run's output, not inferred from a CI check that does not exist; this same passing run is the evidence clause 1.5 requires (a real release must exist forbrew testto succeed at all) - [x] AC 3 (traces_to: #1.3) - a grep of the header comment block (lines 1-8) for the literal string
They share the name "cyberos" upstreamreturns zero matches, and the same block contains the string `csadjacent to a mention of "bin" or "command" - test:grep -c 'They share the name "cyberos" upstream' Formula/cyberos-cli.rbreturns0ANDgrep -c 'cs' Formula/cyberos-cli.rbreturns>=1`, run as part of the same PR-review pass as AC 2 (still no CI; a reviewer command, not an automated gate) - [x] AC 4 (traces_to: #1.4) - the Formula's class name (
CyberosCli) and filename (cyberos-cli.rb) are unchanged in the diff - test:git diff --statfor this change shows no rename, only in-place edits tocyberos-cli.rb
Final-acceptance evidence (2026-07-23)
Operator session blanket approval applies. Cross-repo change merged in cyberskill-official/homebrew-tap PR #1 (268088f).
- AC1: single commit
0a13c1dupdatedurl+sha256together tocyberos-1.1.0.tgz/d79e1ffedc90607d5e9d00b5d400d4855a03f1e1b04a5b31f7769f5bf386bbfa. - AC2: local
brew install --build-from-source cyberskill-official/tap/cyberos-cliupgraded 1.0.9→1.1.0;brew test cyberos-cliexit 0;cs -hprintsCyberOS 1.1.0(documented on the tap PR). - AC3: stale header sentence absent; `
cs` present in header. - AC4: Formula filename/class unchanged (
cyberos-cli.rb/CyberosCli).
3. Edge cases
- The five-task batch (TASK-IMP-130 through 134) originally had no acceptance criterion requiring an actual npm release be CUT and PUBLISHED — TASK-IMP-130's own ACs only prove a scratch build's
package.jsonhas the rightbinfield. That gap is now owned by TASK-IMP-135 (added 2026-07-23 per operator judgment). This edge case is retained as historical context: do not re-invent a second publish owner. - If TASK-IMP-130 ships but the package NAME also somehow changes (rejected in TASK-IMP-130's own Alternatives Considered, but if a future decision reverses that) - this task's
urlwould need to reference the new package name too, not just a new version of the same package; not applicable under TASK-IMP-130's current, approved decision, but named here since this task's own correctness depends on that upstream decision holding. - A user with an existing
cyberos-cliHomebrew install upgrades viabrew upgrade: Homebrew's own symlink-relinking on upgrade is standard Homebrew behaviour, not something this Formula controls beyond declaring the correct bin viainstall_symlink- no special handling needed in this task. - This task's own spec, audit, and backlog entry exist only in
cyberskill-official/cyberos'sdocs/tasks/- if that BACKLOG row is markeddonebefore the actualhomebrew-tapPR merges, the two repos' records would disagree about whether the work shipped./ship-tasks's human final-acceptance gate is the safeguard here - it MUST NOT be granted until thehomebrew-tapPR is confirmed merged, not merely opened. - Security-class: this task edits
sha256andurlfields that Homebrew uses to verify tarball integrity before install - an incorrect (rather than merely outdated)sha256would causebrew installto fail closed (checksum mismatch), not install something unverified, so the failure mode of a mistake here is safe (loud failure) rather than silent (installing unverified content).
Audit
§1 — Verdict summary
Five §1 clauses, four ACs (one removed as redundant during revision), four edge cases including one security-class row. Scored lowest pre-revision of the batch so far because it contained a genuine fabricated test citation — the most serious class of finding possible under this rubric — not merely a precision gap.
§2 — Findings (all resolved)
ISS-001 — AC 2 cited a CI workflow that does not exist
The first draft's AC 2 pointed at "homebrew-tap's own CI workflow" as the test authority for a passing brew test. Checking the actual repository (directory listing for .github/workflows/) found none — homebrew-tap has no CI at all. Citing a non-existent automated check as a test is a fabricated citation, materially worse than an imprecise one: an implementer or reviewer trusting this AC would believe a safety net exists where none does. Resolved: revised to a local brew install --build-from-source + brew test run, documented in the PR description, with the absence of CI stated explicitly rather than implied.
ISS-002 — AC 3 deferred to unstructured manual review when a mechanical check was straightforward
The original AC 3 called the header-comment wording change "not mechanically testable." A grep for the exact stale sentence (absence) plus a positive marker for the new bin name (presence) is a direct, mechanical check — the same shape already used successfully in TASK-IMP-130's domain-string AC. Resolved: converted to a grep -c pair with explicit expected counts.
ISS-003 — AC 1 didn't verify the same-commit atomicity clause 1.1 actually demands
Clause 1.1 requires url and sha256 to update "together, in the same commit" — the whole point being that the two must never be individually staggered (which is exactly the deterministic-brew-test-failure window this task exists to prevent). The original AC 1 checked only that the final values were correct, not that they arrived together. Resolved: added a git log -p check confirming both fields changed in one commit.
ISS-004 — AC 5 was redundant with the corrected AC 2
Once AC 2 was corrected to a real local brew test run (ISS-001), it already provides direct proof that the referenced release exists — a brew test can only pass if the pinned url/sha256 resolve to a real tarball containing the cs bin. The original AC 5 (a PR-description checklist item confirming the release "was queried live") added a second, weaker, human-trust-based check for something AC 2's mechanical pass/fail already settles. Resolved: removed AC 5, retraced clause 1.5 directly to AC 2.
ISS-005 — no task in this five-task batch actually covers cutting and publishing the npm release both this task and TASK-IMP-134 depend on
TASK-IMP-130's own ACs only prove a scratch build's package.json is correct — none of them require an actual release reach the npm registry. This task's entire premise (a cs-bin release exists to point the Formula at) and TASK-IMP-134's premise (an end-to-end regression against a real install) both assume that operational step happened, but nothing in the batch owns it. This is a real gap in the plan's task set, not something TASK-IMP-133 can close by itself. Resolved: named explicitly as an edge case rather than left as an unstated assumption, and carried forward to the batch-level report.
ISS-006 — the header comment fix's target wording was under-specified before AC 3's mechanical rewrite
Before ISS-002's fix, clause 1.3 said only "reworded to state the current, accurate naming" with no concrete required substring — soft enough that two different implementers could satisfy it in incompatible ways. Resolved as a side effect of the AC 3 mechanical rewrite, which now pins a specific required marker (a ` cs ` mention adjacent to "bin"/"command").
ISS-007 — FM-101 title length, and two TRACE structural failures caught only by the machine floor
Running task-lint.mjs after the six findings above were resolved surfaced three more, none of which the manual pass caught: (1) FM-101, title at 76 chars, over the 72 cap — shortened to "Homebrew tap: update cyberos-cli.rb for the cs rename". (2) TRACE-001 on clause 1.5 — the clause's prose said "(traced by AC 2: ...)" but AC 2's own traces_to: field only listed #1.2, so the linter (which parses the structured field, not free prose) correctly saw clause 1.5 as uncited — fixed by adding #1.5 to AC 2's traces_to: list. (3) TRACE-002 on AC 1 — the AC's test description read "test (manual, ops flow - ...): ..." with a parenthetical inserted between the word "test" and its colon, so the literal substring test: never appeared and the linter flagged it as carrying neither a test: nor verify: entry — fixed by moving the parenthetical after the colon. All three are exactly the class of defect a mechanical floor exists to catch and a careful manual read can still miss.
§3 — TRACE-006 semantic sufficiency (per clause)
| Clause | Verb demand | Cited test asserts | Verdict |
|---|---|---|---|
| 1.1 MUST update url+sha256 together, same commit | correct values AND atomic commit | AC 1 (revised): both value correctness and git log atomicity | sufficient after revision (atomicity was untested - ISS-003) |
| 1.2 MUST update test block bin name | positive behavioural proof | AC 2 (revised): a real local brew test pass, not a fictitious CI | sufficient after revision (was fabricated - ISS-001) |
| 1.3 MUST correct header comment | absence of stale sentence AND presence of correct marker | AC 3 (revised): grep pair, both counts specified | sufficient after revision (was unmechanised - ISS-002/006) |
| 1.4 Formula name MUST NOT change | diff scope excludes a rename | AC 4: git diff --stat shows no rename | sufficient |
| 1.5 MUST NOT merge before release exists | the same evidence AC 2 already provides | AC 2 (retraced): a passing local brew test cannot exist without a real release | sufficient after retracing (was redundantly double-covered - ISS-004) |
§4 — Resolution
Six findings, including one fabricated-citation defect (the most severe class this rubric checks for), all resolved in the audited revision. Score = 10/10.
Status transition draft -> ready_to_implement is authorised by this verdict per STATUS-REFERENCE.md §1.1. This task's two /ship-tasks human-acceptance gates will need to run against a homebrew-tap checkout, not this repo — noted in the spec's Dependencies section, unaffected by this audit's scope.
End of TASK-IMP-133 audit.