diff --git a/.claude/agents/pagekit-evaluator-pass.md b/.claude/agents/pagekit-evaluator-pass.md new file mode 100644 index 0000000..6fda20a --- /dev/null +++ b/.claude/agents/pagekit-evaluator-pass.md @@ -0,0 +1,84 @@ +--- +name: pagekit-evaluator-pass +description: Skeptical, read-only adversarial second read of a completed PageKit run. Produces runs//evaluator-pass.md. Runs after evaluation.md exists. Use when the user asks for an evaluator pass or when the pagekit orchestrator finishes a run and needs one. +tools: Read, Grep, Glob, Bash, Write +--- + +You are the PageKit evaluator-pass subagent. + +## Job + +Read a completed PageKit run (with `evaluation.md` already written) and produce an adversarial second read. You are read-only on everything except `runs//evaluator-pass.md`. + +The evaluator pass is not the evaluation. The evaluation is the run's own honest read. The evaluator pass is a skeptical outside voice that pressure-tests what the run is quietly claiming. + +## Inputs + +The orchestrator (or the user) gives you: +- path to the run folder (e.g., `runs/kind-bowl-real/`) + +Expect these inputs inside the run folder: +- `goal.md` +- all 7 artifacts (signal-doc, message-spine, first-page-decision, page-argument-shape, proof-map, first-page-draft, claim-check) +- `evaluation.md` +- `working-log.md` + +## Read first + +- `frameworks/run-logging.md` — what the evaluator pass is for and where it fits +- `frameworks/anti-slop.md` — the patterns that matter +- The existing `evaluation.md` — to know what the run claims + +## Procedure + +1. Walk the run end-to-end. Look for what the run is quietly claiming that deserves scrutiny. Examples of quiet claims: + - "The first-page decision is right" — is it? What is the confidence basis (data / signal / hypothesis)? If hypothesis, does the run label it as such? + - "The draft is ready for publication" — is it? What is still missing (testimonials, real mechanism detail, scope confirmations)? + - "The claim-check caught everything" — did it? Are there lines in the corrected draft that still read as slop or overclaim? + - "This proves X" — does it? Single runs prove less than the evaluation sometimes suggests. +2. For each scrutiny item, state the **implication**: what does it suggest for the method, the template, the framework, the skill, or the anti-slop rules? +3. End with a **punch list** of specific repo improvements the run exposed. Each item should name the file that would change. This is how the run-to-repo-improvement loop closes. +4. Close with a **final evaluator read**: one paragraph. Is the run real? What does it prove? What does it not prove? + +## Output + +Write `runs//evaluator-pass.md` with sections: + +```markdown +# Evaluator Pass + +Skeptical second read of the run. Not the same voice as `evaluation.md`; this pass is deliberately adversarial. + +## Things the run is quietly claiming that deserve scrutiny + +### 1. + + +**Implication:** + +### 2. +... + +## Punch list for repo improvement + +1. **** — +2. **** — + +## Final evaluator read + + +``` + +## Hard rules + +- Do not reward defensiveness. Skeptical means skeptical. +- Do not generate new artifacts for the run (no new drafts, no new proof maps). You are read-only on the run itself. +- Do not mark items as "already fixed" that the run did not actually fix. +- If the run skipped the claim-check step or did not hit the fully-logged tier, call it out in section 1 regardless of what `evaluation.md` says. + +## Return + +When done, hand back to the caller: +- path to `runs//evaluator-pass.md` +- count of scrutiny items and punch-list items +- final evaluator read in one line diff --git a/.claude/skills/pagekit-evaluator-pass/SKILL.md b/.claude/skills/pagekit-evaluator-pass/SKILL.md new file mode 100644 index 0000000..860f4ac --- /dev/null +++ b/.claude/skills/pagekit-evaluator-pass/SKILL.md @@ -0,0 +1,43 @@ +--- +name: pagekit-evaluator-pass +description: Run the adversarial evaluator pass on a completed PageKit run. Post-evaluation skeptical second read. Use when a run has an evaluation.md but no evaluator-pass.md, or when the orchestrator needs an evaluator pass. Delegates to the pagekit-evaluator-pass subagent. +--- + +# PageKit Evaluator Pass + +You are invoking the adversarial evaluator pass on a completed run. + +## When to use + +- After the run's `evaluation.md` is written. +- Before declaring the run fully-logged (the fully-logged tier requires `evaluator-pass.md`). +- When a reviewer asks "is this run actually as good as the evaluation says?" + +## Read first +- `frameworks/run-logging.md` — where the evaluator pass fits in the run-logging tier +- `.claude/agents/pagekit-evaluator-pass.md` — the subagent you will delegate to + +## Inputs +- path to the run folder (e.g., `runs/kind-bowl-real/`) + +## Procedure + +1. Confirm the run has `evaluation.md`. If not, the evaluator pass is premature — finish the evaluation first. +2. Invoke the `pagekit-evaluator-pass` subagent. Pass the run-folder path. +3. The subagent runs read-only, produces `runs//evaluator-pass.md`, and hands back a summary (count of scrutiny items, count of punch-list items, one-line final read). +4. Relay the result to the caller. If the punch list contains actionable repo changes, name them for the caller so the run-to-repo-improvement loop can close. + +## Quality gate + +A strong evaluator pass: +- names specific quiet claims from the run, not general impressions +- writes an "implication" for each scrutiny item (what this suggests for the method or the repo) +- ends with a concrete punch list of file-level changes +- does not reward defensiveness + +If the subagent's output is general rather than specific, ask it to retry with more direct reference to the run's artifacts. + +## Relationship to `pagekit-claim-checker` + +- `pagekit-claim-checker` reviews the **draft** line by line at a chosen severity. +- `pagekit-evaluator-pass` reviews the **whole run** including what the evaluation quietly claims. Different target, different voice. diff --git a/.github/ISSUE_TEMPLATE/bug.md b/.github/ISSUE_TEMPLATE/bug.md new file mode 100644 index 0000000..8d173d8 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.md @@ -0,0 +1,31 @@ +--- +name: Bug (scripts / skills / hook misbehaving) +about: Something in the PageKit tooling broke. Not a method issue. +title: "[bug] " +labels: bug +--- + +## What broke + + + +## Repro + +1. +2. +3. + +## Expected vs. actual + + + +## Environment + +- OS: +- Shell: +- Claude Code / Codex / Cowork version: +- Anything non-default about the install? + +## Output + + diff --git a/.github/ISSUE_TEMPLATE/method-feedback.md b/.github/ISSUE_TEMPLATE/method-feedback.md new file mode 100644 index 0000000..24d90ef --- /dev/null +++ b/.github/ISSUE_TEMPLATE/method-feedback.md @@ -0,0 +1,22 @@ +--- +name: Method feedback (I used PageKit) +about: You ran PageKit on an object and something broke, drifted, or felt wrong. +title: "[feedback] " +labels: method-feedback +--- + +## What you were trying to do + + + +## What actually happened + + + +## Run link (if logged) + + + +## Your read on the fix + + diff --git a/.github/ISSUE_TEMPLATE/method-proposal.md b/.github/ISSUE_TEMPLATE/method-proposal.md new file mode 100644 index 0000000..78d4111 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/method-proposal.md @@ -0,0 +1,26 @@ +--- +name: Method proposal (add / change / retire a part of PageKit) +about: You want to add a step, framework, template, skill, or change the chain. +title: "[proposal] " +labels: method-proposal +--- + +## What you're proposing + + + +## Why this exists + + + +## What changes + + + +## What stays stable + + + +## Risk + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..3572325 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,23 @@ + + +## Summary + + + +## What changed + + + +## Verification + +- [ ] `bash scripts/doctor.sh` → PASS +- [ ] `bash scripts/slop-check.sh` → exit 0 clean +- [ ] (if the PR touches run structure) `bash scripts/run-check.sh runs/` → FULLY LOGGED (or tier you target) +- [ ] (if the PR touches prompts/frameworks) reviewed against `AGENTS.md` and `CLAUDE.md` for consistency + +## Notes for the reviewer + + diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 0000000..0e74597 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,23 @@ +name: PageKit checks + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + checks: + name: doctor + slop-check + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Make scripts executable + run: chmod +x scripts/*.sh + + - name: Run doctor + run: bash scripts/doctor.sh + + - name: Run slop-check (default scan) + run: bash scripts/slop-check.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..fde70ab --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,33 @@ +# Pre-commit configuration for PageKit. +# +# Install locally: +# pip install pre-commit +# pre-commit install +# +# What runs on every commit: +# - slop-check.sh against tracked drafts (catches the mechanical AI-slop +# tells before the PR stage) +# - doctor.sh (the same pre-flight that the SessionStart hook runs) +# +# Slower / semantic checks (claim-check prompt expansion, run-check) are +# not wired here because they need arguments. Invoke them manually from +# the run folder. + +repos: + - repo: local + hooks: + - id: pagekit-slop-check + name: PageKit slop-check (default scan) + entry: bash scripts/slop-check.sh + language: system + pass_filenames: false + always_run: true + stages: [pre-commit] + + - id: pagekit-doctor + name: PageKit doctor + entry: bash scripts/doctor.sh + language: system + pass_filenames: false + always_run: true + stages: [pre-commit] diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..225df27 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,50 @@ +# Changelog + +All notable changes to PageKit are documented here. + +Format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). SemVer applies loosely — we bump minor when the canonical method changes, patch when only docs/tooling change. + +## [Unreleased] + +### Added +- `.github/workflows/check.yml` runs `doctor.sh` and `slop-check.sh` on every push and PR. +- `.github/PULL_REQUEST_TEMPLATE.md` + issue templates (`method-feedback`, `bug`, `method-proposal`). +- `CONTRIBUTING.md` — four shapes of contribution, required checks, what bad contribution looks like. +- `CHANGELOG.md` — this file. +- `.pre-commit-config.yaml` — local enforcement of `slop-check.sh`. +- `scripts/new-source-brief.sh` — scaffold an individual source brief (wedge / mechanism / proof / comparison). +- `.claude/agents/pagekit-evaluator-pass.md` — read-only subagent for adversarial evaluator-pass work. +- `.claude/skills/pagekit-evaluator-pass/SKILL.md` — skill wrapper that delegates to the subagent. +- `scripts/run-check.sh` — new tier above FULLY LOGGED: **PUBLISHABLE** (fully logged + claim-check present + slop-check clean). + +### Changed +- `README.md` — sharper public-facing hero; points at `runs/vegan-dog-food-verdel/` as the canonical worked example. +- `scripts/doctor.sh` — includes the new subagent and skill in its manifest checks. + +## [0.1.0] — 2026-04-14 + +Baseline public release. The agentic foundation is in place. + +### Added +- Canonical method manifest (`pagekit.yaml`) and canonical prompts (`prompts/01-07-*.md`). +- `AGENTS.md` (Codex-first agent contract) + expanded `CLAUDE.md` operational section. +- Anti-slop framework (`frameworks/anti-slop.md`) + regression script (`scripts/slop-check.sh`). +- Claim-check framework + severity calibration (light / normal / hard) + `ai-slop tell` flag type. +- Run-logging framework with fully-logged / summary-logged tiers; `sources/` and `evaluator-pass` required at fully-logged. +- First-page-decision framework with hard "case FOR each candidate" requirement and the first-page-alternatives-vs-later-funnel-pages distinction. +- Page-argument-shape framework with length/density consideration and the anti-slop drafting constraints block. +- 8 templates including `output-judgment-template.md`, `wedge-definition-template.md`, `claim-check-template.md`. +- 7 guided-run READMEs (`guided-runs/01-07`). +- 5 tool guides (ChatGPT, Claude, Perplexity, Grok, OpenAI) and 5 matching quickstarts — all reference canonical prompts by path, not by copy. +- Third tier `agentic/` with paths for Claude Code, Codex, Claude Cowork. +- Claude Code skills bundle: master `pagekit` orchestrator + 7 per-step skills + 3 tooling skills + `pagekit-claim-checker` subagent. +- `.claude/settings.json` SessionStart hook running `scripts/doctor.sh`. +- Scripts: `new-run.sh`, `run-check.sh`, `claim-check.sh`, `slop-check.sh`, `doctor.sh`; `Makefile` with discoverable targets. +- `runs/vegan-dog-food-verdel/` — first fully-logged run on the agentic foundation. Non-homepage first page. First real exercise of the claim-check step. +- `LICENSE` (MIT) and `.gitignore`. + +### Notes +- PRs #1–#8 all merged prior to this release. See the GitHub PR history for the run-to-repo-improvement loop that produced the method surface. + +[Unreleased]: https://github.com/hnshah/pagekit/compare/v0.1.0...HEAD +[0.1.0]: https://github.com/hnshah/pagekit/releases/tag/v0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3c2f38b --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,75 @@ +# Contributing to PageKit + +Thanks for looking at this. PageKit is a methodology repo plus the scaffolding that lets an agent drive the method end-to-end. Contributions fall into four shapes, each with a slightly different bar. + +## The method in one sentence + +**Signal doc → message spine → first-page decision → page argument shape → proof map → first page draft → (optional) claim check.** + +Canonical source of truth: `pagekit.yaml` and `prompts/`. Edit canonical prompts in one place; guides reference them. + +## Four kinds of contribution + +### 1. Method change (add/change/retire a step, framework, template, rule) + +The bar is high and the shape is prescribed: + +1. Open an issue using the `method-proposal` template. Name the run or evaluator-pass that surfaced the gap. Proposals without run evidence land lower. +2. If we agree on the change, the PR should update the canonical surface plus every downstream surface that references it (framework, template, prompt, skill, guided-run, CLAUDE.md, AGENTS.md if relevant). Run `bash scripts/doctor.sh` to verify. +3. When the change is driven by a specific run's evaluator-pass, cite that run in the PR body. The method-change loop is: `run → evaluator-pass → punch list → method change`. + +### 2. A logged run + +The most useful contribution for strengthening the method is a real run. + +- Use `bash scripts/new-run.sh ` to scaffold. +- Fully-logged tier is the bar for anything you want counted as evidence. Run `bash scripts/run-check.sh runs/` to verify. +- Run the slop-check before claim-check and after: `bash scripts/slop-check.sh`. +- Include an `evaluator-pass.md` (adversarial, skeptical). This is the part most easily skipped and the part that most often surfaces the improvements in the next PR. +- If the run exposes a repo gap, file a `method-proposal` issue (or a follow-up PR) so the loop closes. + +### 3. Tooling (scripts, CI, hooks, skills, subagents) + +- Scripts live in `scripts/`. POSIX-leaning bash, exit 0 on success / non-zero on failure (so they work in hooks and CI). +- Skills live in `.claude/skills/pagekit-*/SKILL.md`. Each has YAML frontmatter (`name`, `description`, optional `tools`). The description is what determines auto-invocation — front-load the trigger phrase. +- Subagents live in `.claude/agents/`. Scope the `tools:` field tightly. +- Always update `scripts/doctor.sh` if you add a file the repo should guarantee exists. + +### 4. Docs (README, guides, quickstarts, CLAUDE.md, AGENTS.md) + +- Canonical prompts live in `prompts/`. Guides reference them; do not duplicate the prompt text into a guide. +- Anything in `README.md`, `START-HERE.md`, `CLAUDE.md`, or `AGENTS.md` that describes the method must agree with `pagekit.yaml` and with `frameworks/`. If you change one, grep for the others. +- Anti-slop rules apply to the docs too. See `frameworks/anti-slop.md`. `scripts/slop-check.sh` catches the mechanical tells. + +## Required checks before a PR + +```sh +bash scripts/doctor.sh # PASS +bash scripts/slop-check.sh # exit 0 +# if the PR touches runs/ +bash scripts/run-check.sh runs/ +``` + +CI runs `doctor.sh` and `slop-check.sh` on every PR (see `.github/workflows/check.yml`). + +If you want local enforcement before commit, `.pre-commit-config.yaml` is set up; install with `pip install pre-commit && pre-commit install`. + +## PR shape + +Use the PR template. Keep summaries short, verification concrete. Reviews look for: +- does the PR follow the source-of-truth rule (edit canonical, let downstream pick it up)? +- does CI pass? +- if it touches prompts/frameworks/skills, do they still agree with each other? +- if it claims to fix something a run surfaced, is the run named? + +## What bad contribution looks like + +- A draft rewrite with no slop-check / claim-check audit trail +- A new guide that duplicates a prompt instead of referencing `prompts/` +- A method change without a run behind it +- A run that skips the evaluator pass and calls itself fully-logged +- A PR that adds 35 mentions of the same rule across 5 guides instead of editing one canonical file + +## Questions + +Open an issue. Use the `method-feedback` template for "I tried to use this and it didn't work," the `bug` template for tooling, the `method-proposal` template for "I want to change the chain." diff --git a/README.md b/README.md index 466c60d..d43f518 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,28 @@ # PageKit -*A practical system for getting to better pages by strengthening the source materials that shape the copy.* +**Better page copy usually starts with better source materials.** + +PageKit is a method for producing web pages that do not sound AI-written. It works by strengthening the inputs (signal, spine, first-page decision, page-argument shape, proof map) before asking any model to draft the page. An anti-slop layer and an optional claim-check step keep the draft honest. + +The repo ships the method, the canonical prompts, a Claude Code skills bundle, a Codex `AGENTS.md` contract, a Claude Cowork plugin body, and scripts that mechanize the structural work. Everything an agent needs to run PageKit end-to-end is here. + +**See what a run looks like**: [`runs/vegan-dog-food-verdel/`](runs/vegan-dog-food-verdel/) is the canonical worked example. Fully-logged, non-homepage first page, claim-checked at hard severity, with evaluator pass. + +## What PageKit helps you go from -PageKit helps you go from: - vague market understanding - weak source material - generic page direction +- AI-slop drafts + +## … to -to: - a sharper signal doc - a clearer message spine - a deliberate first-page decision - a page argument shape that fits the object - a proof map with honest constraints -- a page draft grounded in better inputs - -This repo gives you a guided, markdown-first way to improve the materials that drive page copy. +- a page draft grounded in better inputs that does not read as machine-written ## Who this is for diff --git a/scripts/doctor.sh b/scripts/doctor.sh index 17c27f6..2ad8a0c 100755 --- a/scripts/doctor.sh +++ b/scripts/doctor.sh @@ -110,6 +110,7 @@ echo echo "Scripts:" check_exec "scripts/new-run.sh" +check_exec "scripts/new-source-brief.sh" check_exec "scripts/run-check.sh" check_exec "scripts/claim-check.sh" check_exec "scripts/slop-check.sh" @@ -119,10 +120,11 @@ echo echo "Claude Code bundle:" check_file ".claude/skills/pagekit/SKILL.md" -for s in signal-doc message-spine first-page-decision page-argument-shape proof-map first-page-draft claim-check new-run run-check slop-check; do +for s in signal-doc message-spine first-page-decision page-argument-shape proof-map first-page-draft claim-check evaluator-pass new-run run-check slop-check; do check_file ".claude/skills/pagekit-$s/SKILL.md" done check_file ".claude/agents/pagekit-claim-checker.md" +check_file ".claude/agents/pagekit-evaluator-pass.md" check_file ".claude/settings.json" echo diff --git a/scripts/new-source-brief.sh b/scripts/new-source-brief.sh new file mode 100755 index 0000000..1b23705 --- /dev/null +++ b/scripts/new-source-brief.sh @@ -0,0 +1,253 @@ +#!/usr/bin/env bash +# new-source-brief.sh — scaffold a single source brief inside a run. +# +# Usage: +# scripts/new-source-brief.sh +# +# is one of: +# wedge — wedge-definition brief (when signal is still category-level) +# mechanism — mechanism brief (how the product does what it claims) +# proof — proof brief (what evidence exists; what does not) +# comparison — comparison brief (what the product is and is not compared to) +# +# Creates runs//sources/NN--brief.md where NN is the +# next available number in the sources/ folder (02 and up; 01 is source-capture). +# +# Scripted source briefs keep runs structurally consistent and stop agents +# from reconstructing brief layouts from memory on every run. + +set -euo pipefail + +usage() { + cat <&2 +usage: scripts/new-source-brief.sh + +brief-type options: + wedge wedge-definition brief + mechanism mechanism brief + proof proof brief + comparison comparison brief + +examples: + scripts/new-source-brief.sh kind-bowl wedge + scripts/new-source-brief.sh kind-bowl mechanism +EOF + exit 2 +} + +[ "$#" -eq 2 ] || usage + +RUN_NAME="$1" +BRIEF="$2" + +case "$BRIEF" in + wedge|mechanism|proof|comparison) ;; + *) usage ;; +esac + +REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)" +RUN_DIR="$REPO_ROOT/runs/$RUN_NAME" +SRC_DIR="$RUN_DIR/sources" + +[ -d "$RUN_DIR" ] || { echo "error: run folder not found: $RUN_DIR" >&2; exit 1; } +[ -d "$SRC_DIR" ] || { echo "error: sources/ not found in $RUN_DIR; scaffold the run first with new-run.sh" >&2; exit 1; } + +# Pick the next two-digit index. Start at 02 (01 is reserved for source-capture). +next_index() { + local max=1 + local f n + # shellcheck disable=SC2045 + for f in $(ls "$SRC_DIR" 2>/dev/null); do + n="$(echo "$f" | grep -Eo '^[0-9]{2}' || true)" + [ -z "$n" ] && continue + # strip leading zero for arithmetic + n="$((10#$n))" + [ "$n" -gt "$max" ] && max="$n" + done + printf "%02d" $((max + 1)) +} + +INDEX="$(next_index)" +OUT="$SRC_DIR/${INDEX}-${BRIEF}-brief.md" + +# Canonical content per brief type. Kept in one place so the four briefs stay consistent. +case "$BRIEF" in + + wedge) + cat > "$OUT" < "$OUT" < "$OUT" < "$OUT" < # -# Classifies the run as fully-logged, summary-logged, artifact-only, or -# incomplete, per frameworks/run-logging.md. Lists missing files for the -# highest tier not met. +# Tiers (ascending): +# INCOMPLETE no core artifacts +# ARTIFACT-ONLY core artifacts but missing logging scaffolding +# SUMMARY LOGGED goal + working-log + models + evaluation + all 6 artifacts +# FULLY LOGGED + sources/, prompts/NN-*.md, outputs/NN-*-output.md, evaluator-pass.md +# PUBLISHABLE + claim-check.md, and slop-check clean on the drafts # # Exit code: -# 0 fully-logged -# 0 summary-logged (also treated as valid) -# 1 artifact-only or incomplete +# 0 SUMMARY LOGGED, FULLY LOGGED, or PUBLISHABLE +# 1 ARTIFACT-ONLY or INCOMPLETE set -u @@ -112,8 +114,68 @@ done echo "run-check: $RUN" echo +# PUBLISHABLE tier check: FULLY LOGGED + claim-check.md filled in (not a +# placeholder) + slop-check clean on the relevant drafts. +# +# The scaffold from new-run.sh seeds every required file with a bracketed +# `*[Filled in by step NN ...]*` placeholder. PUBLISHABLE requires those +# placeholders to be replaced with real content in claim-check.md and in +# the final artifact most sensitive to content: first-page-draft.md. +check_publishable() { + local run="$1" + local missing_pub=() + + # claim-check.md required AND not still the scaffolded placeholder. + if [ ! -f "$run/claim-check.md" ]; then + missing_pub+=("missing file: claim-check.md") + elif grep -q "Filled in by step 07" "$run/claim-check.md" 2>/dev/null; then + missing_pub+=("claim-check.md still carries the scaffold placeholder — not yet filled in") + fi + + # first-page-draft.md required AND not still the scaffolded placeholder. + if [ ! -f "$run/first-page-draft.md" ]; then + missing_pub+=("missing file: first-page-draft.md") + elif grep -q "Filled in by step 06" "$run/first-page-draft.md" 2>/dev/null; then + missing_pub+=("first-page-draft.md still carries the scaffold placeholder — not yet filled in") + fi + + # slop-check must come back clean on the draft and the corrected draft if + # it exists. If scripts/slop-check.sh is missing, we treat that as a + # repo-health problem, not a run problem. + local slop_script + slop_script="$(cd "$(dirname "$0")" && pwd)/slop-check.sh" + if [ -x "$slop_script" ]; then + local slop_targets=() + [ -f "$run/first-page-draft.md" ] && slop_targets+=("$run/first-page-draft.md") + [ -f "$run/first-page-draft-corrected.md" ] && slop_targets+=("$run/first-page-draft-corrected.md") + if [ "${#slop_targets[@]}" -gt 0 ]; then + if ! bash "$slop_script" "${slop_targets[@]}" >/dev/null 2>&1; then + missing_pub+=("slop-check flagged at least one pattern on the draft(s)") + fi + fi + fi + + printf '%s\n' "${missing_pub[@]}" +} + if [ "${#missing_fully[@]}" -eq 0 ]; then + # Already fully-logged. Try to upgrade to PUBLISHABLE. + missing_pub=() + while IFS= read -r line; do + [ -n "$line" ] && missing_pub+=("$line") + done < <(check_publishable "$RUN") + + if [ "${#missing_pub[@]}" -eq 0 ]; then + echo "tier: PUBLISHABLE" + exit 0 + fi + echo "tier: FULLY LOGGED" + echo + echo "This run does not meet PUBLISHABLE. Missing for publishable:" + for m in "${missing_pub[@]}"; do + echo " - $m" + done exit 0 fi