Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .agents/pm/history/pm-k2n4.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{"ts":"2026-06-26T04:13:20.706Z","author":"claude-code-agent","op":"create","patch":[{"op":"add","path":"/metadata/id","value":"pm-k2n4"},{"op":"add","path":"/metadata/title","value":"pm validate --check-files mis-handles remote (URL) doc/file references: flagged as deleted and silently destroyed by --prune-missing"},{"op":"add","path":"/metadata/description","value":"A linked artifact `path` (pm files / pm docs) is normally a workspace-relative or absolute local filesystem path, but `pm docs --add` legitimately records REMOTE references too — most commonly an `https://` URL to a pull request, issue, or external design doc (e.g. pm-bhmk/pm-v37g/pm-qawd each link https://github.com/unbraind/pm-cli/pull/362|364). These remote references are not local files, yet three validation surfaces blindly `fs.stat` them:\n\n1. buildFilesCheck (src/cli/commands/validate.ts ~L1666): every project-scoped files+docs artifact is stat'd; a URL resolves to a bogus local path -> stat fails -> pushed to missing_linked_paths and staleLinkRows.\n2. classifyStaleLinkedPaths then labels it `deleted` (no basename candidate match).\n3. planStaleLinkPruneFixes (src/core/validate/fix-planning.ts) prunes every `deleted`-classified link -> `pm validate --prune-missing` SILENTLY DELETES the intentionally-recorded PR/URL doc reference. This is data loss of recorded context (project management = context management).\n4. validateLinkedPaths (src/cli/commands/linked-artifacts.ts ~L402) used by `pm files/docs --validate-paths` reports the URL as a missing_path for the same reason.\n\nImpact: false-positive validator noise (URL refs counted among the 148 missing_linked_paths seen on this repo, inflating pm-j8z6's reconciliation backlog) AND a latent destructive-fix bug. Follow-up to pm-0v2m (GH-184) which introduced moved/deleted classification + --prune-missing without remote-reference awareness."},{"op":"add","path":"/metadata/type","value":"Issue"},{"op":"add","path":"/metadata/status","value":"open"},{"op":"add","path":"/metadata/priority","value":1},{"op":"add","path":"/metadata/tags","value":["agent-ux","area:cli","context-management","data-safety","linked-files"]},{"op":"add","path":"/metadata/created_at","value":"2026-06-26T04:13:20.706Z"},{"op":"add","path":"/metadata/updated_at","value":"2026-06-26T04:13:20.706Z"},{"op":"add","path":"/metadata/author","value":"claude-code-agent"},{"op":"add","path":"/metadata/parent","value":"pm-mpbb"},{"op":"add","path":"/metadata/risk","value":"low"},{"op":"add","path":"/metadata/confidence","value":"high"}],"before_hash":"3cc22dff72be7b14824654a7a64ea62b04799939b2fee54c1b5f52ca60bf6df0","after_hash":"aa1f6c5fc9566e05c7961dd61741fe5350d7f88e7af5701d82b761e374439c96","message":""}
{"ts":"2026-06-26T04:13:59.848Z","author":"claude-code-agent","op":"update","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-06-26T04:13:59.848Z"},{"op":"add","path":"/metadata/dependencies","value":[{"id":"pm-0v2m","kind":"related","created_at":"2026-06-26T04:13:59.840Z"},{"id":"pm-j8z6","kind":"related","created_at":"2026-06-26T04:13:59.840Z"},{"id":"pm-o2kc","kind":"related","created_at":"2026-06-26T04:13:59.840Z"}]}],"before_hash":"aa1f6c5fc9566e05c7961dd61741fe5350d7f88e7af5701d82b761e374439c96","after_hash":"b66acd8b2ace83eb2109567febf793d2ea5ab4282b2b3bc4f5fd3b5a2e49a03b","message":"Link bug to GH-184 prune feature (pm-0v2m), the linked-file reconciliation chore it de-noises (pm-j8z6), and the data-durability epic (pm-o2kc)"}
{"ts":"2026-06-26T04:20:15.950Z","author":"claude-code-agent","op":"append","patch":[{"op":"replace","path":"/body","value":"## Implementation (branch fix/validate-remote-reference-awareness)\n\nNew pure module `src/core/validate/linked-artifact-reference.ts` exposing `isRemoteLinkedArtifactReference(path)` — matches `^[a-z][a-z0-9+.-]+:\\/\\//i` (scheme of 2+ chars + `://` authority) so `https://`/`ftp://`/`ssh://`/`file://` are remote while `C:/…`, `C:\\…`, `//server/share`, relative and absolute POSIX paths are local.\n\nWired into both stat-based surfaces:\n- `buildFilesCheck` (src/cli/commands/validate.ts): remote refs are collected into a new benign `remote_linked_paths{,_count,_total,_truncated}` details category and `continue` before the existence probe — so they never enter `missing_linked_paths`, `staleLinkRows`, classification, or `staleLinkPruneRows`.\n- `validateLinkedPaths` (src/cli/commands/linked-artifacts.ts): remote refs go to a new `remote_references[]` field instead of `missing_paths` (surfaced by `pm files/docs --validate-paths`).\n\n## Verification\n\nManual temp-dir smoke (real built CLI, `pm init` + Task with a real file, a missing local file, and a PR URL doc ref):\n- `validate --check-files`: `remote_linked_paths_count=1` (the PR URL), `missing_linked_paths=['ghost-file.ts']` only — URL not flagged.\n- `validate --prune-missing --dry-run`: single planned fix `pm files <id> --remove \"ghost-file.ts\"` — the URL doc ref is NEVER targeted (data-loss bug fixed).\n- `pm docs --validate-paths`: `remote_references=['https://…/pull/362']`, `missing_paths=[]`.\n\nGates: `pnpm typecheck` clean; targeted suites 122/122 pass; `contracts:check` current; `quality:static` (incl. docstring coverage) passes. Full 100% coverage gate running."},{"op":"replace","path":"/metadata/updated_at","value":"2026-06-26T04:20:15.950Z"}],"before_hash":"b66acd8b2ace83eb2109567febf793d2ea5ab4282b2b3bc4f5fd3b5a2e49a03b","after_hash":"d908f8eae4b67712ad7bbbe514add2f72b60211305de2b7c73332eff2d3cb917"}
{"ts":"2026-06-26T04:20:21.106Z","author":"claude-code-agent","op":"files_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-06-26T04:20:21.106Z"},{"op":"add","path":"/metadata/files","value":[{"path":"src/core/validate/linked-artifact-reference.ts","scope":"project","note":"remote-reference detection helper"},{"path":"tests/unit/validate/linked-artifact-reference.spec.ts","scope":"project","note":"helper unit tests"}]}],"before_hash":"d908f8eae4b67712ad7bbbe514add2f72b60211305de2b7c73332eff2d3cb917","after_hash":"8f6d767583a7e05299e9bdcee557789f07bfe407771f8645888b5833100e757a","message":"Link new source/test artifacts for remote-reference awareness"}
{"ts":"2026-06-26T04:24:45.702Z","author":"claude-code-agent","op":"docs_add","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-06-26T04:24:45.702Z"},{"op":"add","path":"/metadata/docs","value":[{"path":"https://github.com/unbraind/pm-cli/pull/372","scope":"project","note":"PR: remote-reference awareness fix"}]}],"before_hash":"8f6d767583a7e05299e9bdcee557789f07bfe407771f8645888b5833100e757a","after_hash":"7b12efbb52f344242efcf36780fb03c3d506d63c9cabbf2bca37e02858cc0459","message":"Record PR #372 (remote doc-ref, exercises the fix)"}
{"ts":"2026-06-26T04:37:40.853Z","author":"claude-code-agent","op":"update","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-06-26T04:37:40.853Z"},{"op":"add","path":"/metadata/resolution","value":"Added pure helper isRemoteLinkedArtifactReference (scheme:// detection, 2+ char scheme so Windows drive/UNC paths stay local) and wired it into buildFilesCheck (validate.ts) and validateLinkedPaths (linked-artifacts.ts): remote (URL) refs are now surfaced in benign remote_linked_paths / remote_references categories and are never stat'd, classified moved/deleted, counted missing, or planned for --prune-missing. Shipped in PR #372."},{"op":"add","path":"/metadata/expected_result","value":"A recorded https:// doc reference (e.g. a PR URL) stays a benign tracked reference; pm validate --check-files does not report it as missing/deleted and pm validate --prune-missing never deletes it."},{"op":"add","path":"/metadata/actual_result","value":"Before the fix the URL fs.stat-failed, was classified 'deleted', and was planned for deletion by --prune-missing (silent data loss); after the fix it appears under remote_linked_paths and is never pruned (verified by temp-dir smoke + unit tests)."}],"before_hash":"7b12efbb52f344242efcf36780fb03c3d506d63c9cabbf2bca37e02858cc0459","after_hash":"199dcf87c18950236c05adc9be4d61ffca9939a5161f2fd110db7d8981a63c2c","message":"Record resolution evidence before close (PR #372)"}
{"ts":"2026-06-26T04:37:46.946Z","author":"claude-code-agent","op":"close","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-06-26T04:37:46.946Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/close_reason","value":"Fixed in PR #372: remote (URL) doc/file references are now recognized and excluded from local-file existence checks, missing/stale classification, and --prune-missing. Verified by 5131-test 100% coverage suite, contracts/static/changelog gates, and a temp-dir end-to-end smoke. CI green across the full matrix; CodeRabbit review clean (1 nitpick addressed); Gemini at daily quota / Codex not connected this cycle."}],"before_hash":"199dcf87c18950236c05adc9be4d61ffca9939a5161f2fd110db7d8981a63c2c","after_hash":"3d8440489844821303a05982caf8b20d8a7b799ca6715fac50c02859c905f526"}
1 change: 1 addition & 0 deletions .agents/pm/history/pm-z5nb.jsonl
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
{"ts":"2026-06-06T20:08:08.275Z","author":"codex-zw0n","op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/4","value":{"created_at":"2026-06-06T20:08:08.275Z","author":"codex-zw0n","text":"Reconciliation note during pm-zw0n cycle: pm-z5nb remains intentionally open as a coordination container (already merged work evidence in history/comments) and should stay open unless maintainers want this plan-type tracker item closed; no outstanding schema-customization implementation debt discovered in this cycle."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-06-06T20:08:08.275Z"}],"before_hash":"96a6b9769e88e8e8d22c8eb81bbb007365aded3b20189df9d0229b786e95ca63","after_hash":"b78d139223c377111ac4f405f8b5616df870890a7cd768634cde484091ec3c2a"}
{"ts":"2026-06-07T10:27:39.050Z","author":"maintainer-agent","op":"close","patch":[{"op":"replace","path":"/metadata/updated_at","value":"2026-06-07T10:27:39.050Z"},{"op":"replace","path":"/metadata/status","value":"closed"},{"op":"add","path":"/metadata/close_reason","value":"Schema-customization completion plan fully delivered (remove-type pm-k8ik, add-status pm-e77a, per-type workflows pm-f4r1, create_default_type pm-jpwo all closed via PR #106). Closing stale-open done plan; forward schema work continues under pm-8jdc."}],"before_hash":"b78d139223c377111ac4f405f8b5616df870890a7cd768634cde484091ec3c2a","after_hash":"646b8ce916ae66723608617cf524cc32c184a1d1b6acb0641c693241f8b1ae02"}
{"ts":"2026-06-07T10:38:07.011Z","author":"maintainer-agent","op":"update","patch":[{"op":"remove","path":"/metadata/close_reason"},{"op":"replace","path":"/metadata/updated_at","value":"2026-06-07T10:38:07.011Z"},{"op":"replace","path":"/metadata/status","value":"open"}],"before_hash":"646b8ce916ae66723608617cf524cc32c184a1d1b6acb0641c693241f8b1ae02","after_hash":"c4aabc78f4965edc1b809eef3fa931c3e7eec2783ce37b26e701b0af709d1edc","message":"Revert prior close: keep open to avoid changelog classifier mis-routing the plan title ('remove-type' substring) into the Removed section; stale-done-plan cleanup is out of scope for this backlog-rebuild PR."}
{"ts":"2026-06-26T04:22:12.908Z","author":"claude-code-agent","op":"comment_add","patch":[{"op":"add","path":"/metadata/comments/5","value":{"created_at":"2026-06-26T04:22:12.908Z","author":"claude-code-agent","text":"Status audit 2026-06-26 (claude-code-agent): every sub-item of this completion Plan is now closed/shipped — pm-k8ik (remove-type), pm-e77a (add-status), pm-f4r1 (per-type workflows), pm-jpwo (config create_default_type), pm-mt7k (schema list/show), pm-vhd9 (init --type-preset). The parent epic pm-8jdc is at 22/24 closed. This Plan is functionally complete and is a candidate for a dedicated governance-close pass (kept open here to avoid mixing a release-changelog regeneration trigger into an unrelated code PR, per pm-j8z6's bundling guidance)."}},{"op":"replace","path":"/metadata/updated_at","value":"2026-06-26T04:22:12.908Z"}],"before_hash":"c4aabc78f4965edc1b809eef3fa931c3e7eec2783ce37b26e701b0af709d1edc","after_hash":"3c7c74f919c6d1bc8ba10a0f944ca3efbb3fe26689ce67c148ab316a2e614ec7"}
27 changes: 27 additions & 0 deletions .agents/pm/issues/pm-k2n4.toon
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
id: pm-k2n4
title: "pm validate --check-files mis-handles remote (URL) doc/file references: flagged as deleted and silently destroyed by --prune-missing"
description: "A linked artifact `path` (pm files / pm docs) is normally a workspace-relative or absolute local filesystem path, but `pm docs --add` legitimately records REMOTE references too — most commonly an `https://` URL to a pull request, issue, or external design doc (e.g. pm-bhmk/pm-v37g/pm-qawd each link https://github.com/unbraind/pm-cli/pull/362|364). These remote references are not local files, yet three validation surfaces blindly `fs.stat` them:\n\n1. buildFilesCheck (src/cli/commands/validate.ts ~L1666): every project-scoped files+docs artifact is stat'd; a URL resolves to a bogus local path -> stat fails -> pushed to missing_linked_paths and staleLinkRows.\n2. classifyStaleLinkedPaths then labels it `deleted` (no basename candidate match).\n3. planStaleLinkPruneFixes (src/core/validate/fix-planning.ts) prunes every `deleted`-classified link -> `pm validate --prune-missing` SILENTLY DELETES the intentionally-recorded PR/URL doc reference. This is data loss of recorded context (project management = context management).\n4. validateLinkedPaths (src/cli/commands/linked-artifacts.ts ~L402) used by `pm files/docs --validate-paths` reports the URL as a missing_path for the same reason.\n\nImpact: false-positive validator noise (URL refs counted among the 148 missing_linked_paths seen on this repo, inflating pm-j8z6's reconciliation backlog) AND a latent destructive-fix bug. Follow-up to pm-0v2m (GH-184) which introduced moved/deleted classification + --prune-missing without remote-reference awareness."
type: Issue
status: closed
priority: 1
tags[5]: agent-ux,"area:cli",context-management,data-safety,linked-files
created_at: "2026-06-26T04:13:20.706Z"
updated_at: "2026-06-26T04:37:46.946Z"
author: claude-code-agent
parent: pm-mpbb
risk: low
confidence: high
resolution: "Added pure helper isRemoteLinkedArtifactReference (scheme:// detection, 2+ char scheme so Windows drive/UNC paths stay local) and wired it into buildFilesCheck (validate.ts) and validateLinkedPaths (linked-artifacts.ts): remote (URL) refs are now surfaced in benign remote_linked_paths / remote_references categories and are never stat'd, classified moved/deleted, counted missing, or planned for --prune-missing. Shipped in PR #372."
expected_result: "A recorded https:// doc reference (e.g. a PR URL) stays a benign tracked reference; pm validate --check-files does not report it as missing/deleted and pm validate --prune-missing never deletes it."
actual_result: "Before the fix the URL fs.stat-failed, was classified 'deleted', and was planned for deletion by --prune-missing (silent data loss); after the fix it appears under remote_linked_paths and is never pruned (verified by temp-dir smoke + unit tests)."
dependencies[3]{id,kind,created_at,author,source_kind}:
pm-0v2m,related,"2026-06-26T04:13:59.840Z",null,null
pm-j8z6,related,"2026-06-26T04:13:59.840Z",null,null
pm-o2kc,related,"2026-06-26T04:13:59.840Z",null,null
files[2]{path,scope,note}:
src/core/validate/linked-artifact-reference.ts,project,remote-reference detection helper
tests/unit/validate/linked-artifact-reference.spec.ts,project,helper unit tests
docs[1]{path,scope,note}:
"https://github.com/unbraind/pm-cli/pull/372",project,"PR: remote-reference awareness fix"
close_reason: "Fixed in PR #372: remote (URL) doc/file references are now recognized and excluded from local-file existence checks, missing/stale classification, and --prune-missing. Verified by 5131-test 100% coverage suite, contracts/static/changelog gates, and a temp-dir end-to-end smoke. CI green across the full matrix; CodeRabbit review clean (1 nitpick addressed); Gemini at daily quota / Codex not connected this cycle."
body: "## Implementation (branch fix/validate-remote-reference-awareness)\n\nNew pure module `src/core/validate/linked-artifact-reference.ts` exposing `isRemoteLinkedArtifactReference(path)` — matches `^[a-z][a-z0-9+.-]+:\\/\\//i` (scheme of 2+ chars + `://` authority) so `https://`/`ftp://`/`ssh://`/`file://` are remote while `C:/…`, `C:\\…`, `//server/share`, relative and absolute POSIX paths are local.\n\nWired into both stat-based surfaces:\n- `buildFilesCheck` (src/cli/commands/validate.ts): remote refs are collected into a new benign `remote_linked_paths{,_count,_total,_truncated}` details category and `continue` before the existence probe — so they never enter `missing_linked_paths`, `staleLinkRows`, classification, or `staleLinkPruneRows`.\n- `validateLinkedPaths` (src/cli/commands/linked-artifacts.ts): remote refs go to a new `remote_references[]` field instead of `missing_paths` (surfaced by `pm files/docs --validate-paths`).\n\n## Verification\n\nManual temp-dir smoke (real built CLI, `pm init` + Task with a real file, a missing local file, and a PR URL doc ref):\n- `validate --check-files`: `remote_linked_paths_count=1` (the PR URL), `missing_linked_paths=['ghost-file.ts']` only — URL not flagged.\n- `validate --prune-missing --dry-run`: single planned fix `pm files <id> --remove \"ghost-file.ts\"` — the URL doc ref is NEVER targeted (data-loss bug fixed).\n- `pm docs --validate-paths`: `remote_references=['https://…/pull/362']`, `missing_paths=[]`.\n\nGates: `pnpm typecheck` clean; targeted suites 122/122 pass; `contracts:check` current; `quality:static` (incl. docstring coverage) passes. Full 100% coverage gate running."
Loading
Loading