release: v0.3.0-beta.3 - #168
Conversation
Add a bounded, in-memory kubeconfig directory importer for the loopback fleet IDE. Imported contexts retain unique identities, safe relative source labels, and per-file diagnostics while preserving the direct local-operation path. GSTACK-Checkpoint: 2026-07-14/f11-kubeconfig-directory-import#1 Signed-off-by: Gnani Rahul <gnani.nutakki@gmail.com>
GSTACK-Checkpoint: 2026-07-14/f11-kubeconfig-directory-import#2 Signed-off-by: Gnani Rahul <gnani.nutakki@gmail.com>
…onfig-directory-import feat(f11): import kubeconfig directories in local UI
Cap all filesystem traversal entries, redact root traversal errors, and prove multi-context source filtering in the real cluster suite. GSTACK-Checkpoint: 2026-07-14/f11-directory-import-review#1 Signed-off-by: Gnani Rahul <gnani.nutakki@gmail.com>
…ory-import-review fix(f11): harden kubeconfig directory import review gaps
Keep the all-entry traversal cap as the sole directory-import limit after peer review. GSTACK-Checkpoint: 2026-07-14/f11-directory-entry-cap#1 Signed-off-by: Gnani Rahul <gnani.nutakki@gmail.com>
…ory-entry-cap fix(f11): remove redundant directory candidate bound
Package the existing local fleet IDE in a Wails v2 macOS shell with a native, path-private kubeconfig-folder import flow. Preserve the hardened in-process UI boundary and atomic session handoff. GSTACK-Checkpoint: 2026-07-14/f11-native-desktop-shell#1 Signed-off-by: Gnani Rahul <gnani.nutakki@gmail.com>
Use non-blocking session leases, a sanitized hydration-stop state, directory-only startup, graceful signal shutdown, and reproducible pinned Wails packaging with ARM64 verification. GSTACK-Checkpoint: 2026-07-14/f11-native-desktop-shell#2 Signed-off-by: Gnani Rahul <gnani.nutakki@gmail.com>
Signed-off-by: Gnani Rahul <gnani.nutakki@gmail.com>
…e-desktop-shell feat(f11): add native macOS fleet desktop
|
Important Review skippedNo new commits to review since the last review. ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughAdds bounded kubeconfig directory import with safe diagnostics and source metadata, integrates it into the WebUI, and introduces a Wails-based macOS desktop shell with native folder selection, in-process request handling, ARM64 packaging, signing checks, documentation, and tests. ChangesKubeconfig directory import and metadata
In-process WebUI
Desktop runtime
Packaging and documentation
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review Please review this dev-to-main beta promotion for release-boundary regressions only: tag ancestry, beta/latest semantics, macOS ARM64 archive claims, release provenance, and privacy wording. The code changes were individually reviewed and CI-verified in their feature PRs. |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
gh pr view 168 --repo ArdurAI/sith --json title,body,baseRefName,headRefName,commits,files,mergeable,additions,deletions
echo "---DIFF STAT---"
gh pr diff 168 --repo ArdurAI/sith --stat
echo "---FILES---"
gh pr diff 168 --repo ArdurAI/sith --name-onlyLength of output: 11634 🏁 Script executed: #!/bin/bash
set -euo pipefail
cd /tmp 2>/dev/null || true
echo "--- README diff ---"
gh pr diff 168 --repo ArdurAI/sith --patch -- README.md || true
echo "--- Makefile diff ---"
gh pr diff 168 --repo ArdurAI/sith --patch -- Makefile || true
echo "--- tags ---"
gh api repos/ArdurAI/sith/tags --jq '.[].name' | head -50
echo "--- releases ---"
gh api repos/ArdurAI/sith/releases --jq '.[] | {tag: .tag_name, prerelease, draft, created_at}' | head -50
echo "--- workflow files ---"
gh api repos/ArdurAI/sith/contents/.github/workflows --jq '.[].name' 2>/dev/null || trueLength of output: 1299 🏁 Script executed: #!/bin/bash
set -euo pipefail
git clone --depth 100 https://github.com/ArdurAI/sith.git repo 2>&1 | tail -5
cd repo
git fetch origin dev main 2>&1 | tail -5
echo "--- merge-base ---"
git merge-base main origin/dev
git log --oneline main..origin/dev | tail -30
echo "--- README diff ---"
git diff main origin/dev -- README.md
echo "--- Makefile diff ---"
git diff main origin/dev -- Makefile
echo "--- release.yml diff ---"
git diff main origin/dev -- .github/workflows/release.ymlLength of output: 1065 🏁 Script executed: #!/bin/bash
set -euo pipefail
cd repo
git remote set-branches origin '*'
git fetch --depth 200 origin dev main
echo "--- merge-base ---"
git merge-base origin/main origin/dev
echo "--- commits main..dev ---"
git log --oneline origin/main..origin/dev
echo "--- README diff ---"
git diff origin/main origin/dev -- README.md
echo "--- Makefile diff ---"
git diff origin/main origin/dev -- Makefile
echo "--- release.yml diff ---"
git diff origin/main origin/dev -- .github/workflows/release.ymlLength of output: 7462 🏁 Script executed: #!/bin/bash
set -euo pipefail
cd repo
echo "--- tag beta.2 commit ---"
git rev-list -n1 v0.3.0-beta.2
echo "--- is beta.2 ancestor of dev head 7f9302d ---"
git merge-base --is-ancestor v0.3.0-beta.2 origin/dev && echo yes || echo no
echo "--- is beta.2 ancestor of main ---"
git merge-base --is-ancestor v0.3.0-beta.2 origin/main && echo yes || echo no
echo "--- current main head ---"
git rev-parse origin/main
echo "--- current dev head ---"
git rev-parse origin/dev
echo "--- check CI run status for 29381529839 ---"
gh run view 29381529839 --repo ArdurAI/sith --json status,conclusion,headBranch,headSha,workflowName 2>&1 || true
echo "--- check PR 167 status ---"
gh pr view 167 --repo ArdurAI/sith --json state,mergedAt,mergeCommit 2>&1 || trueLength of output: 1506 🏁 Script executed: #!/bin/bash
set -euo pipefail
cd repo
echo "--- commits in main not in dev ---"
git log --oneline origin/dev..origin/main
echo "--- commits count ---"
git log --oneline origin/dev..origin/main | wc -lLength of output: 692 🏁 Script executed: #!/bin/bash
set -euo pipefail
cd repo
fd -i goreleaser
echo "--- goreleaser diff dev vs main ---"
git diff origin/main origin/dev -- .goreleaser.yml .goreleaser.yaml 2>/dev/null || true
echo "--- goreleaser darwin/arm64 mention ---"
rg -n 'darwin|arm64' .goreleaser.yml 2>/dev/null | head -20
echo "--- homebrew formula ---"
fd -i formula
rg -n 'homebrew|formula' .goreleaser.yml 2>/dev/null
echo "--- SLSA/SBOM/sigstore refs in release.yml ---"
rg -n 'slsa|sbom|sigstore|cosign|provenance' .github/workflows/release.yml -iLength of output: 907 🏁 Script executed: #!/bin/bash
cd repo
echo "--- find goreleaser config ---"
fd -i -a goreleaser 2>/dev/null
find . -iname '*goreleaser*' -not -path '*/.git/*'
echo "--- release.yml content search ---"
grep -inE 'slsa|sbom|sigstore|cosign|provenance|darwin|arm64|homebrew|formula' .github/workflows/release.ymlLength of output: 3467 This confirms release.yml provides the darwin/arm64 SBOM/provenance/Sigstore/Homebrew claims made in the PR body, and this workflow is unchanged between Release-boundary review summary
Tag ancestry & immutability ✅
beta/latest semantics ✅
macOS ARM64 archive claims ✅
Release provenance ✅
Privacy wording ✅
No release-boundary regressions found. I did not re-review the F11.7/F11.8 implementation logic itself, per your scope request. ✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
internal/fleetcache/store_test.go (1)
445-456: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winVerify diagnostics slice isolation.
Mutate the original diagnostics after
SetDiscovery, then mutate the first snapshot and query again. The current assertions would still pass if either clone were accidentally removed.Proposed test extension
- store.SetDiscovery(fleet.LocalWorkspace, connector.Discovery{ + diagnostics := []connector.Diagnostic{{Source: "bad.yaml", Message: "invalid kubeconfig"}} + store.SetDiscovery(fleet.LocalWorkspace, connector.Discovery{ Scopes: []connector.Scope{{ Name: "import-123/context/prod", DisplayName: "prod", Origin: "team-a.yaml", Reachable: true, ObservedAt: now, }}, - Diagnostics: []connector.Diagnostic{{Source: "bad.yaml", Message: "invalid kubeconfig"}}, + Diagnostics: diagnostics, }) + diagnostics[0].Message = "mutated input" snapshot := store.Query(fleet.LocalWorkspace, Query{}) ... + snapshot.Diagnostics[0].Message = "mutated output" + if got := store.Query(fleet.LocalWorkspace, Query{}).Diagnostics[0].Message; got != "invalid kubeconfig" { + t.Fatalf("stored diagnostic was mutated through snapshot: %q", got) + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/fleetcache/store_test.go` around lines 445 - 456, Extend the SetDiscovery/Query test around store.SetDiscovery to verify diagnostics slice isolation: mutate the original diagnostics after storing, mutate the diagnostics in the first snapshot, then query again and assert the stored result remains unchanged with the expected diagnostic. Keep the existing scope assertions intact.internal/webui/server_test.go (1)
177-191: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winExercise redaction with an actual local path.
The fixture contains only
team-a.yamlandbroken.yaml, so the/Users/assertion passes even if absoluteOriginor diagnostic-source values are serialized unchanged. Seed a representative absolute path at the layer responsible for redaction and assert that only the safe filename reaches the snapshot.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/webui/server_test.go` around lines 177 - 191, Update the snapshot fixture setup in the test around SetDiscovery to seed an actual absolute local path in the Origin or diagnostic source field handled by redaction, while retaining the existing fixture coverage. Extend the response assertion to require the safe filename and reject the absolute path prefix, verifying that the redaction layer—not incidental fixture names—produces the sanitized snapshot.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/cli/desktop_execute.go`:
- Around line 17-22: Update the error handling around runDesktop to recognize
expected context cancellation from the signal.NotifyContext shutdown path and
return a successful exit code instead of 1; preserve stderr reporting and the
existing failure exit code for other errors.
In `@internal/cli/ui.go`:
- Around line 43-49: Reorder the initialization in the surrounding UI setup so
the options.kubeconfigDir branch constructs and assigns the directory adapter
before the existing nil-client validation runs. Then validate the resulting
reader and local dependencies, preserving the current kubeconfig.New error
wrapping and normal client initialization behavior.
In `@internal/connector/kubeconfig/directory.go`:
- Around line 145-150: Update the file-opening logic in the kubeconfig import
flow around the os.Open call to prevent symlink traversal for the final path
component after WalkDir classification. Open the file relative to a handle
pinned to the selected directory, or use an equivalent no-follow strategy, while
preserving the existing size limit, error propagation, and deferred close
behavior.
---
Nitpick comments:
In `@internal/fleetcache/store_test.go`:
- Around line 445-456: Extend the SetDiscovery/Query test around
store.SetDiscovery to verify diagnostics slice isolation: mutate the original
diagnostics after storing, mutate the diagnostics in the first snapshot, then
query again and assert the stored result remains unchanged with the expected
diagnostic. Keep the existing scope assertions intact.
In `@internal/webui/server_test.go`:
- Around line 177-191: Update the snapshot fixture setup in the test around
SetDiscovery to seed an actual absolute local path in the Origin or diagnostic
source field handled by redaction, while retaining the existing fixture
coverage. Extend the response assertion to require the safe filename and reject
the absolute path prefix, verifying that the redaction layer—not incidental
fixture names—produces the sanitized snapshot.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: f7bec039-b3c3-4d2d-bd9e-b50d00804ebc
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (38)
.gitignoreMakefileREADME.mdcmd/sith-desktop/frontend/.gitkeepcmd/sith-desktop/main.gocmd/sith-desktop/wails.jsondocs/adr/0010-native-local-desktop-shell.mddocs/adr/README.mdgo.modinternal/cli/desktop.gointernal/cli/desktop_darwin.gointernal/cli/desktop_execute.gointernal/cli/desktop_other.gointernal/cli/desktop_test.gointernal/cli/local_test.gointernal/cli/root.gointernal/cli/ui.gointernal/connector/contract.gointernal/connector/kubeconfig/adapter.gointernal/connector/kubeconfig/directory.gointernal/connector/kubeconfig/directory_test.gointernal/connector/kubeconfig/local_objects.gointernal/fleetcache/store.gointernal/fleetcache/store_test.gointernal/privacy/boundary_test.gointernal/webui/assets/app.cssinternal/webui/assets/app.jsinternal/webui/assets/index.htmlinternal/webui/desktop.gointernal/webui/desktop_test.gointernal/webui/server.gointernal/webui/server_test.gosessions/2026-07-14-f11-directory-entry-cap-cleanup.mdsessions/2026-07-14-f11-directory-import-review-fixes.mdsessions/2026-07-14-f11-kubeconfig-directory-import.mdsessions/2026-07-14-f11-native-desktop-shell.mdtests/e2e/kind_fanout_test.gotests/e2e/kind_web_ui_test.go
| ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) | ||
| defer stop() | ||
| if err := runDesktop(ctx, adapter, adapter, ""); err != nil { | ||
| _, _ = fmt.Fprintln(os.Stderr, err) | ||
| return 1 | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== files ==\n'
git ls-files 'internal/cli/desktop_execute.go' 'cmd/sith-desktop/main.go' 'internal/cli/*' | sed 's#^`#-` #'
printf '\n== desktop entrypoint references ==\n'
rg -n "runDesktop|NotifyContext|SIGTERM|os.Interrupt|sith-desktop|desktop_execute" internal cmd -g '!**/node_modules/**' || true
printf '\n== file excerpts ==\n'
for f in internal/cli/desktop_execute.go cmd/sith-desktop/main.go; do
if [ -f "$f" ]; then
echo "--- $f ---"
nl -ba "$f" | sed -n '1,120p'
fi
doneRepository: ArdurAI/sith
Length of output: 1894
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
for p in [Path('internal/cli/desktop_execute.go'), Path('cmd/sith-desktop/main.go')]:
print(f'## {p}')
if p.exists():
for i, line in enumerate(p.read_text().splitlines(), 1):
print(f'{i:4d}: {line}')
PYRepository: ArdurAI/sith
Length of output: 1172
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for f in internal/cli/desktop_darwin.go internal/cli/desktop_other.go internal/cli/desktop.go internal/cli/root.go; do
if [ -f "$f" ]; then
echo "--- $f ---"
python3 - <<'PY' "$f"
from pathlib import Path
import sys
p = Path(sys.argv[1])
for i, line in enumerate(p.read_text().splitlines(), 1):
print(f"{i:4d}: {line}")
PY
echo
fi
done
echo "--- build tags / signals ---"
rg -n "^//go:build|NotifyContext|os\.Interrupt|SIGTERM|context\.Canceled|Canceled" internal/cli cmd -g '!**/node_modules/**'Repository: ArdurAI/sith
Length of output: 19162
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for f in internal/cli/desktop_darwin.go internal/cli/desktop_other.go internal/cli/desktop.go internal/cli/root.go; do
if [ -f "$f" ]; then
echo "--- $f ---"
python3 - <<'PY' "$f"
from pathlib import Path
import sys
p = Path(sys.argv[1])
for i, line in enumerate(p.read_text().splitlines(), 1):
print(f"{i:4d}: {line}")
PY
echo
fi
done
echo "--- build tags / signals ---"
rg -n "^//go:build|NotifyContext|os\.Interrupt|SIGTERM|context\.Canceled|Canceled" internal/cli cmd -g '!**/node_modules/**'Repository: ArdurAI/sith
Length of output: 19162
🌐 Web query:
Wails v2 quit shutdown wails.Run returns error context canceled signal.NotifyContext os.Interrupt SIGTERM
💡 Result:
In Wails v2, the observation that wails.Run may return a context canceled error after receiving an OS interrupt (such as Ctrl+C) is related to how the framework handles process termination and signal monitoring [1][2]. Wails v2 maintains an internal signal manager that listens for OS signals like SIGINT (Interrupt) and SIGTERM [1]. When these signals are detected, the framework triggers a shutdown process [1]. If your application or a parent process uses signal.NotifyContext to manage application lifecycle, the cancellation of that context is often the expected and correct behavior when the application is requested to shut down via these signals [3]. Key points regarding this behavior: 1. Signal Handling Integration: Wails v2 hooks into OS signals to initiate a graceful shutdown, which includes running defined OnShutdown callbacks [1][4]. 2. Context Cancellation: The error context canceled is a standard Go result when a context derived from signal.NotifyContext is cancelled by a caught OS signal [3]. If your application logic relies on this context, it will naturally receive this signal as a trigger to stop operations [5]. 3. Premature Termination Issues: Historically, some users have reported that terminating via Ctrl+C can cause an immediate exit that may bypass or truncate custom cleanup routines [2]. If your shutdown logic is not completing, it is generally recommended to ensure that critical cleanup tasks are handled within the OnShutdown lifecycle hook provided in the application options [4][6], rather than relying on the main thread to block indefinitely after receiving a termination signal. If you are seeing this error during development or execution and it is causing unexpected crashes, ensure that your application is not prematurely closing resources that the Wails runtime still requires during its own internal shutdown phase [2]. If the application terminates cleanly despite the error, it is typically an indicator that the context cancellation was successful [3].
Citations:
- 1: https://github.com/wailsapp/wails/blob/4d0abeb3/v2/internal/signal/signal.go
- 2: Terminating a Wails App with Ctrl+C Causes Premature Application Termination wailsapp/wails#3077
- 3: https://pkg.go.dev/os/signal
- 4: https://github.com/wailsapp/wails/blob/4d0abeb3/v2/pkg/options/options.go
- 5: https://v3.wails.io/concepts/lifecycle/
- 6: https://wails.io/docs/next/guides/migrating/
Preserve graceful shutdown semantics. Treat expected cancellation from the desktop launcher as a clean exit instead of returning exit code 1.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/cli/desktop_execute.go` around lines 17 - 22, Update the error
handling around runDesktop to recognize expected context cancellation from the
signal.NotifyContext shutdown path and return a successful exit code instead of
1; preserve stderr reporting and the existing failure exit code for other
errors.
| if options.kubeconfigDir != "" { | ||
| adapter, err := kubeconfig.New(kubeconfig.WithDirectory(options.kubeconfigDir)) | ||
| if err != nil { | ||
| return fmt.Errorf("import kubeconfig directory: %w", err) | ||
| } | ||
| reader, local = adapter, adapter | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Construct the directory adapter before rejecting missing clients.
The preceding nil check runs first, so directory-only startup fails before this branch can provide both clients. Select the adapter first, then validate the resulting dependencies.
Proposed fix
RunE: func(command *cobra.Command, _ []string) error {
- if reader == nil || local == nil {
- return fmt.Errorf("local fleet UI requires a Kubernetes reader and local operations client")
- }
if options.kubeconfigDir != "" {
adapter, err := kubeconfig.New(kubeconfig.WithDirectory(options.kubeconfigDir))
if err != nil {
return fmt.Errorf("import kubeconfig directory: %w", err)
}
reader, local = adapter, adapter
}
+ if reader == nil || local == nil {
+ return fmt.Errorf("local fleet UI requires a Kubernetes reader and local operations client")
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if options.kubeconfigDir != "" { | |
| adapter, err := kubeconfig.New(kubeconfig.WithDirectory(options.kubeconfigDir)) | |
| if err != nil { | |
| return fmt.Errorf("import kubeconfig directory: %w", err) | |
| } | |
| reader, local = adapter, adapter | |
| } | |
| if options.kubeconfigDir != "" { | |
| adapter, err := kubeconfig.New(kubeconfig.WithDirectory(options.kubeconfigDir)) | |
| if err != nil { | |
| return fmt.Errorf("import kubeconfig directory: %w", err) | |
| } | |
| reader, local = adapter, adapter | |
| } | |
| if reader == nil || local == nil { | |
| return fmt.Errorf("local fleet UI requires a Kubernetes reader and local operations client") | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/cli/ui.go` around lines 43 - 49, Reorder the initialization in the
surrounding UI setup so the options.kubeconfigDir branch constructs and assigns
the directory adapter before the existing nil-client validation runs. Then
validate the resulting reader and local dependencies, preserving the current
kubeconfig.New error wrapping and normal client initialization behavior.
| file, err := os.Open(path) // #nosec G304 -- path is discovered beneath a user-selected directory without symlink traversal. | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| defer func() { _ = file.Close() }() | ||
| payload, err := io.ReadAll(io.LimitReader(file, maxImportBytes+1)) |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check whether the repository already provides a no-follow/openat helper.
rg -n --type=go -C3 '\b(Openat|O_NOFOLLOW|open.*NoFollow|WalkDir)\b' .Repository: ArdurAI/sith
Length of output: 2537
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the kubeconfig directory loader around the reported lines.
file="internal/connector/kubeconfig/directory.go"
wc -l "$file"
sed -n '1,240p' "$file"Repository: ArdurAI/sith
Length of output: 7508
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for any no-follow/openat helper or tests around symlink replacement in kubeconfig loading.
rg -n --type=go -C3 '\b(Openat|O_NOFOLLOW|no-?follow|symlink|LocationOfOrigin|ResolveLocalPaths|loadKubeconfigFile)\b' internal/connector/kubeconfig internal/privacyRepository: ArdurAI/sith
Length of output: 4232
Pin file opens to the selected directory.
A file can still be swapped in after WalkDir classifies it, so os.Open(path) may follow a symlink and read content outside the chosen directory. Open through a pinned directory handle or use a no-follow strategy for the final path component.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/connector/kubeconfig/directory.go` around lines 145 - 150, Update
the file-opening logic in the kubeconfig import flow around the os.Open call to
prevent symlink traversal for the final path component after WalkDir
classification. Open the file relative to a handle pinned to the selected
directory, or use an equivalent no-follow strategy, while preserving the
existing size limit, error propagation, and deferred close behavior.
Native fleet IDE beta\n\nPromotes the fully verified F11.7 kubeconfig-directory importer and F11.8 native macOS fleet desktop from
devtomainfor the immutablev0.3.0-beta.3release tag.\n\n### What beta.3 delivers\n\n- signed/provenance-backeddarwin/arm64CLI archive, includingsith uiand the nativesith desktopcommand\n- privacy-first local kubeconfig-folder import through the native picker; no TCP listener, account, telemetry, or kubeconfig-path leak\n- all previous release archive, SPDX SBOM, Sigstore, SLSA, and Homebrew-formula protections\n\n### Deliberate distribution boundary\n\nThis is a beta CLI archive, not a separately distributable notarized macOS.app.sith desktopis runnable from the macOS ARM64 archive, while Developer ID signing, notarization, and stapling for a Finder-distributed.appremain an E9 follow-up.\n\n### Evidence\n\n- exactdevmerge CI for7f9302d: run29381529839passed build, race tests, tenant isolation, reproducible archives/SBOM, and real two-cluster fan-out\n- PR #167 received red-team review corrections before merge; its exact post-merge CI passed\n-v0.3.0-beta.2is immutable and remains untouched\n\nAfter this release PR is green and merged, the exactmainCI will be verified before the SSH-signedv0.3.0-beta.3tag is created.Summary by CodeRabbit
New Features
desktopcommand and ARM64 macOS app build support.Bug Fixes
Documentation