Skip to content

Commit c52c469

Browse files
committed
fix(agent): harden macos es/ne scaffolding and supervision
1 parent 5d6409e commit c52c469

File tree

65 files changed

+8033
-154
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+8033
-154
lines changed

.codex/swarm/lanes.tsv

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
lane worktree branch profile role brief_id description docs bootstrap
2-
orch huntronomer-workspace-orch feature/huntronomer-workspace-orchestrator swarm-orchestrator workstream_orchestrator ORCH Workspace-shell orchestrator lane for metadata, shared shell wiring, merge sequencing, and capability policy docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/roadmap.md,docs/specs/17-huntronomer-workspace-services.md,docs/specs/18-huntronomer-shell-command-model.md cd apps/desktop && bun install --frozen-lockfile && cargo fetch --locked --manifest-path src-tauri/Cargo.toml
3-
ws1 ws1-workspace-core feature/huntronomer-ws-core swarm-worker lane_worker WS1 Workspace-core lane for trusted roots, canonical paths, filesystem contracts, and settings persistence docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/target-architecture.md,docs/specs/17-huntronomer-workspace-services.md cd apps/desktop && bun install --frozen-lockfile && cargo fetch --locked --manifest-path src-tauri/Cargo.toml
4-
ws2 ws2-search-watch feature/huntronomer-ws-search-watch swarm-worker lane_worker WS2 Watcher and search lane for notify, fd, rg, and allowlisted sidecar process management docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/roadmap.md,docs/specs/17-huntronomer-workspace-services.md cd apps/desktop && bun install --frozen-lockfile && cargo fetch --locked --manifest-path src-tauri/Cargo.toml
5-
ws3 ws3-workspace-shell feature/huntronomer-ws-shell-ui swarm-worker lane_worker WS3 Workspace-shell UI lane for route scaffolding, tree layout, breadcrumbs, pane state, and command entry points docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/target-architecture.md,docs/specs/18-huntronomer-shell-command-model.md cd apps/desktop && bun install --frozen-lockfile
6-
ws4 ws4-monaco-editor feature/huntronomer-ws-monaco swarm-worker lane_worker WS4 Monaco editor lane for buffer models, tab flows, save and reload behavior, and editor tests docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/roadmap.md,docs/specs/17-huntronomer-workspace-services.md cd apps/desktop && bun install --frozen-lockfile
7-
ws5 ws5-terminal-pty feature/huntronomer-ws-terminal swarm-worker lane_worker WS5 Terminal lane for PTY session lifecycle, xterm integration, resize behavior, and task-versus-shell sessions docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/target-architecture.md,docs/specs/17-huntronomer-workspace-services.md cd apps/desktop && bun install --frozen-lockfile && cargo fetch --locked --manifest-path src-tauri/Cargo.toml
8-
ws6 ws6-search-git-ui feature/huntronomer-ws-search-git-ui swarm-worker lane_worker WS6 Search and git UX lane for quick-open, content search, git status, diff summaries, and editor deep links docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/roadmap.md,docs/specs/17-huntronomer-workspace-services.md cd apps/desktop && bun install --frozen-lockfile
9-
ws7 ws7-language-client feature/huntronomer-ws-language-client swarm-worker lane_worker WS7 Language-intelligence lane for monaco-languageclient, language-server supervision, diagnostics, and symbol navigation docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/roadmap.md,docs/specs/17-huntronomer-workspace-services.md,docs/specs/18-huntronomer-shell-command-model.md cd apps/desktop && bun install --frozen-lockfile && cargo fetch --locked --manifest-path src-tauri/Cargo.toml
10-
ws8 ws8-release-verify feature/huntronomer-ws-release-verify swarm-worker lane_worker WS8 Persistence and release-hardening lane for session recall, packaging checks, smoke verification, and optional index evaluation docs/plans/clawdstrike/huntronomer/workspace-shell/swarm-plan.md,docs/plans/clawdstrike/huntronomer/workspace-shell/roadmap.md,docs/specs/17-huntronomer-workspace-services.md,docs/specs/18-huntronomer-shell-command-model.md cd apps/desktop && bun install --frozen-lockfile && cargo fetch --locked --manifest-path src-tauri/Cargo.toml
2+
ORCH macos-es-ne-orch feature/macos-es-ne-orchestrator swarm-orchestrator workstream_orchestrator ORCH Orchestrator lane for the macOS EndpointSecurity and NetworkExtension implementation wave; owns shared metadata, architecture exceptions, merge order, and final consolidation docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/network-extension-provider-and-topology.md,docs/plans/clawdstrike/macos-es-ne/endpoint-security-auth-contract.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md,docs/plans/multi-agent/codex-swarm-playbook.md cargo-fetch-locked
3+
HOST macos-es-ne-host-foundation feature/macos-es-ne-host-foundation swarm-worker lane_worker HOST Containing-app foundation lane for apps/agent macOS host modules, combined-system-extension lifecycle hooks, and frozen local IPC contract docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/network-extension-provider-and-topology.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md cargo-fetch-agent-locked
4+
RHOST macos-es-ne-host-review feature/macos-es-ne-host-review swarm-review merge_reviewer RHOST Review lane for HOST focused on ownership violations, contract drift, degraded-state handling, and missing verification docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md cargo-fetch-agent-locked
5+
POLAT macos-es-ne-policy-attest feature/macos-es-ne-policy-attest swarm-worker lane_worker POLAT Policy and attestation lane for the frozen macOS runtime contract, ES fail-open semantics, and receipt schema changes docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/network-extension-provider-and-topology.md,docs/plans/clawdstrike/macos-es-ne/endpoint-security-auth-contract.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md,docs/nono-integration/04-policy-translation.md,docs/nono-integration/06-receipt-attestation.md cargo-fetch-locked
6+
RPOLAT macos-es-ne-policy-review feature/macos-es-ne-policy-review swarm-review merge_reviewer RPOLAT Review lane for POLAT focused on contract integrity, degraded-state truthfulness, test coverage, and merge risk docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/endpoint-security-auth-contract.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md,docs/nono-integration/04-policy-translation.md,docs/nono-integration/06-receipt-attestation.md cargo-fetch-locked
7+
ESINT macos-es-ne-es-integration feature/macos-es-ne-es-integration swarm-worker lane_worker ESINT EndpointSecurity implementation lane for the combined-system-extension ES subtree; must drive host macOS status plus attestation provider_states and deadline counters truthfully docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/endpoint-security-auth-contract.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md cargo-fetch-agent-locked
8+
NEINT macos-es-ne-ne-integration feature/macos-es-ne-ne-integration swarm-worker lane_worker NEINT NetworkExtension implementation lane for the combined-system-extension NE subtree; must drive host and attestation provider state with the content-filter baseline while preserving actual backend reporting docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/network-extension-provider-and-topology.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md,docs/nono-integration/04-policy-translation.md cargo-fetch-agent-locked
9+
RESINT macos-es-ne-es-review feature/macos-es-ne-es-review swarm-review merge_reviewer RESINT Review lane for ESINT focused on contract adherence, deadline/fail-open semantics, host and receipt degraded-state truthfulness, and verification evidence docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/endpoint-security-auth-contract.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md cargo-fetch-agent-locked
10+
RNEINT macos-es-ne-ne-review feature/macos-es-ne-ne-review swarm-review merge_reviewer RNEINT Review lane for NEINT focused on provider choice, backend-truthful network reporting, degraded-state handling, and verification evidence docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/network-extension-provider-and-topology.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md cargo-fetch-agent-locked
11+
PKG macos-es-ne-pkg-sign feature/macos-es-ne-pkg-sign swarm-worker lane_worker PKG MacOS packaging lane for the combined system extension, entitlements, signing, notarization, and CI release wiring in apps/agent docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/network-extension-provider-and-topology.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md cargo-fetch-agent-locked
12+
RPKG macos-es-ne-pkg-review feature/macos-es-ne-pkg-review swarm-review merge_reviewer RPKG Review lane for PKG focused on deployment-model correctness, signing integrity, denied-path coverage, and release pipeline regressions docs/plans/clawdstrike/macos-es-ne/swarm-plan.md,docs/plans/clawdstrike/macos-es-ne/deployment-and-verification.md cargo-fetch-agent-locked

.codex/swarm/waves.tsv

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
wave lanes
2-
wave0 orch
3-
wave1 ws1,ws3
4-
wave2 ws2,ws4
5-
wave3 ws5,ws6
6-
wave4 ws7
7-
wave5 ws8
2+
wave0 ORCH
3+
wave1 HOST
4+
wave2 RHOST
5+
wave3 POLAT
6+
wave4 RPOLAT
7+
wave5 ESINT,NEINT
8+
wave6 RESINT,RNEINT
9+
wave7 PKG
10+
wave8 RPKG
11+
wave9 ORCH

.github/workflows/ci.yml

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -245,8 +245,27 @@ jobs:
245245
- name: Check desktop Tauri crate
246246
run: cargo check --manifest-path apps/desktop/src-tauri/Cargo.toml
247247

248-
- name: Check agent Tauri crate
249-
run: cargo check --manifest-path apps/agent/src-tauri/Cargo.toml
248+
- name: Check agent macOS packaging sources
249+
shell: bash
250+
run: |
251+
set -euo pipefail
252+
253+
required=(
254+
apps/agent/src-tauri/macos/system-extension/entitlements/agent-app.entitlements
255+
apps/agent/src-tauri/macos/system-extension/entitlements/combined-system-extension.entitlements
256+
apps/agent/src-tauri/macos/system-extension/plists/agent-packaging-template.plist
257+
apps/agent/src-tauri/macos/system-extension/plists/combined-system-extension-template.plist
258+
apps/agent/src-tauri/macos/system-extension/profiles/developer-id-profile-template.plist
259+
)
260+
261+
for path in "${required[@]}"; do
262+
[[ -f "$path" ]] || {
263+
echo "missing macOS packaging asset: $path" >&2
264+
exit 1
265+
}
266+
done
267+
268+
CLAWDSTRIKE_VALIDATE_MACOS_PACKAGING=1 cargo check --manifest-path apps/agent/src-tauri/Cargo.toml
250269
251270
desktop-frontend:
252271
name: Desktop Frontend

.github/workflows/release.yml

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,36 @@ jobs:
7070
- name: Validate version consistency
7171
run: scripts/release-preflight.sh "${{ needs.resolve-version.outputs.version }}"
7272

73+
- name: Validate macOS packaging sources are release-capable
74+
shell: bash
75+
run: |
76+
set -euo pipefail
77+
78+
required=(
79+
apps/agent/src-tauri/macos/system-extension/entitlements/agent-app.entitlements
80+
apps/agent/src-tauri/macos/system-extension/entitlements/combined-system-extension.entitlements
81+
apps/agent/src-tauri/macos/system-extension/plists/agent-packaging-template.plist
82+
apps/agent/src-tauri/macos/system-extension/plists/combined-system-extension-template.plist
83+
apps/agent/src-tauri/macos/system-extension/profiles/developer-id-profile-template.plist
84+
)
85+
86+
for path in "${required[@]}"; do
87+
[[ -f "$path" ]] || {
88+
echo "missing macOS packaging asset: $path" >&2
89+
exit 1
90+
}
91+
done
92+
93+
if grep -R -nE "__[A-Z0-9_]+__" apps/agent/src-tauri/macos/system-extension; then
94+
echo "macOS combined-system-extension packaging still contains placeholders; replace them before release." >&2
95+
exit 1
96+
fi
97+
98+
if grep -R -n "scaffold_only" apps/agent/src-tauri/macos/system-extension; then
99+
echo "macOS packaging sources still declare scaffold_only state; release requires concrete source metadata plus a real embedded system extension bundle." >&2
100+
exit 1
101+
fi
102+
73103
- name: Run tests
74104
run: cargo test --workspace
75105

@@ -710,6 +740,14 @@ jobs:
710740
name: Build Agent DMG
711741
runs-on: macos-latest
712742
needs: preflight
743+
env:
744+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
745+
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
746+
NOTARYTOOL_PROFILE: ${{ secrets.NOTARYTOOL_PROFILE }}
747+
APPLE_ID: ${{ secrets.APPLE_ID }}
748+
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
749+
CLAWDSTRIKE_REQUIRE_CONCRETE_MACOS_PACKAGING: "1"
750+
NOTARIZE_OUT_DIR: ${{ runner.temp }}/clawdstrike-notarization
713751
steps:
714752
- uses: actions/checkout@v6
715753

@@ -723,9 +761,8 @@ jobs:
723761
- name: Install tauri-cli
724762
run: cargo install tauri-cli --locked --version '^2'
725763

726-
- name: Build agent DMG bundle
727-
working-directory: apps/agent
728-
run: cargo tauri build --bundles dmg
764+
- name: Build and notarize agent app bundle
765+
run: bash scripts/notarize-agent-macos.sh
729766

730767
- name: Upload agent DMG artifact
731768
uses: actions/upload-artifact@v6
@@ -734,6 +771,14 @@ jobs:
734771
path: apps/agent/src-tauri/target/release/bundle/dmg/*.dmg
735772
if-no-files-found: error
736773

774+
- name: Upload notarization evidence
775+
if: always()
776+
uses: actions/upload-artifact@v6
777+
with:
778+
name: clawdstrike-agent-notarization
779+
path: ${{ env.NOTARIZE_OUT_DIR }}/
780+
if-no-files-found: ignore
781+
737782
create-release:
738783
name: Create GitHub Release
739784
runs-on: ubuntu-latest

apps/agent/src-tauri/build.rs

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,111 @@
1+
use std::{env, fs, path::PathBuf};
2+
3+
const REQUIRED_MACOS_PACKAGING_FILES: &[&str] = &[
4+
"macos/system-extension/entitlements/agent-app.entitlements",
5+
"macos/system-extension/entitlements/combined-system-extension.entitlements",
6+
"macos/system-extension/plists/agent-packaging-template.plist",
7+
"macos/system-extension/plists/combined-system-extension-template.plist",
8+
"macos/system-extension/profiles/developer-id-profile-template.plist",
9+
];
10+
11+
const TAURI_CONFIG_PATH: &str = "tauri.conf.json";
12+
const SCAFFOLD_ONLY_MARKER: &str = "scaffold_only";
13+
const REQUIRED_TAURI_CONFIG_SNIPPETS: &[&str] = &[
14+
"\"minimumSystemVersion\": \"13.0\"",
15+
"\"macos/system-extension/**/*\"",
16+
"\"entitlements\": \"macos/system-extension/entitlements/agent-app.entitlements\"",
17+
];
18+
119
fn main() {
20+
println!("cargo:rerun-if-changed={TAURI_CONFIG_PATH}");
21+
for relative_path in REQUIRED_MACOS_PACKAGING_FILES {
22+
println!("cargo:rerun-if-changed={relative_path}");
23+
}
24+
25+
if should_validate_macos_packaging() {
26+
validate_macos_packaging()
27+
.unwrap_or_else(|error| panic!("macOS packaging validation failed: {error}"));
28+
}
29+
230
tauri_build::build()
331
}
32+
33+
fn should_validate_macos_packaging() -> bool {
34+
env::var("TARGET")
35+
.map(|target| target.contains("apple-darwin"))
36+
.unwrap_or(false)
37+
|| env::var_os("CLAWDSTRIKE_VALIDATE_MACOS_PACKAGING").is_some()
38+
}
39+
40+
fn validate_macos_packaging() -> Result<(), String> {
41+
let manifest_dir = manifest_dir()?;
42+
43+
let mut missing_files = Vec::new();
44+
for relative_path in REQUIRED_MACOS_PACKAGING_FILES {
45+
if !manifest_dir.join(relative_path).is_file() {
46+
missing_files.push((*relative_path).to_string());
47+
}
48+
}
49+
if !missing_files.is_empty() {
50+
return Err(format!(
51+
"missing required packaging assets: {}",
52+
missing_files.join(", ")
53+
));
54+
}
55+
56+
let tauri_config = fs::read_to_string(manifest_dir.join(TAURI_CONFIG_PATH))
57+
.map_err(|error| format!("failed to read {TAURI_CONFIG_PATH}: {error}"))?;
58+
let missing_config = REQUIRED_TAURI_CONFIG_SNIPPETS
59+
.iter()
60+
.filter(|snippet| !tauri_config.contains(**snippet))
61+
.copied()
62+
.collect::<Vec<_>>();
63+
if !missing_config.is_empty() {
64+
return Err(format!(
65+
"tauri.conf.json is missing required macOS packaging entries: {}",
66+
missing_config.join(", ")
67+
));
68+
}
69+
70+
if env::var_os("CLAWDSTRIKE_REQUIRE_CONCRETE_MACOS_PACKAGING").is_some() {
71+
let files_with_placeholders = REQUIRED_MACOS_PACKAGING_FILES
72+
.iter()
73+
.filter_map(|relative_path| {
74+
fs::read_to_string(manifest_dir.join(relative_path))
75+
.ok()
76+
.filter(|contents| contents.contains("__"))
77+
.map(|_| (*relative_path).to_string())
78+
})
79+
.collect::<Vec<_>>();
80+
if !files_with_placeholders.is_empty() {
81+
return Err(format!(
82+
"release-gated packaging placeholders remain in: {}",
83+
files_with_placeholders.join(", ")
84+
));
85+
}
86+
87+
let files_with_scaffold_marker = REQUIRED_MACOS_PACKAGING_FILES
88+
.iter()
89+
.filter_map(|relative_path| {
90+
fs::read_to_string(manifest_dir.join(relative_path))
91+
.ok()
92+
.filter(|contents| contents.contains(SCAFFOLD_ONLY_MARKER))
93+
.map(|_| (*relative_path).to_string())
94+
})
95+
.collect::<Vec<_>>();
96+
if !files_with_scaffold_marker.is_empty() {
97+
return Err(format!(
98+
"release-gated packaging sources still declare scaffold_only state: {}",
99+
files_with_scaffold_marker.join(", ")
100+
));
101+
}
102+
}
103+
104+
Ok(())
105+
}
106+
107+
fn manifest_dir() -> Result<PathBuf, String> {
108+
env::var("CARGO_MANIFEST_DIR")
109+
.map(PathBuf::from)
110+
.map_err(|error| format!("missing CARGO_MANIFEST_DIR: {error}"))
111+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// swift-tools-version: 5.9
2+
import PackageDescription
3+
4+
let package = Package(
5+
name: "EndpointSecurityExtension",
6+
platforms: [
7+
.macOS(.v13)
8+
],
9+
products: [
10+
.library(
11+
name: "EndpointSecurityExtension",
12+
targets: ["EndpointSecurityExtension"]
13+
),
14+
.executable(
15+
name: "endpoint-security-status-tool",
16+
targets: ["EndpointSecurityStatusTool"]
17+
)
18+
],
19+
targets: [
20+
.target(
21+
name: "EndpointSecurityExtension"
22+
),
23+
.executableTarget(
24+
name: "EndpointSecurityStatusTool",
25+
dependencies: ["EndpointSecurityExtension"]
26+
),
27+
.testTarget(
28+
name: "EndpointSecurityExtensionTests",
29+
dependencies: ["EndpointSecurityExtension"]
30+
)
31+
]
32+
)

0 commit comments

Comments
 (0)