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
13 changes: 13 additions & 0 deletions .beads/issues.jsonl
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
{"_type":"issue","id":"risus-cli-q0d","title":"T009: Add post-notarization codesign/spctl verification step","description":"speckit:005-macos-signed-release | T009 | Add post-notarization verification step (if: runner.os == macOS) in .github/workflows/release.yml running codesign --verify and spctl --assess","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:21:13Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:09Z","closed_at":"2026-05-03T19:26:09Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-q0d","depends_on_id":"risus-cli-77n","type":"blocks","created_at":"2026-05-03T21:22:15Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-sa3","title":"T008: Update macOS artifact upload to use zip in release.yml","description":"speckit:005-macos-signed-release | T008 | Update macOS artifact upload step in .github/workflows/release.yml to upload risus-macos-arm64.zip and .sha256","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:21:12Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:09Z","closed_at":"2026-05-03T19:26:09Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-sa3","depends_on_id":"risus-cli-457","type":"blocks","created_at":"2026-05-03T21:22:20Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-457","title":"T007: Update checksum step to hash zip on macOS in release.yml","description":"speckit:005-macos-signed-release | T007 | Update Compute checksum step in .github/workflows/release.yml to hash risus-macos-arm64.zip on macOS","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:21:10Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:08Z","closed_at":"2026-05-03T19:26:08Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-457","depends_on_id":"risus-cli-77n","type":"blocks","created_at":"2026-05-03T21:22:14Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-77n","title":"T006: Add xcrun notarytool submit step to release.yml","description":"speckit:005-macos-signed-release | T006 | Add xcrun notarytool submit --wait step (if: runner.os == macOS, timeout-minutes: 15) in .github/workflows/release.yml","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:21:09Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:08Z","closed_at":"2026-05-03T19:26:08Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-77n","depends_on_id":"risus-cli-7bc","type":"blocks","created_at":"2026-05-03T21:22:13Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"risus-cli-7bc","title":"T005: Add ditto zip step to release.yml after signing","description":"speckit:005-macos-signed-release | T005 | Add ditto -c -k --keepParent step (if: runner.os == macOS) after signing in .github/workflows/release.yml","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:21:08Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:07Z","closed_at":"2026-05-03T19:26:07Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-7bc","depends_on_id":"risus-cli-161","type":"blocks","created_at":"2026-05-03T21:22:08Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-161","title":"T004: Add codesign step to release.yml after binary rename","description":"speckit:005-macos-signed-release | T004 | Add codesign --force --verbose --timestamp --sign step (if: runner.os == macOS) after binary rename in .github/workflows/release.yml","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:21:06Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:07Z","closed_at":"2026-05-03T19:26:07Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-161","depends_on_id":"risus-cli-p7l","type":"blocks","created_at":"2026-05-03T21:22:07Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-p7l","title":"T002: Add apple-actions/import-codesign-certs@v7 to release.yml","description":"speckit:005-macos-signed-release | T002 | Add apple-actions/import-codesign-certs@v7 step (if: runner.os == macOS) to macOS matrix job in .github/workflows/release.yml","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:21:05Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:06Z","closed_at":"2026-05-03T19:26:06Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-p7l","depends_on_id":"risus-cli-2my","type":"blocks","created_at":"2026-05-03T21:21:59Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-6rk","title":"T014: Run manual end-to-end verification per quickstart.md","description":"speckit:005-macos-signed-release | T014 | Run manual end-to-end verification per specs/005-macos-signed-release/quickstart.md against first notarized release artifact","status":"open","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:20:59Z","created_by":"galadriel","updated_at":"2026-05-03T19:20:59Z","dependencies":[{"issue_id":"risus-cli-6rk","depends_on_id":"risus-cli-t58","type":"blocks","created_at":"2026-05-03T21:22:33Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"risus-cli-t58","title":"T013: Update macOS job name to Build \u0026 Sign in release.yml","description":"speckit:005-macos-signed-release | T013 | Update macOS entry in release workflow job name from Build (macos-latest) to Build \u0026 Sign (macos-latest)","status":"closed","priority":2,"issue_type":"task","owner":"galadriel@example.com","created_at":"2026-05-03T19:20:58Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:11Z","closed_at":"2026-05-03T19:26:11Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-t58","depends_on_id":"risus-cli-0op","type":"blocks","created_at":"2026-05-03T21:22:24Z","created_by":"galadriel","metadata":"{}"},{"issue_id":"risus-cli-t58","depends_on_id":"risus-cli-92w","type":"blocks","created_at":"2026-05-03T21:22:26Z","created_by":"galadriel","metadata":"{}"},{"issue_id":"risus-cli-t58","depends_on_id":"risus-cli-hb2","type":"blocks","created_at":"2026-05-03T21:22:25Z","created_by":"galadriel","metadata":"{}"},{"issue_id":"risus-cli-t58","depends_on_id":"risus-cli-q0d","type":"blocks","created_at":"2026-05-03T21:22:23Z","created_by":"galadriel","metadata":"{}"},{"issue_id":"risus-cli-t58","depends_on_id":"risus-cli-sa3","type":"blocks","created_at":"2026-05-03T21:22:21Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":5,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-92w","title":"T012: Add pre-tag secrets check to AGENTS.md Release Checklist","description":"speckit:005-macos-signed-release | T012 | Add pre-tag check to Release Checklist in AGENTS.md: verify all 6 Apple signing secrets configured","status":"closed","priority":2,"issue_type":"task","assignee":"galadriel","owner":"galadriel@example.com","created_at":"2026-05-03T19:20:57Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:11Z","started_at":"2026-05-03T19:24:04Z","closed_at":"2026-05-03T19:26:11Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-92w","depends_on_id":"risus-cli-2my","type":"blocks","created_at":"2026-05-03T21:22:02Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-hb2","title":"T011: Update build.yml on.push.branches for feature branch CI","description":"speckit:005-macos-signed-release | T011 | Update on.push.branches in .github/workflows/build.yml to add 005-macos-signed-release","status":"closed","priority":2,"issue_type":"task","assignee":"galadriel","owner":"galadriel@example.com","created_at":"2026-05-03T19:20:55Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:10Z","started_at":"2026-05-03T19:24:03Z","closed_at":"2026-05-03T19:26:10Z","close_reason":"Closed","dependencies":[{"issue_id":"risus-cli-hb2","depends_on_id":"risus-cli-2my","type":"blocks","created_at":"2026-05-03T21:22:01Z","created_by":"galadriel","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-0op","title":"T010: Add Signing Setup subsection to AGENTS.md Release Checklist","description":"speckit:005-macos-signed-release | T010 | Add Signing Setup subsection to Release Checklist in AGENTS.md documenting 6 required GitHub Actions secrets","status":"closed","priority":2,"issue_type":"task","assignee":"galadriel","owner":"galadriel@example.com","created_at":"2026-05-03T19:20:54Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:10Z","started_at":"2026-05-03T19:24:03Z","closed_at":"2026-05-03T19:26:10Z","close_reason":"Closed","dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"risus-cli-2my","title":"T001: Create build/entitlements.plist with 4 Hardened Runtime entitlements","description":"speckit:005-macos-signed-release | T001 | Create build/entitlements.plist with 4 entitlements required for PyInstaller Python runtime under Hardened Runtime","status":"closed","priority":2,"issue_type":"task","assignee":"galadriel","owner":"galadriel@example.com","created_at":"2026-05-03T19:20:52Z","created_by":"galadriel","updated_at":"2026-05-03T19:26:06Z","started_at":"2026-05-03T19:24:01Z","closed_at":"2026-05-03T19:26:06Z","close_reason":"Closed","dependency_count":0,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"risus-cli-znu","title":"Fix silent connection failure in WSClient.start()","description":"WSClient.start() treats a 'disconnected' frame as a successful connection. When the WebSocket handshake fails (SSL, DNS, network), _async_run swallows the exception and puts a 'disconnected' frame in the inbox. start() reads it, doesn't recognise it as failure, puts it back and returns — showing the user a working menu that is not actually connected to any server.","acceptance_criteria":"1. When connection fails for any reason (SSL, DNS, network), the program exits immediately with a clear error message instead of showing the menu. 2. Error message reads: 'Connection to {server} failed — check address, network, and that the server is running.' 3. WSClient emits a 'connected' sentinel frame after successful WebSocket handshake, before reader starts. 4. start() raises TimeoutError immediately on 'disconnected' frame rather than waiting the full timeout. 5. Existing tests pass. 6. Manual test: wrong server address → immediate exit with correct message.","status":"closed","priority":2,"issue_type":"bug","owner":"galadriel@example.com","created_at":"2026-05-03T17:23:42Z","created_by":"galadriel","updated_at":"2026-05-03T17:26:45Z","closed_at":"2026-05-03T17:26:45Z","close_reason":"connected sentinel + immediate TimeoutError on disconnected + updated error message; 77 unit tests pass","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"risus-cli-cn0","title":"T026: Validate quickstart.md local dev scenario","description":"speckit:004-secure-session | T026 | Validate quickstart.md scenario with --token dev-token-for-testing uses ws://","status":"closed","priority":2,"issue_type":"task","assignee":"Eudicy","owner":"eudicy@boos.systems","created_at":"2026-05-03T07:33:54Z","created_by":"Eudicy","updated_at":"2026-05-03T08:07:52Z","started_at":"2026-05-03T08:07:10Z","closed_at":"2026-05-03T08:07:52Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"risus-cli-ddm","title":"T025: Verify server logs show reason but not token","description":"speckit:004-secure-session | T025 | Verify server logs show reason=token_absent or reason=token_mismatch but never token value","status":"closed","priority":2,"issue_type":"task","assignee":"Eudicy","owner":"eudicy@boos.systems","created_at":"2026-05-03T07:33:53Z","created_by":"Eudicy","updated_at":"2026-05-03T08:07:52Z","started_at":"2026-05-03T08:07:10Z","closed_at":"2026-05-03T08:07:52Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ name: Build

on:
push:
branches: [main, 003-standalone-client]
branches: [main, 003-standalone-client, 005-macos-signed-release]
pull_request:
branches: [main, 003-standalone-client]
branches: [main, 003-standalone-client, 005-macos-signed-release]

jobs:
build:
Expand All @@ -15,9 +15,9 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- uses: actions/setup-python@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"

Expand All @@ -39,7 +39,7 @@ jobs:
shell: pwsh

- name: Upload artifact
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v7
with:
name: risus-${{ matrix.os }}
path: dist/risus*
81 changes: 72 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ permissions:

jobs:
build:
name: Build (${{ matrix.os }})
name: Build & Sign (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -26,9 +26,9 @@ jobs:
binary: dist/risus.exe

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- uses: actions/setup-python@v5
- uses: actions/setup-python@v6
with:
python-version: "3.12"

Expand All @@ -47,8 +47,61 @@ jobs:
run: Rename-Item dist\risus.exe ${{ matrix.artifact }}
shell: pwsh

- name: Compute checksum (Unix)
if: runner.os != 'Windows'
- name: Import signing certificate
if: runner.os == 'macOS'
uses: apple-actions/import-codesign-certs@v7
with:
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}

- name: Sign binary
if: runner.os == 'macOS'
run: |
codesign --force --verbose --timestamp \
--sign "Developer ID Application: $APPLE_TEAM_ID" \
--options=runtime --no-strict \
--entitlements build/entitlements.plist \
dist/risus-macos-arm64
env:
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}

- name: Package signed binary
if: runner.os == 'macOS'
run: ditto -c -k --keepParent dist/risus-macos-arm64 dist/risus-macos-arm64.zip

- name: Notarize
if: runner.os == 'macOS'
timeout-minutes: 15
run: |
echo "$APPLE_API_KEY_CONTENT" | base64 --decode > /tmp/apple_api_key.p8
xcrun notarytool submit dist/risus-macos-arm64.zip \
--wait \
--key /tmp/apple_api_key.p8 \
--key-id "$APPLE_API_KEY_ID" \
--issuer "$APPLE_API_ISSUER_ID"
env:
APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY_CONTENT }}
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }}
APPLE_API_ISSUER_ID: ${{ secrets.APPLE_API_ISSUER_ID }}

- name: Clean up API key
if: always() && runner.os == 'macOS'
run: rm -f /tmp/apple_api_key.p8

- name: Verify signature and notarization
if: runner.os == 'macOS'
run: |
codesign --verify --deep --strict --verbose=2 dist/risus-macos-arm64
spctl --assess --type execute --verbose dist/risus-macos-arm64

- name: Compute checksum (macOS)
if: runner.os == 'macOS'
run: |
cd dist
sha256sum risus-macos-arm64.zip > risus-macos-arm64.zip.sha256

- name: Compute checksum (Linux)
if: runner.os == 'Linux'
run: |
cd dist
sha256sum ${{ matrix.artifact }} > ${{ matrix.artifact }}.sha256
Expand All @@ -60,8 +113,18 @@ jobs:
"$hash ${{ matrix.artifact }}" | Out-File -FilePath dist\${{ matrix.artifact }}.sha256 -Encoding ascii
shell: pwsh

- name: Upload artifact (macOS)
if: runner.os == 'macOS'
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact }}
path: |
dist/risus-macos-arm64.zip
dist/risus-macos-arm64.zip.sha256

- name: Upload artifact
uses: actions/upload-artifact@v4
if: runner.os != 'macOS'
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact }}
path: |
Expand All @@ -73,16 +136,16 @@ jobs:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6

- name: Download all artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v8
with:
path: release-assets
merge-multiple: true

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
uses: softprops/action-gh-release@v3
with:
files: |
release-assets/*
Expand Down
Loading