← back to Cli Printing Press
fix(skills): forward --research-dir to scorecard --live-check in mid-pipeline polish (#980)
e0240ceae66362d78ebf2097bbd66cedf155250a · 2026-05-10 15:53:25 -0700 · Trevin Chow
* fix(skills): forward --research-dir to scorecard --live-check in mid-pipeline polish
Polish skill computed $RESEARCH_FLAG and forwarded it to dogfood but not to
scorecard --live-check, and the output-review sub-skill invoked scorecard with
no research-dir hint at all. In mid-pipeline mode ($CLI_DIR under
$PRESS_RUNSTATE/runs/<id>/working/<cli>), research.json lives two directories
up, scorecard's live-check defaulted to looking adjacent to the binary, found
nothing, and returned unable=true. Output-review then SKIPped the most
informative review window.
- polish: extend RESEARCH_DIR detection to fall back to $CLI_DIR's grandparent
when the manuscripts glob misses (mid-pipeline runs aren't in manuscripts
yet), and pass $RESEARCH_FLAG to the scorecard --live-check call.
- output-review: self-detect the mid-pipeline layout by checking $CLI_DIR
first and grandparent second, then forward --research-dir when the
fallback hits. Keeps the sub-skill robust regardless of caller.
Closes #795
* fix(skills): key mid-pipeline detection on .runstate/ path, switch to array form
Addresses Greptile review on PR #980.
P1 — polish skill RESEARCH_DIR fallback. The grandparent fallback was
guarded by an empty RESEARCH_DIR, which only holds on first-generation
runs. On re-generation of a previously-published API, the manuscripts
glob matches the prior run's research.json, RESEARCH_DIR stays
non-empty, and the fallback never fires — pointing scorecard at stale
data from a prior generation. Key the branch on $CLI_DIR path
structure instead (case "*.runstate/*"), matching the same sentinel
the Publish Offer section already uses for mid-pipeline detection.
P2 — both skills. Replace $RESEARCH_FLAG (single string with embedded
space) with a bash array RESEARCH_ARGS, expanded as "${RESEARCH_ARGS[@]}".
Survives paths where $HOME or $PRESS_RUNSTATE resolves through a
directory containing spaces.
* fix(skills): forward RESEARCH_ARGS to Phase 3 re-diagnose dogfood
Phase 1's dogfood now passes RESEARCH_ARGS so checkNovelFeatures syncs
novel_features_built into .printing-press.json. Phase 3's re-diagnose
dogfood call omitted the flag — if Phase 2 modified novel features,
Phase 3 wouldn't re-sync them and publish-validate's transcendence
gate would read stale state from Phase 1.
Greptile flag on PR #980.
Files touched
M skills/printing-press-output-review/SKILL.mdM skills/printing-press-polish/SKILL.md
Diff
commit e0240ceae66362d78ebf2097bbd66cedf155250a
Author: Trevin Chow <trevin@trevinchow.com>
Date: Sun May 10 15:53:25 2026 -0700
fix(skills): forward --research-dir to scorecard --live-check in mid-pipeline polish (#980)
* fix(skills): forward --research-dir to scorecard --live-check in mid-pipeline polish
Polish skill computed $RESEARCH_FLAG and forwarded it to dogfood but not to
scorecard --live-check, and the output-review sub-skill invoked scorecard with
no research-dir hint at all. In mid-pipeline mode ($CLI_DIR under
$PRESS_RUNSTATE/runs/<id>/working/<cli>), research.json lives two directories
up, scorecard's live-check defaulted to looking adjacent to the binary, found
nothing, and returned unable=true. Output-review then SKIPped the most
informative review window.
- polish: extend RESEARCH_DIR detection to fall back to $CLI_DIR's grandparent
when the manuscripts glob misses (mid-pipeline runs aren't in manuscripts
yet), and pass $RESEARCH_FLAG to the scorecard --live-check call.
- output-review: self-detect the mid-pipeline layout by checking $CLI_DIR
first and grandparent second, then forward --research-dir when the
fallback hits. Keeps the sub-skill robust regardless of caller.
Closes #795
* fix(skills): key mid-pipeline detection on .runstate/ path, switch to array form
Addresses Greptile review on PR #980.
P1 — polish skill RESEARCH_DIR fallback. The grandparent fallback was
guarded by an empty RESEARCH_DIR, which only holds on first-generation
runs. On re-generation of a previously-published API, the manuscripts
glob matches the prior run's research.json, RESEARCH_DIR stays
non-empty, and the fallback never fires — pointing scorecard at stale
data from a prior generation. Key the branch on $CLI_DIR path
structure instead (case "*.runstate/*"), matching the same sentinel
the Publish Offer section already uses for mid-pipeline detection.
P2 — both skills. Replace $RESEARCH_FLAG (single string with embedded
space) with a bash array RESEARCH_ARGS, expanded as "${RESEARCH_ARGS[@]}".
Survives paths where $HOME or $PRESS_RUNSTATE resolves through a
directory containing spaces.
* fix(skills): forward RESEARCH_ARGS to Phase 3 re-diagnose dogfood
Phase 1's dogfood now passes RESEARCH_ARGS so checkNovelFeatures syncs
novel_features_built into .printing-press.json. Phase 3's re-diagnose
dogfood call omitted the flag — if Phase 2 modified novel features,
Phase 3 wouldn't re-sync them and publish-validate's transcendence
gate would read stale state from Phase 1.
Greptile flag on PR #980.
---
skills/printing-press-output-review/SKILL.md | 17 +++++++-
skills/printing-press-polish/SKILL.md | 60 +++++++++++++++++++++-------
2 files changed, 61 insertions(+), 16 deletions(-)
diff --git a/skills/printing-press-output-review/SKILL.md b/skills/printing-press-output-review/SKILL.md
index 73007c09..afdc22aa 100644
--- a/skills/printing-press-output-review/SKILL.md
+++ b/skills/printing-press-output-review/SKILL.md
@@ -39,7 +39,22 @@ Bugs that rule-based checks miss, typically surfaced by 5 minutes of hands-on te
### Step 1: Gather sample data
```bash
-printing-press scorecard --dir "$CLI_DIR" --live-check --json > /tmp/output-review-livecheck.json 2>&1 || true
+# Locate research.json. Adjacent to the binary covers the post-promote
+# layout (standalone polish, shipcheck against the library copy). The
+# grandparent fallback covers mid-pipeline invocations where $CLI_DIR is
+# $PRESS_RUNSTATE/runs/<id>/working/<cli> and research.json lives at
+# $PRESS_RUNSTATE/runs/<id>/research.json. Without the fallback, scorecard
+# reports `unable: true` mid-pipeline and we SKIP the most informative review.
+# Use a bash array so the flag survives paths with spaces.
+RESEARCH_ARGS=()
+if [ ! -f "$CLI_DIR/research.json" ]; then
+ _grandparent="$(dirname "$(dirname "$CLI_DIR")")"
+ if [ -f "$_grandparent/research.json" ]; then
+ RESEARCH_ARGS=(--research-dir "$_grandparent")
+ fi
+fi
+
+printing-press scorecard --dir "$CLI_DIR" "${RESEARCH_ARGS[@]}" --live-check --json > /tmp/output-review-livecheck.json 2>&1 || true
```
If the scorecard call fails or `/tmp/output-review-livecheck.json` is empty, return the SKIP result (Step 3) without dispatching the reviewer.
diff --git a/skills/printing-press-polish/SKILL.md b/skills/printing-press-polish/SKILL.md
index 083596b6..404a843f 100644
--- a/skills/printing-press-polish/SKILL.md
+++ b/skills/printing-press-polish/SKILL.md
@@ -147,23 +147,45 @@ if [ -n "$SPEC_PATH" ]; then
SPEC_FLAG="--spec $SPEC_PATH"
fi
-# Locate the research dir (parent of the spec's research/ folder, i.e.
-# manuscripts/<api>/<run-id>/). dogfood's --research-dir triggers
+# Locate the research dir. dogfood's --research-dir triggers
# checkNovelFeatures, which writes novel_features_built back into
# research.json AND syncs the verified list into .printing-press.json.
# Without this flag, legacy CLIs whose manifest predates the
# novel_features schema fail publish-validate's transcendence gate.
+#
+# Two layouts to handle, keyed on $CLI_DIR path structure (NOT on the
+# absence of a manuscripts entry — re-generating a previously-published
+# API leaves stale manuscript entries from prior runs that would point
+# scorecard at the wrong research.json):
+# 1. Mid-pipeline polish (invoked from the main printing-press flow
+# before promote): $CLI_DIR is under $PRESS_RUNSTATE/.../runs/<id>/working/<cli>
+# (i.e. the path contains `.runstate/`), and research.json lives at
+# $PRESS_RUNSTATE/.../runs/<id>/research.json — $CLI_DIR's grandparent.
+# 2. Post-promote (standalone polish): research.json lives at
+# manuscripts/<api>/<run-id>/research.json.
RESEARCH_DIR=""
-for d in "$PRESS_HOME/manuscripts/$API_SLUG"/*/research.json "$PRESS_HOME/manuscripts/$CLI_NAME"/*/research.json; do
- if [ -f "$d" ]; then
- RESEARCH_DIR="$(dirname "$d")"
- break
- fi
-done
+case "$CLI_DIR" in
+ *.runstate/*)
+ _grandparent="$(dirname "$(dirname "$CLI_DIR")")"
+ if [ -f "$_grandparent/research.json" ]; then
+ RESEARCH_DIR="$_grandparent"
+ fi
+ ;;
+ *)
+ for d in "$PRESS_HOME/manuscripts/$API_SLUG"/*/research.json "$PRESS_HOME/manuscripts/$CLI_NAME"/*/research.json; do
+ if [ -f "$d" ]; then
+ RESEARCH_DIR="$(dirname "$d")"
+ break
+ fi
+ done
+ ;;
+esac
-RESEARCH_FLAG=""
+# Use a bash array so the flag survives paths with spaces (e.g. when
+# $HOME or $PRESS_RUNSTATE resolves through a path containing spaces).
+RESEARCH_ARGS=()
if [ -n "$RESEARCH_DIR" ]; then
- RESEARCH_FLAG="--research-dir $RESEARCH_DIR"
+ RESEARCH_ARGS=(--research-dir "$RESEARCH_DIR")
fi
```
@@ -208,11 +230,11 @@ cd "$CLI_DIR"
# Build
go build -o "$CLI_NAME" ./cmd/"$CLI_NAME" 2>&1
-# Diagnostics. SPEC_FLAG and RESEARCH_FLAG are set in the "Find spec
-# and research dir" step above. RESEARCH_FLAG enables dogfood to
+# Diagnostics. SPEC_FLAG and RESEARCH_ARGS are set in the "Find spec
+# and research dir" step above. RESEARCH_ARGS enables dogfood to
# verify novel features and sync them into .printing-press.json
# (required for publish-validate's transcendence gate).
-printing-press dogfood --dir "$CLI_DIR" $SPEC_FLAG $RESEARCH_FLAG 2>&1
+printing-press dogfood --dir "$CLI_DIR" $SPEC_FLAG "${RESEARCH_ARGS[@]}" 2>&1
printing-press verify --dir "$CLI_DIR" $SPEC_FLAG --json 2>&1
printing-press workflow-verify --dir "$CLI_DIR" --json > /tmp/polish-workflow-verify.json 2>&1 || true
printing-press verify-skill --dir "$CLI_DIR" --json > /tmp/polish-verify-skill.json 2>&1 || true
@@ -220,7 +242,11 @@ printing-press publish validate --dir "$CLI_DIR" --json > /tmp/polish-publish-va
# --live-check samples novel-feature outputs and populates
# live_check.features[].warnings (Wave B entity detection) — required for
# the "Output entity warnings" row below to have data to read.
-printing-press scorecard --dir "$CLI_DIR" $SPEC_FLAG --live-check --json > /tmp/polish-scorecard.json 2>&1 || true
+# RESEARCH_ARGS points scorecard at the run's research.json when the
+# CLI lives under $PRESS_RUNSTATE/runs/<id>/working/<cli> (mid-pipeline
+# polish). Without it, scorecard looks adjacent to the binary, doesn't
+# find research.json, and reports `unable: true`.
+printing-press scorecard --dir "$CLI_DIR" $SPEC_FLAG "${RESEARCH_ARGS[@]}" --live-check --json > /tmp/polish-scorecard.json 2>&1 || true
printing-press scorecard --dir "$CLI_DIR" $SPEC_FLAG 2>&1
printing-press tools-audit "$CLI_DIR" --json > /tmp/polish-tools-audit-before.json 2>&1 || true
go vet ./... 2>&1
@@ -474,7 +500,11 @@ gofmt -w .
Re-run the diagnostic sweep on the fixed CLI:
```bash
-printing-press dogfood --dir "$CLI_DIR" $SPEC_FLAG 2>&1
+# RESEARCH_ARGS must travel with dogfood here too — without it,
+# checkNovelFeatures doesn't re-sync novel_features_built after Phase 2
+# edits, and publish-validate's transcendence gate reads stale state
+# from Phase 1's pass.
+printing-press dogfood --dir "$CLI_DIR" $SPEC_FLAG "${RESEARCH_ARGS[@]}" 2>&1
printing-press verify --dir "$CLI_DIR" $SPEC_FLAG --json 2>&1
printing-press workflow-verify --dir "$CLI_DIR" --json 2>&1
printing-press verify-skill --dir "$CLI_DIR" --json 2>&1
← 618fa456 fix(cli): preserve hand-edits to templated files on --force
·
back to Cli Printing Press
·
fix(cli): force UTF-8 stdio in verify-skill Python subproces cb1697ed →