Task — engineering-spec@1

"Homebrew tap: update cyberos-cli.rb for the cs rename"

doneTASK-IMP-133
module improvement · class product · priority p1 · created 2026-07-22 · shipped null
depends on TASK-IMP-130, TASK-IMP-135 · blocks none

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

Success Metrics

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

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

1. Description (normative)

2. Acceptance criteria

Final-acceptance evidence (2026-07-23)

Operator session blanket approval applies. Cross-repo change merged in cyberskill-official/homebrew-tap PR #1 (268088f).

3. Edge cases

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)

ClauseVerb demandCited test assertsVerdict
1.1 MUST update url+sha256 together, same commitcorrect values AND atomic commitAC 1 (revised): both value correctness and git log atomicitysufficient after revision (atomicity was untested - ISS-003)
1.2 MUST update test block bin namepositive behavioural proofAC 2 (revised): a real local brew test pass, not a fictitious CIsufficient after revision (was fabricated - ISS-001)
1.3 MUST correct header commentabsence of stale sentence AND presence of correct markerAC 3 (revised): grep pair, both counts specifiedsufficient after revision (was unmechanised - ISS-002/006)
1.4 Formula name MUST NOT changediff scope excludes a renameAC 4: git diff --stat shows no renamesufficient
1.5 MUST NOT merge before release existsthe same evidence AC 2 already providesAC 2 (retraced): a passing local brew test cannot exist without a real releasesufficient 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.