perf: Use `Arc<str>` for task dependency hashes to avoid heap clones (#11962)
## Summary
- Store task hashes as `Arc<str>` in `TaskHashTrackerState` instead of
`String`, so that `calculate_dependency_hashes` clones a ref-counted
pointer (atomic increment) instead of heap-allocating a new `String` for
each dependency hash lookup.
## Why
`queue_task` is called once per task in the topological dispatch loop.
For each task, `calculate_dependency_hashes` looks up every dependency's
hash and clones it into a `Vec`. On large monorepos like `api` (1687
tasks, ~3 deps each), that's ~5000 `String` heap allocations per run —
all for 16-char hex strings that are already stored in the tracker and
never mutated.
Switching to `Arc<str>` makes each "clone" a pointer-width copy + atomic
ref count increment instead of a heap allocation + memcpy.
## Testing
- All existing pinned-hash tests pass (the capnp serialization produces
identical bytes since `Arc<str>` derefs to `str`).
- Added `task_hashable_multiple_dependency_hashes` test with a pinned
hash value to guard against serialization regressions.
- Profiled on the our biggest repo (1039 packages, 1687 tasks):
`queue_task` self-time dropped from ~208ms to ~193ms.