Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
45636f8
feat: add native Devin ACP community distribution
fenner888 Jul 26, 2026
9cc6e1f
docs: record Developer ID signing rehearsal
fenner888 Jul 26, 2026
9b393e2
ci: make desktop and container builds fork-safe
fenner888 Jul 27, 2026
0b24670
fix: stabilize ACP runtime catalog projection
fenner888 Jul 27, 2026
7a61ace
docs: mark Devin local proof complete
fenner888 Jul 27, 2026
364a78b
docs: clarify Devin one-shot permissions
fenner888 Jul 27, 2026
b554f3a
docs: record prepared upstream Devin series
fenner888 Jul 27, 2026
c2cdc92
docs: record upstream Devin draft
fenner888 Jul 27, 2026
ede1962
docs: record refreshed Devin validation
fenner888 Jul 27, 2026
c3754ca
fix(desktop): read the agent directory from managed-agent events
fenner888 Jul 27, 2026
90b776e
fix(desktop): offer allowlisted relay agents in mention autocomplete
fenner888 Jul 27, 2026
da34d69
fix(desktop): edit the agent instance from its profile panel
fenner888 Jul 27, 2026
f49abf2
fix(desktop): stop publishing a revoked allowlist
fenner888 Jul 27, 2026
277c6f6
fix(desktop): scrub inherited ACP_BACKEND from the Devin adapter
fenner888 Jul 27, 2026
4455f2d
docs: record Devin allowlist and ACP credential findings
fenner888 Jul 27, 2026
0dd1e44
docs: record confirmed revocation denial and the two-place revocation…
fenner888 Jul 27, 2026
d444186
docs: mark cross-owner denial proven by the revocation test
fenner888 Jul 27, 2026
dbf7f94
fix(desktop): stop one unsupported respond-to mode hiding every agent
fenner888 Jul 27, 2026
415b225
refactor(desktop): move the managed-agent directory projection into i…
fenner888 Jul 27, 2026
e71f175
test(desktop): align agent E2E expectations
fenner888 Jul 27, 2026
fd899c2
docs: add cross-platform Devin builder preview
fenner888 Jul 27, 2026
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
247 changes: 247 additions & 0 deletions .github/workflows/buzz-for-devin-signed-macos-canary.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
name: Buzz for Devin Signed macOS Canary

# Manual-only release gate. This workflow never creates a tag, GitHub Release,
# updater manifest, or public community. It produces a short-lived signed and
# notarized Apple Silicon DMG for clean-machine acceptance testing.
on:
workflow_dispatch:
inputs:
accept_unmaintained_rust_risk:
description: >-
Explicitly accept the documented no-safe-upgrade Rust maintenance
advisories for this short-lived canary only
required: true
default: false
type: boolean

permissions:
contents: read

jobs:
build:
name: Build signed Buzz for Devin canary
if: github.repository == 'fenner888/BuzzforDevin'
runs-on: macos-latest
timeout-minutes: 120
environment: buzz-for-devin-release
env:
TARGET: aarch64-apple-darwin
BUZZ_BUILD_KEYRING_SERVICE: buzz-for-devin-desktop
BUZZ_BUILD_DEEP_LINK_SCHEME: buzz-for-devin
BUZZ_BUILD_NEST_DIR: .buzz-for-devin
BUZZ_BUILD_CLI_LINK_NAME: buzz-for-devin
VITE_BUZZ_APP_NAME: Buzz for Devin
VITE_BUZZ_DEEP_LINK_SCHEME: buzz-for-devin
VITE_BUZZ_RELEASES_URL: https://github.com/fenner888/BuzzforDevin/releases
VITE_BUZZ_RELEASES_API_URL: https://api.github.com/repos/fenner888/BuzzforDevin/releases?per_page=10
MACOSX_DEPLOYMENT_TARGET: "11.0"
CMAKE_OSX_DEPLOYMENT_TARGET: "11.0"
TAURI_BUNDLER_DMG_IGNORE_CI: "true"
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false

- uses: cashapp/activate-hermit@cea9af7913204a965fd488637a8d1811bba2e616 # v1

- name: Require signing and notarization secrets
shell: bash
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
set -euo pipefail
for name in \
APPLE_CERTIFICATE \
APPLE_CERTIFICATE_PASSWORD \
APPLE_SIGNING_IDENTITY \
APPLE_ID \
APPLE_PASSWORD \
APPLE_TEAM_ID \
KEYCHAIN_PASSWORD
do
if [[ -z "${!name:-}" ]]; then
echo "::error::Required protected secret $name is not configured"
exit 1
fi
done

- name: Install pinned dependencies
run: pnpm install --frozen-lockfile

- name: Run complete repository validation
run: just ci

- name: Audit JavaScript dependencies
run: pnpm audit --audit-level=low

- name: Audit Rust dependency policy
shell: bash
env:
ACCEPT_UNMAINTAINED_RUST_RISK: ${{ inputs.accept_unmaintained_rust_risk }}
run: |
set -euo pipefail
export GIT_CONFIG_GLOBAL=/dev/null
export GIT_CONFIG_SYSTEM=/dev/null

cargo deny --locked check advisories
cargo deny --locked check bans licenses sources
cargo deny --locked \
--manifest-path desktop/src-tauri/Cargo.toml \
check bans licenses sources

set +e
cargo deny --locked \
--manifest-path desktop/src-tauri/Cargo.toml \
--target "$TARGET" \
check advisories
DESKTOP_ADVISORY_STATUS=$?
set -e

if [[ "$DESKTOP_ADVISORY_STATUS" == "0" ]]; then
echo "Apple Silicon desktop advisory gate passed."
elif [[ "$ACCEPT_UNMAINTAINED_RUST_RISK" == "true" ]]; then
echo "::warning::Proceeding with the explicitly accepted, documented no-safe-upgrade maintenance advisories for this canary."
else
echo "::error::Apple Silicon desktop advisory gate failed. Review the documented findings or explicitly accept them for this canary."
exit "$DESKTOP_ADVISORY_STATUS"
fi

- name: Derive isolated canary version
id: version
shell: bash
run: |
set -euo pipefail
BASE_VERSION=$(node -p "require('./desktop/package.json').version")
if ! [[ "$BASE_VERSION" =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)(-[0-9A-Za-z.-]+)?$ ]]; then
echo "::error::Desktop version '$BASE_VERSION' is not semver"
exit 1
fi
VERSION="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}.$((BASH_REMATCH[3] + 1))-devin-test.${GITHUB_RUN_NUMBER}"
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
echo "Building Buzz for Devin canary $VERSION from $GITHUB_SHA"

- name: Patch canary version
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
set -euo pipefail
cd desktop
node scripts/set-version-from-tag.mjs "$VERSION"
ruby - "$VERSION" <<'RUBY'
path = "src-tauri/Cargo.lock"
version = ARGV.fetch(0)
lock = File.read(path)
pattern = /(\[\[package\]\]\nname = "buzz-desktop"\nversion = ")[^"]+(")/
matches = lock.scan(pattern).length
abort "expected exactly one buzz-desktop lock entry, found #{matches}" unless matches == 1
File.write(path, lock.sub(pattern, "\\1#{version}\\2"))
RUBY
cd src-tauri
cargo metadata --locked --format-version 1 >/dev/null

- name: Generate isolated non-updating config
run: cd desktop && node scripts/build-buzz-for-devin-config.mjs

- name: Build and stage sidecars
shell: bash
run: |
set -euo pipefail
cargo build --release --target "$TARGET" \
-p buzz-acp \
-p buzz-agent \
-p buzz-dev-mcp \
-p git-credential-nostr \
-p buzz-cli
./scripts/bundle-sidecars.sh "$TARGET"
for binary in buzz-acp buzz-agent buzz-dev-mcp git-credential-nostr buzz; do
test -x "desktop/src-tauri/binaries/${binary}-${TARGET}"
done

- name: Import Apple Developer ID certificate
shell: bash
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
run: |
set -euo pipefail
umask 077
CERTIFICATE_PATH="$RUNNER_TEMP/buzz-for-devin-certificate.p12"
KEYCHAIN_PATH="$RUNNER_TEMP/buzz-for-devin-signing.keychain-db"
printf '%s' "$APPLE_CERTIFICATE" | base64 --decode > "$CERTIFICATE_PATH"
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 3600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security import "$CERTIFICATE_PATH" \
-k "$KEYCHAIN_PATH" \
-P "$APPLE_CERTIFICATE_PASSWORD" \
-T /usr/bin/codesign \
-T /usr/bin/security
security set-key-partition-list \
-S apple-tool:,apple:,codesign: \
-s \
-k "$KEYCHAIN_PASSWORD" \
"$KEYCHAIN_PATH"
security find-identity -v -p codesigning "$KEYCHAIN_PATH" |
grep -F -- "$APPLE_SIGNING_IDENTITY" >/dev/null
security list-keychains -d user -s "$KEYCHAIN_PATH"
rm -f "$CERTIFICATE_PATH"

- name: Build, sign, notarize, and staple DMG
shell: bash
env:
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
set -euo pipefail
cd desktop
pnpm tauri build \
--verbose \
--target "$TARGET" \
--bundles dmg \
--config src-tauri/tauri.buzz-for-devin.conf.json

- name: Verify signed artifact
id: artifact
shell: bash
run: |
set -euo pipefail
BUNDLE_ROOT="desktop/src-tauri/target/$TARGET/release/bundle"
APP_PATH="$BUNDLE_ROOT/macos/Buzz for Devin.app"
DMG_COUNT=$(find "$BUNDLE_ROOT/dmg" -name '*.dmg' -type f | wc -l | tr -d ' ')
[[ "$DMG_COUNT" == "1" ]] || {
echo "::error::Expected exactly one DMG, found $DMG_COUNT"
exit 1
}
DMG_PATH=$(find "$BUNDLE_ROOT/dmg" -name '*.dmg' -type f -print -quit)
./scripts/verify-buzz-for-devin-macos-app.sh "$APP_PATH"
codesign --verify --deep --strict --verbose=2 "$APP_PATH"
spctl --assess --type execute --verbose=4 "$APP_PATH"
xcrun stapler validate "$DMG_PATH"
desktop/scripts/verify-macos-entitlements.sh "$APP_PATH"
echo "path=$DMG_PATH" >> "$GITHUB_OUTPUT"

- name: Upload signed canary
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: buzz-for-devin-macos-${{ steps.version.outputs.version }}-${{ github.sha }}
path: ${{ steps.artifact.outputs.path }}
if-no-files-found: error
retention-days: 7

- name: Remove temporary signing keychain
if: always()
shell: bash
run: |
KEYCHAIN_PATH="$RUNNER_TEMP/buzz-for-devin-signing.keychain-db"
security delete-keychain "$KEYCHAIN_PATH" >/dev/null 2>&1 || true
rm -f "$RUNNER_TEMP/buzz-for-devin-certificate.p12"
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1010,14 +1010,14 @@ jobs:
touch "desktop/src-tauri/binaries/buzz-dev-mcp-$TARGET"
touch "desktop/src-tauri/binaries/git-credential-nostr-$TARGET"
touch "desktop/src-tauri/binaries/buzz-$TARGET"
# Mesh rev is derived from Cargo.lock so a dependency bump needs no
# lockstep edit here; the cache key tracks it automatically.
# The desktop crate is excluded from the root workspace, so its own
# lockfile is authoritative for the mesh revision and cache key.
- name: Resolve mesh-llm rev
id: mesh_rev
run: |
set -euo pipefail
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from Cargo.lock"; exit 1; }
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("desktop/src-tauri/Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from desktop/src-tauri/Cargo.lock"; exit 1; }
echo "rev=$REV" >> "$GITHUB_OUTPUT"
echo "short=${REV:0:7}" >> "$GITHUB_OUTPUT"
- name: Restore mesh llama build cache
Expand Down
23 changes: 14 additions & 9 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ env:
# variable to override (e.g., for forks that want to push to their own
# namespace without forking this file).
IMAGE_NAME: ${{ vars.GHCR_IMAGE != '' && vars.GHCR_IMAGE || 'ghcr.io/block/buzz' }}
# Keep the separately published push gateway fork-configurable too.
GATEWAY_IMAGE: ${{ vars.GHCR_GATEWAY_IMAGE != '' && vars.GHCR_GATEWAY_IMAGE || 'ghcr.io/block/buzz-push-gateway' }}

jobs:
build:
Expand Down Expand Up @@ -350,7 +352,7 @@ jobs:
id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
images: ghcr.io/block/buzz-push-gateway
images: ${{ env.GATEWAY_IMAGE }}
labels: |
org.opencontainers.image.title=Buzz Push Gateway
org.opencontainers.image.description=Capability-gated APNs last hop for Buzz
Expand All @@ -363,9 +365,9 @@ jobs:
file: ./Dockerfile.push-gateway
platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }}
outputs: type=image,name=ghcr.io/block/buzz-push-gateway,push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
cache-from: type=registry,ref=ghcr.io/block/buzz-push-gateway-buildcache:${{ matrix.arch }}
cache-to: ${{ (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && format('type=registry,ref=ghcr.io/block/buzz-push-gateway-buildcache:{0},mode=max,compression=zstd', matrix.arch) || '' }}
outputs: type=image,name=${{ env.GATEWAY_IMAGE }},push-by-digest=true,name-canonical=true,push=${{ github.event_name != 'pull_request' }}
cache-from: type=registry,ref=${{ env.GATEWAY_IMAGE }}-buildcache:${{ matrix.arch }}
cache-to: ${{ (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) && format('type=registry,ref={0}-buildcache:{1},mode=max,compression=zstd', env.GATEWAY_IMAGE, matrix.arch) || '' }}
- name: Export digest
if: github.event_name != 'pull_request'
env:
Expand Down Expand Up @@ -410,7 +412,7 @@ jobs:
id: meta
uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 # v6.1.0
with:
images: ghcr.io/block/buzz-push-gateway
images: ${{ env.GATEWAY_IMAGE }}
tags: |
type=ref,event=branch,enable=${{ github.event_name != 'workflow_dispatch' || inputs.version == '' }}
type=sha,prefix=sha-,format=short,enable=${{ github.event_name != 'workflow_dispatch' || inputs.version == '' }}
Expand All @@ -420,29 +422,32 @@ jobs:
id: manifest
working-directory: /tmp/gateway-digests
env:
GATEWAY_IMAGE: ${{ env.GATEWAY_IMAGE }}
META_TAGS: ${{ steps.meta.outputs.tags }}
run: |
set -euo pipefail
tags=(); while IFS= read -r tag; do [ -n "$tag" ] && tags+=("-t" "$tag"); done <<< "$META_TAGS"
digests=(); for digest in *; do digests+=("ghcr.io/block/buzz-push-gateway@sha256:${digest}"); done
digests=(); for digest in *; do digests+=("${GATEWAY_IMAGE}@sha256:${digest}"); done
docker buildx imagetools create "${tags[@]}" "${digests[@]}"
first_tag=$(echo "$META_TAGS" | head -n1)
digest=$(docker buildx imagetools inspect "$first_tag" --format '{{json .Manifest}}' | jq -r '.digest')
echo "digest=${digest}" >> "$GITHUB_OUTPUT"
- name: Attest gateway image provenance
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
with:
subject-name: ghcr.io/block/buzz-push-gateway
subject-name: ${{ env.GATEWAY_IMAGE }}
subject-digest: ${{ steps.manifest.outputs.digest }}
push-to-registry: true
- name: Gateway publication summary
env:
GATEWAY_IMAGE: ${{ env.GATEWAY_IMAGE }}
GATEWAY_DIGEST: ${{ steps.manifest.outputs.digest }}
GATEWAY_TAGS: ${{ steps.meta.outputs.tags }}
GATEWAY_OWNER: ${{ github.repository_owner }}
run: |
set -euo pipefail
{
echo "### Published \`ghcr.io/block/buzz-push-gateway\`"
echo "### Published \`${GATEWAY_IMAGE}\`"
echo
printf "**Digest:** \`%s\`\n" "$GATEWAY_DIGEST"
echo
Expand All @@ -453,6 +458,6 @@ jobs:
echo
echo 'Verify provenance before deployment:'
echo "\`\`\`"
printf 'gh attestation verify oci://ghcr.io/block/buzz-push-gateway@%s --owner block\n' "$GATEWAY_DIGEST"
printf 'gh attestation verify oci://%s@%s --owner %s\n' "$GATEWAY_IMAGE" "$GATEWAY_DIGEST" "$GATEWAY_OWNER"
echo "\`\`\`"
} >> "$GITHUB_STEP_SUMMARY"
7 changes: 4 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,14 @@ jobs:
cargo build --release -p buzz-acp -p buzz-agent -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
./scripts/bundle-sidecars.sh

# Mesh rev derived from Cargo.lock (no lockstep edit on dep bump); cache key tracks it.
# The desktop crate is excluded from the root workspace, so its own
# lockfile is authoritative for the mesh revision and cache key.
- name: Resolve mesh-llm rev
id: mesh_rev
run: |
set -euo pipefail
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from Cargo.lock"; exit 1; }
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("desktop/src-tauri/Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from desktop/src-tauri/Cargo.lock"; exit 1; }
echo "rev=$REV" >> "$GITHUB_OUTPUT"
echo "short=${REV:0:7}" >> "$GITHUB_OUTPUT"
- name: Restore mesh llama build cache
Expand Down
7 changes: 4 additions & 3 deletions .github/workflows/signed-macos-canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,14 @@ jobs:
cargo build --release -p buzz-acp -p buzz-agent -p buzz-dev-mcp -p git-credential-nostr -p buzz-cli
./scripts/bundle-sidecars.sh

# Mesh rev derived from Cargo.lock (no lockstep edit on dep bump); cache key tracks it.
# The desktop crate is excluded from the root workspace, so its own
# lockfile is authoritative for the mesh revision and cache key.
- name: Resolve mesh-llm rev
id: mesh_rev
run: |
set -euo pipefail
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from Cargo.lock"; exit 1; }
REV=$(python3 -c 'import tomllib; d=tomllib.load(open("desktop/src-tauri/Cargo.lock", "rb")); p=next(p for p in d["package"] if p["name"] == "mesh-llm-sdk"); print(p["source"].rsplit("#", 1)[1])')
[[ -n "$REV" ]] || { echo "::error::could not resolve mesh-llm rev from desktop/src-tauri/Cargo.lock"; exit 1; }
echo "rev=$REV" >> "$GITHUB_OUTPUT"
echo "short=${REV:0:7}" >> "$GITHUB_OUTPUT"

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/target/
/dist/
/admin-web/dist/
/desktop/src-tauri/tauri.buzz-for-devin.conf.json

# lefthook-generated hook scripts (machine-specific)
.hooks/
Expand Down
Loading