From 431f6a94b675585911bee66699d11e98d2fd0aa5 Mon Sep 17 00:00:00 2001
From: "David J. Kim"
Date: Wed, 22 Jul 2026 16:14:04 -0400
Subject: [PATCH 1/4] feedback-capture: route low-friction feedback to
Discussions
- ISSUE_TEMPLATE/config.yml: add a Discussions contact link (ask a question
or share a catch) ahead of the docs link, so the issue chooser offers the
lower-friction path first.
- first_catch.yml: trim required fields to stack, what-was-caught, and card
or report (command/where/version now optional); restate share-safe; close
by thanking and inviting a star.
- .github/FUNDING.yml: commented template, no active sponsor handle.
- CONTRIBUTING.md: add a 30-second smallest-useful-contribution path up top.
---
.github/FUNDING.yml | 9 +++++++++
.github/ISSUE_TEMPLATE/config.yml | 3 +++
.github/ISSUE_TEMPLATE/first_catch.yml | 18 +++++++++++++-----
CONTRIBUTING.md | 14 ++++++++++++++
4 files changed, 39 insertions(+), 5 deletions(-)
create mode 100644 .github/FUNDING.yml
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..c535311
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,9 @@
+# Sponsor button for the repo. This file is a template: every line is commented,
+# so no sponsor button renders until a maintainer opts in.
+#
+# To turn it on, uncomment one line and set the real handle. The GitHub Sponsors
+# handle below is a placeholder, not an active account: confirm the org has a
+# Sponsors profile before uncommenting.
+#
+# github: [attenlabs]
+# custom: ["https://hotato.dev/"]
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 34d5866..df02442 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,5 +1,8 @@
blank_issues_enabled: true
contact_links:
+ - name: Ask a question or share a catch
+ url: https://github.com/attenlabs/hotato/discussions
+ about: Questions, a moment hotato caught, an integration you wired up, or an idea. Lower friction than an issue, and others can chime in.
- name: Documentation
url: https://hotato.dev/docs/
about: Guides for capture, scoring, CI gating, and the MCP server.
diff --git a/.github/ISSUE_TEMPLATE/first_catch.yml b/.github/ISSUE_TEMPLATE/first_catch.yml
index 9bb7e7d..0e8f19e 100644
--- a/.github/ISSUE_TEMPLATE/first_catch.yml
+++ b/.github/ISSUE_TEMPLATE/first_catch.yml
@@ -32,10 +32,10 @@ body:
id: command
attributes:
label: Command you ran
- description: The exact invocation, credentials removed.
+ description: The exact invocation, credentials removed. Optional, but it helps us reproduce.
placeholder: "hotato investigate --stack vapi --call-id "
validations:
- required: true
+ required: false
- type: textarea
id: what_was_caught
attributes:
@@ -68,19 +68,27 @@ body:
- Gating a branch in CI (contract verify)
- Still a candidate, deciding
validations:
- required: true
+ required: false
- type: input
id: version
attributes:
label: hotato version
- description: Output of `hotato --version`.
+ description: Output of `hotato --version`. Optional.
placeholder: "hotato x.y.z"
validations:
- required: true
+ required: false
- type: checkboxes
id: share_safe
attributes:
label: Share-safe
+ description: The card and the text report carry timings and measurements only. Keep it that way.
options:
- label: No audio is attached, and the paste carries no call id, phone number, or name of any call participant.
required: true
+ - type: markdown
+ attributes:
+ value: >-
+ Thank you. A first catch from a stack we did not operate is the
+ clearest signal this tool works. If it earned a place in your loop,
+ a [star on the repo](https://github.com/attenlabs/hotato) helps the
+ next person find it.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6bb5614..9917346 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,6 +9,20 @@ ever a single blended score.
Every kind of contribution is welcome. This guide gets your first one merged with
the least friction, then points you at the contribution that helps most.
+## The 30-second contribution
+
+The smallest useful change, start to finish:
+
+- **A one-line doc fix.** A typo, a stale flag, a command that reads wrong.
+ Edit the file on GitHub, open the PR. Done.
+- **A labeled synthetic fixture.** One JSON scenario that stresses a timing
+ edge the suites miss. Copy an existing label under
+ [`corpus/suites/`](corpus/suites/), change the timings, run
+ `python3 corpus/validate.py your_label.json` until it prints PASS.
+
+Both are reviewed quickly and merge without a release. If you have more time,
+read on.
+
## Ways to help
Pick whatever fits the time you have:
From e27c1db8a702a091d4a764e750f5a92b614078f8 Mon Sep 17 00:00:00 2001
From: "David J. Kim"
Date: Wed, 22 Jul 2026 16:14:20 -0400
Subject: [PATCH 2/4] conversion: README star-ask + MIT badge + star-history +
animated demo cast; CLI first-run star footer
---
README.md | 18 +++++++-
README.pypi.md | 18 +++++++-
docs/assets/hotato-demo-cast.svg | 79 ++++++++++++++++++++++++++++++++
src/hotato/start.py | 5 ++
tests/test_start_cli.py | 14 ++++++
5 files changed, 130 insertions(+), 4 deletions(-)
create mode 100644 docs/assets/hotato-demo-cast.svg
diff --git a/README.md b/README.md
index a4c1fc7..e09928f 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,9 @@
-
+
+
+
# hotato
@@ -14,6 +16,8 @@
Your evals are green. Your agent still ships bugs they can't see: talk-over, dead air, a tool it swore it ran. hotato catches them on your machine and gates CI so they stay fixed.
+
+
**[hotato.dev](https://hotato.dev)**
@@ -30,6 +34,8 @@ Conversation failed: Agent did not yield; measured talk-over was 2.66 s.
That transcript passed every text eval. The timing did not. hotato pins the catch as a CI contract that reproduces byte for byte, so a fixed bug stays fixed. It measures timing and say-do, not intent.
+If hotato caught something your evals missed, a [star](https://github.com/attenlabs/hotato) helps other teams find it.
+
## The loop
Turn production failures into portable tests, run candidate releases against them, and carry evidence with every release. Five steps, one command each, nothing leaves your machine.
@@ -164,10 +170,18 @@ Timing is measurable only when the two voices arrive on separate channels; a mon
Issues and PRs welcome: [`CONTRIBUTING.md`](CONTRIBUTING.md) · [`SECURITY.md`](SECURITY.md) · [`CHANGELOG`](CHANGELOG.md) · [`docs/`](docs/)
+## Star history
+
+
+
## License
MIT ([`LICENSE`](LICENSE))
-
Know when to pass it on.
+
+If hotato caught something your evals missed, a star helps other teams find it.
+
+Know when to pass it on.
+
mcp-name: io.github.attenlabs/hotato
diff --git a/README.pypi.md b/README.pypi.md
index 3245b8e..9e11562 100644
--- a/README.pypi.md
+++ b/README.pypi.md
@@ -6,7 +6,9 @@
-
+
+
+
# hotato
@@ -14,6 +16,8 @@
Your evals are green. Your agent still ships bugs they can't see: talk-over, dead air, a tool it swore it ran. hotato catches them on your machine and gates CI so they stay fixed.
+
+
**[hotato.dev](https://hotato.dev)**
@@ -30,6 +34,8 @@ Conversation failed: Agent did not yield; measured talk-over was 2.66 s.
That transcript passed every text eval. The timing did not. hotato pins the catch as a CI contract that reproduces byte for byte, so a fixed bug stays fixed. It measures timing and say-do, not intent.
+If hotato caught something your evals missed, a [star](https://github.com/attenlabs/hotato) helps other teams find it.
+
## The loop
Turn production failures into portable tests, run candidate releases against them, and carry evidence with every release. Five steps, one command each, nothing leaves your machine.
@@ -164,10 +170,18 @@ Timing is measurable only when the two voices arrive on separate channels; a mon
Issues and PRs welcome: [`CONTRIBUTING.md`](https://github.com/attenlabs/hotato/blob/main/CONTRIBUTING.md) · [`SECURITY.md`](https://github.com/attenlabs/hotato/blob/main/SECURITY.md) · [`CHANGELOG`](https://github.com/attenlabs/hotato/blob/main/CHANGELOG.md) · [`docs/`](https://github.com/attenlabs/hotato/blob/main/docs/)
+## Star history
+
+
+
## License
MIT ([`LICENSE`](https://github.com/attenlabs/hotato/blob/main/LICENSE))
-
Know when to pass it on.
+
+If hotato caught something your evals missed, a star helps other teams find it.
+
+Know when to pass it on.
+
mcp-name: io.github.attenlabs/hotato
diff --git a/docs/assets/hotato-demo-cast.svg b/docs/assets/hotato-demo-cast.svg
new file mode 100644
index 0000000..e8f24ba
--- /dev/null
+++ b/docs/assets/hotato-demo-cast.svg
@@ -0,0 +1,79 @@
+
diff --git a/src/hotato/start.py b/src/hotato/start.py
index 8807e43..bed75ee 100644
--- a/src/hotato/start.py
+++ b/src/hotato/start.py
@@ -848,6 +848,11 @@ def run_start(*, demo: bool = False, stereo: Optional[str] = None,
event_wav_rel = (f"{contract_info['bundle_rel']}/audio/event.wav"
if contract_written else None)
print(_next_commands_text(event_wav_rel))
+ # One quiet footer on the successful demo path only (never on errors or
+ # other subcommands): a star is how the next team finds this.
+ print("")
+ print("Useful? A star helps other teams find it: "
+ "github.com/attenlabs/hotato")
return 0
diff --git a/tests/test_start_cli.py b/tests/test_start_cli.py
index 427c775..508e1ce 100644
--- a/tests/test_start_cli.py
+++ b/tests/test_start_cli.py
@@ -118,6 +118,20 @@ def test_start_demo_prints_the_next_commands(tmp_path, capsys):
not in joined)
+def test_start_demo_prints_one_quiet_star_ask_footer(tmp_path, capsys):
+ """The successful --demo text path closes with exactly ONE quiet star-ask
+ footer -- printed once, on the success path only. A usage error (no mode)
+ never reaches it."""
+ assert cli.main(["start", "--demo", "--dir", str(tmp_path)]) == 0
+ out = capsys.readouterr().out
+ ask = "Useful? A star helps other teams find it: github.com/attenlabs/hotato"
+ assert ask in out
+ assert out.count(ask) == 1
+ # not emitted on the mode-usage-error path (exit 2, nothing scored)
+ assert cli.main(["start"]) == 2
+ assert ask not in capsys.readouterr().out
+
+
def test_start_demo_json_format(tmp_path, capsys):
rc = cli.main(["start", "--demo", "--dir", str(tmp_path),
"--format", "json"])
From d98c395a0090e831b814c7136186d9a742dbfc47 Mon Sep 17 00:00:00 2001
From: "David J. Kim"
Date: Wed, 22 Jul 2026 16:29:05 -0400
Subject: [PATCH 3/4] growth: drop the star-ask (operator decision)
Removes the star solicitations (README top + bottom lines, the Star history
section, the CLI first-run star footer, and its test) per operator direction.
Keeps the MIT license badge and the animated demo cast: those are a factual
badge and a product demo, not a star ask. Feedback-capture and the /use-cases
inbound content stay.
Claude-Session: https://claude.ai/code/session_01BqJW5Dey1DzqBeBCAJXrH9
---
README.md | 12 +-----------
README.pypi.md | 12 +-----------
src/hotato/start.py | 5 -----
tests/test_start_cli.py | 14 --------------
4 files changed, 2 insertions(+), 41 deletions(-)
diff --git a/README.md b/README.md
index e09928f..f624b0e 100644
--- a/README.md
+++ b/README.md
@@ -34,8 +34,6 @@ Conversation failed: Agent did not yield; measured talk-over was 2.66 s.
That transcript passed every text eval. The timing did not. hotato pins the catch as a CI contract that reproduces byte for byte, so a fixed bug stays fixed. It measures timing and say-do, not intent.
-If hotato caught something your evals missed, a [star](https://github.com/attenlabs/hotato) helps other teams find it.
-
## The loop
Turn production failures into portable tests, run candidate releases against them, and carry evidence with every release. Five steps, one command each, nothing leaves your machine.
@@ -170,18 +168,10 @@ Timing is measurable only when the two voices arrive on separate channels; a mon
Issues and PRs welcome: [`CONTRIBUTING.md`](CONTRIBUTING.md) · [`SECURITY.md`](SECURITY.md) · [`CHANGELOG`](CHANGELOG.md) · [`docs/`](docs/)
-## Star history
-
-
-
## License
MIT ([`LICENSE`](LICENSE))
-
-If hotato caught something your evals missed, a star helps other teams find it.
-
-Know when to pass it on.
-
+
Know when to pass it on.
mcp-name: io.github.attenlabs/hotato
diff --git a/README.pypi.md b/README.pypi.md
index 9e11562..2547550 100644
--- a/README.pypi.md
+++ b/README.pypi.md
@@ -34,8 +34,6 @@ Conversation failed: Agent did not yield; measured talk-over was 2.66 s.
That transcript passed every text eval. The timing did not. hotato pins the catch as a CI contract that reproduces byte for byte, so a fixed bug stays fixed. It measures timing and say-do, not intent.
-If hotato caught something your evals missed, a [star](https://github.com/attenlabs/hotato) helps other teams find it.
-
## The loop
Turn production failures into portable tests, run candidate releases against them, and carry evidence with every release. Five steps, one command each, nothing leaves your machine.
@@ -170,18 +168,10 @@ Timing is measurable only when the two voices arrive on separate channels; a mon
Issues and PRs welcome: [`CONTRIBUTING.md`](https://github.com/attenlabs/hotato/blob/main/CONTRIBUTING.md) · [`SECURITY.md`](https://github.com/attenlabs/hotato/blob/main/SECURITY.md) · [`CHANGELOG`](https://github.com/attenlabs/hotato/blob/main/CHANGELOG.md) · [`docs/`](https://github.com/attenlabs/hotato/blob/main/docs/)
-## Star history
-
-
-
## License
MIT ([`LICENSE`](https://github.com/attenlabs/hotato/blob/main/LICENSE))
-
-If hotato caught something your evals missed, a star helps other teams find it.
-
-Know when to pass it on.
-
+
Know when to pass it on.
mcp-name: io.github.attenlabs/hotato
diff --git a/src/hotato/start.py b/src/hotato/start.py
index bed75ee..8807e43 100644
--- a/src/hotato/start.py
+++ b/src/hotato/start.py
@@ -848,11 +848,6 @@ def run_start(*, demo: bool = False, stereo: Optional[str] = None,
event_wav_rel = (f"{contract_info['bundle_rel']}/audio/event.wav"
if contract_written else None)
print(_next_commands_text(event_wav_rel))
- # One quiet footer on the successful demo path only (never on errors or
- # other subcommands): a star is how the next team finds this.
- print("")
- print("Useful? A star helps other teams find it: "
- "github.com/attenlabs/hotato")
return 0
diff --git a/tests/test_start_cli.py b/tests/test_start_cli.py
index 508e1ce..427c775 100644
--- a/tests/test_start_cli.py
+++ b/tests/test_start_cli.py
@@ -118,20 +118,6 @@ def test_start_demo_prints_the_next_commands(tmp_path, capsys):
not in joined)
-def test_start_demo_prints_one_quiet_star_ask_footer(tmp_path, capsys):
- """The successful --demo text path closes with exactly ONE quiet star-ask
- footer -- printed once, on the success path only. A usage error (no mode)
- never reaches it."""
- assert cli.main(["start", "--demo", "--dir", str(tmp_path)]) == 0
- out = capsys.readouterr().out
- ask = "Useful? A star helps other teams find it: github.com/attenlabs/hotato"
- assert ask in out
- assert out.count(ask) == 1
- # not emitted on the mode-usage-error path (exit 2, nothing scored)
- assert cli.main(["start"]) == 2
- assert ask not in capsys.readouterr().out
-
-
def test_start_demo_json_format(tmp_path, capsys):
rc = cli.main(["start", "--demo", "--dir", str(tmp_path),
"--format", "json"])
From 37a1c93dffb33d0724e6ae05939a4f0709900fb6 Mon Sep 17 00:00:00 2001
From: "David J. Kim"
Date: Wed, 22 Jul 2026 16:51:17 -0400
Subject: [PATCH 4/4] chore: regenerate llms-full.txt (CONTRIBUTING
30-second-path edit)
The feedback commit's CONTRIBUTING.md change feeds llms-full; regenerate so the
committed copy matches (test_llms_full_txt_committed_copy_is_up_to_date).
---
llms-full.txt | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/llms-full.txt b/llms-full.txt
index 05e4eef..13d9b20 100644
--- a/llms-full.txt
+++ b/llms-full.txt
@@ -10,7 +10,9 @@ FILE: README.md
-
+
+
+
# hotato
@@ -18,6 +20,8 @@ FILE: README.md
Your evals are green. Your agent still ships bugs they can't see: talk-over, dead air, a tool it swore it ran. hotato catches them on your machine and gates CI so they stay fixed.
+
+
**[hotato.dev](https://hotato.dev)**