agentskills.codes
LO

looprinter-interview

Interview the user about what a loop harness should accomplish, then generate KEY_OBJECTIVE, verify_objective(), prompt functions, and the verify() gate directly into loop.sh. Use when the user wants to configure a new loop task, or says "looprinter-interview", "new loop", or "loop interview".

Install

mkdir -p .claude/skills/looprinter-interview && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/14754" && unzip -o skill.zip -d .claude/skills/looprinter-interview && rm skill.zip

Installs to .claude/skills/looprinter-interview

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Interview the user about what a loop harness should accomplish, then generate KEY_OBJECTIVE, verify_objective(), prompt functions, and the verify() gate directly into loop.sh. Use when the user wants to configure a new loop task, or says "looprinter-interview", "new loop", or "loop interview".
294 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)

About this skill

looprinter-interview

Interviews the user, then writes the result directly into loop.sh — the key objective, its programmatic verifier, and the per-cycle prompt functions and verify gate.

Output is code, not documents. There is no specs/ directory. The spec lives as executable shell functions inside loop.sh.

The interview is structured around a two-gate model:

  • verify_objective() — global gate. Decides whether the loop is truly done. Pinned to KEY_OBJECTIVE. Activating it (removing the LOOPRINTER_OBJECTIVE_TODO guard) means the loop will not exit on cycle verify alone.
  • verify() — cycle gate. Decides whether the current cycle's plan executed correctly. Failure triggers a re-plan with errors.

Stage 1 of the interview defines the global gate. Stages 2–4 define the cycle gate, deliverables, and build constraints.

What Gets Generated

From a single interview session, produce these in loop.sh:

SymbolRole
KEY_OBJECTIVE (variable)One-line north star. Injected into every prompt and paired with the global gate.
verify_objective()Global completion gate — the loop will not exit until this returns 0.
gen_plan_prompt()Plan schema + cycle deliverables.
gen_build_prompt()One-task-per-iteration contract.
gen_replan_prompt()Recovery prompt fed by cycle errors and/or objective gap.
verify()Cycle-level quality gate — did this cycle's plan execute correctly?
POST_PHASES + gen_<name>_prompt()Optional phases that run only after both gates pass.

The two gates are intentionally distinct:

  • verify()did this cycle's plan execute correctly? (schema, files exist, tasks all passes:true)
  • verify_objective()is the key objective truly met? (domain-level completion check)

The loop only exits when both return 0. If verify() passes but verify_objective() fails, the engine archives the plan as working-records/plan_cycle_<N>_objective_gap.json, removes output/plan.json, and re-plans the next increment with the objective gap injected into the replan prompt.

Interview Process

Use AskUserQuestion for each stage. Keep questions sharp — uncover what's needed to write working shell functions, not abstract requirements.

Stage 1: Key Objective (the north star)

This is the most important stage. The answers here become KEY_OBJECTIVE and verify_objective() — the global gate that decides when the loop is truly done.

Push for two things:

(a) One-line statement. Concrete, observable, no fluff. Bad: "Build a great CLI." Good: "./mycli --help exits 0 and lists at least 5 subcommands, each documented in README.md."

(b) How a script can detect it. This is what verify_objective() will run. Reject answers that need human judgment.

questions:
  - question: "What single sentence describes 'truly done' for this loop?"
    header: "Key Objective"
    options:
      - label: "Generate code/files"
        description: "A specific set of files exists with specific content"
      - label: "Transform existing code"
        description: "Existing files reach a measurable end state (tests pass, lint clean, etc.)"
      - label: "Analyze and produce a report"
        description: "A report file exists with required sections"
      - label: "Something else"
        description: "I'll describe it"

  - question: "How can a shell script detect that the objective is met?"
    header: "Objective Verifier"
    multiSelect: true
    options:
      - label: "File(s) exist with required content"
        description: "Check existence + grep for required patterns"
      - label: "Test suite or script exits 0"
        description: "Run a command and check the exit code"
      - label: "Specific count threshold"
        description: "e.g., at least N items in a JSON array"
      - label: "External signal file"
        description: "A specific file is written by a downstream check"
      - label: "Custom"
        description: "I'll describe the check"

The verifier answers must be deterministic and fast. No LLM calls. If the user can't articulate a programmatic check, push back — without one, the loop has no way to stop on real success and the brand promise of "key objective" collapses.

Stage 2: Cycle Deliverables

What artifacts must exist for verify() to pass each cycle? (This is the cycle-level gate, distinct from Stage 1's global gate.)

questions:
  - question: "Where should the loop write its deliverables?"
    header: "Output Location"
    options:
      - label: "output/ (gitignored sandbox)"
        description: "All artifacts go under output/ — disposable, easy to wipe between runs"
      - label: "Project root (committed)"
        description: "Artifacts land at the repo root or in real project paths (src/, docs/, etc.) — meant to be committed"
      - label: "Modify existing project files"
        description: "Loop edits files already in the repo (loop.sh, README, source files)"
      - label: "Mixed"
        description: "Some artifacts in output/, others in project root or existing files"

Follow up to nail down specifics:

  • Exact paths (e.g., output/report.md vs ./report.md vs src/foo.ts)
  • Whether the path should be gitignored or tracked
  • File formats (JSON, Markdown, shell, etc.)

This decision drives both the prompt (targetFile paths agents will write to) and verify() (which paths to check for existence).

Stage 3: Cycle-Level Verification

What sanity checks should run on every cycle, distinct from the global objective? This becomes the body added to verify().

This is the per-cycle gate. It catches plan execution problems (missing files, syntax errors, test regressions) that should fail the cycle and trigger a re-plan with errors. It is not where the "are we done?" question lives — that belongs in Stage 1's verify_objective().

questions:
  - question: "What should the per-cycle gate check?"
    header: "Cycle Verify"
    multiSelect: true
    options:
      - label: "Per-cycle file existence"
        description: "Files the current cycle was supposed to create/modify"
      - label: "Lint / syntax check"
        description: "Run a linter or syntax validator on changed files"
      - label: "Quick smoke tests"
        description: "Fast tests that should always pass — not the full objective verifier"
      - label: "Content sanity"
        description: "Grep for expected patterns in cycle outputs"
      - label: "Nothing extra"
        description: "Default plan-schema + progress.txt checks are enough"

For each selected method, drill into specifics:

  • Which files? Which patterns?
  • What command? What exit code = pass?

Boundary rule: if a check answers "are we done?" rather than "did this cycle execute correctly?", move it to Stage 1's verify_objective() instead.

Stage 4: Constraints

questions:
  - question: "Any constraints for the build agent?"
    header: "Build Rules"
    multiSelect: true
    options:
      - label: "Don't modify specific files"
        description: "Certain files are off-limits"
      - label: "Follow existing patterns"
        description: "Agent should study existing code first"
      - label: "Use specific tools/libraries"
        description: "Mandate certain dependencies"
      - label: "No constraints"
        description: "Agent has full freedom within output/"

Writing the Functions

After the interview, generate the symbols below. The engine prepends a "Key Objective" block to every prompt automatically via _objective_blockdo not duplicate the objective inside the prompt bodies.

KEY_OBJECTIVE (variable at the top of loop.sh)

KEY_OBJECTIVE="{one-line north star from Stage 1, no trailing period}"

If the objective is too long for one line, escalate to a function:

KEY_OBJECTIVE=""  # set blank when the function below is in use
gen_objective() {
    cat <<'EOF'
{multi-line objective}
EOF
}

…and update _objective_block to call gen_objective instead of expanding $KEY_OBJECTIVE. Default to the single-string form unless the user gave a multi-paragraph objective.

verify_objective() — the global gate

This is the function that decides whether the loop is truly done. Replace the entire body (including the LOOPRINTER_OBJECTIVE_TODO guard) with deterministic checks derived from Stage 1's "Objective Verifier" answer.

verify_objective() {
    echo "── VERIFY OBJECTIVE ──"

    local gaps=()

    # — file existence —
    [[ ! -f "output/final_report.md" ]] && gaps+=("output/final_report.md missing")

    # — required content —
    grep -q "## Conclusion" output/final_report.md 2>/dev/null \
        || gaps+=("final_report.md missing ## Conclusion section")

    # — test suite —
    if [[ -f "output/run_tests.sh" ]]; then
        bash output/run_tests.sh >/tmp/objective_tests.log 2>&1 \
            || gaps+=("test suite failed: $(tail -1 /tmp/objective_tests.log)")
    else
        gaps+=("output/run_tests.sh missing")
    fi

    if [[ ${#gaps[@]} -gt 0 ]]; then
        OBJECTIVE_GAP=$(printf '%s\n' "${gaps[@]}")
        echo "GAP:"
        printf '  - %s\n' "${gaps[@]}"
        return 1
    fi

    OBJECTIVE_GAP=""
    echo "MET"
    return 0
}

Rules:

  • Removing the LOOPRINTER_OBJECTIVE_TODO guard activates strict enforcement. Once removed, the loop will not exit until this function returns 0, so make sure real checks exist before deleting the guard.
  • OBJECTIVE_GAP must be set whenever returning 1 — it feeds the next cycle's replan prompt.
  • No LLM calls. No long-running operations. Same fast-and-deterministic rule as verify().
  • Prefer running an existing test script over hand-rolled greps when the user has tests.

gen_plan_prompt()

gen_plan_prompt() {
    _objective_block
    cat <<'PROMPT_EOF'
You are a planning agent. Create a task plan that moves toward

---

*Content truncated.*

Search skills

Search the agent skills registry