@plainconceptsplatform/agent-harness 2.4.1 → 2.5.1

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.
Files changed (81) hide show
  1. package/README.md +435 -437
  2. package/cli/fragments/archive/az.md +97 -95
  3. package/cli/fragments/archive/gh.md +96 -94
  4. package/cli/fragments/archive/gl.md +96 -94
  5. package/cli/fragments/archive/none.md +75 -73
  6. package/cli/fragments/guardrails/codegraph.md +5 -7
  7. package/cli/fragments/guardrails/humanizer.md +4 -4
  8. package/cli/fragments/guardrails/memory.md +4 -4
  9. package/cli/fragments/guardrails/rtk.md +3 -3
  10. package/cli/fragments/guardrails/simple-english.md +4 -4
  11. package/cli/fragments/ops-backlog/az.md +1 -1
  12. package/cli/fragments/ops-backlog/gh.md +1 -1
  13. package/cli/fragments/ops-backlog/jira.md +1 -1
  14. package/cli/fragments/ops-evidence/az.md +44 -41
  15. package/cli/fragments/ops-evidence/gh.md +54 -53
  16. package/cli/fragments/ops-evidence/jira.md +42 -38
  17. package/cli/fragments/ops-review/az.md +1 -1
  18. package/cli/fragments/ops-review/gh.md +1 -1
  19. package/cli/fragments/ops-review/gl.md +1 -1
  20. package/cli/fragments/ops-ship/az.md +81 -80
  21. package/cli/fragments/ops-ship/gh.md +68 -68
  22. package/cli/fragments/ops-ship/gl.md +85 -85
  23. package/cli/presets/agents-content.json +34 -53
  24. package/cli/steps/copy/agents.js +18 -17
  25. package/cli/steps/copy/opencode-json.js +5 -1
  26. package/cli/steps/copy/skills.js +98 -5
  27. package/cli/steps/optimization/patch-guardrails.js +5 -3
  28. package/cli/utils/copy.js +27 -3
  29. package/cli/utils/update-manifest.js +28 -2
  30. package/harness/.agents/skills/pc-guardrails-generic/SKILL.md +47 -68
  31. package/harness/.agents/skills/pc-make-architecture/SKILL.md +31 -51
  32. package/harness/.agents/skills/pc-make-design/SKILL.md +45 -68
  33. package/harness/.agents/skills/pc-make-engineer/SKILL.md +59 -219
  34. package/harness/.agents/skills/pc-make-engineer/signal-mapping.md +53 -68
  35. package/harness/.agents/skills/pc-make-engineer/template.md +42 -80
  36. package/harness/.agents/skills/pc-make-evidence-scaffold/SKILL.md +18 -18
  37. package/harness/.agents/skills/pc-make-evidence-scaffold/evidence-contract.md +29 -29
  38. package/harness/.agents/skills/pc-make-guardrails/SKILL.md +43 -74
  39. package/harness/.agents/skills/pc-make-guardrails/category-reference.md +10 -5
  40. package/harness/.agents/skills/pc-make-merge-risk-assess/category-reference.md +26 -7
  41. package/harness/.agents/skills/pc-make-user-model/SKILL.md +56 -66
  42. package/harness/.agents/skills/pc-ops-evidence/SKILL.md +133 -127
  43. package/harness/.agents/skills/pc-plan-apply/SKILL.md +14 -5
  44. package/harness/.agents/skills/pc-plan-apply/simple-mode.md +21 -21
  45. package/harness/.agents/skills/pc-plan-archive/SKILL.md +66 -66
  46. package/harness/.agents/skills/pc-plan-explore/SKILL.md +19 -2
  47. package/harness/.agents/skills/pc-plan-goal/SKILL.md +7 -5
  48. package/harness/.agents/skills/pc-plan-goal/output-mode.md +1 -0
  49. package/harness/.agents/skills/pc-plan-goal/output.md +71 -65
  50. package/harness/.agents/skills/pc-plan-propose/SKILL.md +1 -1
  51. package/harness/.agents/skills/pc-plan-quick/SKILL.md +46 -62
  52. package/harness/.agents/skills/pc-plan-story/SKILL.md +48 -149
  53. package/harness/.agents/skills/pc-repo-help/SKILL.md +89 -91
  54. package/harness/.agents/skills/pc-repo-initialize/SKILL.md +112 -130
  55. package/harness/.agents/skills/pc-repo-onboard/SKILL.md +32 -87
  56. package/harness/.agents/skills/pc-repo-verify/SKILL.md +2 -0
  57. package/harness/.agents/skills/pc-userstory-az/SKILL.md +71 -157
  58. package/harness/.agents/skills/pc-userstory-browser/SKILL.md +50 -122
  59. package/harness/.agents/skills/pc-userstory-gh/SKILL.md +63 -120
  60. package/harness/.agents/skills/pc-userstory-jira/SKILL.md +74 -131
  61. package/harness/.opencode/commands/init.md +5 -5
  62. package/harness/.opencode/commands/make-architecture.md +5 -5
  63. package/harness/.opencode/commands/make-design.md +5 -5
  64. package/harness/.opencode/commands/make-engineer.md +5 -5
  65. package/harness/.opencode/commands/make-evidence-scaffold.md +5 -5
  66. package/harness/.opencode/commands/make-guardrails.md +5 -5
  67. package/harness/.opencode/commands/make-user-model.md +5 -5
  68. package/harness/.opencode/commands/plan-apply.md +9 -9
  69. package/harness/.opencode/commands/plan-goal.md +5 -5
  70. package/harness/.opencode/commands/plan-quick.md +5 -5
  71. package/harness/.opencode/commands/plan-story.md +9 -9
  72. package/harness/.opencode/commands/repo-audit.md +5 -5
  73. package/harness/.opencode/commands/repo-initialize.md +5 -5
  74. package/harness/.opencode/commands/repo-onboard.md +5 -5
  75. package/harness/.opencode/commands/repo-verify.md +5 -5
  76. package/harness/.opencode/plugins/pc-subagent-monitor.js +82 -2
  77. package/harness/.opencode/plugins/pc-subagent-tiers.js +9 -6
  78. package/harness/.opencode/plugins/pc-system-reminders.js +329 -3
  79. package/harness/AGENTS.md +49 -71
  80. package/harness/opencode.jsonc +1 -1
  81. package/package.json +1 -1
@@ -1,73 +1,75 @@
1
- 2. **Find the oldest unarchived change**
2
-
3
- List unarchived changes (top-level only, excludes `archive/`):
4
-
5
- ```bash
6
- find "$REPO_ROOT/openspec/changes" -mindepth 1 -maxdepth 1 -type d -not -name 'archive' | sort
7
- ```
8
-
9
- If empty, report a blocker and stop. Otherwise select the **oldest** change (by directory creation/sort order) as the candidate.
10
-
11
- This mode has no platform PR integration, so completion is judged from local state only. Do not look up remote PRs or work items.
12
-
13
- 3. **Confirm the candidate**
14
-
15
- Show the candidate (ID, title) and any other unarchived changes, then ask:
16
-
17
- ```text
18
- Oldest unarchived change found:
19
- ID: {change-id}
20
- Title: {title from proposal.md}
21
-
22
- Proceed with archiving? [yes/no]
23
- ```
24
-
25
- Stop if the user does not confirm.
26
-
27
- 4. **Archive the change**
28
-
29
- ```bash
30
- git checkout -b archive/{change-id}
31
- ```
32
-
33
- Load `@openspec-archive-change` skill and follow it to archive the change.
34
-
35
- 5. **Update docs**
36
-
37
- Compare the archived change's specs against `ARCHITECTURE.md` and `DESIGN.md`. If updates are needed, show them and get user approval before applying.
38
-
39
- 6. **Commit the archive**
40
-
41
- ```bash
42
- git add -A
43
- git commit -m "archive: {title} ({change-id})"
44
- ```
45
-
46
- No PR is created in this mode. Leave the `archive/{change-id}` branch for the user to merge or push manually if they choose.
47
-
48
- If work was stashed in step 1, restore it after the commit unless the user opts out.
49
-
50
- 7. **Report**
51
-
52
- Display:
53
-
54
- ```text
55
- Archive complete
56
-
57
- Change ID: {change-id}
58
- Title: {title}
59
- Archive branch: archive/{change-id}
60
-
61
- Documentation updates:
62
- - ARCHITECTURE.md: {count} changes applied
63
- - DESIGN.md: {count} changes applied
64
- ```
65
-
66
- ## Rules
67
-
68
- - All OpenSpec paths resolve from `git rev-parse --show-toplevel`. Never use `/openspec/...`.
69
- - Only process top-level directories in `$REPO_ROOT/openspec/changes/`; exclude `archive/`.
70
- - Use change ID and slug only as search hints; do not assume the source branch name.
71
- - The oldest unarchived change is the only candidate: never ask the user which change to archive.
72
- - This mode has no GitHub or Azure DevOps integration. Never call `gh` or `az`, and never use browser tools or direct web requests for PR/work-item lookups.
73
- - Never invent or guess PR, branch, or merge metadata.
1
+ 2. **Find the oldest unarchived change**
2
+
3
+ List unarchived changes (top-level only, excludes `archive/`):
4
+
5
+ ```bash
6
+ find "$REPO_ROOT/openspec/changes" -mindepth 1 -maxdepth 1 -type d -not -name 'archive' | sort
7
+ ```
8
+
9
+ If empty, report a blocker and stop. Otherwise select the **oldest** change (by directory creation/sort order) as the candidate.
10
+
11
+ This mode has no platform PR integration, so completion is judged from local state only. Do not look up remote PRs or work items.
12
+
13
+ 3. **Confirm the candidate**
14
+
15
+ Show the candidate (ID, title) and any other unarchived changes, then ask:
16
+
17
+ ```text
18
+ Oldest unarchived change found:
19
+ ID: {change-id}
20
+ Title: {title from proposal.md}
21
+
22
+ Proceed with archiving? [yes/no]
23
+ ```
24
+
25
+ Stop if the user does not confirm.
26
+
27
+ 4. **Archive the change**
28
+
29
+ ```bash
30
+ git checkout -b archive/{change-id}
31
+ ```
32
+
33
+ Load `@openspec-archive-change` skill and follow it to archive the change.
34
+
35
+ 5. **Update docs**
36
+
37
+ Compare the archived change's specs against `ARCHITECTURE.md` and `DESIGN.md`. If updates are needed, show them and get user approval before applying.
38
+
39
+ 6. **Commit the archive**
40
+
41
+ ```bash
42
+ # Stage specific paths only: a shared tree may hold another agent's or a
43
+ # person's edits, and -A commits them under this message.
44
+ git add openspec/changes/ # plus ARCHITECTURE.md / DESIGN.md if step 5 updated them
45
+ git commit -m "archive: {title} ({change-id})"
46
+ ```
47
+
48
+ No PR is created in this mode. Leave the `archive/{change-id}` branch for the user to merge or push manually if they choose.
49
+
50
+ If work was stashed in step 1, restore it after the commit unless the user opts out.
51
+
52
+ 7. **Report**
53
+
54
+ Display:
55
+
56
+ ```text
57
+ Archive complete
58
+
59
+ Change ID: {change-id}
60
+ Title: {title}
61
+ Archive branch: archive/{change-id}
62
+
63
+ Documentation updates:
64
+ - ARCHITECTURE.md: {count} changes applied
65
+ - DESIGN.md: {count} changes applied
66
+ ```
67
+
68
+ ## Rules
69
+
70
+ - All OpenSpec paths resolve from `git rev-parse --show-toplevel`. Never use `/openspec/...`.
71
+ - Only process top-level directories in `$REPO_ROOT/openspec/changes/`; exclude `archive/`.
72
+ - Use change ID and slug only as search hints; do not assume the source branch name.
73
+ - The oldest unarchived change is the only candidate: never ask the user which change to archive.
74
+ - This mode has no GitHub or Azure DevOps integration. Never call `gh` or `az`, and never use browser tools or direct web requests for PR/work-item lookups.
75
+ - Never invent or guess PR, branch, or merge metadata.
@@ -1,7 +1,5 @@
1
- ## CodeGraph
2
-
3
- - **Use `codegraph_explore` INSTEAD OF grep, glob, or read.** It is always available. Do not assume it might be missing.
4
- - One call returns the relevant symbols' verbatim, line-numbered source plus the call paths between them, use it as a full replacement for Read, Grep, and file-reading sub-tasks when working with indexed code.
5
- - If you instinctively reach for grep or read to find or understand code, STOP: call `codegraph_explore` instead with the symbol name, file path, or a natural-language question. It covers the same ground in one call instead of a dozen.
6
- - **Fall back to grep/glob/read ONLY when `codegraph_explore` returns no results** or the query is for something codegraph does not index (config files, plain-text docs, `.env` patterns, raw string searches). When you do fall back, you MUST state that codegraph returned nothing.
7
- - Do NOT run `codegraph` in bash: it is an MCP server, not a CLI tool.
1
+ ## CodeGraph
2
+
3
+ - `codegraph_explore` replaces grep, glob and read for anything indexed: one call returns the relevant symbols' verbatim, line-numbered source plus the call paths between them, where finding the same thing by hand takes a dozen. Give it a symbol name, a file path, or a plain question.
4
+ - Fall back to grep, glob and read when it returns nothing, or for what it does not index: config files, plain-text docs, `.env` patterns, raw string searches. Say that it returned nothing when you do.
5
+ - It is an MCP server, not a CLI. Never run `codegraph` in bash.
@@ -1,4 +1,4 @@
1
- ## Humanizer (optimization skill — MANDATORY LOAD)
2
-
3
- - **You MUST call `skill("humanizer")` via the skill tool before writing any prose** (commit messages, PR descriptions, docs, proposals) to remove AI writing patterns and sound more natural.
4
- - Do NOT apply humanizer to code, config files, or terminal output: only to prose.
1
+ ## Humanizer (optimization skill)
2
+
3
+ - Load `skill("humanizer")` before writing prose (commit messages, PR descriptions, docs, proposals); unhumanized prose reads as machine-written. Editing, shell and spawning stay blocked until it is loaded (pc-system-reminders).
4
+ - Never apply it to code, config files, or terminal output: prose only.
@@ -1,4 +1,4 @@
1
- ## Agentmemory
2
-
3
- - Use agentmemory MCP tools (`memory_smart_search`, `memory_save`, `memory_sessions`, `memory_governance_delete`) for cross-session context: `memory_smart_search` for prior decisions before implementing unfamiliar areas, `memory_save` for architecture decisions and cross-agent context.
4
- - Do NOT run `agentmemory` in bash: it is an MCP server. Start the server with `agentmemory` in a separate terminal, then use MCP tools.
1
+ ## Agentmemory
2
+
3
+ - Cross-session context lives in the agentmemory MCP tools: `memory_smart_search` for prior decisions before working somewhere unfamiliar, `memory_save` for architecture decisions and anything the next agent will need, plus `memory_sessions` and `memory_governance_delete`.
4
+ - It is an MCP server, not a CLI. Never run `agentmemory` in bash; start it with `agentmemory` in a separate terminal and use the tools.
@@ -1,3 +1,3 @@
1
- ## RTK
2
-
3
- - Prefix ALL CLI commands with `rtk` (e.g. `rtk git diff`, `rtk pnpm test`). Read-only commands like `cat`, `ls`, `Get-Content` are exempt.
1
+ ## RTK
2
+
3
+ - Prefix CLI commands with `rtk` (`rtk git diff`, `rtk pnpm test`); it strips the output down to what matters. Read-only commands like `cat`, `ls` and `Get-Content` are exempt.
@@ -1,4 +1,4 @@
1
- ## Simple English (optimization skill - MANDATORY LOAD)
2
-
3
- - **You MUST call `skill("simple-english")` via the skill tool before responding.** This is not optional. Apply Simplified Technical English to all prose responses.
4
- - Keep code blocks, identifiers, CLI commands, file paths, quoted errors, and product names exact.
1
+ ## Simple English (optimization skill)
2
+
3
+ - Apply Simplified Technical English to all prose: `skill("simple-english")`. Editing, shell and spawning stay blocked until it is loaded (pc-system-reminders).
4
+ - Keep code blocks, identifiers, CLI commands, file paths, quoted errors, and product names exact.
@@ -1,4 +1,4 @@
1
- **Browser MCP tools are FORBIDDEN for all Azure DevOps operations.**
1
+ Azure DevOps data comes from the `az` CLI; a page fetch of dev.azure.com is denied (pc-system-reminders). If `az` is unavailable, report it as a blocker.
2
2
 
3
3
  ---
4
4
 
@@ -1,4 +1,4 @@
1
- **ALL GitHub data MUST come from `gh` CLI. NEVER use webfetch, HTTP requests, or browser MCP tools for GitHub operations, even if gh CLI fails. If `gh` is unavailable, report as a blocker.**
1
+ GitHub data comes from the `gh` CLI; a page fetch of github.com is denied (pc-system-reminders). If `gh` is unavailable, report it as a blocker.
2
2
  Always pass `--repo {owner}/{repo}` explicitly, never rely on git context to resolve the repo.
3
3
 
4
4
  ---
@@ -1,4 +1,4 @@
1
- **NEVER use browser tools to navigate to atlassian.net: use `acli` CLI only.**
1
+ Jira data comes from the `acli` CLI; a page fetch of atlassian.net is denied (pc-system-reminders). If `acli` is unavailable, report it as a blocker.
2
2
 
3
3
  ---
4
4
 
@@ -1,41 +1,44 @@
1
- **Browser MCP tools are FORBIDDEN for all Azure DevOps operations. Use `az boards` CLI only. If `az` is unavailable, skip publishing (report it) — do not fail the pipeline unless the caller declared publishing a ship gate.**
2
-
3
- Publish one status comment for every manifest. A `blocked` or `failed` manifest must include its status and reason, never a success claim.
4
-
5
- ### Step 1 — Image hosting caveat
6
-
7
- Azure DevOps discussion comments do not render an image from a repo blob URL the way GitHub does, and `az boards` cannot upload an attachment inline. Use text evidence and derive a commit-pinned repository URL from `git remote get-url origin` when possible. Otherwise include the committed asset path, branch, and SHA.
8
-
9
- ```
10
- Screenshot committed at: {asset-path} (branch {branch}, commit {sha})
11
- ```
12
-
13
- ### Step 2 — Build the comment with a stable marker (idempotent)
14
-
15
- ```
16
- <!-- pc-visual-evidence:{change-id} -->
17
-
18
- Status: `{status}`
19
-
20
- {reason?}
21
-
22
- Manifest and assets: {commit-pinned links when available, otherwise committed paths and SHA}
23
-
24
- {prMarkdown}
25
-
26
- {image-line?}
27
- ```
28
-
29
- ### Step 3 — Upsert the discussion comment on the work item (and the PR when provided)
30
-
31
- `az boards work-item update --discussion` appends a comment; to stay idempotent, first read existing discussion comments and skip if one already carries the marker for this change id, otherwise post:
32
-
33
- ```bash
34
- # best-effort existing-comment check via the work-item comments API
35
- az boards work-item show --id {work-item-id} --query 'fields."System.History"' -o tsv 2>/dev/null | grep -q "pc-visual-evidence:{change-id}" \
36
- || az boards work-item update --id {work-item-id} --discussion "$BODY"
37
- ```
38
-
39
- When a PR number is provided, also add the same body as a PR thread comment (`az repos pr` thread APIs) if available.
40
-
41
- - If a comment call fails: report it. Fail the run ONLY when publishing was declared a ship gate; otherwise continue.
1
+ Azure DevOps data comes from the `az` CLI; a page fetch of dev.azure.com is denied (pc-system-reminders). If `az` is unavailable, skip publishing and report it; do not fail the pipeline unless the caller declared publishing a ship gate.
2
+
3
+ Publish one status comment for every manifest. A `blocked` or `failed` manifest must include its status and reason, never a success claim.
4
+
5
+ ### Step 1 — Image hosting caveat
6
+
7
+ Azure DevOps discussion comments do not render an image from a repo blob URL the way GitHub does, and `az boards` cannot upload an attachment inline. Use text evidence and derive a commit-pinned repository URL from `git remote get-url origin` when possible. Otherwise include the committed asset path, branch, and SHA.
8
+
9
+ ```
10
+ Screenshot committed at: {asset-path} (branch {branch}, commit {sha})
11
+ ```
12
+
13
+ ### Step 2 — Build the comment with a stable marker (idempotent)
14
+
15
+ ```
16
+ <!-- pc-visual-evidence:{change-id} -->
17
+ <!-- pc-visual-evidence-status:{status} -->
18
+
19
+ Status: `{status}`
20
+
21
+ {reason?}
22
+
23
+ Manifest and assets: {commit-pinned links when available, otherwise committed paths and SHA}
24
+
25
+ {prMarkdown}
26
+
27
+ {image-line?}
28
+ ```
29
+
30
+ ### Step 3 — Upsert the discussion comment on the work item (and the PR when provided)
31
+
32
+ `az boards work-item update --discussion` appends a comment and cannot edit one in place, so match on the status probe rather than the change id alone. Matching the change id alone leaves a stale `blocked` comment standing after a later run succeeds:
33
+
34
+ ```bash
35
+ # Skip only when this exact status is already published for this change.
36
+ az boards work-item show --id {work-item-id} --query 'fields."System.History"' -o tsv 2>/dev/null | grep -q "pc-visual-evidence-status:{status}" \
37
+ || az boards work-item update --id {work-item-id} --discussion "$BODY"
38
+ ```
39
+
40
+ When an earlier comment carries this change id with a different status, this one supersedes it: open the body with `Supersedes the earlier evidence comment for this change.` so a reader can tell which is current.
41
+
42
+ When a PR number is provided, also add the same body as a PR thread comment (`az repos pr` thread APIs) if available.
43
+
44
+ - If a comment call fails: report it. Fail the run ONLY when publishing was declared a ship gate; otherwise continue.
@@ -1,53 +1,54 @@
1
- **ALL GitHub data MUST come from `gh` CLI. NEVER use webfetch, HTTP requests, or browser MCP tools for GitHub. If `gh` is unavailable, skip publishing (report it) — do not fail the pipeline over it unless the caller declared publishing a ship gate.**
2
- Always pass `--repo {owner}/{repo}` (or `repos/{owner}/{repo}` for `gh api`) explicitly.
3
-
4
- Publish one status comment for every manifest. A `blocked` or `failed` manifest must include its status and reason, never a success claim.
5
-
6
- ### Step 1 — Build commit-pinned repository links
7
-
8
- An embedded image must be a raw URL pinned to the commit that actually contains it, and that commit must be pushed. For each asset in `evidence.json`:
9
-
10
- ```bash
11
- SHA="$(git log -n 1 --format=%H -- '{asset-path}')" # the commit that added this asset
12
- [ -z "$SHA" ] && echo "asset not committed: {asset-path}" && exit-skip
13
- gh api "repos/{owner}/{repo}/contents/{asset-path}?ref=$SHA" --silent # 404 → not pushed yet → skip embedding
14
- ```
15
-
16
- Build a blob link for every committed manifest and asset: `https://github.com/{owner}/{repo}/blob/{SHA}/{asset-path}`. Use the raw URL only for a verified embeddable image: `https://raw.githubusercontent.com/{owner}/{repo}/{SHA}/{asset-path}`. If verification fails, include the asset path and SHA as text; never post a dead link.
17
-
18
- ### Step 2 — Build the comment body with a stable marker (idempotent)
19
-
20
- Prefix the body with a hidden marker so re-runs update the same comment instead of piling on:
21
-
22
- ```
23
- <!-- pc-visual-evidence:{change-id} -->
24
-
25
- Status: `{status}`
26
-
27
- {reason?}
28
-
29
- Manifest: {commit-pinned evidence.json link}
30
-
31
- Assets: {commit-pinned asset links}
32
-
33
- {prMarkdown}
34
- ```
35
-
36
- ### Step 3 — Upsert the comment on BOTH the issue and the PR
37
-
38
- For each target number (the originating issue, and the PR number when provided), find an existing marked comment and PATCH it, else POST a new one:
39
-
40
- ```bash
41
- # find existing
42
- ID="$(gh api "repos/{owner}/{repo}/issues/{number}/comments" --paginate --jq \
43
- '.[] | select(.body | contains("<!-- pc-visual-evidence:{change-id} -->")) | .id' | head -1)"
44
-
45
- if [ -n "$ID" ]; then
46
- gh api --method PATCH "repos/{owner}/{repo}/issues/comments/$ID" -f body="$BODY" --silent
47
- else
48
- gh api --method POST "repos/{owner}/{repo}/issues/{number}/comments" -f body="$BODY" --silent
49
- fi
50
- ```
51
-
52
- - Text-only (no verified image, or `default` mode / nothing pushed): drop the image lines, keep the summary (tasks N/N, verification result, commits).
53
- - If a comment call fails: report it. Fail the run ONLY when the caller declared publishing a ship gate; otherwise continue.
1
+ GitHub data comes from the `gh` CLI; a page fetch of github.com is denied (pc-system-reminders). If `gh` is unavailable, skip publishing and report it; do not fail the pipeline unless the caller declared publishing a ship gate.
2
+ Always pass `--repo {owner}/{repo}` (or `repos/{owner}/{repo}` for `gh api`) explicitly.
3
+
4
+ Publish one status comment for every manifest. A `blocked` or `failed` manifest must include its status and reason, never a success claim.
5
+
6
+ ### Step 1 — Build commit-pinned repository links
7
+
8
+ An embedded image must be a raw URL pinned to the commit that actually contains it, and that commit must be pushed. For each asset in `evidence.json`:
9
+
10
+ ```bash
11
+ SHA="$(git log -n 1 --format=%H -- '{asset-path}')" # the commit that added this asset
12
+ [ -z "$SHA" ] && echo "asset not committed: {asset-path}" && exit-skip
13
+ gh api "repos/{owner}/{repo}/contents/{asset-path}?ref=$SHA" --silent # 404 → not pushed yet → skip embedding
14
+ ```
15
+
16
+ Build a blob link for every committed manifest and asset: `https://github.com/{owner}/{repo}/blob/{SHA}/{asset-path}`. Use the raw URL only for a verified embeddable image: `https://raw.githubusercontent.com/{owner}/{repo}/{SHA}/{asset-path}`. If verification fails, include the asset path and SHA as text; never post a dead link.
17
+
18
+ ### Step 2 — Build the comment body with a stable marker (idempotent)
19
+
20
+ Prefix the body with a hidden marker so re-runs update the same comment instead of piling on:
21
+
22
+ ```
23
+ <!-- pc-visual-evidence:{change-id} -->
24
+ <!-- pc-visual-evidence-status:{status} -->
25
+
26
+ Status: `{status}`
27
+
28
+ {reason?}
29
+
30
+ Manifest: {commit-pinned evidence.json link}
31
+
32
+ Assets: {commit-pinned asset links}
33
+
34
+ {prMarkdown}
35
+ ```
36
+
37
+ ### Step 3 — Upsert the comment on BOTH the issue and the PR
38
+
39
+ For each target number (the originating issue, and the PR number when provided), find an existing marked comment and PATCH it, else POST a new one:
40
+
41
+ ```bash
42
+ # find existing
43
+ ID="$(gh api "repos/{owner}/{repo}/issues/{number}/comments" --paginate --jq \
44
+ '.[] | select(.body | contains("<!-- pc-visual-evidence:{change-id} -->")) | .id' | head -1)"
45
+
46
+ if [ -n "$ID" ]; then
47
+ gh api --method PATCH "repos/{owner}/{repo}/issues/comments/$ID" -f body="$BODY" --silent
48
+ else
49
+ gh api --method POST "repos/{owner}/{repo}/issues/{number}/comments" -f body="$BODY" --silent
50
+ fi
51
+ ```
52
+
53
+ - Text-only (no verified image, or `default` mode / nothing pushed): drop the image lines, keep the summary (tasks N/N, verification result, commits).
54
+ - If a comment call fails: report it. Fail the run ONLY when the caller declared publishing a ship gate; otherwise continue.
@@ -1,38 +1,42 @@
1
- **NEVER use browser tools to navigate to atlassian.net: use `acli` CLI only. If `acli` is unavailable, skip publishing (report it) — do not fail the pipeline unless the caller declared publishing a ship gate.**
2
-
3
- Publish one status comment for every manifest. A `blocked` or `failed` manifest must include its status and reason, never a success claim.
4
-
5
- ### Step 1 — Image hosting caveat
6
-
7
- Jira comments cannot embed an image from a repo blob URL, and `acli` does not upload attachments inline. Use text evidence and derive a commit-pinned repository URL from `git remote get-url origin` when possible. Otherwise include the committed asset path, branch, and SHA:
8
-
9
- ```
10
- Screenshot committed at: {asset-path} (branch {branch}, commit {sha})
11
- ```
12
-
13
- ### Step 2 — Build the comment with a stable marker (idempotent)
14
-
15
- ```
16
- <!-- pc-visual-evidence:{change-id} -->
17
-
18
- Status: `{status}`
19
-
20
- {reason?}
21
-
22
- Manifest and assets: {commit-pinned links when available, otherwise committed paths and SHA}
23
-
24
- {prMarkdown}
25
-
26
- {image-line?}
27
- ```
28
-
29
- ### Step 3 — Upsert the comment on the issue
30
-
31
- Keep it idempotent: list existing comments and skip if one already carries the marker for this change id, otherwise add:
32
-
33
- ```bash
34
- acli jira issue comment list --key {issue-key} 2>/dev/null | grep -q "pc-visual-evidence:{change-id}" \
35
- || acli jira issue comment --key {issue-key} --body "$BODY"
36
- ```
37
-
38
- - If the comment command fails: report it. Fail the run ONLY when publishing was declared a ship gate; otherwise continue.
1
+ Jira data comes from the `acli` CLI; a page fetch of atlassian.net is denied (pc-system-reminders). If `acli` is unavailable, skip publishing and report it; do not fail the pipeline unless the caller declared publishing a ship gate.
2
+
3
+ Publish one status comment for every manifest. A `blocked` or `failed` manifest must include its status and reason, never a success claim.
4
+
5
+ ### Step 1 — Image hosting caveat
6
+
7
+ Jira comments cannot embed an image from a repo blob URL, and `acli` does not upload attachments inline. Use text evidence and derive a commit-pinned repository URL from `git remote get-url origin` when possible. Otherwise include the committed asset path, branch, and SHA:
8
+
9
+ ```
10
+ Screenshot committed at: {asset-path} (branch {branch}, commit {sha})
11
+ ```
12
+
13
+ ### Step 2 — Build the comment with a stable marker (idempotent)
14
+
15
+ ```
16
+ <!-- pc-visual-evidence:{change-id} -->
17
+ <!-- pc-visual-evidence-status:{status} -->
18
+
19
+ Status: `{status}`
20
+
21
+ {reason?}
22
+
23
+ Manifest and assets: {commit-pinned links when available, otherwise committed paths and SHA}
24
+
25
+ {prMarkdown}
26
+
27
+ {image-line?}
28
+ ```
29
+
30
+ ### Step 3 — Upsert the comment on the issue
31
+
32
+ `acli` cannot edit a comment in place, so match on the status probe rather than the change id alone. Matching the change id alone leaves a stale `blocked` comment standing after a later run succeeds:
33
+
34
+ ```bash
35
+ # Skip only when this exact status is already published for this change.
36
+ acli jira issue comment list --key {issue-key} 2>/dev/null | grep -q "pc-visual-evidence-status:{status}" \
37
+ || acli jira issue comment --key {issue-key} --body "$BODY"
38
+ ```
39
+
40
+ When an earlier comment carries this change id with a different status, this one supersedes it: open the body with `Supersedes the earlier evidence comment for this change.` so a reader can tell which is current.
41
+
42
+ - If the comment command fails: report it. Fail the run ONLY when publishing was declared a ship gate; otherwise continue.
@@ -1,4 +1,4 @@
1
- **Browser MCP tools are FORBIDDEN for all Azure DevOps operations.**
1
+ Azure DevOps data comes from the `az` CLI; a page fetch of dev.azure.com is denied (pc-system-reminders). If `az` is unavailable, report it as a blocker.
2
2
 
3
3
  ---
4
4
 
@@ -1,4 +1,4 @@
1
- **ALL GitHub data MUST come from `gh` CLI. NEVER use webfetch, HTTP requests, or browser MCP tools for GitHub operations, even if gh CLI fails. If `gh` is unavailable, report as a blocker.**
1
+ GitHub data comes from the `gh` CLI; a page fetch of github.com is denied (pc-system-reminders). If `gh` is unavailable, report it as a blocker.
2
2
  Always pass `--repo {owner}/{repo}` explicitly, never rely on git context to resolve the repo.
3
3
 
4
4
  ---
@@ -1,4 +1,4 @@
1
- **ALL GitLab data MUST come from `glab` CLI. NEVER use webfetch, HTTP requests, or browser MCP tools for GitLab operations, even if glab CLI fails. If `glab` is unavailable, report as a blocker.**
1
+ GitLab data comes from the `glab` CLI; a page fetch of gitlab.com is denied (pc-system-reminders). If `glab` is unavailable, report it as a blocker.
2
2
  Always pass `--repo {owner}/{repo}` explicitly, never rely on git context to resolve the repo.
3
3
 
4
4
  ---