Skip to content

generate: run until stopped when no --count is given (cangen-style)#486

Merged
hexsecs merged 2 commits into
mainfrom
claude/open-issues-h218yf
Jul 23, 2026
Merged

generate: run until stopped when no --count is given (cangen-style)#486
hexsecs merged 2 commits into
mainfrom
claude/open-issues-h218yf

Conversation

@hexsecs

@hexsecs hexsecs commented Jul 21, 2026

Copy link
Copy Markdown
Owner

Summary

canarchy generate <interface> with no --count sent a single frame and exited. The reference tool cangen (can-utils) streams continuously by default, so this changes --count to default to unbounded: omitting it now generates and transmits frames continuously, spaced by --gap, until interrupted (Ctrl-C / SIGINT).

Closes #477

Changes

  • canarchy generate <interface> with no --count now streams frames continuously until Ctrl-C, matching cangen; --count N keeps its existing exact-N-frames behavior.
  • Frame generation streams one frame at a time (new iter_generated_frames / LocalTransport.generate_stream_events) instead of materializing an unbounded list in memory.
  • The CLI dispatches an unbounded live run to a new streaming emitter (emit_live_generate), mirroring the existing capture / gateway --text pattern, so text and JSON/JSONL output both stream per-frame and SIGINT exits cleanly (exit 0).
  • --dry-run without --count plans a single frame rather than requiring or attempting an unbounded plan (preserves existing MCP dry_run default behavior).
  • Entry points that can't deliver Ctrl-C — the MCP server, or anything calling execute_command directly — get a structured MISSING_COUNT error instead of hanging on an unbounded live run.

Test plan

  • uv run pytest tests/test_cli.py tests/test_transport.py tests/test_mcp.py -q — 620 passed, 1 skipped, 24 subtests passed
  • uv run ruff check / uv run ruff format --check
  • Manual run against the scaffold backend: unbounded generate --text/--json streams frames and exits 0 on SIGINT (timeout --preserve-status -s INT); --dry-run without --count plans exactly 1 frame; --count 3 unchanged
  • Added/updated unit and CLI tests for the unbounded stream, dry-run default, and MCP MISSING_COUNT guard

Documentation

  • CHANGELOG.md updated under [Unreleased]
  • docs/command_spec.md updated (command surface changed)
  • Touched docs/design/ spec updated (EARS syntax) — docs/design/generate-command.md
  • Touched docs/tests/ spec updated (Gherkin Given/When/Then) — docs/tests/generate-command.md
  • docs/event-schema.md updated — not needed, event shape is unchanged
  • AGENTS.md / docs/agents.md updated — not needed, MCP tool contract description already covers this
  • mkdocs.yml nav updated — no new docs pages added

Safety

  • Active-transmit commands require --ack-active (unchanged)
  • SECURITY.md reviewed against the new behaviour — no change needed; unbounded generation is opt-in (same as omitting --count always was) and still gated by the existing active-transmit confirmation model

Generated by Claude Code

claude added 2 commits July 21, 2026 14:04
`canarchy generate <interface>` with no `--count` now streams frames
continuously, spaced by `--gap`, until interrupted (Ctrl-C), matching
`cangen` from can-utils. `--count N` keeps its existing exact-N behavior.

- `iter_generated_frames`/`LocalTransport.generate_stream_events` stream
  frames one at a time instead of materializing an unbounded list, and
  the CLI dispatches unbounded live runs to a streaming emitter (mirrors
  the existing `capture`/`gateway --text` pattern) so SIGINT exits cleanly.
- `--dry-run` without `--count` plans a single frame rather than
  requiring or attempting an unbounded plan.
- Entry points that can't deliver Ctrl-C (the MCP server, calling
  `execute_command` directly) get a structured `MISSING_COUNT` error
  instead of hanging on an unbounded live run.

Fixes #477.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TAw8L4vcLP5uBEJxVHivxJ
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TAw8L4vcLP5uBEJxVHivxJ
@hexsecs
hexsecs marked this pull request as ready for review July 23, 2026 14:20
@hexsecs
hexsecs merged commit 40432e3 into main Jul 23, 2026
8 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 31e67e54de

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/canarchy/cli.py
def emit_live_generate(args: argparse.Namespace, output_format: str) -> int:
"""Stream generated frames until Ctrl+C — used when `generate` has no `--count`."""
transport = LocalTransport()
enforce_active_transmit_safety(args)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve structured acknowledgement failures

When --count is omitted, main() calls this emitter outside execute_command()'s exception wrapper. If active acknowledgement is required, or if --ack-active receives anything other than YES, enforce_active_transmit_safety() raises CommandError here before the try block and it escapes as a traceback instead of the documented ACTIVE_ACK_REQUIRED or ACTIVE_CONFIRMATION_DECLINED result envelope. Catch and emit this error at the streaming boundary so active-safety failures remain actionable and machine-readable.

AGENTS.md reference: AGENTS.md:L359-L370

Useful? React with 👍 / 👎.

Comment on lines 100 to +104
"count": {
"type": "integer",
"description": "Number of frames to generate",
"description": (
"Number of frames to generate. Defaults to 1 for a dry-run plan; "
"required (and must be finite) when `dry_run=false`, since this "

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Document the changed MCP generate contract

Update both AGENTS.md and docs/agents.md for this changed MCP workflow: a live generate call without count now returns MISSING_COUNT, whereas the existing agent guide only says active tools default to dry-run and does not tell agents that count becomes mandatory when they opt into dry_run=false. This command-surface and MCP-tool change does not meet the repository's required agent-guide acceptance gate.

AGENTS.md reference: AGENTS.md:L82-L90

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

generate: run until stopped when no --count is given (cangen-style)

2 participants