@plainconceptsplatform/agent-harness 2.4.1 → 2.5.0
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/README.md +435 -437
- package/cli/fragments/archive/az.md +97 -95
- package/cli/fragments/archive/gh.md +96 -94
- package/cli/fragments/archive/gl.md +96 -94
- package/cli/fragments/archive/none.md +75 -73
- package/cli/fragments/guardrails/codegraph.md +5 -7
- package/cli/fragments/guardrails/humanizer.md +4 -4
- package/cli/fragments/guardrails/memory.md +4 -4
- package/cli/fragments/guardrails/rtk.md +3 -3
- package/cli/fragments/guardrails/simple-english.md +4 -4
- package/cli/fragments/ops-backlog/az.md +1 -1
- package/cli/fragments/ops-backlog/gh.md +1 -1
- package/cli/fragments/ops-backlog/jira.md +1 -1
- package/cli/fragments/ops-evidence/az.md +44 -41
- package/cli/fragments/ops-evidence/gh.md +54 -53
- package/cli/fragments/ops-evidence/jira.md +42 -38
- package/cli/fragments/ops-review/az.md +1 -1
- package/cli/fragments/ops-review/gh.md +1 -1
- package/cli/fragments/ops-review/gl.md +1 -1
- package/cli/fragments/ops-ship/az.md +81 -80
- package/cli/fragments/ops-ship/gh.md +68 -68
- package/cli/fragments/ops-ship/gl.md +85 -85
- package/cli/presets/agents-content.json +34 -53
- package/cli/steps/copy/agents.js +18 -17
- package/cli/steps/copy/opencode-json.js +5 -1
- package/cli/steps/copy/skills.js +98 -5
- package/cli/steps/optimization/patch-guardrails.js +5 -3
- package/cli/utils/copy.js +8 -3
- package/cli/utils/update-manifest.js +28 -2
- package/harness/.agents/skills/pc-guardrails-generic/SKILL.md +47 -68
- package/harness/.agents/skills/pc-make-architecture/SKILL.md +31 -51
- package/harness/.agents/skills/pc-make-design/SKILL.md +45 -68
- package/harness/.agents/skills/pc-make-engineer/SKILL.md +59 -219
- package/harness/.agents/skills/pc-make-engineer/signal-mapping.md +53 -68
- package/harness/.agents/skills/pc-make-engineer/template.md +42 -80
- package/harness/.agents/skills/pc-make-evidence-scaffold/SKILL.md +18 -18
- package/harness/.agents/skills/pc-make-evidence-scaffold/evidence-contract.md +29 -29
- package/harness/.agents/skills/pc-make-guardrails/SKILL.md +43 -74
- package/harness/.agents/skills/pc-make-guardrails/category-reference.md +10 -5
- package/harness/.agents/skills/pc-make-merge-risk-assess/category-reference.md +26 -7
- package/harness/.agents/skills/pc-make-user-model/SKILL.md +56 -66
- package/harness/.agents/skills/pc-ops-evidence/SKILL.md +133 -127
- package/harness/.agents/skills/pc-plan-apply/SKILL.md +14 -5
- package/harness/.agents/skills/pc-plan-apply/simple-mode.md +21 -21
- package/harness/.agents/skills/pc-plan-archive/SKILL.md +66 -66
- package/harness/.agents/skills/pc-plan-explore/SKILL.md +19 -2
- package/harness/.agents/skills/pc-plan-goal/SKILL.md +7 -5
- package/harness/.agents/skills/pc-plan-goal/output-mode.md +1 -0
- package/harness/.agents/skills/pc-plan-goal/output.md +71 -65
- package/harness/.agents/skills/pc-plan-propose/SKILL.md +1 -1
- package/harness/.agents/skills/pc-plan-quick/SKILL.md +46 -62
- package/harness/.agents/skills/pc-plan-story/SKILL.md +48 -149
- package/harness/.agents/skills/pc-repo-help/SKILL.md +89 -91
- package/harness/.agents/skills/pc-repo-initialize/SKILL.md +112 -130
- package/harness/.agents/skills/pc-repo-onboard/SKILL.md +32 -87
- package/harness/.agents/skills/pc-repo-verify/SKILL.md +2 -0
- package/harness/.agents/skills/pc-userstory-az/SKILL.md +71 -157
- package/harness/.agents/skills/pc-userstory-browser/SKILL.md +50 -122
- package/harness/.agents/skills/pc-userstory-gh/SKILL.md +63 -120
- package/harness/.agents/skills/pc-userstory-jira/SKILL.md +74 -131
- package/harness/.opencode/commands/init.md +5 -5
- package/harness/.opencode/commands/make-architecture.md +5 -5
- package/harness/.opencode/commands/make-design.md +5 -5
- package/harness/.opencode/commands/make-engineer.md +5 -5
- package/harness/.opencode/commands/make-evidence-scaffold.md +5 -5
- package/harness/.opencode/commands/make-guardrails.md +5 -5
- package/harness/.opencode/commands/make-user-model.md +5 -5
- package/harness/.opencode/commands/plan-apply.md +9 -9
- package/harness/.opencode/commands/plan-goal.md +5 -5
- package/harness/.opencode/commands/plan-quick.md +5 -5
- package/harness/.opencode/commands/plan-story.md +9 -9
- package/harness/.opencode/commands/repo-audit.md +5 -5
- package/harness/.opencode/commands/repo-initialize.md +5 -5
- package/harness/.opencode/commands/repo-onboard.md +5 -5
- package/harness/.opencode/commands/repo-verify.md +5 -5
- package/harness/.opencode/plugins/pc-subagent-monitor.js +82 -2
- package/harness/.opencode/plugins/pc-subagent-tiers.js +9 -6
- package/harness/.opencode/plugins/pc-system-reminders.js +312 -3
- package/harness/AGENTS.md +49 -71
- package/harness/opencode.jsonc +1 -1
- 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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
-
|
|
71
|
-
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
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
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
2
|
-
|
|
3
|
-
-
|
|
4
|
-
-
|
|
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
|
-
-
|
|
4
|
-
-
|
|
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
|
|
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
|
|
2
|
-
|
|
3
|
-
-
|
|
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
|
-
|
|
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,41 +1,44 @@
|
|
|
1
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
-
|
|
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
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
---
|