diff --git a/README.md b/README.md index 11c7a854..dd30e55e 100644 --- a/README.md +++ b/README.md @@ -442,6 +442,12 @@ work items. criteria, repo, branch, status and plan progress. A work item that waits on open work is refused with the names of what it waits on. +`work-store.sh item ` prints a work item the same way, with the address of +its page in production, and does not claim it. `pr-scribe` reads the work item +this way when it is handed one, writes its criteria as the body's ACs Covered, +and ends the body with `Work item:
` in place of `Closes #`. A work +item production cannot find stops the scribe with production's message. + ### Choosing each agent's model Put a file at `~/.config/symphony/agent-models.json`, next to the rules diff --git a/agents/pr-scribe.md b/agents/pr-scribe.md index 7abc6f7b..127ff3a1 100644 --- a/agents/pr-scribe.md +++ b/agents/pr-scribe.md @@ -24,7 +24,9 @@ with nothing real in it. ## Your input The repo, the branch, and the issue number — or, if there is no issue, the -acceptance criteria inlined. The caller may also tell you a PR already exists. +acceptance criteria inlined. In a repo that keeps its work in dyb_web the +caller hands you a work item number in place of the issue number, and says it +is a work item. The caller may also tell you a PR already exists. The input may be messy or thin; the diff is what you actually work from. ## What you do @@ -56,6 +58,15 @@ is how the person who ran you sees which step you are on. of the repo, so read it when it exists and expect it not to. `.ticket` is the same shape for the ticket the branch is billed against. + For a work item, read it from production in place of `gh issue view`: + ``` + ~/.claude/bin/work-store.sh item + ``` + It prints the work item's title, request and acceptance criteria, and the + address of its page in production, and it does not claim the item. Its + acceptance criteria are the ticket's criteria for every step below. When it + exits non-zero, stop, write nothing, and return the message it printed. + If the branch is not pushed yet, push it (`git push -u origin `). Never rewrite commits — no amend, no rebase, no force-push. @@ -155,7 +166,10 @@ is how the person who ran you sees which step you are on. paste unchanged. 8. **Add the `Closes #` trailer** on its own line at the end when there is an - issue. That trailer is machine-readable wiring, not a tenth section. + issue. That trailer is machine-readable wiring, not a tenth section. For a + work item there is no `Closes #` line, and the trailer is + `Work item: ` instead, with the address `work-store.sh item` + printed. 9. **Append the version stamp; do not write it.** Below `Closes #`, under a `---` rule, run: diff --git a/bin/work-store.sh b/bin/work-store.sh index 1079c67a..6bd2ce24 100755 --- a/bin/work-store.sh +++ b/bin/work-store.sh @@ -6,6 +6,7 @@ usage() { usage: work-store.sh show|check work-store.sh file-plan <plan-body-file> work-store.sh take <work-item-id> + work-store.sh item <work-item-id> show Prints where the current repo keeps its plans and work: github, or dyb_web with the link and pipeline its setting names. @@ -15,6 +16,8 @@ file-plan Adds the plan to dyb_web production as a draft, linked as the repo's setting names, and prints its page's address. take Claims the work item in dyb_web production for this machine's session, and prints it as production reads it. +item Prints the work item as production reads it, with the address of + its page, without claiming it. USAGE exit 64 } @@ -77,10 +80,16 @@ take() { "$(dirname "$0")/dyb-hub.sh" get work_item "work_item_id=$1" } +item() { + "$(dirname "$0")/dyb-hub.sh" get work_item "work_item_id=$1" \ + | jq -c --arg address "$("$(dirname "$0")/dyb-hub.sh" page "/console/pipelines/work_items/$1")" '. + {address: $address}' +} + case "${1:-}" in show) show ;; check) check ;; file-plan) [ $# -eq 3 ] || usage; file_plan "$2" "$3" ;; take) [ $# -eq 2 ] || usage; take "$2" ;; + item) [ $# -eq 2 ] || usage; item "$2" ;; *) usage ;; esac diff --git a/rules/pr-body.md b/rules/pr-body.md index 3eca5a6e..8c598984 100644 --- a/rules/pr-body.md +++ b/rules/pr-body.md @@ -125,6 +125,10 @@ A PR that resolves an issue ends with `Closes #<n>` on its own line after the last section. That trailer is machine-readable wiring, not a tenth section — it is one of the two things allowed outside the nine. +A PR for a dyb_web work item carries no `Closes #<n>` line, since the work item +is not a GitHub issue. Its trailer is `Work item: <address>` in the same place, +naming the work item's page in production. + ## The version stamp The other. Every body ends with a stamp naming the versions that wrote it, diff --git a/tests/work_store_test.zsh b/tests/work_store_test.zsh index d768e891..5d562a57 100644 --- a/tests/work_store_test.zsh +++ b/tests/work_store_test.zsh @@ -130,6 +130,19 @@ assert_equals "Export quotes waits on Import quotes." \ STUB_CLAIM_BODY='{"error": "Export quotes waits on Import quotes."}' STUB_BODY='{"answer": {"title": "Export quotes"}}' "$SCRIPT" take 12 2>&1)" \ "reports a work item that waits on open work with the names of what it waits on" +echo "" +echo "work-store.sh item:" + +assert_equals '{"title":"Export quotes","acceptance_criteria":["A rep can export quotes"],"address":"https://dyb.example/console/pipelines/work_items/12"}' \ + "$(cd "$REPO" && PATH="$STUB_BIN:$PATH" SYMPHONY_DYB_WEB_FILE="$CONNECTION" \ + STUB_BODY='{"answer": {"title": "Export quotes", "acceptance_criteria": ["A rep can export quotes"]}}' "$SCRIPT" item 12 2>&1)" \ + "prints the work item with the address of its page in production" + +assert_equals $'No work item 99.\nexit 1' \ + "$(cd "$REPO" && PATH="$STUB_BIN:$PATH" SYMPHONY_DYB_WEB_FILE="$CONNECTION" STUB_STATUS=422 \ + STUB_BODY='{"error": "No work item 99."}' "$SCRIPT" item 99 2>&1; echo "exit $?")" \ + "reports a work item production cannot find with production's message" + echo "" echo "$PASS passed, $FAIL failed" rm -rf "$WORK"