fix(core): randomize generated session branches#1533
Conversation
Greptile SummaryThis PR fixes a branch collision issue in shared repos by appending a random 5-character alphanumeric suffix to AO-generated freeform session branches (e.g.
Confidence Score: 5/5Safe to merge — the change is additive and well-isolated, with all three affected paths (branch generation, remote scanning, display formatting) updated consistently. Branch generation uses a cryptographically sound source of randomness, the remote scan regex is made backward-compatible with an optional suffix group, and the dashboard stripping regex handles the full range of session ID shapes (simple and orchestrator-style). Legacy branches without suffixes continue to work unchanged in both the scan and the display paths. Test coverage was extended for each of the three changed behaviors. No files require special attention.
|
| Filename | Overview |
|---|---|
| packages/core/src/session-manager.ts | Adds cryptographically random 5-char suffix to freeform session branches and updates the remote-scan regex to optionally match the suffix. Implementation is correct — randomInt indexing, backcompat regex, and deduplication all look fine. |
| packages/web/src/lib/format.ts | Strips the 5-char random suffix from session branch display text. Regex correctly handles orchestrator-style IDs (e.g. ao-orchestrator-8) via backtracking; old-format branches (no suffix) pass through unchanged. |
| packages/core/src/tests/session-manager/spawn.test.ts | Existing branch assertions updated to regex patterns; new test for suffixed remote branch scanning added. Coverage looks adequate for the changed paths. |
| packages/web/src/lib/tests/format.test.ts | Two new cases added: suffix stripping in humanizeBranch and the empty-string signal path for suffixed branches. Both cover the real display paths. |
| .changeset/randomize-session-branches.md | Correct patch-level changeset for both affected packages. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[spawn called] --> B{spawnConfig.branch set?}
B -- Yes --> C[Use explicit branch as-is]
B -- No --> D{issueId provided?}
D -- Yes --> E[Derive branch from issue / tracker]
D -- No --> F[Generate freeform session branch]
F --> G["session/{sessionId}-{randomSuffix(5)}"]
G --> H[randomInt from node:crypto\nAlphabet: 0-9 a-z]
subgraph Remote scan
I["ls-remote session/{prefix}-*"] --> J["Regex: -(\\d+)(?:-[a-z0-9]{5})?$"]
J --> K[Extract session number]
K --> L[Deduplicate & find max]
end
subgraph Dashboard display
M["branch: session/ao-52-k7f2m"] --> N["humanizeBranch()"]
N --> O["Strip suffix via regex\n^(...-\\d+)-[a-z0-9]{5}$"]
O --> P["Display: 'Ao 52'"]
end
Reviews (2): Last reviewed commit: "Merge remote-tracking branch 'upstream/m..." | Re-trigger Greptile
3dcfca8 to
78d24f5
Compare
Problem
Freeform AO sessions used deterministic branches like
session/ao-153. In shared repos, a manually pushed branch with the same shape can be mistaken for AO-owned work, causing another AO instance to skip/adopt the branch and link unrelated PRs.Closes #1529.
What changed
session/<sessionId>-<random5>.session/app-22branches and newsession/app-22-k7f2mbranches.Validation
pnpm --filter @aoagents/ao-core test -- src/__tests__/session-manager/spawn.test.tspnpm --filter @aoagents/ao-web test -- src/lib/__tests__/format.test.tspnpm --filter @aoagents/ao-core typecheckpnpm --filter @aoagents/ao-web typecheckpnpm --filter @aoagents/ao-core testNote:
pnpm --filter @aoagents/ao-web teststill has unrelated existing failures inapi-routes.test.ts,serialize.test.ts,page.test.tsx, and the tmux integration test when tmux is unavailable locally. The focused formatter test and web typecheck pass.Checklist