This is an automated email from the ASF dual-hosted git repository.

spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 8d4955baa552ef151550db0ff64ef6f8f390a8ae
Author: Stephen Mallette <[email protected]>
AuthorDate: Fri Oct 9 15:44:17 2026 -0400

    Clear earlier tinker-review runs on re-run
    
    A re-run stops what the previous run left running and empties the work dir.
    SKILL.md now says teardown keeps the work dir, which holds the report.
    
    Assisted-by: Claude Code:claude-opus-5-5
---
 .skills/tinker-review/SKILL.md          | 25 ++++++++++++-------------
 .skills/tinker-review/scripts/review.js | 23 ++++++++++++++++++++++-
 2 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/.skills/tinker-review/SKILL.md b/.skills/tinker-review/SKILL.md
index 4f370c86c6..d110fcd19d 100644
--- a/.skills/tinker-review/SKILL.md
+++ b/.skills/tinker-review/SKILL.md
@@ -60,7 +60,8 @@ coverage gaps, centrality, blast radius, cluster analysis) → 
write evidence JS
 **Server:** remains running (the agent needs it for enrichment)
 **Worktree:** available at `/tmp/pr-review-<pr>/src/`
 
-If re-running, the script cleans up stale worktrees/branches automatically.
+If re-running, the script clears the earlier run first (container, functional
+server, worktrees, and the work dir with its old evidence and report).
 
 ### 2. Choose the playbooks
 
@@ -315,23 +316,21 @@ Every section is always present — if you didn't provide a 
field, it shows
 node -e "import { teardown } from './scripts/review.js'; await 
teardown('/tmp/pr-review-<pr>');"
 ```
 
-Or simply stop the Docker container and clean up manually:
-```bash
-docker stop $(cat /tmp/pr-review-<pr>/session.json | python3 -c "import 
json,sys; print(json.load(sys.stdin)['containerId'])")
-rm -rf /tmp/pr-review-<pr>
-git worktree prune
-git branch -D pr-review/<pr>
-```
+This stops the knowledge graph server, removes the `src/` worktree and deletes
+the `pr-review/<pr>` branch. If a functional test ran (step 4), teardown also
+stops that server (via its `pid` in `functional.json`) and removes the `build/`
+worktree. Call this ONLY after all phases are complete.
 
-This stops the knowledge graph server, removes worktrees, deletes the branch.
-If a functional test ran (step 4), teardown also stops that server (via its
-`pid` in `functional.json`) and removes the `build/` worktree. Call this ONLY
-after all phases are complete.
+Teardown **keeps** `/tmp/pr-review-<pr>/`: it holds `report.html`, 
`report.json`
+and `evidence.json`. Delete it yourself once the report is no longer needed
+(`rm -rf /tmp/pr-review-<pr>`). Re-running the review on the same PR clears it,
+along with anything the earlier run left running.
 
 ## Important Notes
 
 - NEVER push to the `upstream` remote. It is fetch-only.
 - ALL output goes to `/tmp/pr-review-<pr>/` — never write inside the git repo.
 - The Gremlin Server stays alive until teardown. Don't kill it early.
-- If re-running, the script auto-cleans stale state.
+- If re-running, the script clears the earlier run first: its container, 
functional
+  server, worktrees and the whole work dir, including any old report.
 - The agent populates JSON narrative fields; the renderer produces HTML. No 
agent writes raw HTML.
diff --git a/.skills/tinker-review/scripts/review.js 
b/.skills/tinker-review/scripts/review.js
index a179f0ff70..4175f42862 100644
--- a/.skills/tinker-review/scripts/review.js
+++ b/.skills/tinker-review/scripts/review.js
@@ -250,6 +250,27 @@ async function cleanupWorktree(repoPath, worktreePath, 
prBranch) {
   await exec("git", ["branch", "-D", prBranch], { cwd: repoPath }).catch(() => 
{});
 }
 
+// A re-run starts clean: stop whatever an earlier run of this PR left running
+// (its Gremlin container and functional server), remove its worktrees, and
+// delete the old work dir with its evidence and report.
+async function cleanupPreviousRun(repoPath, workDir, worktreePath, prBranch) {
+  if (!existsSync(workDir)) return;
+  const { readFile: rf } = await import("node:fs/promises");
+  const readJson = (name) => rf(join(workDir, name), 
"utf-8").then(JSON.parse).catch(() => null);
+  const functionalHandle = await readJson("functional.json");
+  if (functionalHandle) {
+    const { stop: stopFunctional } = await import("./functional/setup.js");
+    await stopFunctional(functionalHandle, { repoPath }).catch(() => {});
+  }
+  const previous = await readJson("session.json");
+  if (previous?.containerId) {
+    await exec("docker", ["stop", previous.containerId]).catch(() => {});
+    await exec("docker", ["rm", previous.containerId]).catch(() => {});
+  }
+  await cleanupWorktree(repoPath, worktreePath, prBranch);
+  await rm(workDir, { recursive: true, force: true });
+}
+
 // ============================================================
 // SETUP — fetch PR, create worktree, start server
 // Returns a session object the agent uses for all subsequent phases.
@@ -302,8 +323,8 @@ export async function setup(params) {
   const workDir = `/tmp/pr-review-${pr}`;
   const worktreePath = `${workDir}/src`;
 
+  await cleanupPreviousRun(repoPath, workDir, worktreePath, prBranch);
   await mkdir(workDir, { recursive: true });
-  await cleanupWorktree(repoPath, worktreePath, prBranch);
 
   log(`PR #${pr} — targets ${baseBranch}, fetching...`);
   await exec("git", ["fetch", remote, baseBranch], { cwd: repoPath }).catch(() 
=> {});

Reply via email to