Skip to content
Agentmart
Submit a tool

harness-stream

Streaming / living-pool mode.

Skill by Alan-IFT

IndexedMIT
Write a review

Chalk Labs

Need help deploying harness-stream?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

Install

Works with Claude Code. Read the repository before you give any tool access to your data.

npx agentmarket install skill/alan-ift-harness-stream

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Streaming / living-pool mode. Drains a continuously-growable task pool one task at a time through pm-orchestrator, re-reading the pool every iteration so tasks you add mid-run are picked up without re-invoking. Best-effort — a failed task is marked and skipped, and a task needing human input is deferred and surfaced at stream end rather than halting the stream. Includes an ambient mode (invoke with no pool-id) where every chat message folds new requirements into the default pool and drains it. Use when you want to fire requirements at the AI as they occur to you and only watch results — "keep draining a pool I keep adding to", "边开发边不断加任务", "想到啥需求就丢进去,只看结果". NOT /harness-batch (a fixed list that cannot grow mid-run).

Use cases: productivity

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/harness-stream

Tools it pre-approves 8

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Read,
  • Write,
  • Edit,
  • Glob,
  • Grep,
  • Bash,
  • TodoWrite,
  • Task

What's inside

Skill name
harness-stream
Description
Streaming / living-pool mode. Drains a continuously-growable task pool one task at a time through pm-orchestrator, re-reading the pool every iteration so tasks you add mid-run are picked up without re-invoking. Best-effort — a failed task is marked and skipped, and a task needing human input is deferred and surfaced at stream end rather than halting the stream. Includes an ambient mode (invoke with no pool-id) where every chat message folds new requirements into the default pool and drains it. Use when you want to fire requirements at the AI as they occur to you and only watch results — "keep draining a pool I keep adding to", "边开发边不断加任务", "想到啥需求就丢进去,只看结果". NOT /harness-batch (a fixed list that cannot grow mid-run).
License
MIT
Allowed tools
Read,, Write,, Edit,, Glob,, Grep,, Bash,, TodoWrite,, Task
Instructions
214 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves some shell commands

Files (1)

  • SKILL.md

SKILL.md (first lines)

# /harness-stream

Drain a **living task pool** through the full 7-stage pipeline, one task at a time, re-reading the pool every iteration. Unlike `/harness-batch` (which freezes the plan at start and stops on the first hard failure), the stream **picks up tasks you add while it runs** and keeps going past a single task's failure. This is the **"I only propose requirements and watch results"** mode.

## When to invoke

- You're developing and keep discovering new work — "also add X", "while you're at it fix Y" — and you don't want to wait for the current run to finish before queuing it.
- You want a standing drain loop: keep a pool of tasks topped up, let the AI plan order and execute, you just append and observe.
- You've been using `/harness-batch` and want the same pool to stay *open* instead of freezing at start.

The hallmark: the task list is **open-ended and grows during execution**, and you prefer "keep completing everything, tell me what broke, but don't halt the whole run over one failure".

## When NOT to invoke

| Symptom | Use this instead |
|---|---|
| A fixed, known list of tasks; stop on first failure | `/harness-batch` |
| Exactly one task | `/harness` (full 7-stage) |
| Iterate ONE goal until a measurable criterion | `/harness-goal` |
| "Vet a design before code" | `/harness-plan` |
| "Can we even do X?" / research | `/harness-explore` |
| Pause / redirect a running stream | `/harness-intervene` (or append to the pool) |

## The pool

The pool reuses the batch plan format so a batch can graduate into a stream and vice-versa:

- File: `docs/batches/<pool-id>/BATCH_PLAN.md`.
- Columns: `ID | Slug | Goal | Mode | Depends on | Status` (same validation as `/harness-batch`).
- If invoked **with a pool-id** and that file doesn't exist, point the user at `docs/batches/_template/BATCH_PLAN.md`, ask them to copy it to `docs/batches/<pool-id>/BATCH_PLAN.md`, seed at least one `pending` row, then re-invoke. (A typo'd pool-id therefore errors loudly rather than silently creating a new pool.)
- If invoked **with no pool-id**, the pool resolves to the **default pool** `docs/batches/default/BATCH_PLAN.md`, and — unlike the named-pool case — it is **auto-created** when absent by copying `docs/batches/_template/BATCH_PLAN.md`, replacing `<batch-id>` with `default`, and **stripping the example `T-01..T-03` rows** so the table starts empty. The no-arg default pool is the foundation of ambient mode (below).

The pool is **append-only-friendly**: you may add rows at any time, including while the stream is running. The stream re-reads the file every iteration, so new `pending` rows are planned into the topological frontier on the next pass.

## Two ways to add work mid-run (and the timing truth)

A running stream consumes input from two channels. Understand the timing — it's the whole point of this mode:

1. **File channel (instant).** Append a `pending` row to `BATCH_PLAN.md`, or drop an `ADD <slug> — <goal>` line in `.harness/intervention.md` (via `/harness-intervene` or by hand). The loop re-reads both at the **top of every iteration**, so a file write lands on the **next task boundary** regardless of what the AI is doing. This works even in a single continuous run.

2. **Chat channel (next tick).** Type the requirement in the chat box. While the AI is mid-task its turn is busy, so your message **queues and is delivered when the current turn ends** — i.e. it is ingested at the next iteration, not mid-task. To make this prompt, run the stream under the `/loop` driver (below) so each iteration is its own short turn. The stream **mirrors any chat-supplied requirement into the pool file** before acting on it, so nothing is lost.

If you want truly instant insertion without waiting for a task to finish, use the file channel. If you want to "just type and forget", use the chat channel under `/loop`.

## Drivers — pick one

- **Hands-off chat driver (recommended for "fire in chat").** Run `/loop /harness-stream <pool-id>` (self-paced). Each tick is its OWN turn that processes one task, so a chat message typed during a task is delivered when that tick ends and ingested on the next tick. **This is the only driver that delivers the headline "type a requirement in chat, AI folds it in, I just watch" experience**, because only a fresh turn can carry your queued chat. It also makes the "keep the pool topped up and idle until I add more" behavior real — each tick is a genuine new turn.
- **Continuous run (no dependencies, file-channel only).** Invoke `/harness-stream <pool-id>` once; the skill loops internally in a single turn, re-reading the pool file each iteration. The **file channel works perfectly here** (each iteration re-reads `BATCH_PLAN.md` + `intervention.md`), but **chat does NOT** — a message typed mid-run is queued by Claude Code until the whole invocation ends, so it cannot be ingested between internal iterations. Use this when you'll add work by appending to the pool / sending `ADD` interventions, not by chatting. Because a single turn cannot block-wait, this driver **drains the current pool and exits** rather than idling for future additions (re-invoke to drain more).

**Always state the chosen driver to the user at start, and the timing truth above.** In particular: if `/loop` is unavailable, warn explicitly that the pure chat-driven experience is not available — they must add work via the file / `ADD` channel, and chat typed mid-run won't be picked up until the run ends.

## Ambient mode (no-arg default pool + chat heartbeat)

Ambient mode is the **minimal "start once, then just keep typing" experience**: you enter ambient mode once, then every ordinary chat message becomes a turn in which the AI folds any requirement into the **default pool** and drains it — **no `/loop`, no pool-id, no re-invocation**. It works because each user message is itself a turn, and a `UserPromptSubmit` hook turns that turn into the scheduler's heartbeat.

### How it works

- **The flag.** Ambient mode is gated by a single transient flag file `.harness/ambient.flag` (gitignored, like `.harness/intervention.md`). **Presence = ambient ON; absence = ambient OFF.** It is **session-scoped**: a `SessionStart` hook (`.harness/scripts/ambient-reset.sh`) deletes the flag at the start of every new session, so ambient never silently carries over and there is no "off" keyword to remember.
- **The heartbeat hook.** A `UserPromptSubmit` hook (`.harness/scripts/ambient-prompt.sh`, wired in `.claude/settings.json`) runs on every user turn. When `.harness/ambient.flag` is present it prints an instruction block that Claude Code injects into the turn as added context — telling the agent to ingest+drain (below). When the flag is absent the hook prints **nothing** (no-op), so normal chat is unaffected. The hook never does the work itself and never blocks a turn (it always exits 0); Claude is the worker.
- **Serial only.** One task at a time — same as the rest of this skill. No parallel dispatch.
- **Resume is free.** The default pool file is the persistent state; a partially-drained pool resumes on the next message via the existing resume semantics (skip rows whose `07_DELIVERY.md` is DELIVERED).

### Enter / exit

- **Enter:** just invoke **`/harness-stream` with no pool-id** — that single action *is* "ambient on" (no keyword to remember). On enter the skill: (1) writes `.harness/ambient.flag`; (2) ensures `docs/batches/default/BATCH_PLAN.md` exists (auto-create from `_template`, empty table); (3) tells you: "Ambient mode on for this session. Type requirements; I'll fold each into the default pool and drain it."
- **Exit:** **automatic** — ambient mode is **session-scoped**. A `SessionStart` hook (`.harness/scripts/ambient-reset.sh`) clears `.harness/ambient.flag` at the start of every new session, so a fresh session is never silently in ambient mode; re-invoke `/harness-stream` to resume. To stop mid-session, delete `.harness/ambient.flag` (or just tell the AI to stop). There is no "off" keyword to remember.

### Each ambient turn (what the agent does when the flag is set)

1. **Ingest.** If your message reads as a requirement (not a question or aside), normalize it into `docs/batches/default/BATCH_PLAN.md` per "Ingest triage" below — one `pending` row, or N decomposed rows when the triage test fires (`Mode` per row, default `full`), de-duplicating against existing slugs/goals first. If a message is ambiguous (you cannot file it as exactly one well-formed task), do NOT guess and do NOT block: record a needs-human clarification entry ("clarify before I can file this as a task: <the ambiguous message verbatim>") to the deferred-human queue and keep draining. A plain question/aside creates **no** row.
2. **Drain.** Drain ready tasks in topological order via `pm-orchestrator`, one at a time, best-effort, honoring the existing hard-safety stops, until the pool is empty — identical to the Procedure loop below.
3. **Stop and wait** for your next message.

### Ambient vs the `/loop` chat driver

Ambient mode is **not** `/loop`. `/loop` makes the AI act while you're **silent** (idle/unattended progress); ambient mode acts **only on your messages** — your own typing is the heartbeat. Ambient mode is explicitly the minimal version: no idle progress, no background process. If you want progress while you're away, that is a separate (out-of-scope-here) `/loop` concern.

## Ingest triage (one row or many)

Applies wherever the STREAM normalizes natural language into pool rows: chat-channel ingest (Procedure 3a) and ambient turns. It NEVER applies to rows the user authored — an `ADD <slug> — <goal>` line or a hand-written pool row is honored verbatim as ONE task, at the user's chosen granularity, and an existing row is never re-triaged.

**Triage test — decompose only when BOTH hold:**
1. The message contains two or more outcomes that are each *independently verifiable deliverables* — each could pass its own QA and reach DELIVERED on its own (signals: an "and"-chain or enumeration of distinct outcomes; outcomes touching distinct subsystems or artifact classes; phased phrasing — "X, then Y" / "先…再…").
2. No single one-sentence Goal can state the requirement without conjoining those outcomes.

**NOT complex (always one row):** a single deliverable with wide fan-out (one change echoed across many files); long prose describing one outcome; a list of acceptance details for one outcome.

**When the test fires, write N ≥ 2 `pending` rows (same columns, no schema change):**
- **Slug:** derive a base slug from the requirement; every sub-row slug starts with `<base>-` (e.g. `csv-export-endpoint`, `csv-export-button`). Add one provenance line to the pool's `## Notes` section: `Decomposed <base>-* (N rows) ← "<original requirement, one line>" (YYYY-MM-DD)`.
- **Goal:** one sentence, exactly ONE independently verifiable deliverable per row. **Union invariant:** the union of the sub-row Goals must equal the original message — no invented scope, no dropped scope. If any requested outcome cannot be placed in exactly one row, that is ambiguity: ask, don't guess.
- **Depends on:** chain only REAL consumption (row B uses an artifact or behavior row A produces). Independent siblings stay unchained (`—`) so a failed sibling never blocks them.
- **Mode:** per row via the normal workflow-entry mapping (default `full`; a pure research sub-step may be `explore`).
- **Fixed point:** every produced row must FAIL test 1 on its own (exactly one deliverable), so re-running triage on any produced row returns it unchanged.
- De-duplicate each sub-row against existing slugs/goals, as for any new row.
- **Announce** in the ack which IDs/slugs were created from the requirement and the dependency shape; correct a wrong split via the pool, `SKIP`, or `/harness-intervene`.

A requirement that fails the test gets exactly today's one-row path — no marker, no announcement. Once written, derived rows are ordinary pool rows: resume, de-dup, `SKIP`, edits, and failure semantics apply identically.

Each row the triage writes (and each hand-authored row) should be a tracer-bullet vertical slice sized to the smart zone — see `harness-plan` → "Task-decomposition discipline" for what makes a good row.

## Procedure

1. **Argument validation.** With a pool-id: confirm `docs/batches/<pool-id>/BATCH_PLAN.md` exists; if not, surface the template path and stop. **With no pool-id:** resolve to `docs/batches/default/BATCH_PLAN.md` and **auto-create it** (from `_template`, empty table) if absent — this is the ambient-mode default pool.

2. **Pre-flight (once per stream start; cheap and idempotent so it's safe under `/loop`):**
   - `.harness/scripts/verify_all` baseline — capture PASS/WARN/FAIL. If already FAIL, **refuse to start** (a broken baseline makes per-task regression detection impossible). Surface and exit.
   - `.harness/insight-index.md` — read once; surface relevant lines into each task's pm-orchestrator dispatch prompt.
   - `.harness/intervention.md` — consume any pending signal per `.harness/rules/65-intervention.md` (a `STOP` here aborts before any task).

3. **Iteration loop** (one task per pass; repeat until the exit condition fires):
   - **a. Ingest.** **File channel (always):** re-read `BATCH_PLAN.md` and check `.harness/intervention.md` (below). **Chat channel (only under the `/loop` driver):** the user message(s) delivered with *this tick's turn* may contain new requirements — for each that clearly reads as a task (not a question or aside), **normalize it into `pending` row(s) per "Ingest triage" above** — one row, or N decomposed rows when the triage test fires (assign `ID`/`Slug`/`Goal`/`Mode`/`Depends on` per row), de-duplicating against existing slugs/goals first; if a message is ambiguous, do NOT guess and do NOT issue a blocking prompt: record a needs-human clarification entry (`stage=ingest`, verbatim message, "clarify before I can file this as a task") to the deferred-human queue and continue draining. Under the continuous driver there is no mid-run chat to read — skip the chat part. Then act on `.harness/intervention.md`:
     - `ADD <slug> — <goal>` → append/upsert a `pending` row, delete the intervention file, continue (user-authored: honored verbatim as ONE row, never triaged).
     - `STOP` → halt the stream (strong signal). `NOTE` → attach to the next dispatch. `SKIP <id>` → mark that row `skipped`. (`REDIRECT <id>` → reject; it targets stages, not tasks.)
   - **b. Plan.** Validate the table (required columns, unique slugs, no `Depends on` cycle). Build the topological frontier of runnable rows honoring `Depends on`. **Resume semantics (same as batch):** a row whose `docs/features/<slug>/07_DELIVERY.md` parses as `DELIVERED` (primary) OR contains a line matching `Final verify_all result: PASS` (secondary, format-tolerant fallback) is treated as done — mark `done`, skip. Every other status — `pending` / `in-progress` / `failed` / `blocked` / `needs-human` — is **re-evaluated and runnable** (so a `failed` row from a prior run is retried once its cause is fixed; a `blocked` row becomes runnable once its blocker resolves; a `needs-human` row re-runs once you supply the input recorded in the report's "Needs your input" section).
   - **c. Pick.** Take the next ready task in topological order. If none is ready (frontier empty but `pending` rows remain blocked by failures) → go to exit check.
   - **d. Dispatch.** Mark the row `in-progress`. Append to `docs/batches/<pool-id>/STREAM_LOG.md`: `<ISO-8601 UTC> · <id> · dispatching pm-orchestrator · slug=<slug> · mode=<mode>`. **Dispatch `harness-kit:pm-orchestrator` via the `Task` tool** (mode `full` unless the row says otherwise), in its OWN context, **and include in the dispatch prompt the line `deferred-human mode: defer, do not ask` so the sub-agent knows interactive asks are unavailable and returns a `BLOCKED: NEEDS-HUMAN — …` verdict instead** (see `.harness/playbooks/pm-orchestrator.md`). The stream never sees the stage docs, only the return summary. This is identical to `/harness-batch` step 4c; never bypass pm-orchestrator.
   - **e. Record.** Read the sub-agent's return summary (verdict `DELIVERED` / `BLOCKED` / `BLOCKED: NEEDS-HUMAN — …` / `FAILED`, path to `07_DELIVERY.md`, files-changed, final `verify_all`). Append one line to `STREAM_LOG.md`.
   - **f. Regression gate.** Run `.harness/scripts/verify_all`. If it returns **FAIL** (the task broke the baseline) → **hard stop** (see Stop conditions). Otherwise continue.
   - **g. Best-effort outcome.** Update the row `Status` from the verdict (keep the verdicts distinct so the report tallies stay honest):

From Alan-IFT/harness-kit, MIT.

More from Alan-IFT/harness-kit

Signals

Stars
0
Forks
0
Open issues
0
Last commit (this folder)
Aug 8, 2026 (2 months ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from Alan-IFT

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get harness-stream running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying harness-stream?

CallGet help
Cite this page

harness-stream skill. Agent Mart. https://agentmart.dev/skills/alan-ift-harness-stream (last updated 2026-10-24)