Skip to content

Commit 7640ca1

Browse files
Ahad690claude
andcommitted
docs(pattern): add §8 notifications.py — user-facing contribution nudge
Document the contribution-reminder pattern in HF_AUTOMERGE_PATTERN.md: embed the nudge in the deliverable (not stderr, which the agent reads — not the user), deliverable-step only, config-toggle default on, with a generalized notifications.py snippet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent cfde5a0 commit 7640ca1

1 file changed

Lines changed: 66 additions & 0 deletions

File tree

patterns/hf-community-dataset/HF_AUTOMERGE_PATTERN.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,72 @@ keep-list, assert no forbidden fields, and upload to
208208

209209
---
210210

211+
## 8. The contribution nudge (`notifications.py`)
212+
213+
A self-growing dataset needs people to actually contribute, so prompt them — but
214+
put the nudge **where the *user* sees it, not on stderr.** This is the key lesson:
215+
in an agent-run tool (Claude Code, an MCP server, any CLI an LLM drives), **stderr
216+
is read by the agent, not the human.** A "please contribute" line printed to
217+
stderr is noise in the agent's tool output and the end user never sees it. So:
218+
219+
1. **Embed the nudge in the deliverable artifact** the user opens (the generated
220+
HTML report, PDF, dashboard, etc.) — not in logs/stderr.
221+
2. **Only the deliverable step emits it** (e.g. the report renderer), not the
222+
intermediate scripts the agent loops over — otherwise it spams the agent's
223+
context and fires many times per session.
224+
3. **Config-toggle, default on**`ui.contribution_reminder: true`. One flag the
225+
maintainer (or end user) can flip off.
226+
4. **HTML-escape** the repo link; read it from the same config as everything else.
227+
228+
Generalized helper — drop in next to `validate.py` / `automerge.py`:
229+
230+
```python
231+
# notifications.py — the user-facing contribution nudge (rendered into the
232+
# deliverable, never printed to stderr).
233+
import html, json, os
234+
235+
def _cfg(cfg=None):
236+
if cfg is not None:
237+
return cfg
238+
here = os.path.dirname(os.path.abspath(__file__))
239+
try:
240+
with open(os.path.join(here, "config.json"), encoding="utf-8") as fh:
241+
return json.load(fh)
242+
except (OSError, json.JSONDecodeError):
243+
return {}
244+
245+
def contribution_banner_html(cfg=None):
246+
"""Return an HTML banner (or '' if disabled). Render this into your report."""
247+
cfg = _cfg(cfg)
248+
if not cfg.get("ui", {}).get("contribution_reminder", True):
249+
return ""
250+
repo = html.escape(cfg.get("dataset_repo", "https://huggingface.co/"))
251+
return (
252+
'<div class="contrib" style="margin:12px 0;padding:10px 14px;'
253+
'border-left:4px solid #2d6;border-radius:8px;background:#0e1a12;'
254+
'color:#bdf5cf;font-size:14px">'
255+
'✨ Help this dataset grow — '
256+
f'<a href="{repo}" target="_blank" rel="noopener" '
257+
'style="color:#5ee08a;font-weight:600">contribute your anonymized data</a>'
258+
' so everyone gets better results.</div>'
259+
)
260+
```
261+
262+
Use it in your report renderer (the deliverable), e.g.:
263+
```python
264+
import notifications
265+
html_out = TEMPLATE.replace("__CONTRIB__", notifications.contribution_banner_html())
266+
```
267+
268+
For a pure-CLI tool with no visual artifact, the equivalent is to print the line
269+
to **stdout** as part of the final human-facing summary (still gated by the flag,
270+
still only on the last step) — never bury it in stderr/logs.
271+
272+
*(Reference implementation: `skills/fiverr-gig-optimizer/scripts/reminders.py`,
273+
rendered by `build_catalog.py` into the catalog the user opens.)*
274+
275+
---
276+
211277
*Reference implementation this was extracted from:
212278
[Ahad690/fiverr-gig-optimizer](https://github.com/Ahad690/fiverr-gig-optimizer)
213279
(`skills/fiverr-gig-optimizer/scripts/{contribute,refresh_dataset,automerge_prs}.py`).*

0 commit comments

Comments
 (0)