Skip to content

Update README content - #4

Merged
Crash0v3rrid3 merged 2 commits into
browserstack:mainfrom
vivek-g-browserstack:main
Dec 2, 2025
Merged

Update README content#4
Crash0v3rrid3 merged 2 commits into
browserstack:mainfrom
vivek-g-browserstack:main

Conversation

@vivek-g-browserstack

@vivek-g-browserstack vivek-g-browserstack commented Dec 2, 2025

Copy link
Copy Markdown
Collaborator
  • Made some changes to the content
  • Added docs CLI link
Update content
@vivek-g-browserstack
vivek-g-browserstack requested a review from a team as a code owner December 2, 2025 07:12
@Crash0v3rrid3
Crash0v3rrid3 merged commit aba1197 into browserstack:main Dec 2, 2025
2 checks passed
Crash0v3rrid3 added a commit that referenced this pull request Jul 30, 2026
Follow-up to the PR #32 review, closing the report-only findings:

- Staging leak (#4): extraction helpers exit() via forwardExit on failure and
  SIGKILL bypasses defer, leaking .tmp.* staging dirs. Add sweepStaleStaging(),
  a best-effort mtime-gated sweep (>1h old only, so a concurrent build's in-flight
  staging is never deleted) run at the start of prepareArtifact.
- Cross-platform moveItem (#5): stop depending on moveItem's throw-on-existing
  semantics (Darwin throws; POSIX rename silently replaces an empty dir). Check
  versionDirectory existence explicitly; absent -> atomic rename, present ->
  reuse/replace. Removes the untestable platform assumption.
- Windows archive (#6): download the .zip to a sibling temp file outside the
  staging dir (with its own defer cleanup) so a failed removal can never bake the
  archive into the published version directory; a leftover is swept later.

Not addressed here: binary integrity/signature verification (#7) is pre-existing,
needs a trusted out-of-band digest source, and belongs with APPSEC-415 — not this
TOCTOU fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Crash0v3rrid3 added a commit that referenced this pull request Jul 30, 2026
…A11Y-483)

Addresses all code-review findings on the first cut:

- #1 Decide manifest ownership UNDER the lock from the live filesystem, not a
  startup PACKAGE_EXISTS snapshot. The lock is now taken unconditionally, so a
  peer that starts after the synthetic Package.swift already exists still
  serializes instead of running unprotected and getting its file deleted.
- #2 Reclaim a crashed peer's lock by PID liveness (kill -0), not a 5-min mtime
  that would steal a slow-but-alive long scan's lock.
- #3 Claim a stale lock atomically via rename so two waiters can't both reclaim.
- #4 Wait-timeout is non-fatal: it skips the scan (exit 0) with a visible
  'waiting...'/'skipping' notice instead of hanging a git commit then aborting it.
- #5 A non-EEXIST mkdir failure (unwritable/read-only/full TMPDIR) fails fast
  with an actionable message instead of waiting out the full timeout.
- #6 The lock lives under TMPDIR keyed by the package path, never inside the
  working tree, so a crash can't leave it to be git-added.
- #7 Consistent 'A11y scan:' message prefix.
- Also fixes a latent bug from the first cut: cleanup state (lock_dir/have_lock/
  created_package) is now global, since the EXIT trap fires after a11y_scan
  returns when its locals are out of scope (verified) -- previously the lock was
  never released on a normal run.

Verified with an integration test (staggered concurrent runs serialize; both
scans see Package.swift throughout; no tree/TMPDIR residue) and unit tests for
stale reclaim, live-owner detection, and fail-fast. Applied to bash/zsh/fish.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Crash0v3rrid3 added a commit that referenced this pull request Aug 3, 2026
…-482) (#32)

* fix(cache): atomic version-dir publish to close cache TOCTOU (DEVA11Y-482)

Extract the CLI into a unique staging directory and atomically rename it
into place instead of the check-delete-recreate sequence. Concurrent SPM
builds sharing ~/.cache can no longer wipe each other's in-progress
extraction; a build that loses the publish race reuses the winner's
fully-formed binary rather than running a partially-written one.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(review): correct nested-binary publish + harden publish race (DEVA11Y-482)

Review of PR #32 found a regression and residual races in the atomic-publish
change:

- P1: locateExecutable recurses, so a binary with the right name can sit in a
  nested subdir; the old lastPathComponent check skipped relocating it, leaving
  stagedExecutableURL/expectedExecutableURL pointing at a non-existent top-level
  path (ensureExecutablePermissions would throw). Compare full standardized URLs
  so any not-already-in-place binary is relocated.
- P2: the publish catch did a non-atomic fileExists->removeItem->moveItem that
  could ENOENT-crash or fail a build when a peer republished concurrently. Make
  removeItem best-effort and, on retry failure, reuse a peer's valid binary
  instead of throwing.
- P3: reword the publishVersionDirectory doc to stop overstating atomicity of the
  replace path; use UUID().uuidString for the staging suffix to match the file's
  existing convention.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(review): resolve residual cache-publish findings (DEVA11Y-482)

Follow-up to the PR #32 review, closing the report-only findings:

- Staging leak (#4): extraction helpers exit() via forwardExit on failure and
  SIGKILL bypasses defer, leaking .tmp.* staging dirs. Add sweepStaleStaging(),
  a best-effort mtime-gated sweep (>1h old only, so a concurrent build's in-flight
  staging is never deleted) run at the start of prepareArtifact.
- Cross-platform moveItem (#5): stop depending on moveItem's throw-on-existing
  semantics (Darwin throws; POSIX rename silently replaces an empty dir). Check
  versionDirectory existence explicitly; absent -> atomic rename, present ->
  reuse/replace. Removes the untestable platform assumption.
- Windows archive (#6): download the .zip to a sibling temp file outside the
  staging dir (with its own defer cleanup) so a failed removal can never bake the
  archive into the published version directory; a leftover is swept later.

Not addressed here: binary integrity/signature verification (#7) is pre-existing,
needs a trusted out-of-band digest source, and belongs with APPSEC-415 — not this
TOCTOU fix.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Crash0v3rrid3 added a commit that referenced this pull request Aug 3, 2026
…ft (DEVA11Y-483) (#33)

* fix(spm): serialize concurrent scans to protect synthetic Package.swift (DEVA11Y-483)

Guard the setup/scan/cleanup cycle with an atomic per-directory mkdir lock so
concurrent spm.sh invocations in the same working directory no longer race: the
first instance to exit can no longer delete the shared synthetic Package.swift
out from under a still-running peer. Stale locks left by killed peers are
reclaimed after 5 minutes; mkdir is used instead of flock(1) for macOS
portability. Applied to the bash, zsh and fish variants.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(spm): redesign concurrency lock to fully close the scan race (DEVA11Y-483)

Addresses all code-review findings on the first cut:

- #1 Decide manifest ownership UNDER the lock from the live filesystem, not a
  startup PACKAGE_EXISTS snapshot. The lock is now taken unconditionally, so a
  peer that starts after the synthetic Package.swift already exists still
  serializes instead of running unprotected and getting its file deleted.
- #2 Reclaim a crashed peer's lock by PID liveness (kill -0), not a 5-min mtime
  that would steal a slow-but-alive long scan's lock.
- #3 Claim a stale lock atomically via rename so two waiters can't both reclaim.
- #4 Wait-timeout is non-fatal: it skips the scan (exit 0) with a visible
  'waiting...'/'skipping' notice instead of hanging a git commit then aborting it.
- #5 A non-EEXIST mkdir failure (unwritable/read-only/full TMPDIR) fails fast
  with an actionable message instead of waiting out the full timeout.
- #6 The lock lives under TMPDIR keyed by the package path, never inside the
  working tree, so a crash can't leave it to be git-added.
- #7 Consistent 'A11y scan:' message prefix.
- Also fixes a latent bug from the first cut: cleanup state (lock_dir/have_lock/
  created_package) is now global, since the EXIT trap fires after a11y_scan
  returns when its locals are out of scope (verified) -- previously the lock was
  never released on a normal run.

Verified with an integration test (staggered concurrent runs serialize; both
scans see Package.swift throughout; no tree/TMPDIR residue) and unit tests for
stale reclaim, live-owner detection, and fail-fast. Applied to bash/zsh/fish.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(review): regenerate spm.sh checksum sidecars after lock redesign (DEVA11Y-483)

The concurrency-lock redesign edited all three spm.sh launchers but left their
.sha256 sidecars stale, which would make the self-update integrity check abort
on every run (dead on arrival, same class as the DEVA11Y-475 fix). Regenerate
all three sidecars to match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants