@ericrisco/rsc 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/manifest.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.3",
2
+ "version": "2.0.4",
3
3
  "counts": {
4
4
  "skills": 273,
5
5
  "agents": 33,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ericrisco/rsc",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "description": "A guided harness builder that turns your goal into a minimal, verified AI-agent setup using strict best practices.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -194,13 +194,23 @@ export function provenanceOf(root, wt) {
194
194
  * The reflog is git's own record of the ref moving; when it cannot answer, the answer is no, because
195
195
  * accumulating a stale worktree costs a directory and the other mistake costs someone's afternoon.
196
196
  */
197
- export function hasLandedWork(root, wt, trunk) {
198
- const tip = git(root, ['rev-parse', `${trunk}^{commit}`]);
199
- if (tip.ok && wt.head && tip.out === wt.head) return false;
197
+ export function hasLandedWork(root, wt) {
200
198
  if (!wt.branch) return false;
199
+ // Ask the reflog FIRST. It is the only record that distinguishes the two states that look
200
+ // identical from the outside: a worktree sitting at the trunk because it was just created there,
201
+ // and one sitting at the trunk because its work landed by fast-forward and took the trunk with
202
+ // it. Until 2.0.3 the tip comparison below ran first and answered "nothing landed" for both, so
203
+ // every branch landed the ordinary FTD way — commit, push, fast-forward — was kept for ever.
204
+ // Found on 2026-09-18 watching this repo refuse to sweep its own branch for the wrong reason.
201
205
  const log = git(root, ['reflog', 'show', '--format=%gs', wt.branch]);
202
- if (!log.ok || !log.out) return false;
203
- return log.out.split('\n').some((line) => line.startsWith('commit'));
206
+ if (log.ok && log.out) return log.out.split('\n').some((line) => line.startsWith('commit'));
207
+ // No reflog to ask — a fresh clone, or a branch whose reflog has expired. There is then no
208
+ // evidence this branch ever carried anything, and this whole module fails towards keeping the
209
+ // directory: unproven is not proven. (The tip comparison that used to sit here is deliberately
210
+ // gone rather than kept as a fallback: both of its outcomes are this same answer, and a line
211
+ // that cannot change the result while reading like a guard is the kind of decoration that made
212
+ // the bug above hard to see.)
213
+ return false;
204
214
  }
205
215
 
206
216
  export function integrationOf(root, wt, trunk) {
@@ -294,7 +304,7 @@ export function classifyWorktrees(root) {
294
304
 
295
305
  const integration = integrationOf(root, wt, trunk);
296
306
  if (integration !== 'integrated') return { ...base, reasons: [integration] };
297
- if (!hasLandedWork(root, wt, trunk)) return { ...base, reasons: ['nothing-landed'] };
307
+ if (!hasLandedWork(root, wt)) return { ...base, reasons: ['nothing-landed'] };
298
308
 
299
309
  const { dirty, outside, readable } = contentOutsideHistory(wt.path);
300
310
  if (!readable) return { ...base, reasons: ['unreadable'] };