* fix(#2415): close_phase_todos stages the pending/ deletion alongside completed/ Bug: the workflow step moved resolved todos from .planning/todos/pending/ to .planning/todos/completed/ with a plain 'mv', then committed listing ONLY the destination directory in --files: mv "$TODO_FILE" "$COMPLETED_DIR/" gsd_run query commit '...' --files .planning/todos/completed/ .planning/STATE.md Git's index still tracked the moved file at its old pending/<name>.md path. The commit therefore only staged the new completed/<name>.md copy — the deletion at pending/ was never staged, never committed, and lingered as an unstaged deletion in git status indefinitely until some later broad 'git add -A' caught it. The phase genuinely closed the todo, but the working tree was never clean. Fix: add .planning/todos/pending/ to the --files list. 'git add' of that directory (since git 2.0) stages deletions of tracked files in the pathspec, so the moved-away file is staged as a deletion atomically with the new completed/ copy in the same commit. Chose plain mv + two-dir --files over 'git mv' because git mv FAILS on: - untracked todos (new todo file not yet committed) - non-git .planning dirs (worktree safety / pre-init projects) Plain mv has neither failure mode. Regression tests in tests/close-phase-todos-stage-deletion.test.cjs (source-text-is-the-product: workflow .md text IS what the runtime loads) cover: - the commit --files list includes BOTH completed/ AND pending/ - the move uses plain 'mv' (not 'git mv') so untracked + non-git cases work * chore(#2415): trim commit subject to keep execute-phase.md under byte ceiling The fix added '.planning/todos/pending/' (~26 bytes) to the commit --files list. To stay under the ADR-857 Phase 6 pre-phase-6 byte ceiling margin (93400 bytes, hard ceiling 93600), shortened the commit subject from 'auto-close N todo(s) resolved by this phase' to 'close N resolved todo(s)'. Net change vs origin/next: +6 bytes (93384 → 93390), well under the margin. Also regenerates the golden-install-parity fixtures (execute-phase.md content-hash update across all runtimes). * chore(#2415): bump execute-phase.md workflow-size baseline (93384 → 93390) The +pending/ fix added 6 net bytes (93384 → 93390), still well under the ADR-857 Phase 6 pre-phase-6 byte ceiling margin (93400). * chore(changeset): backfill pr:2447 in .changeset/sturdy-wasps-run.md * fix(#2415): add issue ref to allow-test-rule annotation (ADR-456) CI lint-allow-test-rule-refs failed on the prior commit — ADR-456 requires '// allow-test-rule: <category> see #NNNN' so every exemption is traceable to an issue. Added 'see #2415' to the source-text-is-the-product annotation.
This commit is contained in:
5
.changeset/sturdy-wasps-run.md
Normal file
5
.changeset/sturdy-wasps-run.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 2447
|
||||
---
|
||||
**`close_phase_todos` no longer leaves moved todos as phantom unstaged deletions in `git status`** — the workflow step moved resolved todos from `.planning/todos/pending/` to `.planning/todos/completed/` with a plain `mv`, then committed by listing only the destination directory in `--files`. Git's index still tracked the moved file at its old `pending/` path, so the deletion was never staged and the moved-away file lingered as an unstaged deletion in `git status` until some later broad `git add -A` happened to catch it. The step's commit `--files` list now includes BOTH directories so `git add .planning/todos/pending/` stages the deletion atomically with the new `completed/` copy in the same commit. (#2415)
|
||||
@@ -1541,7 +1541,7 @@ for TODO_FILE in "$PENDING_DIR"/*.md; do
|
||||
done
|
||||
|
||||
if [ ${#CLOSED[@]} -gt 0 ]; then
|
||||
gsd_run query commit "docs(phase-${PHASE_NUMBER}): auto-close ${#CLOSED[@]} todo(s) resolved by this phase" --files .planning/todos/completed/ .planning/STATE.md|| true
|
||||
gsd_run query commit "docs(phase-${PHASE_NUMBER}): close ${#CLOSED[@]} resolved todo(s)" --files .planning/todos/completed/ .planning/todos/pending/ .planning/STATE.md|| true
|
||||
echo "◆ Closed ${#CLOSED[@]} todo(s) resolved by Phase ${PHASE_NUMBER}:"
|
||||
for f in "${CLOSED[@]}"; do echo " ✓ $f"; done
|
||||
fi
|
||||
|
||||
57
tests/close-phase-todos-stage-deletion.test.cjs
Normal file
57
tests/close-phase-todos-stage-deletion.test.cjs
Normal file
@@ -0,0 +1,57 @@
|
||||
// allow-test-rule: source-text-is-the-product see #2415
|
||||
// Workflow .md files — their text IS what the runtime loads. Testing text content
|
||||
// tests the deployed contract. Per CONTRIBUTING.md exception matrix.
|
||||
'use strict';
|
||||
|
||||
const { describe, test } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const EXECUTE_PHASE = path.join(__dirname, '..', 'gsd-core', 'workflows', 'execute-phase.md');
|
||||
|
||||
describe('#2415: close_phase_todos must stage the pending/ deletion alongside completed/', () => {
|
||||
test('the close_phase_todos commit --files list includes .planning/todos/pending/', () => {
|
||||
const content = fs.readFileSync(EXECUTE_PHASE, 'utf8');
|
||||
|
||||
// Isolate the close_phase_todos step body so we don't match unrelated --files lists
|
||||
// elsewhere in the workflow (other steps commit different paths for different reasons).
|
||||
const stepStart = content.indexOf('<step name="close_phase_todos">');
|
||||
assert.ok(stepStart > -1, 'close_phase_todos step must exist in execute-phase.md');
|
||||
const stepEnd = content.indexOf('</step>', stepStart);
|
||||
assert.ok(stepEnd > stepStart, 'close_phase_todos step must be properly closed');
|
||||
const stepBody = content.slice(stepStart, stepEnd);
|
||||
|
||||
// The commit must include BOTH the destination (completed/) AND the source (pending/)
|
||||
// — git add of pending/ stages the deletion of each moved file. Without pending/ in
|
||||
// the list, only the new completed/ copy gets committed and the moved-away file
|
||||
// persists as an unstaged deletion in git status until some later broad git add -A
|
||||
// happens to catch it (#2415).
|
||||
const gsdRunCommit = /gsd_run\s+query\s+commit\b[^\n]*--files\s+([^\n]+)/;
|
||||
const match = stepBody.match(gsdRunCommit);
|
||||
assert.ok(match, `close_phase_todos step must contain a gsd_run query commit ... --files invocation. Step body:\n${stepBody}`);
|
||||
const filesList = match[1];
|
||||
|
||||
assert.match(filesList, /\.planning\/todos\/completed/, 'commit --files must include .planning/todos/completed/ (destination of the move)');
|
||||
assert.match(filesList, /\.planning\/todos\/pending/, 'commit --files must include .planning/todos/pending/ so the moved-away file is staged as a deletion (#2415)');
|
||||
assert.match(filesList, /\.planning\/STATE\.md/, 'commit --files must still include .planning/STATE.md (the step also updates state)');
|
||||
});
|
||||
|
||||
test('close_phase_todos uses plain mv (not git mv) so untracked todos and non-git .planning dirs still work', () => {
|
||||
const content = fs.readFileSync(EXECUTE_PHASE, 'utf8');
|
||||
const stepStart = content.indexOf('<step name="close_phase_todos">');
|
||||
const stepEnd = content.indexOf('</step>', stepStart);
|
||||
const stepBody = content.slice(stepStart, stepEnd);
|
||||
|
||||
// Strip bash comments so a doc comment mentioning "git mv" (rationale) doesn't
|
||||
// trip the assertion. We care about the actual command, not the prose.
|
||||
const withoutComments = stepBody.replace(/^\s*#.*$/gm, '');
|
||||
|
||||
// git mv would stage the rename atomically, but it FAILS on untracked todos and on
|
||||
// non-git .planning dirs. Plain mv + the two-dir --files list (verified above) is
|
||||
// more robust and what the fix uses. Pin the choice so a future contributor doesn't
|
||||
// switch to git mv without revisiting the failure modes.
|
||||
assert.match(withoutComments, /\bmv\s+"\$TODO_FILE"\s+"\$COMPLETED_DIR\/"/, 'close_phase_todos must use plain shell mv to move the file');
|
||||
assert.doesNotMatch(withoutComments, /\bgit\s+mv\b/, 'close_phase_todos must NOT use git mv as the actual move command — it fails on untracked todos and on non-git .planning dirs');
|
||||
});
|
||||
});
|
||||
@@ -243,7 +243,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "8e986e26d0e6e1a0",
|
||||
"gsd-core/workflows/edit-phase.md": "fc932e82ba1f585a",
|
||||
"gsd-core/workflows/eval-review.md": "eb4040eaa5b8497f",
|
||||
"gsd-core/workflows/execute-phase.md": "21c3aa8c771fcdc7",
|
||||
"gsd-core/workflows/execute-phase.md": "2e9ca8842df9e543",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "55d0706e80a2554a",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "13aa54f8279960ae",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "f35922d15b7061c9",
|
||||
"gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04",
|
||||
"gsd-core/workflows/eval-review.md": "f898936e2cfe4130",
|
||||
"gsd-core/workflows/execute-phase.md": "09d5f9829424c68b",
|
||||
"gsd-core/workflows/execute-phase.md": "982d35b8ed16619d",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "4e265392b3f2ba0e",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -313,7 +313,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "cd753783ab95da00",
|
||||
"gsd-core/workflows/edit-phase.md": "dbbb6191f5a8b65e",
|
||||
"gsd-core/workflows/eval-review.md": "086a1f2b3c11462c",
|
||||
"gsd-core/workflows/execute-phase.md": "0086536412e218d3",
|
||||
"gsd-core/workflows/execute-phase.md": "66e4f92099ba3a7a",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "6d38bfd540030da4",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "a7f9b9a45303382f",
|
||||
|
||||
@@ -242,7 +242,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "63082608d3ae92be",
|
||||
"gsd-core/workflows/edit-phase.md": "8323bfe10faa0c0a",
|
||||
"gsd-core/workflows/eval-review.md": "f59e8329dae1e528",
|
||||
"gsd-core/workflows/execute-phase.md": "1c67162c7a87cdbc",
|
||||
"gsd-core/workflows/execute-phase.md": "7a7f63e7839f530d",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "facb0e816d87a0c7",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -246,7 +246,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "39f288623a8f6f32",
|
||||
"gsd-core/workflows/edit-phase.md": "9c9fadc047c61d74",
|
||||
"gsd-core/workflows/eval-review.md": "3e1d7829ed2ed494",
|
||||
"gsd-core/workflows/execute-phase.md": "6984700bf0a94ce7",
|
||||
"gsd-core/workflows/execute-phase.md": "5aa6d3220bb3c755",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "67ebc93f51968cb6",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "35612890c1173577",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "f35922d15b7061c9",
|
||||
"gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04",
|
||||
"gsd-core/workflows/eval-review.md": "f898936e2cfe4130",
|
||||
"gsd-core/workflows/execute-phase.md": "02bc29efd6441a58",
|
||||
"gsd-core/workflows/execute-phase.md": "77629722f47ec6c7",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "4e265392b3f2ba0e",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -349,7 +349,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "e255317df939e302",
|
||||
"gsd-core/workflows/edit-phase.md": "e592a4d85ce5380f",
|
||||
"gsd-core/workflows/eval-review.md": "63d0d0670b54c244",
|
||||
"gsd-core/workflows/execute-phase.md": "d7a6237dc2097828",
|
||||
"gsd-core/workflows/execute-phase.md": "4771222b9f9609d0",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "f4cacd27d37bac65",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -244,7 +244,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "9292cfa3c52c434e",
|
||||
"gsd-core/workflows/edit-phase.md": "8667c28b22b1599f",
|
||||
"gsd-core/workflows/eval-review.md": "81c8e72ba3862856",
|
||||
"gsd-core/workflows/execute-phase.md": "2ab0e3d8db52f54b",
|
||||
"gsd-core/workflows/execute-phase.md": "9ecbabf9c4e62e80",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "63b712920f21a40f",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "25bebed74e645109",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "e86d7d7e2e3dac6d",
|
||||
"gsd-core/workflows/edit-phase.md": "8323bfe10faa0c0a",
|
||||
"gsd-core/workflows/eval-review.md": "a86279dd98dd5c03",
|
||||
"gsd-core/workflows/execute-phase.md": "203a3e4afa6c0ba4",
|
||||
"gsd-core/workflows/execute-phase.md": "0b9c81c3085926e6",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "facb0e816d87a0c7",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "ba4cf926fc463cbe",
|
||||
"gsd-core/workflows/edit-phase.md": "7f27003f20e88fb8",
|
||||
"gsd-core/workflows/eval-review.md": "f510e5762212dc6f",
|
||||
"gsd-core/workflows/execute-phase.md": "3ab3465c0071f873",
|
||||
"gsd-core/workflows/execute-phase.md": "df3020f022405a84",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "14a27cc0828f59d3",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "26ee34c543926402",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "362123fdf99e9980",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "79afaaf19fd527cc",
|
||||
"gsd-core/workflows/edit-phase.md": "8323bfe10faa0c0a",
|
||||
"gsd-core/workflows/eval-review.md": "926eda8bbee28b23",
|
||||
"gsd-core/workflows/execute-phase.md": "37b8f39d1ef48997",
|
||||
"gsd-core/workflows/execute-phase.md": "ae91076f29981cc2",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "facb0e816d87a0c7",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "f35922d15b7061c9",
|
||||
"gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04",
|
||||
"gsd-core/workflows/eval-review.md": "f898936e2cfe4130",
|
||||
"gsd-core/workflows/execute-phase.md": "79094f7c09b76e5b",
|
||||
"gsd-core/workflows/execute-phase.md": "ae2c1d3f9518bee5",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "4e265392b3f2ba0e",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "850366c2ef8fb780",
|
||||
"gsd-core/workflows/edit-phase.md": "1876c855fb0a0a39",
|
||||
"gsd-core/workflows/eval-review.md": "5394694d29ad7543",
|
||||
"gsd-core/workflows/execute-phase.md": "a0de8c44d3234203",
|
||||
"gsd-core/workflows/execute-phase.md": "83e7df675b781f8f",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "1804215577f1ad35",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "c4cba01539f0368a",
|
||||
|
||||
2
tests/fixtures/golden-install-parity/pi.json
vendored
2
tests/fixtures/golden-install-parity/pi.json
vendored
@@ -210,7 +210,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "f35922d15b7061c9",
|
||||
"gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04",
|
||||
"gsd-core/workflows/eval-review.md": "f898936e2cfe4130",
|
||||
"gsd-core/workflows/execute-phase.md": "a0becf39cc735598",
|
||||
"gsd-core/workflows/execute-phase.md": "60d61e7d2332e889",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "4e265392b3f2ba0e",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "45d2f0d173c84e07",
|
||||
"gsd-core/workflows/edit-phase.md": "0fb5e0123cfc6f36",
|
||||
"gsd-core/workflows/eval-review.md": "6dee8a1e40ececd4",
|
||||
"gsd-core/workflows/execute-phase.md": "a771448bed59407a",
|
||||
"gsd-core/workflows/execute-phase.md": "c06b2630c14ebac3",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "36af8d91e4ae8b9c",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "0b04cc2dcab61107",
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "f13571f08e083356",
|
||||
"gsd-core/workflows/edit-phase.md": "7facd0faa33c8cad",
|
||||
"gsd-core/workflows/eval-review.md": "37d545d4f0db4927",
|
||||
"gsd-core/workflows/execute-phase.md": "364c2617ed78c71d",
|
||||
"gsd-core/workflows/execute-phase.md": "4a8b484097cae892",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "c985a30317a1aa6b",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7d30384e9bf82664",
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "70f73cc8c27e0ca0",
|
||||
"gsd-core/workflows/edit-phase.md": "c0ae7d0063f3e789",
|
||||
"gsd-core/workflows/eval-review.md": "b28be79ef29f16fd",
|
||||
"gsd-core/workflows/execute-phase.md": "8e349e33d7fa4b41",
|
||||
"gsd-core/workflows/execute-phase.md": "3989e6302807b826",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "47ae5482f8e64100",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "fb4497767cdf73a3",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"gsd-core/workflows/docs-update.md": "f35922d15b7061c9",
|
||||
"gsd-core/workflows/edit-phase.md": "966a3eadd1bebc04",
|
||||
"gsd-core/workflows/eval-review.md": "f898936e2cfe4130",
|
||||
"gsd-core/workflows/execute-phase.md": "945cab2f2b2d6fc7",
|
||||
"gsd-core/workflows/execute-phase.md": "e0f1d13f102364a8",
|
||||
"gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md": "4e265392b3f2ba0e",
|
||||
"gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md": "7ebb7d1af6082028",
|
||||
"gsd-core/workflows/execute-phase/steps/post-merge-gate.md": "7b2d9a4a4013fd6a",
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"docs-update.md": 55706,
|
||||
"edit-phase.md": 12927,
|
||||
"eval-review.md": 9967,
|
||||
"execute-phase.md": 93384,
|
||||
"execute-phase.md": 93390,
|
||||
"execute-plan.md": 34262,
|
||||
"explore.md": 10541,
|
||||
"extract-learnings.md": 12893,
|
||||
|
||||
Reference in New Issue
Block a user