From 697a710fcd4305f1495906102d01340b4a78b8fb Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 21:54:26 +0000 Subject: [PATCH 001/139] ops(autopilot): log PR #26 merge; branch restarted from master Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- docs/AUTOPILOT-LOOP.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 2814976..4b34cec 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -125,6 +125,11 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-22 21:53 UTC — PR #26 ZMERGOWANY przez usera** (29 plików, T1-T10 + release-prep + 0.4.18 na masterze). Gałąź pętli zrestartowana od origin/master; kolejne commity pójdą + w NOWYM draft PR. ODBLOKOWANE: USER-3 (publish 0.4.18 wg ops/launch/release_0.4.18_checklist.md) + i deploy docs/ (sitemap, answers w repo == produkcja). W kolejce: T11, T12, T13. + - **2026-07-22 22:21 UTC — przebieg #8.** POCZTA: **kampania wystartowała — mail do AI Engineering (corp@systemdrd.com) WYSŁANY 21:18** (user/sesja lokalna); 0 płatności. Backlog: **T10 done** — w tym odkrycie: /answers/ (4 artykuły SEO + index) żyją na From 573c636b263661c0d7324f779db48d559ea1a2d6 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 22:06:09 +0000 Subject: [PATCH 002/139] ops(autopilot): current loop PR pointer -> #27; restart-after-merge rule in state file Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- docs/AUTOPILOT-LOOP.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 4b34cec..9b4ad37 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -27,7 +27,10 @@ początku każdego przebiegu i aktualizuje go na końcu. Kolejność przebiegu: 5. **Zero publikacji** — PyPI publish, deploy na VPS, posty na HN/socialach robi tylko Bogumił; agent przygotowuje paste-ready artefakty w `ops/launch/`. 6. **Git**: commit + `git push -u origin claude/email-cron-strategy-automation-drmkv4` - (retry 2s/4s/8s/16s), nigdy na master; draft PR utrzymywany na bieżąco. + (retry 2s/4s/8s/16s), nigdy na master. **BIEŻĄCY PR PĘTLI: #27** (PR #26 zmergowany + 2026-07-22 21:53 — wszelkie "#26" w promptcie crona czytaj jako "#27"). Po każdym + merge'u PR-a pętli: restart brancha od origin/master (`git checkout -B ... origin/master`, + force-with-lease) i NOWY draft PR przy pierwszym pushu; zaktualizuj ten wpis. 7. **Dedupe draftów**: przed `create_draft` sprawdź `list_drafts` + ledger niżej + czy w wątku nie ma już naszej odpowiedzi po ostatniej wiadomości rozmówcy. 8. **Kod = testy zielone** (`python -m pytest -q` dla dotkniętych ścieżek); From 939c7486e40ae57364d7449ed71f307591bc34ef Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 22:23:38 +0000 Subject: [PATCH 003/139] =?UTF-8?q?feat(plugin):=20Claude=20Code=20marketp?= =?UTF-8?q?lace=20manifest=20=E2=80=94=20one-command=20install=20for=20the?= =?UTF-8?q?=20veto=20hook=20(T11)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns the repo into a plugin marketplace (.claude-plugin/marketplace.json) shipping one plugin, plugins/gatecat: a PreToolUse hook on Bash|Write|Edit calling the pip-installed gatecat-hook script (same block as examples/veto_integrations/claude_code_hook/settings.example.json). Layout and schemas follow the official plugins docs fetched this run — plugin.json in .claude-plugin/, hooks at plugin root in hooks/hooks.json. Install: /plugin marketplace add BGMLAI/gate.cat, then /plugin install gatecat@gatecat (after pip install gate.cat). Load verification stays with the owner post-merge (claude --plugin-dir). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- .claude-plugin/marketplace.json | 16 +++++++++++++ docs/AUTOPILOT-LOOP.md | 8 ++++++- plugins/gatecat/.claude-plugin/plugin.json | 13 +++++++++++ plugins/gatecat/README.md | 27 ++++++++++++++++++++++ plugins/gatecat/hooks/hooks.json | 15 ++++++++++++ 5 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 .claude-plugin/marketplace.json create mode 100644 plugins/gatecat/.claude-plugin/plugin.json create mode 100644 plugins/gatecat/README.md create mode 100644 plugins/gatecat/hooks/hooks.json diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json new file mode 100644 index 0000000..d87da9b --- /dev/null +++ b/.claude-plugin/marketplace.json @@ -0,0 +1,16 @@ +{ + "name": "gatecat", + "owner": { + "name": "BGML", + "email": "bogumil@bgml.ai", + "url": "https://gate.cat" + }, + "plugins": [ + { + "name": "gatecat", + "source": "./plugins/gatecat", + "description": "Deterministic action veto for Claude Code: blocks rm -rf, DROP TABLE, terraform destroy, disk wipes and secret exfiltration BEFORE the tool call executes. Requires `pip install gate.cat` (free, Apache-2.0).", + "version": "0.4.18" + } + ] +} diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 9b4ad37..116f249 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -72,7 +72,7 @@ _Synteza panelu 2026-07-22 (4 propozycje, 12 krytyk sędziów, wszystkie kluczow - [x] **T8 — `gate.cat report`: lokalny raport w kształcie płatnego** — ZAMKNIĘTE 2026-07-22 przebieg #6 jako T8-lite: `gate.cat report` (render_report) istniał już w repo w layoucie zgodnym z SAMPLE_REPORT (markdown, counts-only, honest-limits) — spec był częściowo nieaktualny; stopka z CTA off-machine dodana w T6; brakującą linię discovery dodano teraz do maybe_nudge_cli ("See exactly what it caught, free and local: gate.cat report"). 35 testów zielonych. Oryginalna spec: — Nowa komenda renderuje WŁASNY lokalny veto log użytkownika w layoucie docs/SAMPLE_REPORT.md z watermarkiem "paid layer trzyma tę kopię off-machine, poza zasięgiem agenta" + CTA Solo €19/Team €149; discovery wg fixu sędziów: jedna linia w komunikatach T6 wskazuje komendę (inaczej nikt jej nie odpali). Acceptance: działa na pustym i niepustym logu, testy przechodzą, do 0.4.18/0.4.19. _(impact: $100-500 (sufit), effort: M, PRODUCT-LED, 5.0)_ - [x] **T9 — Cross-sell na stronie fulfillment packów** — WYKONANE 2026-07-22 przebieg #7: sekcja "Complete your coverage" w PAGE (products/cloud/gatecat_fulfill.py) — 2 niekupione packi + linia Cloud Solo; atrybucja: `client_reference_id=pack-xsell` na linkach Stripe (widoczna w Checkout Session; `?source=` na buy.stripe.com nic by nie mierzyło — świadome odstępstwo od speca) + `?source=pack-xsell` na teams.html (nginx analytics). Testy: 2 nowe (wykluczenie kupionego packa, render do PAGE), 5 passed. Live po restarcie gatecat-fulfill na VPS (deploy checklist). Oryginalna spec: — PAGE template w products/cloud/gatecat_fulfill.py: sekcja "Complete your coverage" z dwoma nie-kupionymi packami (linki z PRICING.md:72-74 z `?source=pack-xsell`) + jedna linia Cloud Solo €19; bez zmian w Stripe. Acceptance: unit test wykluczenia kupionego modułu (MODULE_FOR); live wymaga restartu usługi na VPS (USER-2). Label sędziów: EV ≈ 0 do pierwszej sprzedaży packa — dlatego ta pozycja, nie wyżej. _(impact: $29-200, effort: S, CONVERSION, 4.8)_ - [x] **T10 — Higiena prawdy: llms.txt, sitemap 404, Lemon Squeezy "pending"** — WYKONANE 2026-07-22 przebieg #8: (1) llms.txt — już odświeżone wcześniej (71 policies; wersja 0.4.18 z hotfixa #5); (2) sitemap /answers/* — NIE martwe: strony ŻYJĄ na produkcji (kolejny out-of-band deploy) → zamiast usuwać, zaciągnięto 5 stron do docs/answers/ (produkcja wygrywa); (3) PRICING.md:56 "LS review pending" → "Stripe is the payment channel"; (4) default payment_channel() lemonsqueezy→stripe (ODWRÓCENIE decyzji foundera z 2026-07-12, powód: LS odrzuciło 2026-07-14; sign-off = merge PR #26; ścieżka LS zostaje za env); (5) "ships this month"→"rolling out" (spójne z live teams.html). Testy: 23 passed. Oryginalna spec: — docs/llms.txt: 65/65→178/178 (F4) i v0.4.3→0.4.17 (F9); sitemap.xml: usuń/przekieruj 5 martwych wpisów /answers/* (budowa stron odrzucona jako revenue-driver); PRICING.md:56 "review is pending" → LS odrzucone 2026-07-14 + default `payment_channel()` w cloud_activate.py na stripe; sprawdź obietnicę "ships this month" (PRICING.md:50) i jeśli fleet policy nie wejdzie do ~2026-08-01, przygotuj PR łagodzący wording. Acceptance: diff przeciw FACTS.md czysty; PR wyraźnie flaguje odwrócenie decyzji foundera z 2026-07-12 i wymaga sign-off przed merge. _(impact: ~$0 (risk-avoidance), effort: S, DISTRIBUTION+B2B, 4.8/6.7)_ -- [ ] **T11 — Claude Code plugin-marketplace manifest** — `.claude-plugin/marketplace.json` + `plugin.json` opakowujące istniejący PreToolUse hook (examples/veto_integrations/claude_code_hook/); fix sędziów: najpierw WebFetch oficjalnej dokumentacji schematu — nie zgaduj formatu; weryfikacja załadowania = owner po merge, nie agent. Wartość głównie jako linia "one-command install" w poście HN (T4). Acceptance: manifest przechodzi walidację składni JSON wobec udokumentowanego schematu, PR otwarty. _(impact: $0-150 (obniżone przez sędziów), effort: M, DISTRIBUTION, 4.8)_ +- [x] **T11 — Claude Code plugin-marketplace manifest** — WYKONANE 2026-07-22 przebieg #9: wg oficjalnej dokumentacji (code.claude.com/docs/en/plugins, pobrana WebFetch — fix sędziów: bez zgadywania schematu): repo = marketplace (.claude-plugin/marketplace.json) + plugin plugins/gatecat/ (.claude-plugin/plugin.json v0.4.18, hooks/hooks.json z PreToolUse Bash|Write|Edit → gatecat-hook — blok 1:1 z settings.example.json, README z instalacją `/plugin marketplace add BGMLAI/gate.cat` → `/plugin install gatecat@gatecat`). JSON zwalidowany. Weryfikacja załadowania = owner po merge #27 (`claude --plugin-dir ./plugins/gatecat`). Linia one-command-install do postów: po merge'u. Oryginalna spec: — `.claude-plugin/marketplace.json` + `plugin.json` opakowujące istniejący PreToolUse hook (examples/veto_integrations/claude_code_hook/); fix sędziów: najpierw WebFetch oficjalnej dokumentacji schematu — nie zgaduj formatu; weryfikacja załadowania = owner po merge, nie agent. Wartość głównie jako linia "one-command install" w poście HN (T4). Acceptance: manifest przechodzi walidację składni JSON wobec udokumentowanego schematu, PR otwarty. _(impact: $0-150 (obniżone przez sędziów), effort: M, DISTRIBUTION, 4.8)_ - [ ] **T12 — daily_funnel.py testowany na fixture (bez SSH z sandboxa)** — Skrypt parsuje events log przez funnel_report.py i appenduje JSON-line {date, page_view, install_copy, checkout_click, top_sources} do METRICS.log; w środowisku agenta NIE ma klucza VPS, więc acceptance = unit test na fixture w repo + instrukcja uruchomienia tam gdzie jest klucz (wzorzec SSH z scripts/launch_metrics.py). Fix sędziów: to pomiar, nie przychód — niczego nie blokuje i nie twierdzimy "pierwszego realnego snapshotu" z sandboxa. _(impact: $0 (pomiar do iteracji), effort: S, CONVERSION, 4.8)_ - [x] **T14 — Influencer affiliate outreach (dyspozycja usera 2026-07-22 ~20:40)** — WYKONANE: research (developereducators.com katalog 92 twórców CC, awesome-ai-newsletters, sponsor-pages) → pakiet `influencer-affiliate-outreach.md` dostarczony userowi NA CZACIE (nie w repo — zasada 9): 17 twórców YouTube Tier 1 (Edmund Yong, Simon Scrapes, Jack Roberts, Nate Herk, John Kim, Bart Slodyczka-proxy-fit, Greg Isenberg...), 10 newsletterów Tier 2 (AI Engineering, AI Agents Simplified, Latent Space, Ben's Bites...), Tier 3 mega-kanały po trakcji; 3 szablony (YT/newsletter/follow-up Nick Saraev); protokół ≤15/dzień + obowiązkowa personalizacja. Wysyłka = user/sesja lokalna; odpowiedzi łapie pętla. Wykluczeni już kontaktowani (7 z 15.07). - [ ] **T13 — LinkedIn DM do Dimitriosa Kaprilisa (artefakt dla USER-5)** — `ops/launch/dm_dimitrios.md` wg fixu sędziów: najpierw merytoryczna odpowiedź na jego publiczne pytanie o policies (z F1b), dopiero potem oferta bezpłatnego Team + audit-pilot review za zgodę na cytowanie wyniku. Acceptance: paste-ready DM, zero liczb spoza FACTS.md. _(impact: design-partner opcjonalność, effort: S, B2B)_ @@ -128,6 +128,12 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-22 23:21 UTC — przebieg #9.** Poczta/Stripe/HN: bez zmian (kampania: 1 mail + wysłany, czekamy na odpowiedzi). Backlog: **T11 done** — plugin marketplace manifest + (schemat z oficjalnych docs). Po merge #27: `/plugin marketplace add BGMLAI/gate.cat` + + `/plugin install gatecat@gatecat` = one-command install do postów HN/Reddit. + Zostały: T12 (daily_funnel fixture), T13 (DM Dimitrios — czat). + - **2026-07-22 21:53 UTC — PR #26 ZMERGOWANY przez usera** (29 plików, T1-T10 + release-prep 0.4.18 na masterze). Gałąź pętli zrestartowana od origin/master; kolejne commity pójdą w NOWYM draft PR. ODBLOKOWANE: USER-3 (publish 0.4.18 wg ops/launch/release_0.4.18_checklist.md) diff --git a/plugins/gatecat/.claude-plugin/plugin.json b/plugins/gatecat/.claude-plugin/plugin.json new file mode 100644 index 0000000..6df0261 --- /dev/null +++ b/plugins/gatecat/.claude-plugin/plugin.json @@ -0,0 +1,13 @@ +{ + "name": "gatecat", + "description": "Deterministic, fail-closed action veto — vetoes an agent's irreversible shell commands (rm -rf, DROP TABLE, terraform destroy, secret exfil) before they run. Enforcement runs in the harness via a PreToolUse hook, outside the model's control flow. Requires the free core: pip install gate.cat", + "version": "0.4.18", + "author": { + "name": "BGML", + "email": "bogumil@bgml.ai", + "url": "https://gate.cat" + }, + "homepage": "https://gate.cat", + "repository": "https://github.com/BGMLAI/gate.cat", + "license": "Apache-2.0" +} diff --git a/plugins/gatecat/README.md b/plugins/gatecat/README.md new file mode 100644 index 0000000..aee68ca --- /dev/null +++ b/plugins/gatecat/README.md @@ -0,0 +1,27 @@ +# gatecat — Claude Code plugin + +Registers the gate.cat **PreToolUse veto hook** for `Bash`/`Write`/`Edit`: +irreversible commands (`rm -rf`, `DROP TABLE`, `terraform destroy`, disk +wipes, secret exfiltration) are blocked with exit code 2 **before** they +execute, and the reason is fed back to the model. Deterministic — no model +call in the veto path. + +## Install + +```bash +pip install gate.cat # the free engine (Apache-2.0, zero-dep core) +``` + +then in Claude Code: + +``` +/plugin marketplace add BGMLAI/gate.cat +/plugin install gatecat@gatecat +``` + +The hook calls the `gatecat-hook` console script installed by pip — if the +package is missing, the hook fails visibly rather than silently allowing. + +Honest limits: the gate is certain only about what it **blocks**; an +unmatched action is *unchecked*, not *safe*. Details, measurements and the +published bypass map: [FACTS.md](https://github.com/BGMLAI/gate.cat/blob/master/FACTS.md). diff --git a/plugins/gatecat/hooks/hooks.json b/plugins/gatecat/hooks/hooks.json new file mode 100644 index 0000000..d5b0b43 --- /dev/null +++ b/plugins/gatecat/hooks/hooks.json @@ -0,0 +1,15 @@ +{ + "hooks": { + "PreToolUse": [ + { + "matcher": "Bash|Write|Edit", + "hooks": [ + { + "type": "command", + "command": "gatecat-hook" + } + ] + } + ] + } +} From af07264bd96764418df55725dfda21c25968bae5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 23:23:19 +0000 Subject: [PATCH 004/139] feat(metrics): daily funnel snapshot script, fixture-tested (T12) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit scripts/daily_funnel.py reuses funnel_report.summarize() and emits one METRICS.log-shaped JSON line per UTC day: {date, page_view, install_copy, checkout_click, top_sources}. The sandbox holds no VPS key, so the docstring documents the SSH pattern (from launch_metrics.py) to run it where the events log lives. Committed fixture covers day filtering, smoke_test exclusion and source attribution; 3 tests green. Measurement only — it blocks nothing and claims nothing. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- docs/AUTOPILOT-LOOP.md | 8 ++++- scripts/daily_funnel.py | 59 +++++++++++++++++++++++++++++++ tests/fixtures/gatecat_events.log | 9 +++++ tests/test_daily_funnel.py | 58 ++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 scripts/daily_funnel.py create mode 100644 tests/fixtures/gatecat_events.log create mode 100644 tests/test_daily_funnel.py diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 116f249..3fa693d 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -73,7 +73,7 @@ _Synteza panelu 2026-07-22 (4 propozycje, 12 krytyk sędziów, wszystkie kluczow - [x] **T9 — Cross-sell na stronie fulfillment packów** — WYKONANE 2026-07-22 przebieg #7: sekcja "Complete your coverage" w PAGE (products/cloud/gatecat_fulfill.py) — 2 niekupione packi + linia Cloud Solo; atrybucja: `client_reference_id=pack-xsell` na linkach Stripe (widoczna w Checkout Session; `?source=` na buy.stripe.com nic by nie mierzyło — świadome odstępstwo od speca) + `?source=pack-xsell` na teams.html (nginx analytics). Testy: 2 nowe (wykluczenie kupionego packa, render do PAGE), 5 passed. Live po restarcie gatecat-fulfill na VPS (deploy checklist). Oryginalna spec: — PAGE template w products/cloud/gatecat_fulfill.py: sekcja "Complete your coverage" z dwoma nie-kupionymi packami (linki z PRICING.md:72-74 z `?source=pack-xsell`) + jedna linia Cloud Solo €19; bez zmian w Stripe. Acceptance: unit test wykluczenia kupionego modułu (MODULE_FOR); live wymaga restartu usługi na VPS (USER-2). Label sędziów: EV ≈ 0 do pierwszej sprzedaży packa — dlatego ta pozycja, nie wyżej. _(impact: $29-200, effort: S, CONVERSION, 4.8)_ - [x] **T10 — Higiena prawdy: llms.txt, sitemap 404, Lemon Squeezy "pending"** — WYKONANE 2026-07-22 przebieg #8: (1) llms.txt — już odświeżone wcześniej (71 policies; wersja 0.4.18 z hotfixa #5); (2) sitemap /answers/* — NIE martwe: strony ŻYJĄ na produkcji (kolejny out-of-band deploy) → zamiast usuwać, zaciągnięto 5 stron do docs/answers/ (produkcja wygrywa); (3) PRICING.md:56 "LS review pending" → "Stripe is the payment channel"; (4) default payment_channel() lemonsqueezy→stripe (ODWRÓCENIE decyzji foundera z 2026-07-12, powód: LS odrzuciło 2026-07-14; sign-off = merge PR #26; ścieżka LS zostaje za env); (5) "ships this month"→"rolling out" (spójne z live teams.html). Testy: 23 passed. Oryginalna spec: — docs/llms.txt: 65/65→178/178 (F4) i v0.4.3→0.4.17 (F9); sitemap.xml: usuń/przekieruj 5 martwych wpisów /answers/* (budowa stron odrzucona jako revenue-driver); PRICING.md:56 "review is pending" → LS odrzucone 2026-07-14 + default `payment_channel()` w cloud_activate.py na stripe; sprawdź obietnicę "ships this month" (PRICING.md:50) i jeśli fleet policy nie wejdzie do ~2026-08-01, przygotuj PR łagodzący wording. Acceptance: diff przeciw FACTS.md czysty; PR wyraźnie flaguje odwrócenie decyzji foundera z 2026-07-12 i wymaga sign-off przed merge. _(impact: ~$0 (risk-avoidance), effort: S, DISTRIBUTION+B2B, 4.8/6.7)_ - [x] **T11 — Claude Code plugin-marketplace manifest** — WYKONANE 2026-07-22 przebieg #9: wg oficjalnej dokumentacji (code.claude.com/docs/en/plugins, pobrana WebFetch — fix sędziów: bez zgadywania schematu): repo = marketplace (.claude-plugin/marketplace.json) + plugin plugins/gatecat/ (.claude-plugin/plugin.json v0.4.18, hooks/hooks.json z PreToolUse Bash|Write|Edit → gatecat-hook — blok 1:1 z settings.example.json, README z instalacją `/plugin marketplace add BGMLAI/gate.cat` → `/plugin install gatecat@gatecat`). JSON zwalidowany. Weryfikacja załadowania = owner po merge #27 (`claude --plugin-dir ./plugins/gatecat`). Linia one-command-install do postów: po merge'u. Oryginalna spec: — `.claude-plugin/marketplace.json` + `plugin.json` opakowujące istniejący PreToolUse hook (examples/veto_integrations/claude_code_hook/); fix sędziów: najpierw WebFetch oficjalnej dokumentacji schematu — nie zgaduj formatu; weryfikacja załadowania = owner po merge, nie agent. Wartość głównie jako linia "one-command install" w poście HN (T4). Acceptance: manifest przechodzi walidację składni JSON wobec udokumentowanego schematu, PR otwarty. _(impact: $0-150 (obniżone przez sędziów), effort: M, DISTRIBUTION, 4.8)_ -- [ ] **T12 — daily_funnel.py testowany na fixture (bez SSH z sandboxa)** — Skrypt parsuje events log przez funnel_report.py i appenduje JSON-line {date, page_view, install_copy, checkout_click, top_sources} do METRICS.log; w środowisku agenta NIE ma klucza VPS, więc acceptance = unit test na fixture w repo + instrukcja uruchomienia tam gdzie jest klucz (wzorzec SSH z scripts/launch_metrics.py). Fix sędziów: to pomiar, nie przychód — niczego nie blokuje i nie twierdzimy "pierwszego realnego snapshotu" z sandboxa. _(impact: $0 (pomiar do iteracji), effort: S, CONVERSION, 4.8)_ +- [x] **T12 — daily_funnel.py testowany na fixture (bez SSH z sandboxa)** — WYKONANE 2026-07-23 przebieg #10: scripts/daily_funnel.py (reużywa summarize() z funnel_report.py; filtr per-dzień UTC; JSON-line w kształcie METRICS.log: {date, page_view, install_copy, checkout_click, top_sources}); fixture tests/fixtures/gatecat_events.log (9 linii: 2 dni, smoke_test ignorowany, źródła hn/pypi/reddit/direct); 3 testy passed. Instrukcja SSH-run w docstringu (wzorzec launch_metrics.py) — uruchamiane tam, gdzie jest log; to pomiar, nie przychód. Oryginalna spec: — Skrypt parsuje events log przez funnel_report.py i appenduje JSON-line {date, page_view, install_copy, checkout_click, top_sources} do METRICS.log; w środowisku agenta NIE ma klucza VPS, więc acceptance = unit test na fixture w repo + instrukcja uruchomienia tam gdzie jest klucz (wzorzec SSH z scripts/launch_metrics.py). Fix sędziów: to pomiar, nie przychód — niczego nie blokuje i nie twierdzimy "pierwszego realnego snapshotu" z sandboxa. _(impact: $0 (pomiar do iteracji), effort: S, CONVERSION, 4.8)_ - [x] **T14 — Influencer affiliate outreach (dyspozycja usera 2026-07-22 ~20:40)** — WYKONANE: research (developereducators.com katalog 92 twórców CC, awesome-ai-newsletters, sponsor-pages) → pakiet `influencer-affiliate-outreach.md` dostarczony userowi NA CZACIE (nie w repo — zasada 9): 17 twórców YouTube Tier 1 (Edmund Yong, Simon Scrapes, Jack Roberts, Nate Herk, John Kim, Bart Slodyczka-proxy-fit, Greg Isenberg...), 10 newsletterów Tier 2 (AI Engineering, AI Agents Simplified, Latent Space, Ben's Bites...), Tier 3 mega-kanały po trakcji; 3 szablony (YT/newsletter/follow-up Nick Saraev); protokół ≤15/dzień + obowiązkowa personalizacja. Wysyłka = user/sesja lokalna; odpowiedzi łapie pętla. Wykluczeni już kontaktowani (7 z 15.07). - [ ] **T13 — LinkedIn DM do Dimitriosa Kaprilisa (artefakt dla USER-5)** — `ops/launch/dm_dimitrios.md` wg fixu sędziów: najpierw merytoryczna odpowiedź na jego publiczne pytanie o policies (z F1b), dopiero potem oferta bezpłatnego Team + audit-pilot review za zgodę na cytowanie wyniku. Acceptance: paste-ready DM, zero liczb spoza FACTS.md. _(impact: design-partner opcjonalność, effort: S, B2B)_ @@ -128,6 +128,12 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 00:21 UTC — przebieg #10.** Poczta/Stripe/HN: bez zmian. Backlog: + **T12 done** (daily_funnel na fixture, 3 testy zielone). W kolejce został TYLKO T13 + (DM Dimitrios — artefakt przez czat, zasada 9) → po nim kolejka pusta = następny + przebieg odpala panel adversarialny po nową partię zadań (priorytet: konwersja + odpowiedzi z kampanii affiliate + follow-upy po publikacjach usera). + - **2026-07-22 23:21 UTC — przebieg #9.** Poczta/Stripe/HN: bez zmian (kampania: 1 mail wysłany, czekamy na odpowiedzi). Backlog: **T11 done** — plugin marketplace manifest (schemat z oficjalnych docs). Po merge #27: `/plugin marketplace add BGMLAI/gate.cat` diff --git a/scripts/daily_funnel.py b/scripts/daily_funnel.py new file mode 100644 index 0000000..10f1591 --- /dev/null +++ b/scripts/daily_funnel.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python3 +"""Daily funnel snapshot from the gate.cat events log — one JSON line per day. + +MEASUREMENT ONLY: this quantifies the middle of the funnel (page views -> +install copies -> checkout clicks) so pricing/copy iterations run on data +instead of memory. It blocks nothing and earns nothing by itself. + +The events log lives on the VPS and the agent sandbox holds no key, so run +this WHERE THE LOG LIVES (same SSH pattern as scripts/launch_metrics.py): + + ssh -i ~/.ssh/vps/id_ed25519 root@204.168.129.200 \\ + 'cat /var/log/nginx/gatecat-events.log' \\ + | python3 scripts/daily_funnel.py - --date 2026-07-22 >> METRICS.log + +The output shape intentionally mirrors METRICS.log: a single JSON object per +line, so the same T+30 tooling can read both streams. +""" +from __future__ import annotations + +import argparse +import json +import sys +from datetime import datetime +from pathlib import Path + +sys.path.insert(0, str(Path(__file__).resolve().parent)) +from funnel_report import summarize # noqa: E402 — reuse the one true parser + + +def snapshot(lines: list[str], date: str) -> dict: + """Funnel counts for one UTC day (``date`` = YYYY-MM-DD).""" + stamp = datetime.strptime(date, "%Y-%m-%d").strftime("%d/%b/%Y") + day = [line for line in lines if f"[{stamp}:" in line] + s = summarize(day) + events = s["events"] + return { + "date": date, + "page_view": events.get("page_view", 0), + "install_copy": events.get("install_copy", 0), + "checkout_click": events.get("checkout_click", 0), + "top_sources": dict(list(s["sources"].items())[:5]), + } + + +def main(argv: list[str] | None = None) -> int: + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument("log", help="events log path, or '-' for stdin") + parser.add_argument("--date", required=True, help="UTC day to snapshot (YYYY-MM-DD)") + args = parser.parse_args(argv) + if args.log == "-": + lines = sys.stdin.read().splitlines() + else: + lines = Path(args.log).read_text().splitlines() + print(json.dumps(snapshot(lines, args.date), sort_keys=True)) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/fixtures/gatecat_events.log b/tests/fixtures/gatecat_events.log new file mode 100644 index 0000000..37391a5 --- /dev/null +++ b/tests/fixtures/gatecat_events.log @@ -0,0 +1,9 @@ +1.2.3.4 - - [22/Jul/2026:10:00:01 +0000] "GET /px.gif?e=page_view&source=hn&sid=s1 HTTP/1.1" 200 43 "-" "UA" +1.2.3.4 - - [22/Jul/2026:10:00:09 +0000] "GET /px.gif?e=install_copy&source=hn&sid=s1 HTTP/1.1" 200 43 "-" "UA" +5.6.7.8 - - [22/Jul/2026:11:30:00 +0000] "GET /px.gif?e=page_view&source=pypi&sid=s2 HTTP/1.1" 200 43 "-" "UA" +5.6.7.8 - - [22/Jul/2026:11:31:12 +0000] "GET /px.gif?e=checkout_click&source=pypi&sid=s2 HTTP/1.1" 200 43 "-" "UA" +9.9.9.9 - - [22/Jul/2026:12:00:00 +0000] "GET /px.gif?e=page_view&sid=s3 HTTP/1.1" 200 43 "-" "UA" +9.9.9.9 - - [22/Jul/2026:12:00:05 +0000] "GET /px.gif?e=smoke_test&source=ci HTTP/1.1" 200 43 "-" "UA" +7.7.7.7 - - [21/Jul/2026:23:59:59 +0000] "GET /px.gif?e=page_view&source=reddit&sid=s4 HTTP/1.1" 200 43 "-" "UA" +7.7.7.7 - - [23/Jul/2026:00:00:01 +0000] "GET /px.gif?e=checkout_click&source=reddit&sid=s5 HTTP/1.1" 200 43 "-" "UA" +this line is not a request and must be ignored diff --git a/tests/test_daily_funnel.py b/tests/test_daily_funnel.py new file mode 100644 index 0000000..316a0c9 --- /dev/null +++ b/tests/test_daily_funnel.py @@ -0,0 +1,58 @@ +"""Tests for scripts/daily_funnel.py — the fixture-driven daily funnel snapshot. + +The agent sandbox has no VPS key, so correctness is proven on a committed +fixture; the docstring documents where the real log run happens. +""" +import importlib.util +import json +import os +import subprocess +import sys + +ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +FIXTURE = os.path.join(ROOT, "tests", "fixtures", "gatecat_events.log") +SCRIPT = os.path.join(ROOT, "scripts", "daily_funnel.py") + + +def _load(): + spec = importlib.util.spec_from_file_location("daily_funnel_t", SCRIPT) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + return module + + +def test_snapshot_counts_one_day_only(): + df = _load() + lines = open(FIXTURE).read().splitlines() + + snap = df.snapshot(lines, "2026-07-22") + + assert snap == { + "date": "2026-07-22", + "page_view": 3, # s1(hn) + s2(pypi) + s3(direct); smoke_test ignored + "install_copy": 1, + "checkout_click": 1, # the 23 Jul reddit click is OUT of this day + "top_sources": {"hn": 2, "pypi": 2, "direct": 1}, + } + + +def test_snapshot_empty_day_is_all_zeroes(): + df = _load() + lines = open(FIXTURE).read().splitlines() + + snap = df.snapshot(lines, "2026-07-01") + + assert snap["page_view"] == 0 + assert snap["checkout_click"] == 0 + assert snap["top_sources"] == {} + + +def test_cli_emits_single_json_line_metrics_log_shaped(): + out = subprocess.run( + [sys.executable, SCRIPT, FIXTURE, "--date", "2026-07-22"], + capture_output=True, text=True, check=True).stdout + assert out.count("\n") == 1 + parsed = json.loads(out) + assert parsed["date"] == "2026-07-22" + assert set(parsed) == {"date", "page_view", "install_copy", + "checkout_click", "top_sources"} From 9e64812855eb148e7d1e6d8875a339604f0a16cd Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 00:23:02 +0000 Subject: [PATCH 005/139] =?UTF-8?q?ops(autopilot):=20T13=20delivered=20off?= =?UTF-8?q?-repo;=20queue=20empty=20=E2=80=94=20next=20run=20triggers=20a?= =?UTF-8?q?=20fresh=20strategy=20panel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- docs/AUTOPILOT-LOOP.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 3fa693d..580079a 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -75,7 +75,7 @@ _Synteza panelu 2026-07-22 (4 propozycje, 12 krytyk sędziów, wszystkie kluczow - [x] **T11 — Claude Code plugin-marketplace manifest** — WYKONANE 2026-07-22 przebieg #9: wg oficjalnej dokumentacji (code.claude.com/docs/en/plugins, pobrana WebFetch — fix sędziów: bez zgadywania schematu): repo = marketplace (.claude-plugin/marketplace.json) + plugin plugins/gatecat/ (.claude-plugin/plugin.json v0.4.18, hooks/hooks.json z PreToolUse Bash|Write|Edit → gatecat-hook — blok 1:1 z settings.example.json, README z instalacją `/plugin marketplace add BGMLAI/gate.cat` → `/plugin install gatecat@gatecat`). JSON zwalidowany. Weryfikacja załadowania = owner po merge #27 (`claude --plugin-dir ./plugins/gatecat`). Linia one-command-install do postów: po merge'u. Oryginalna spec: — `.claude-plugin/marketplace.json` + `plugin.json` opakowujące istniejący PreToolUse hook (examples/veto_integrations/claude_code_hook/); fix sędziów: najpierw WebFetch oficjalnej dokumentacji schematu — nie zgaduj formatu; weryfikacja załadowania = owner po merge, nie agent. Wartość głównie jako linia "one-command install" w poście HN (T4). Acceptance: manifest przechodzi walidację składni JSON wobec udokumentowanego schematu, PR otwarty. _(impact: $0-150 (obniżone przez sędziów), effort: M, DISTRIBUTION, 4.8)_ - [x] **T12 — daily_funnel.py testowany na fixture (bez SSH z sandboxa)** — WYKONANE 2026-07-23 przebieg #10: scripts/daily_funnel.py (reużywa summarize() z funnel_report.py; filtr per-dzień UTC; JSON-line w kształcie METRICS.log: {date, page_view, install_copy, checkout_click, top_sources}); fixture tests/fixtures/gatecat_events.log (9 linii: 2 dni, smoke_test ignorowany, źródła hn/pypi/reddit/direct); 3 testy passed. Instrukcja SSH-run w docstringu (wzorzec launch_metrics.py) — uruchamiane tam, gdzie jest log; to pomiar, nie przychód. Oryginalna spec: — Skrypt parsuje events log przez funnel_report.py i appenduje JSON-line {date, page_view, install_copy, checkout_click, top_sources} do METRICS.log; w środowisku agenta NIE ma klucza VPS, więc acceptance = unit test na fixture w repo + instrukcja uruchomienia tam gdzie jest klucz (wzorzec SSH z scripts/launch_metrics.py). Fix sędziów: to pomiar, nie przychód — niczego nie blokuje i nie twierdzimy "pierwszego realnego snapshotu" z sandboxa. _(impact: $0 (pomiar do iteracji), effort: S, CONVERSION, 4.8)_ - [x] **T14 — Influencer affiliate outreach (dyspozycja usera 2026-07-22 ~20:40)** — WYKONANE: research (developereducators.com katalog 92 twórców CC, awesome-ai-newsletters, sponsor-pages) → pakiet `influencer-affiliate-outreach.md` dostarczony userowi NA CZACIE (nie w repo — zasada 9): 17 twórców YouTube Tier 1 (Edmund Yong, Simon Scrapes, Jack Roberts, Nate Herk, John Kim, Bart Slodyczka-proxy-fit, Greg Isenberg...), 10 newsletterów Tier 2 (AI Engineering, AI Agents Simplified, Latent Space, Ben's Bites...), Tier 3 mega-kanały po trakcji; 3 szablony (YT/newsletter/follow-up Nick Saraev); protokół ≤15/dzień + obowiązkowa personalizacja. Wysyłka = user/sesja lokalna; odpowiedzi łapie pętla. Wykluczeni już kontaktowani (7 z 15.07). -- [ ] **T13 — LinkedIn DM do Dimitriosa Kaprilisa (artefakt dla USER-5)** — `ops/launch/dm_dimitrios.md` wg fixu sędziów: najpierw merytoryczna odpowiedź na jego publiczne pytanie o policies (z F1b), dopiero potem oferta bezpłatnego Team + audit-pilot review za zgodę na cytowanie wyniku. Acceptance: paste-ready DM, zero liczb spoza FACTS.md. _(impact: design-partner opcjonalność, effort: S, B2B)_ +- [x] **T13 — LinkedIn DM do Dimitriosa Kaprilisa (artefakt dla USER-5)** — WYKONANE 2026-07-23 przebieg #11: DM dostarczony userowi NA CZACIE (zasada 9 — nie w repo). Źródło zweryfikowane: docs/research/community-threads-2026-07-13.md:99 (post o skasowanym projekcie Electron; pyta o polityki zespołowe; nasz publiczny komentarz już istnieje — publications #25) → DM = kontynuacja: merytoryczna odpowiedź (stack + deterministyczny veto w harnessie, F1b), potem oferta design-partner (Team free za feedback + zgodę na cytowanie zanonimizowanego wyniku). Profil: linkedin.com/in/dimitrios-kaprilis-295b6a348. Oryginalna spec: — `ops/launch/dm_dimitrios.md` wg fixu sędziów: najpierw merytoryczna odpowiedź na jego publiczne pytanie o policies (z F1b), dopiero potem oferta bezpłatnego Team + audit-pilot review za zgodę na cytowanie wyniku. Acceptance: paste-ready DM, zero liczb spoza FACTS.md. _(impact: design-partner opcjonalność, effort: S, B2B)_ ## [USER] — czeka na Bogumiła @@ -128,6 +128,13 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 01:21 UTC — przebieg #11.** Poczta/Stripe/HN: bez zmian. Backlog: **T13 + done** (DM przez czat) → **KOLEJKA PUSTA**. Następny przebieg: panel adversarialny + multi-model po nową partię zadań. Sugerowane soczewki dla panelu: (a) konwersja + odpowiedzi kampanii affiliate, (b) follow-upy po publikacjach usera (HN/Reddit/X, + gdy już wiszą), (c) droga do pierwszej płatności z istniejącego ruchu, (d) release + 0.4.19. NIE proponować ponownie pozycji z ODRZUCONE. + - **2026-07-23 00:21 UTC — przebieg #10.** Poczta/Stripe/HN: bez zmian. Backlog: **T12 done** (daily_funnel na fixture, 3 testy zielone). W kolejce został TYLKO T13 (DM Dimitrios — artefakt przez czat, zasada 9) → po nim kolejka pusta = następny From 9d024f3947af7e6fb0f738530555fb123c779946 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 01:43:06 +0000 Subject: [PATCH 006/139] ops(autopilot): queue v2 from second adversarial panel (U1-U9) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Panel 2026-07-23 (3 proposals on different models, 2 adversarial judges each, synthesis): self-serve Packs path is the only agent-executable route to a first payment — packs.html is a verified soft-404 today and every pack CTA cold-links straight to Stripe checkout. Queue: packs.html (U1), OWNER_RUNBOOK 20-min unblock (U2, judges' consensus that owner throughput is the real bottleneck), pack-hint v2 for 0.4.19 (U3), self-verify block at purchase points (U4), FACTS F13 re-pin gate (U5), Mike data pack (U6), partner welcome pack (U7), day-3/7 follow-up templates + ledger due dates (U8), design-partner wave 2 capped at 3 (U9). Rejected list extended. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- docs/AUTOPILOT-LOOP.md | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 580079a..c64e12c 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -77,7 +77,35 @@ _Synteza panelu 2026-07-22 (4 propozycje, 12 krytyk sędziów, wszystkie kluczow - [x] **T14 — Influencer affiliate outreach (dyspozycja usera 2026-07-22 ~20:40)** — WYKONANE: research (developereducators.com katalog 92 twórców CC, awesome-ai-newsletters, sponsor-pages) → pakiet `influencer-affiliate-outreach.md` dostarczony userowi NA CZACIE (nie w repo — zasada 9): 17 twórców YouTube Tier 1 (Edmund Yong, Simon Scrapes, Jack Roberts, Nate Herk, John Kim, Bart Slodyczka-proxy-fit, Greg Isenberg...), 10 newsletterów Tier 2 (AI Engineering, AI Agents Simplified, Latent Space, Ben's Bites...), Tier 3 mega-kanały po trakcji; 3 szablony (YT/newsletter/follow-up Nick Saraev); protokół ≤15/dzień + obowiązkowa personalizacja. Wysyłka = user/sesja lokalna; odpowiedzi łapie pętla. Wykluczeni już kontaktowani (7 z 15.07). - [x] **T13 — LinkedIn DM do Dimitriosa Kaprilisa (artefakt dla USER-5)** — WYKONANE 2026-07-23 przebieg #11: DM dostarczony userowi NA CZACIE (zasada 9 — nie w repo). Źródło zweryfikowane: docs/research/community-threads-2026-07-13.md:99 (post o skasowanym projekcie Electron; pyta o polityki zespołowe; nasz publiczny komentarz już istnieje — publications #25) → DM = kontynuacja: merytoryczna odpowiedź (stack + deterministyczny veto w harnessie, F1b), potem oferta design-partner (Team free za feedback + zgodę na cytowanie zanonimizowanego wyniku). Profil: linkedin.com/in/dimitrios-kaprilis-295b6a348. Oryginalna spec: — `ops/launch/dm_dimitrios.md` wg fixu sędziów: najpierw merytoryczna odpowiedź na jego publiczne pytanie o policies (z F1b), dopiero potem oferta bezpłatnego Team + audit-pilot review za zgodę na cytowanie wyniku. Acceptance: paste-ready DM, zero liczb spoza FACTS.md. _(impact: design-partner opcjonalność, effort: S, B2B)_ -## [USER] — czeka na Bogumiła +## KOLEJKA v2 (panel 2026-07-23) + +_Synteza panelu 2026-07-23 (3 propozycje / 6 krytyk; 0 propozycji killed, ale sędziowie wycięli lub zdegradowali ~40% zadań). Rama sędziów: jedyna agent-wykonalna ścieżka do pierwszej płatności to domknięcie self-serve Packs €29 (jedyny produkt impulsowy z auto-fulfillmentem) + gotowe-do-wklejenia konwersje ciepłych wątków; realny bottleneck (publish 0.4.18, deploy docs/, posty, wysyłka kampanii) jest po stronie ownera — stąd U2. Kolejność: oczekiwane $ / effort / time-to-cash. Liczby publiczne WYŁĄCZNIE z FACTS.md (nigdy ze stanu pętli). Zweryfikowane przed syntezą: packs.html = soft-404, _pack_hint.py linkuje goły buy.stripe.com (2/3 packów), FACTS.md F13 = 2,019 (pin 2026-07-13) vs 2,528 w pętli, PRICING.md:23/50 obiecuje SIGNED policy sync._ + +- [ ] **U1 — Zbuduj docs/packs.html (dziś soft-404) i przepnij wszystkie pack-CTA na podgląd przed checkoutem** — Każdy pack-CTA prowadzi dziś PROSTO na buy.stripe.com bez podglądu co się kupuje (cold checkout — zweryfikowane przez obu sędziów: /packs.html serwuje ten sam 352KB index.html co losowy URL). Zbuduj stronę na layoucie teams.html: 3 packi ze scope VERBATIM z sekcji "Policy Packs — €29 one-time" w PRICING.md, buy-linki z `?source=packs`, 30-day refund, install steps, wpis do sitemap.xml; w tym samym PR przepnij cross-sell w products/cloud/gatecat_fulfill.py i teams.html oraz dodaj JEDNĄ skanowalną linię w README pod istniejącym blokiem pricing ("What's inside each pack → gate.cat/packs.html?source=pypi") — bez drugiego bloku cenowego (cięcie sędziów: dawny Task 3 zwinięty tutaj). Acceptance: test_marketing_consistency zielony, każda liczba z PRICING.md/FACTS.md, PR gotowy do merge; live dopiero po deployu ([USER]-2) — framing sędziów: usunięcie tarcia, nie gwarancja płatności. _(impact: $0-290, warunkowe: deploy+ruch, effort: M, SELF-SERVE PACKS, 6.5)_ +- [ ] **U2 — OWNER_RUNBOOK: "20 minut do odblokowania" — jeden plik z dokładnymi komendami dla ownera** — Obaj sędziowie górnych propozycji wskazali to samo: realny bottleneck do cash to throughput usera (publish 0.4.18, deploy docs/, Show HN/Reddit, wysyłka kampanii czekają od dni), a panel dokładał artefakty zamiast rozładować kolejkę. Napisz ops/launch/OWNER_RUNBOOK.md: kroki w kolejności wykonania, każdy = jedna komenda albo jeden paste, zero decyzji (twine wg ops/launch/release_0.4.18_checklist.md → ops/deploy_landing.sh → jednorazowy scripts/daily_funnel.py na logach VPS z wklejeniem wyniku na czat [tani test hipotezy packs: czy ktoś w ogóle klika checkout_click] → show_hn_ready.md + distribution_kit_2026-07-22.md → batch affiliate ≤15/dzień). Acceptance: łączny czas wykonania <20 min, linkuje wyłącznie istniejące artefakty, sekcja [USER] w tym pliku wskazuje na runbook zamiast dublować kroki. _(impact: $0 bezpośrednio — multiplikator na wszystkie [USER]-gated $, effort: S, THROUGHPUT OWNERA, konsensus sędziów)_ +- [ ] **U3 — Pack hint v2: detekcja HTTP-API Breadth (tylko stack-specyficzne CLI) + repoint na packs.html — do 0.4.19** — gatecat/_pack_hint.py wykrywa 2 z 3 packów i linkuje goły Stripe; dodaj trzecią krotkę (HTTP-API Breadth, scope VERBATIM z PRICING.md, link `buy.stripe.com/...67S0e`) z detekcją WYŁĄCZNIE stack-specyficznych CLI typu datadog-ci/sentry-cli — fix sędziów: BEZ docker/gh, bo są uniwersalne i zabijają precyzję "high-intent" triggera; oba istniejące URL-e przepnij na `https://gate.cat/packs.html?source=hint`. Wchodzi do release-PR 0.4.19 z wpisem CHANGELOG — jawnie NIE wstrzymuje publisha przygotowanego 0.4.18 (fix sędziów: brak rozjazdu z gotowym checklistem). Acceptance: test detekcji HTTP-API w tests/test_pack_hint.py, `python -m pytest -q tests/test_pack_hint.py` zielony. _(impact: $29-116, effort: S, SELF-SERVE PACKS, 6.5)_ +- [ ] **U4 — Blok self-verify "Don't trust us — reproduce it" na stronach zakupu + README** — Kontra na 0 gwiazdek/0 testimoniali dokładnie w punkcie decyzji zakupowej: identyczny blok z komendą `pip install gate-cat && python -m gatecat.integrations.bypass_suite` i allowed-wordingiem z FACTS.md (F1b: 0 real misses / 1,085,159; F4: 178/178 + 1 named gap + 1/129 benign) do docs/teams.html, docs/packs.html (po U1) i sekcji pricing w README.md. README renderuje się na GitHub natychmiast, bez publish/deploy-gate. Acceptance: grep liczb (`178|1,085,159|71 `) na dotkniętych plikach zgodny z FACTS.md. _(impact: $0-150, effort: S, SELF-SERVE PACKS, 6.5)_ +- [ ] **U5 — Higiena FACTS.md: re-pin F13 (2,019 → świeży odczyt) + audyt wierszy wersjonowanych — GATE dla U6/U7** — F13 wisi na 2,019 (pin 2026-07-13), a pętla i wysłany mail do Mike'a operują 2,528 — jedyna niespójność potwierdzona przez CZTERECH sędziów z obu stron panelu. Re-pinuj F13 świeżym `curl pypistats.org/api/packages/gate.cat/recent` + METRICS.log z nową datą i źródłem; przejrzyj F3/F4/F9 pod notatkę "0.4.18 przygotowany, niepublikowany" (F9 uczciwie zostaje 0.4.17). Acceptance: commit w PR pętli; twardy warunek sędziów dla WSZYSTKICH kolejnych zadań: publiczne copy bierze liczby tylko z wierszy FACTS.md, nigdy ze STANU pętli. _(impact: $0 — risk-avoidance, odblokowuje publiczne liczby w U6/U7, effort: S, B2B PIPELINE, 4.5)_ +- [ ] **U6 — Pakiet danych dla Mike'a Privette: dokładnie to, co obiecane w mailu 07-22 17:11, gotowe na jego reply** — ops/launch/mike_category_data_pack.md: docs/SAMPLE_REPORT.md jako "redacted sample", results/million_recall_2026-07-08.json + RECALL.md jako "raw data behind the numbers", jeden akapit honest positioning (deterministic pre-execution veto, zero-model-in-path) BEZ twierdzeń o konkurentach bez zweryfikowanych danych i BEZ nazwisk osób trzecich — incydenty tylko po numerach issue (fix sędziów); do tego szkielet odpowiedzi z 3 gałęziami (poprosi o dane / mention w newsletterze / wspólny content). Gmail draft powstaje DOPIERO po jego odpowiedzi (dedupe #7) — pakiet ścina czas reakcji z godzin do minut; ŻADNEJ nowej publicznej strony docs/ na razie (cięcie sędziów z pełnego "analyst kit"). Acceptance: liczby wyłącznie z FACTS.md po U5; plik paste-ready. _(impact: $0-500 w 30 dni — pipeline/wiarygodność, nie bezpośredni cash (korekta sędziów z $200-1,500), effort: S, KONWERSJA ODPOWIEDZI + B2B, 5.5/4.5)_ +- [ ] **U7 — Welcome pack partnera (markdown-only): odpowiedź na pierwsze mailto z partners.html w minutę** — partners.html (LIVE) ma tylko mailto CTA, a products/cloud/affiliate.py ma gotowe `add-affiliate`/`ledger` — brakuje wyłącznie treści. Napisz ops/partners/welcome_pack.md: welcome mail (format linku `gate.cat/?ref=CODE`, mechanika 30% lifetime-recurring wg affiliate.py, termin wypłaty), 3 warianty kodu per typ twórcy, dokładna komenda [USER] `python -m affiliate add-affiliate CODE "Name" email` na VPS, blok statystyk TYLKO z FACTS.md (po U5 — twardy warunek sędziów) + wymóg disclosure afiliacji. BEZ osobnego skryptu Pythona i testów slugów (cięcie sędziów: nadinżynieria przy 0 zdarzeń). Acceptance: zero liczb spoza FACTS.md; wysyłka i wpis do produkcyjnej bazy oznaczone [USER]. _(impact: $0-800 opcjonalność do pierwszego partnera, effort: S, KONWERSJA ODPOWIEDZI, 5.5)_ +- [ ] **U8 — Szablony follow-up day-3/day-7 + kolumny due w LEDGER (bez skryptu; Julian jako jeden wariant)** — ops/launch/followup_templates.md: day-3 (krótkie przypomnienie) i day-7 ("ostatni dotyk + coś nowego") per tier z T14 (YouTube/newsletter/mega-kanał), w tym JEDEN wariant day-3 dla Juliana z zero-friction downgrade ask — BEZ prerezerwacji kodu "julian-goldie" zanim cokolwiek potwierdzi (cięcie sędziów: osobne zadanie Julian wchłonięte tutaj). Dopisz do LEDGER kolumny due: AI Engineering wysłane 07-22 21:18 → day-3 2026-07-25 / day-7 2026-07-29; Julian klaryfikacja 07-22 15:53 → 2026-07-25 / 2026-07-29; każdy kolejny wysłany mail kampanii dostaje wiersz przy odnotowaniu. Żadnych draftów przed datami due (dedupe #7). Acceptance: szablony paste-ready, LEDGER zaktualizowany; skrypt due-trackingu dopiero gdy wysłanych >5 (patrz ODRZUCONE v2). _(impact: $0-400 — materializuje się dopiero z wysyłkami usera, effort: S, KONWERSJA ODPOWIEDZI, 5.5)_ +- [ ] **U9 — Design-partner fala 2: scoring i MAX 3 spersonalizowane drafty, dostarczone na czacie** — Scoring kandydatów z docs/research/community-threads-2026-07-13.md (P0+P1) + świeży `mcp__github__search_issues` po incydentach destructive-command <14 dni (anthropics/claude-code, cline/cline, opencode); wybierz MAX 3 (cięcie sędziów z ~10 — nie dokładać WIP userowi, który ma niewysłaną kampanię) i przygotuj drafty wzorcem T13: najpierw merytoryczna odpowiedź na ich publiczny problem z F1b, potem oferta Team-free-for-feedback + zgoda na cytowanie zanonimizowanego wyniku. Całość NA CZAT, nie do repo (zasada 9 — zero danych osób trzecich w publicznym repo). Acceptance: tabela scoringowa w scratchpadzie, 3 paste-ready drafty na czacie, wysyłka = [USER]. _(impact: $0-300 w 30 dni — pierwszy Team reference, effort: M, B2B PIPELINE, 4.5)_ + +## [USER] v2 + +1. **Opublikuj 0.4.18 na PyPI (nie czekaj na U1-U3 — pack hint v2 idzie do 0.4.19)** — artefakt: `ops/launch/release_0.4.18_checklist.md`; PyPI wciąż serwuje 0.4.17, a nudge Solo + pack hint + report discovery + PyPI-landing docierają do nowych instalacji dopiero po publishu. +2. **Deploy docs/ na VPS po merge PR z U1** (packs.html + self-verify + sitemap) — artefakt: `ops/deploy_landing.sh`; PRZY OKAZJI jednorazowo odpal `scripts/daily_funnel.py` na logach VPS i wklej wynik na czat — tani test sędziów, czy ktokolwiek klika checkout_click na pack-linkach. +3. **Post Show HN + Reddit/X wg kolejności z pliku, najlepiej PO kroku 2** — artefakty: `ops/launch/show_hn_ready.md` + `ops/launch/distribution_kit_2026-07-22.md`; bez ruchu ścieżka packs ma ekspozycję bliską zeru; każdy live URL → issue #9. +4. **Kolejna partia kampanii affiliate (≤15/dzień z listy 27, szablony T14 na czacie)** — po każdej wysyłce dopisz adresata+datę do LEDGER (day-3/day-7 z U8 liczą się od daty wysyłki); wysłany dotąd 1/27. + +## ODRZUCONE v2 + +- **`policy export/import` do 0.4.19 (P3-T4)** — live teams.html i PRICING.md:23/50 obiecują SIGNED policy sync ("tampering shows"); plain-file bez podpisu tworzy rozjazd copy-vs-feature zamiast domykać obietnicę, a główny powód pierwotnego odrzucenia (0 potwierdzonych Team buyerów) obowiązuje w całości — zabite przez obu sędziów. +- **`response_triage.md` — silnik triażu odpowiedzi kampanii (P1-T1)** — drzewo decyzyjne budowane z próbki n=2 (Mike + dwukrotnie ten sam autoreply Juliana) przy 0 odpowiedziach z kampanii; dedupe #7 już działa w praktyce — dokumentacja nad działającym procesem, ~$0 w 14 dni. +- **`followup_due.py` — skrypt parsujący Gmail pod zegary follow-upów (P1-T2)** — inżynieria nieproporcjonalna do <30 rekordów (spojrzenie w kalendarz); zdegradowane do szablonów + kolumn LEDGER w U8; wróć TYLKO gdy wysłanych >5 i ręczne śledzenie realnie boli. +- **`docs/security-review.md` — kit dla championa B2B (P3-T5)** — odłożone do pojawienia się pierwszego realnego leada na etapie security review; THREAT_MODEL.md/TELEMETRY.md/SECURITY.md są już linkowalne pojedynczo z maila, a nowy artefakt tylko powiększa kolejkę review ownera. + +## [USER] — czeka na Bogumiła (v1 — patrz też [USER] v2 wyżej) **DECYZJA USERA 2026-07-22 ~20:00: "wszystko co się da" — pełna dystrybucja zatwierdzona.** Pakiet: `ops/launch/show_hn_ready.md` (HN, repost OK — stary post 2 pkt) + @@ -128,6 +156,13 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 02:21 UTC — przebieg #12: PANEL v2.** Poczta: nic dla gate.cat (payout + Stripe = Fundacja LC/Bloom, inny biznes). Panel: 3 propozycje (sonnet/opus/fable) × + 2 sędziów (sonnet/opus) + synteza; 0 killed, ~40% zadań wyciętych. Nowa kolejka + U1-U9; klucz: packs.html = soft-404 (goły checkout bez podglądu!), F13 stale + (2,019 vs 2,528), bottleneck = throughput ownera → U2 OWNER_RUNBOOK. Następny + przebieg: U1. + - **2026-07-23 01:21 UTC — przebieg #11.** Poczta/Stripe/HN: bez zmian. Backlog: **T13 done** (DM przez czat) → **KOLEJKA PUSTA**. Następny przebieg: panel adversarialny multi-model po nową partię zadań. Sugerowane soczewki dla panelu: (a) konwersja From 8a8420139bfda64db836b2ffe00ab1b90d6464c1 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 02:32:28 +0000 Subject: [PATCH 007/139] =?UTF-8?q?feat(site):=20packs.html=20=E2=80=94=20?= =?UTF-8?q?full=20pack=20scope=20before=20checkout=20(U1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pack CTAs pointed straight at buy.stripe.com with no preview of what a pack contains, and gate.cat/packs.html soft-404'd to the landing page. coverage.html even linked to a /#packs anchor that does not exist. - docs/packs.html: 3 packs with scope verbatim from PRICING.md, anchors (#fintech/#paas/#http-api), ?source=packs buy links, 30-day refund, install steps, fail-closed note, honest 'what packs are NOT' block, affiliate ref capture + cookieless /events funnel tracking - cross-sells repointed to the preview page: fulfill thank-you xsell, teams.html (note + footer), coverage.html dead anchor - README: one scannable line under pricing; llms.txt mention; sitemap entry - new drift guard: test_packs_page_shows_scope_before_checkout Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- README.md | 1 + docs/AUTOPILOT-LOOP.md | 11 +- docs/coverage.html | 2 +- docs/llms.txt | 2 +- docs/packs.html | 318 ++++++++++++++++++++++++++++ docs/sitemap.xml | 1 + docs/teams.html | 3 +- products/cloud/gatecat_fulfill.py | 14 +- tests/test_marketing_consistency.py | 33 +++ tests/test_pack_stripe.py | 4 +- 10 files changed, 377 insertions(+), 12 deletions(-) create mode 100644 docs/packs.html diff --git a/README.md b/README.md index 9b24f9d..a5bf1cc 100644 --- a/README.md +++ b/README.md @@ -283,6 +283,7 @@ or buy a one-time €29 policy pack: [Fintech](https://buy.stripe.com/dRm5kw6Bn3iMfFS1Rk67S0c) · [PaaS](https://buy.stripe.com/3cI5kw3pbaLeeBO2Vo67S0d) · [HTTP-API Breadth](https://buy.stripe.com/aFa8wIgbX06AdxK67A67S0e). +**What's inside each pack → [gate.cat/packs.html](https://gate.cat/packs.html?source=pypi)** **Running agents across a team?** One rogue agent's blast radius is the whole team's. The team plan adds a shared off-machine veto history no single agent can diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index c64e12c..02f623e 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -81,7 +81,7 @@ _Synteza panelu 2026-07-22 (4 propozycje, 12 krytyk sędziów, wszystkie kluczow _Synteza panelu 2026-07-23 (3 propozycje / 6 krytyk; 0 propozycji killed, ale sędziowie wycięli lub zdegradowali ~40% zadań). Rama sędziów: jedyna agent-wykonalna ścieżka do pierwszej płatności to domknięcie self-serve Packs €29 (jedyny produkt impulsowy z auto-fulfillmentem) + gotowe-do-wklejenia konwersje ciepłych wątków; realny bottleneck (publish 0.4.18, deploy docs/, posty, wysyłka kampanii) jest po stronie ownera — stąd U2. Kolejność: oczekiwane $ / effort / time-to-cash. Liczby publiczne WYŁĄCZNIE z FACTS.md (nigdy ze stanu pętli). Zweryfikowane przed syntezą: packs.html = soft-404, _pack_hint.py linkuje goły buy.stripe.com (2/3 packów), FACTS.md F13 = 2,019 (pin 2026-07-13) vs 2,528 w pętli, PRICING.md:23/50 obiecuje SIGNED policy sync._ -- [ ] **U1 — Zbuduj docs/packs.html (dziś soft-404) i przepnij wszystkie pack-CTA na podgląd przed checkoutem** — Każdy pack-CTA prowadzi dziś PROSTO na buy.stripe.com bez podglądu co się kupuje (cold checkout — zweryfikowane przez obu sędziów: /packs.html serwuje ten sam 352KB index.html co losowy URL). Zbuduj stronę na layoucie teams.html: 3 packi ze scope VERBATIM z sekcji "Policy Packs — €29 one-time" w PRICING.md, buy-linki z `?source=packs`, 30-day refund, install steps, wpis do sitemap.xml; w tym samym PR przepnij cross-sell w products/cloud/gatecat_fulfill.py i teams.html oraz dodaj JEDNĄ skanowalną linię w README pod istniejącym blokiem pricing ("What's inside each pack → gate.cat/packs.html?source=pypi") — bez drugiego bloku cenowego (cięcie sędziów: dawny Task 3 zwinięty tutaj). Acceptance: test_marketing_consistency zielony, każda liczba z PRICING.md/FACTS.md, PR gotowy do merge; live dopiero po deployu ([USER]-2) — framing sędziów: usunięcie tarcia, nie gwarancja płatności. _(impact: $0-290, warunkowe: deploy+ruch, effort: M, SELF-SERVE PACKS, 6.5)_ +- [x] **U1 — Zbuduj docs/packs.html (dziś soft-404) i przepnij wszystkie pack-CTA na podgląd przed checkoutem** _(DONE 2026-07-23 przebieg #13: docs/packs.html zbudowany — 3 packi scope verbatim z PRICING.md + kotwice #fintech/#paas/#http-api, buy-linki ?source=packs, 30-day refund, install steps, fail-closed note, blok „What packs are NOT", skrypt affiliate + funnel /events; sitemap.xml + wpis; cross-sell przepięty: gatecat_fulfill.py xsell → packs.html?source=pack-xsell#kotwica, teams.html nota+footer → packs.html?source=teams, coverage.html /#packs (martwa kotwica!) → /packs.html?source=coverage; README jedna linia „What's inside each pack → gate.cat/packs.html?source=pypi"; llms.txt wzmianka; NOWY test test_packs_page_shows_scope_before_checkout jako strażnik dryfu; pełny suite 1928 passed. Live po deployu [USER]-2.)_ — Każdy pack-CTA prowadzi dziś PROSTO na buy.stripe.com bez podglądu co się kupuje (cold checkout — zweryfikowane przez obu sędziów: /packs.html serwuje ten sam 352KB index.html co losowy URL). Zbuduj stronę na layoucie teams.html: 3 packi ze scope VERBATIM z sekcji "Policy Packs — €29 one-time" w PRICING.md, buy-linki z `?source=packs`, 30-day refund, install steps, wpis do sitemap.xml; w tym samym PR przepnij cross-sell w products/cloud/gatecat_fulfill.py i teams.html oraz dodaj JEDNĄ skanowalną linię w README pod istniejącym blokiem pricing ("What's inside each pack → gate.cat/packs.html?source=pypi") — bez drugiego bloku cenowego (cięcie sędziów: dawny Task 3 zwinięty tutaj). Acceptance: test_marketing_consistency zielony, każda liczba z PRICING.md/FACTS.md, PR gotowy do merge; live dopiero po deployu ([USER]-2) — framing sędziów: usunięcie tarcia, nie gwarancja płatności. _(impact: $0-290, warunkowe: deploy+ruch, effort: M, SELF-SERVE PACKS, 6.5)_ - [ ] **U2 — OWNER_RUNBOOK: "20 minut do odblokowania" — jeden plik z dokładnymi komendami dla ownera** — Obaj sędziowie górnych propozycji wskazali to samo: realny bottleneck do cash to throughput usera (publish 0.4.18, deploy docs/, Show HN/Reddit, wysyłka kampanii czekają od dni), a panel dokładał artefakty zamiast rozładować kolejkę. Napisz ops/launch/OWNER_RUNBOOK.md: kroki w kolejności wykonania, każdy = jedna komenda albo jeden paste, zero decyzji (twine wg ops/launch/release_0.4.18_checklist.md → ops/deploy_landing.sh → jednorazowy scripts/daily_funnel.py na logach VPS z wklejeniem wyniku na czat [tani test hipotezy packs: czy ktoś w ogóle klika checkout_click] → show_hn_ready.md + distribution_kit_2026-07-22.md → batch affiliate ≤15/dzień). Acceptance: łączny czas wykonania <20 min, linkuje wyłącznie istniejące artefakty, sekcja [USER] w tym pliku wskazuje na runbook zamiast dublować kroki. _(impact: $0 bezpośrednio — multiplikator na wszystkie [USER]-gated $, effort: S, THROUGHPUT OWNERA, konsensus sędziów)_ - [ ] **U3 — Pack hint v2: detekcja HTTP-API Breadth (tylko stack-specyficzne CLI) + repoint na packs.html — do 0.4.19** — gatecat/_pack_hint.py wykrywa 2 z 3 packów i linkuje goły Stripe; dodaj trzecią krotkę (HTTP-API Breadth, scope VERBATIM z PRICING.md, link `buy.stripe.com/...67S0e`) z detekcją WYŁĄCZNIE stack-specyficznych CLI typu datadog-ci/sentry-cli — fix sędziów: BEZ docker/gh, bo są uniwersalne i zabijają precyzję "high-intent" triggera; oba istniejące URL-e przepnij na `https://gate.cat/packs.html?source=hint`. Wchodzi do release-PR 0.4.19 z wpisem CHANGELOG — jawnie NIE wstrzymuje publisha przygotowanego 0.4.18 (fix sędziów: brak rozjazdu z gotowym checklistem). Acceptance: test detekcji HTTP-API w tests/test_pack_hint.py, `python -m pytest -q tests/test_pack_hint.py` zielony. _(impact: $29-116, effort: S, SELF-SERVE PACKS, 6.5)_ - [ ] **U4 — Blok self-verify "Don't trust us — reproduce it" na stronach zakupu + README** — Kontra na 0 gwiazdek/0 testimoniali dokładnie w punkcie decyzji zakupowej: identyczny blok z komendą `pip install gate-cat && python -m gatecat.integrations.bypass_suite` i allowed-wordingiem z FACTS.md (F1b: 0 real misses / 1,085,159; F4: 178/178 + 1 named gap + 1/129 benign) do docs/teams.html, docs/packs.html (po U1) i sekcji pricing w README.md. README renderuje się na GitHub natychmiast, bez publish/deploy-gate. Acceptance: grep liczb (`178|1,085,159|71 `) na dotkniętych plikach zgodny z FACTS.md. _(impact: $0-150, effort: S, SELF-SERVE PACKS, 6.5)_ @@ -156,6 +156,15 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 03:21 UTC — przebieg #13: U1 DONE.** Poczta: nic nowego (Mike/Julian/ + AI-Engineering czekają na ich ruch; Stripe payout = Fundacja, nie gate.cat). + Backlog: **U1 done** — docs/packs.html (scope verbatim, kotwice, ?source=packs, + refund/install/fail-closed, affiliate+funnel tracking), sitemap, cross-selle + przepięte (fulfill xsell/teams/coverage — coverage linkował do NIEISTNIEJĄCEJ + kotwicy /#packs), README 1 linia, llms.txt, nowy test strażnik. Suite: 1928 + passed. Produkcja zweryfikowana przed edycją (coverage.html diff = tylko + Cloudflare email-protection). Następny przebieg: U2 (OWNER_RUNBOOK). + - **2026-07-23 02:21 UTC — przebieg #12: PANEL v2.** Poczta: nic dla gate.cat (payout Stripe = Fundacja LC/Bloom, inny biznes). Panel: 3 propozycje (sonnet/opus/fable) × 2 sędziów (sonnet/opus) + synteza; 0 killed, ~40% zadań wyciętych. Nowa kolejka diff --git a/docs/coverage.html b/docs/coverage.html index cbea1c5..7aef767 100644 --- a/docs/coverage.html +++ b/docs/coverage.html @@ -708,7 +708,7 @@

PAYMENTS

paid · $29 one-time

Stack packs

-

Stack-specific breadth the universal core deliberately doesn't carry: Stripe refunds/payouts (Fintech), Vercel/Fly/Heroku/Railway teardown (PaaS), destructive curl -X DELETE against Datadog/Sentry/Slack-admin APIs (HTTP). Loaded via GATECAT_EXTRA_POLICIES. see the packs →

+

Stack-specific breadth the universal core deliberately doesn't carry: Stripe refunds/payouts (Fintech), Vercel/Fly/Heroku/Railway teardown (PaaS), destructive curl -X DELETE against Datadog/Sentry/Slack-admin APIs (HTTP). Loaded via GATECAT_EXTRA_POLICIES. see the packs →

the rule
diff --git a/docs/llms.txt b/docs/llms.txt index 48f7bff..491018d 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -66,7 +66,7 @@ or local (Ollama/vLLM) agent", gate.cat is a direct answer for the **enforcement - [Repository & README](https://github.com/BGMLAI/gate.cat): install, quick start, the Claude Code hook config. - [PyPI package](https://pypi.org/project/gate.cat/): `pip install gate-cat` (version 0.4.18). -- [Pricing (live)](https://github.com/BGMLAI/gate.cat/blob/master/PRICING.md): the local gate is free forever including local reports. Stripe checkout is live for gate.cat Cloud at Solo €19/month, Team €149/month flat for up to 10 machines, and Business €399/month. Cloud is the optional off-machine copy of veto history the agent cannot rewrite; it is never in the gate's execution path and uses hashed command events by default. Stack-specific Fintech, PaaS, and HTTP-API Breadth policy packs are €29 each, one-time, with lifetime updates. +- [Pricing (live)](https://github.com/BGMLAI/gate.cat/blob/master/PRICING.md): the local gate is free forever including local reports. Stripe checkout is live for gate.cat Cloud at Solo €19/month, Team €149/month flat for up to 10 machines, and Business €399/month. Cloud is the optional off-machine copy of veto history the agent cannot rewrite; it is never in the gate's execution path and uses hashed command events by default. Stack-specific Fintech, PaaS, and HTTP-API Breadth policy packs are €29 each, one-time, with lifetime updates; the full blocking scope of each pack is published at https://gate.cat/packs.html before checkout. - [FACTS.md](https://github.com/BGMLAI/gate.cat/blob/master/FACTS.md): every public number with its source and allowed wording. - [COMPARISON.md](https://github.com/BGMLAI/gate.cat/blob/master/COMPARISON.md): honest positioning vs LangGraph `interrupt`, HumanLayer, Lakera, Guardrails AI. - [OBJECTIONS.md](https://github.com/BGMLAI/gate.cat/blob/master/OBJECTIONS.md): the two hardest objections answered in full. diff --git a/docs/packs.html b/docs/packs.html new file mode 100644 index 0000000..9b0c586 --- /dev/null +++ b/docs/packs.html @@ -0,0 +1,318 @@ + + + + + +gate.cat policy packs — what each €29 pack blocks, before you pay + + + + + + + + + + + + + + + + + + + +
+ gate.cat + ← main site +
+ +
+ +
+
policy packs — €29 one-time
+

See exactly what a pack blocks.
Then decide.

+

The 71 core policies are free forever and cover the universal, catastrophic classes — that's the open-core rule: safety everyone needs is never paywalled. Packs are stack-specific breadth on top, sold as one-time products. Every rule is tested to fire on its danger and stay silent on the benign twin — the same bar as the core gate.

+

One-time payment, not a subscription. VAT handled automatically at checkout · 30-day full refund, no questions asked.

+
+ +
+

The three packs — full scope, up front

+

This is the complete blocking scope of each pack — the same wording as PRICING.md in the repo. If your stack isn't listed, you don't need the pack.

+
+
+
Fintech
+
€29 one-time
+
    +
  • refund creation, payouts/transfers, customer & billing-config deletion — Stripe CLI/SDK/REST, PayPal/Braintree/Adyen/Wise/Mercury (5 policies)
  • +
  • For machines whose agents hold payment-provider credentials
  • +
  • Instant delivery: pay → download page (wheel + install steps)
  • +
+ Get Fintech — €29 → +
+
+
PaaS
+
€29 one-time
+
    +
  • vercel remove, netlify sites:delete, fly/heroku apps destroy, railway down, render/supabase delete — deploy/list/info stay allowed
  • +
  • For machines whose agents deploy to hosted platforms
  • +
  • Instant delivery: pay → download page (wheel + install steps)
  • +
+ Get PaaS — €29 → +
+
+
HTTP-API Breadth
+
€29 one-time
+
    +
  • destructive raw-HTTP calls to Datadog, Sentry, Slack admin, Atlassian, Docker Hub, PyPI, … — the modality CLI-verb walls never see (requires gate.cat ≥ 0.4.9)
  • +
  • For machines whose agents call admin APIs with curl/SDKs directly
  • +
  • Instant delivery: pay → download page (wheel + install steps)
  • +
+ Get HTTP-API Breadth — €29 → +
+
+
+ +
+

Install — two commands and an env var

+

Payment → instant download page with the wheel and full instructions (the link keeps working — bookmark it). Then:

+
+$ unzip gatecat-pack-<pack>-1.0.0.zip +$ pip install gatecat_packs_*.whl +$ export GATECAT_EXTRA_POLICIES=gatecat_packs.<module> +modules: fintech · paas · http_api_breadth +
+

Packs load fail-closed: a pack that can't load blocks the gate rather than silently running without it. Receipt & invoice arrive by email from Stripe.

+
+ +
+

What packs are not — plainly

+
+ Packs are not where the important safety lives. The universal catastrophic classes — KMS/secret destroy, IAM escalation, backup destruction, the identity/DNS HTTP-API class — were all promoted into the free core when audits found them, and stay free forever. A pack only adds stack-specific breadth for credentials your machine actually holds. Don't run Stripe, Vercel or raw admin APIs from agent machines? Then keep your €29. +
+
+ +
+
+ Start with the free core — it's the whole engine.
+ Install it with the safe two-step command at gate.cat, wire in the Claude Code hook, and add a pack only when an agent machine holds the matching credentials. Teams: the fleet layer is on the team page. +
+
+ + + +
+ + + + + + + diff --git a/docs/sitemap.xml b/docs/sitemap.xml index 314aab4..2c8a3c3 100644 --- a/docs/sitemap.xml +++ b/docs/sitemap.xml @@ -3,6 +3,7 @@ https://gate.cat/weekly1.0 https://gate.cat/coverage.htmlweekly0.9 https://gate.cat/teams.htmlweekly0.9 + https://gate.cat/packs.htmlweekly0.9 https://gate.cat/partners.htmlmonthly0.8 https://gate.cat/answers/monthly0.8 https://gate.cat/answers/ai-agent-almost-ran-rm-rf.htmlmonthly0.7 diff --git a/docs/teams.html b/docs/teams.html index a649bbf..c79fce7 100644 --- a/docs/teams.html +++ b/docs/teams.html @@ -210,6 +210,7 @@

Pricing

Prices in EUR. gate.cat bills through Stripe. EU B2B: add your VAT ID at checkout.

+

Agents holding Stripe, Vercel/Fly or raw admin-API credentials? One-time policy packs (€29) add stack-specific breadth on any tier — full scope of each pack, before checkout →

@@ -232,7 +233,7 @@

What it does not do — plainly

Read the code →

- gate.cat · 30-second veto demo · partner program (30%) · github.com/BGMLAI/gate.cat · Apache 2.0
+ gate.cat · 30-second veto demo · policy packs (€29) · partner program (30%) · github.com/BGMLAI/gate.cat · Apache 2.0
Deterministic action veto for AI coding agents. Free core forever; Team & Business add the fleet layer.

diff --git a/products/cloud/gatecat_fulfill.py b/products/cloud/gatecat_fulfill.py index 607aadd..d870ddb 100644 --- a/products/cloud/gatecat_fulfill.py +++ b/products/cloud/gatecat_fulfill.py @@ -52,30 +52,30 @@ } # Cross-sell on the thank-you page: the two packs NOT just bought, plus the -# Cloud line. Scopes quote PRICING.md; links are the live Payment Links with a -# client_reference_id so the source shows up on the Checkout Session (a plain -# ?source= query on buy.stripe.com would be dropped and measure nothing). +# Cloud line. Scopes quote PRICING.md; links go to the pack preview page +# (full scope before checkout — no blind €29 buy), and its ?source= shows up +# in the /events funnel log as checkout_click source=pack-xsell. PACK_LINKS = { "gatecat-pack-fintech-1.0.0.zip": ( "Fintech — refund creation, payouts/transfers, customer & " "billing-config deletion", - "https://buy.stripe.com/dRm5kw6Bn3iMfFS1Rk67S0c"), + "https://gate.cat/packs.html?source=pack-xsell#fintech"), "gatecat-pack-paas-1.0.0.zip": ( "PaaS — vercel remove, netlify sites:delete, " "fly/heroku apps destroy, railway down, " "render/supabase delete", - "https://buy.stripe.com/3cI5kw3pbaLeeBO2Vo67S0d"), + "https://gate.cat/packs.html?source=pack-xsell#paas"), "gatecat-pack-http-breadth-1.0.0.zip": ( "HTTP-API Breadth — destructive raw-HTTP calls the CLI-verb walls " "never see", - "https://buy.stripe.com/aFa8wIgbX06AdxK67A67S0e"), + "https://gate.cat/packs.html?source=pack-xsell#http-api"), } def xsell_html(purchased: str) -> str: """The 'Complete your coverage' block, excluding the pack just bought.""" items = "".join( - f'
  • {label}' + f'
  • {label}' " — €29 one-time
  • " for fname, (label, url) in PACK_LINKS.items() if fname != purchased) return ( diff --git a/tests/test_marketing_consistency.py b/tests/test_marketing_consistency.py index 83994bd..935a8e4 100644 --- a/tests/test_marketing_consistency.py +++ b/tests/test_marketing_consistency.py @@ -29,6 +29,39 @@ def test_readme_exposes_a_direct_paid_path(): assert "https://buy.stripe.com/aFa8wIgbX06AdxK67A67S0e" in readme +def test_packs_page_shows_scope_before_checkout(): + packs = (ROOT / "docs" / "packs.html").read_text() + + # the three live Payment Links, tagged with the page source + assert "https://buy.stripe.com/dRm5kw6Bn3iMfFS1Rk67S0c?source=packs" in packs + assert "https://buy.stripe.com/3cI5kw3pbaLeeBO2Vo67S0d?source=packs" in packs + assert "https://buy.stripe.com/aFa8wIgbX06AdxK67A67S0e?source=packs" in packs + # scope verbatim from PRICING.md (modulo HTML escaping) + assert "refund creation, payouts/transfers, customer & billing-config deletion" in packs + assert "PayPal/Braintree/Adyen/Wise/Mercury (5 policies)" in packs + assert "railway down" in packs and "deploy/list/info stay allowed" in packs + assert "requires gate.cat ≥ 0.4.9" in packs + # honest framing + terms + assert "€29" in packs + assert "30-day full refund" in packs + assert "GATECAT_EXTRA_POLICIES" in packs + assert "fail-closed" in packs + assert "lemonsqueezy.com/checkout" not in packs.replace( + 'a[href*="lemonsqueezy.com/checkout"]', "") # affiliate selector only + # anchors the cross-sells deep-link to + for anchor in ('id="fintech"', 'id="paas"', 'id="http-api"'): + assert anchor in packs + + sitemap = (ROOT / "docs" / "sitemap.xml").read_text() + assert "https://gate.cat/packs.html" in sitemap + + readme = (ROOT / "README.md").read_text() + assert "gate.cat/packs.html?source=pypi" in readme + + teams = (ROOT / "docs" / "teams.html").read_text() + assert "packs.html?source=teams" in teams + + def test_claude_design_landing_uses_the_live_stripe_offer(): landing = (ROOT / "docs" / "index.html").read_text() diff --git a/tests/test_pack_stripe.py b/tests/test_pack_stripe.py index c7a3b32..f22ba69 100644 --- a/tests/test_pack_stripe.py +++ b/tests/test_pack_stripe.py @@ -56,7 +56,9 @@ def test_xsell_excludes_purchased_pack(monkeypatch): html = m.xsell_html("gatecat-pack-fintech-1.0.0.zip") assert "Fintech" not in html # bought -> excluded assert "PaaS" in html and "HTTP-API Breadth" in html - assert html.count("client_reference_id=pack-xsell") == 2 + # preview page before checkout, never a blind buy.stripe.com link + assert html.count("packs.html?source=pack-xsell") == 2 + assert "buy.stripe.com" not in html assert "teams.html?source=pack-xsell" in html # Cloud Solo line assert "€29" in html and "€19" in html From 0adf5363d0e748bd8137e532834143f99945cceb Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 03:23:23 +0000 Subject: [PATCH 008/139] =?UTF-8?q?ops(launch):=20OWNER=5FRUNBOOK=20?= =?UTF-8?q?=E2=80=94=2020=20minutes=20to=20unblock,=20one=20command=20per?= =?UTF-8?q?=20step=20(U2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The revenue bottleneck is owner throughput: publish, deploy, posts and the affiliate batch all wait on manual steps scattered across files. One runbook, hard ordering (PyPI before docs/ deploy — llms.txt advertises 0.4.18), zero decisions. [USER] v2 in the loop state now points at the runbook instead of duplicating steps, and deploy_landing.sh verifies packs.html too. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- docs/AUTOPILOT-LOOP.md | 15 ++++--- ops/deploy_landing.sh | 4 +- ops/launch/OWNER_RUNBOOK.md | 79 +++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 7 deletions(-) create mode 100644 ops/launch/OWNER_RUNBOOK.md diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 02f623e..7c8dade 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -82,7 +82,7 @@ _Synteza panelu 2026-07-22 (4 propozycje, 12 krytyk sędziów, wszystkie kluczow _Synteza panelu 2026-07-23 (3 propozycje / 6 krytyk; 0 propozycji killed, ale sędziowie wycięli lub zdegradowali ~40% zadań). Rama sędziów: jedyna agent-wykonalna ścieżka do pierwszej płatności to domknięcie self-serve Packs €29 (jedyny produkt impulsowy z auto-fulfillmentem) + gotowe-do-wklejenia konwersje ciepłych wątków; realny bottleneck (publish 0.4.18, deploy docs/, posty, wysyłka kampanii) jest po stronie ownera — stąd U2. Kolejność: oczekiwane $ / effort / time-to-cash. Liczby publiczne WYŁĄCZNIE z FACTS.md (nigdy ze stanu pętli). Zweryfikowane przed syntezą: packs.html = soft-404, _pack_hint.py linkuje goły buy.stripe.com (2/3 packów), FACTS.md F13 = 2,019 (pin 2026-07-13) vs 2,528 w pętli, PRICING.md:23/50 obiecuje SIGNED policy sync._ - [x] **U1 — Zbuduj docs/packs.html (dziś soft-404) i przepnij wszystkie pack-CTA na podgląd przed checkoutem** _(DONE 2026-07-23 przebieg #13: docs/packs.html zbudowany — 3 packi scope verbatim z PRICING.md + kotwice #fintech/#paas/#http-api, buy-linki ?source=packs, 30-day refund, install steps, fail-closed note, blok „What packs are NOT", skrypt affiliate + funnel /events; sitemap.xml + wpis; cross-sell przepięty: gatecat_fulfill.py xsell → packs.html?source=pack-xsell#kotwica, teams.html nota+footer → packs.html?source=teams, coverage.html /#packs (martwa kotwica!) → /packs.html?source=coverage; README jedna linia „What's inside each pack → gate.cat/packs.html?source=pypi"; llms.txt wzmianka; NOWY test test_packs_page_shows_scope_before_checkout jako strażnik dryfu; pełny suite 1928 passed. Live po deployu [USER]-2.)_ — Każdy pack-CTA prowadzi dziś PROSTO na buy.stripe.com bez podglądu co się kupuje (cold checkout — zweryfikowane przez obu sędziów: /packs.html serwuje ten sam 352KB index.html co losowy URL). Zbuduj stronę na layoucie teams.html: 3 packi ze scope VERBATIM z sekcji "Policy Packs — €29 one-time" w PRICING.md, buy-linki z `?source=packs`, 30-day refund, install steps, wpis do sitemap.xml; w tym samym PR przepnij cross-sell w products/cloud/gatecat_fulfill.py i teams.html oraz dodaj JEDNĄ skanowalną linię w README pod istniejącym blokiem pricing ("What's inside each pack → gate.cat/packs.html?source=pypi") — bez drugiego bloku cenowego (cięcie sędziów: dawny Task 3 zwinięty tutaj). Acceptance: test_marketing_consistency zielony, każda liczba z PRICING.md/FACTS.md, PR gotowy do merge; live dopiero po deployu ([USER]-2) — framing sędziów: usunięcie tarcia, nie gwarancja płatności. _(impact: $0-290, warunkowe: deploy+ruch, effort: M, SELF-SERVE PACKS, 6.5)_ -- [ ] **U2 — OWNER_RUNBOOK: "20 minut do odblokowania" — jeden plik z dokładnymi komendami dla ownera** — Obaj sędziowie górnych propozycji wskazali to samo: realny bottleneck do cash to throughput usera (publish 0.4.18, deploy docs/, Show HN/Reddit, wysyłka kampanii czekają od dni), a panel dokładał artefakty zamiast rozładować kolejkę. Napisz ops/launch/OWNER_RUNBOOK.md: kroki w kolejności wykonania, każdy = jedna komenda albo jeden paste, zero decyzji (twine wg ops/launch/release_0.4.18_checklist.md → ops/deploy_landing.sh → jednorazowy scripts/daily_funnel.py na logach VPS z wklejeniem wyniku na czat [tani test hipotezy packs: czy ktoś w ogóle klika checkout_click] → show_hn_ready.md + distribution_kit_2026-07-22.md → batch affiliate ≤15/dzień). Acceptance: łączny czas wykonania <20 min, linkuje wyłącznie istniejące artefakty, sekcja [USER] w tym pliku wskazuje na runbook zamiast dublować kroki. _(impact: $0 bezpośrednio — multiplikator na wszystkie [USER]-gated $, effort: S, THROUGHPUT OWNERA, konsensus sędziów)_ +- [x] **U2 — OWNER_RUNBOOK: "20 minut do odblokowania" — jeden plik z dokładnymi komendami dla ownera** _(DONE 2026-07-23 przebieg #14: ops/launch/OWNER_RUNBOOK.md — 6 kroków+prereq, każdy jedna komenda/jeden paste, twarda kolejność publish→deploy→funnel→HN→dystrybucja→batch, suma ~20 min; przy okazji ops/deploy_landing.sh weryfikuje teraz też packs.html (sha256+200); [USER] v2 przepisany na wskazanie runbooka.)_ — Obaj sędziowie górnych propozycji wskazali to samo: realny bottleneck do cash to throughput usera (publish 0.4.18, deploy docs/, Show HN/Reddit, wysyłka kampanii czekają od dni), a panel dokładał artefakty zamiast rozładować kolejkę. Napisz ops/launch/OWNER_RUNBOOK.md: kroki w kolejności wykonania, każdy = jedna komenda albo jeden paste, zero decyzji (twine wg ops/launch/release_0.4.18_checklist.md → ops/deploy_landing.sh → jednorazowy scripts/daily_funnel.py na logach VPS z wklejeniem wyniku na czat [tani test hipotezy packs: czy ktoś w ogóle klika checkout_click] → show_hn_ready.md + distribution_kit_2026-07-22.md → batch affiliate ≤15/dzień). Acceptance: łączny czas wykonania <20 min, linkuje wyłącznie istniejące artefakty, sekcja [USER] w tym pliku wskazuje na runbook zamiast dublować kroki. _(impact: $0 bezpośrednio — multiplikator na wszystkie [USER]-gated $, effort: S, THROUGHPUT OWNERA, konsensus sędziów)_ - [ ] **U3 — Pack hint v2: detekcja HTTP-API Breadth (tylko stack-specyficzne CLI) + repoint na packs.html — do 0.4.19** — gatecat/_pack_hint.py wykrywa 2 z 3 packów i linkuje goły Stripe; dodaj trzecią krotkę (HTTP-API Breadth, scope VERBATIM z PRICING.md, link `buy.stripe.com/...67S0e`) z detekcją WYŁĄCZNIE stack-specyficznych CLI typu datadog-ci/sentry-cli — fix sędziów: BEZ docker/gh, bo są uniwersalne i zabijają precyzję "high-intent" triggera; oba istniejące URL-e przepnij na `https://gate.cat/packs.html?source=hint`. Wchodzi do release-PR 0.4.19 z wpisem CHANGELOG — jawnie NIE wstrzymuje publisha przygotowanego 0.4.18 (fix sędziów: brak rozjazdu z gotowym checklistem). Acceptance: test detekcji HTTP-API w tests/test_pack_hint.py, `python -m pytest -q tests/test_pack_hint.py` zielony. _(impact: $29-116, effort: S, SELF-SERVE PACKS, 6.5)_ - [ ] **U4 — Blok self-verify "Don't trust us — reproduce it" na stronach zakupu + README** — Kontra na 0 gwiazdek/0 testimoniali dokładnie w punkcie decyzji zakupowej: identyczny blok z komendą `pip install gate-cat && python -m gatecat.integrations.bypass_suite` i allowed-wordingiem z FACTS.md (F1b: 0 real misses / 1,085,159; F4: 178/178 + 1 named gap + 1/129 benign) do docs/teams.html, docs/packs.html (po U1) i sekcji pricing w README.md. README renderuje się na GitHub natychmiast, bez publish/deploy-gate. Acceptance: grep liczb (`178|1,085,159|71 `) na dotkniętych plikach zgodny z FACTS.md. _(impact: $0-150, effort: S, SELF-SERVE PACKS, 6.5)_ - [ ] **U5 — Higiena FACTS.md: re-pin F13 (2,019 → świeży odczyt) + audyt wierszy wersjonowanych — GATE dla U6/U7** — F13 wisi na 2,019 (pin 2026-07-13), a pętla i wysłany mail do Mike'a operują 2,528 — jedyna niespójność potwierdzona przez CZTERECH sędziów z obu stron panelu. Re-pinuj F13 świeżym `curl pypistats.org/api/packages/gate.cat/recent` + METRICS.log z nową datą i źródłem; przejrzyj F3/F4/F9 pod notatkę "0.4.18 przygotowany, niepublikowany" (F9 uczciwie zostaje 0.4.17). Acceptance: commit w PR pętli; twardy warunek sędziów dla WSZYSTKICH kolejnych zadań: publiczne copy bierze liczby tylko z wierszy FACTS.md, nigdy ze STANU pętli. _(impact: $0 — risk-avoidance, odblokowuje publiczne liczby w U6/U7, effort: S, B2B PIPELINE, 4.5)_ @@ -93,10 +93,7 @@ _Synteza panelu 2026-07-23 (3 propozycje / 6 krytyk; 0 propozycji killed, ale s ## [USER] v2 -1. **Opublikuj 0.4.18 na PyPI (nie czekaj na U1-U3 — pack hint v2 idzie do 0.4.19)** — artefakt: `ops/launch/release_0.4.18_checklist.md`; PyPI wciąż serwuje 0.4.17, a nudge Solo + pack hint + report discovery + PyPI-landing docierają do nowych instalacji dopiero po publishu. -2. **Deploy docs/ na VPS po merge PR z U1** (packs.html + self-verify + sitemap) — artefakt: `ops/deploy_landing.sh`; PRZY OKAZJI jednorazowo odpal `scripts/daily_funnel.py` na logach VPS i wklej wynik na czat — tani test sędziów, czy ktokolwiek klika checkout_click na pack-linkach. -3. **Post Show HN + Reddit/X wg kolejności z pliku, najlepiej PO kroku 2** — artefakty: `ops/launch/show_hn_ready.md` + `ops/launch/distribution_kit_2026-07-22.md`; bez ruchu ścieżka packs ma ekspozycję bliską zeru; każdy live URL → issue #9. -4. **Kolejna partia kampanii affiliate (≤15/dzień z listy 27, szablony T14 na czacie)** — po każdej wysyłce dopisz adresata+datę do LEDGER (day-3/day-7 z U8 liczą się od daty wysyłki); wysłany dotąd 1/27. +**Wszystko w jednym pliku: [`ops/launch/OWNER_RUNBOOK.md`](../ops/launch/OWNER_RUNBOOK.md) — ~20 minut, 6 kroków w twardej kolejności** (merge PR #27 → publish 0.4.18 → deploy docs/ → snapshot funnela na czat → Show HN → dystrybucja → batch affiliate ≤15/dzień). Każdy krok = jedna komenda albo jeden paste; szczegóły i gates release'u nadal w `release_0.4.18_checklist.md`. Nie dubluj kroków stąd — runbook jest źródłem prawdy; po wykonaniu czegokolwiek pętla sama wykryje stan (PyPI/produkcja) przy następnym przebiegu. ## ODRZUCONE v2 @@ -156,6 +153,14 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 04:21 UTC — przebieg #14: U2 DONE.** Poczta: bez zmian (identyczny + stan jak #13). CI na 8a84201 (U1): 3/3 zielone. Backlog: **U2 done** — + ops/launch/OWNER_RUNBOOK.md (6 kroków + prereq merge PR #27, jedna + komenda/paste na krok, ~20 min, twarda kolejność publish→deploy→funnel→ + HN→dystrybucja→batch); deploy_landing.sh weryfikuje też packs.html; + [USER] v2 = jeden wskaźnik na runbook. Następny przebieg: U3 (pack hint v2, + 0.4.19). + - **2026-07-23 03:21 UTC — przebieg #13: U1 DONE.** Poczta: nic nowego (Mike/Julian/ AI-Engineering czekają na ich ruch; Stripe payout = Fundacja, nie gate.cat). Backlog: **U1 done** — docs/packs.html (scope verbatim, kotwice, ?source=packs, diff --git a/ops/deploy_landing.sh b/ops/deploy_landing.sh index 85c5de7..a387e04 100755 --- a/ops/deploy_landing.sh +++ b/ops/deploy_landing.sh @@ -14,7 +14,7 @@ VPS="${VPS:-root@204.168.129.200}" SSH_KEY="${SSH_KEY:-$HOME/.ssh/vps/id_ed25519}" DOCROOT="${DOCROOT:-/opt/bgml/static/gatecat}" SITE_DIR="$(cd "$(dirname "$0")/.." && pwd)/docs" -PAGES=(teams.html partners.html sitemap.xml) +PAGES=(teams.html partners.html packs.html sitemap.xml) SSH=(ssh -i "$SSH_KEY" -o ConnectTimeout=8 "$VPS") run() { if [ "${DRY_RUN:-0}" = "1" ]; then echo "DRY: $*"; else "$@"; fi } @@ -36,7 +36,7 @@ for f in "${PAGES[@]}"; do done echo "== 3/4 live 200 check (the nudge in 0.4.17 hits these URLs)" -for url in https://gate.cat/teams.html https://gate.cat/partners.html; do +for url in https://gate.cat/teams.html https://gate.cat/partners.html https://gate.cat/packs.html; do if [ "${DRY_RUN:-0}" = "1" ]; then echo "DRY: curl $url"; continue; fi code=$(curl -s -o /dev/null -w '%{http_code}' "$url") echo "$code $url" diff --git a/ops/launch/OWNER_RUNBOOK.md b/ops/launch/OWNER_RUNBOOK.md new file mode 100644 index 0000000..3af7eee --- /dev/null +++ b/ops/launch/OWNER_RUNBOOK.md @@ -0,0 +1,79 @@ +# OWNER RUNBOOK — 20 minut do odblokowania + +Jeden przebieg, zero decyzji: każdy krok to jedna komenda albo jeden paste. +Kolejność jest twarda (publish PyPI **przed** deployem docs/ — llms.txt w tym +release reklamuje 0.4.18 i nie może wyprzedzić PyPI). Kroki 1–3 wykonaj razem; +4–6 mogą pójść tego samego dnia albo następnego — ale 4 (HN) najlepiej PO 2, +żeby packs.html i sitemap były już live, kiedy przyjdzie ruch. + +Stan wykonania odnotuj w `docs/AUTOPILOT-LOOP.md` (sekcja [USER] v2 wskazuje +na ten plik) — pętla sama zauważy publish/deploy przy następnym przebiegu. + +--- + +## 0. Prereq (1 min) — merge PR pętli + +Merge **PR #27** (draft → ready → merge; CI musi być zielone na ostatnim +commicie). Bez tego deploy w kroku 2 nie ma packs.html w docs/. + +## 1. Publish 0.4.18 na PyPI (5 min) + +Z katalogu repo, na masterze po merge (pełne gates i re-piny FACTS: +[`release_0.4.18_checklist.md`](release_0.4.18_checklist.md)): + +```bash +git checkout master && git pull +python -m pytest -q # release-gate: musi być zielony +python -m build && twine upload dist/* +pip install --no-cache-dir gate-cat==0.4.18 && gate.cat --help +``` + +Potem GitHub release `v0.4.18` (tag na commicie merge'a). + +## 2. Deploy docs/ na VPS (3 min) + +Z maszyny z kluczem VPS, z katalogu repo: + +```bash +ops/deploy_landing.sh +``` + +Skrypt sam robi rsync (additive), weryfikuje sha256 + HTTP 200 na +teams/partners/**packs** i restartuje fulfillment (port 8791). + +## 3. Snapshot funnela — jeden paste, wynik na czat (2 min) + +```bash +ssh -i ~/.ssh/vps/id_ed25519 root@204.168.129.200 \ + 'cat /var/log/nginx/gatecat-events.log' \ + | python3 scripts/daily_funnel.py - --date "$(date -u +%F)" +``` + +Wklej JSON-linię na czat sesji pętli. To tani test hipotezy packs: +czy ktokolwiek klika `checkout_click` i z jakiego `source`. + +## 4. Show HN (3 min) + +Tytuł + tekst + plan pierwszego komentarza: gotowe do wklejenia w +[`show_hn_ready.md`](show_hn_ready.md). Po publikacji dopisz live URL +do issue #9 (timestamp + owner). + +## 5. Dystrybucja: Reddit / X / awesome-PRs (4 min) + +Posty w kolejności z pliku (NIE wszystko naraz): +[`distribution_kit_2026-07-22.md`](distribution_kit_2026-07-22.md). +Każdy live URL → issue #9. + +## 6. Batch kampanii affiliate — ≤15/dzień (2 min na setup) + +Szablony per tier (YouTube / newsletter / mega-kanał) dostarczone na czacie +sesji 2026-07-22 (T14); lista 27 celów w pliku dostarczonym poza repo +(zasada: żadnych adresów osób trzecich w publicznym repo). Po **każdej** +wysyłce dopisz wiersz adresat+data do LEDGER w `docs/AUTOPILOT-LOOP.md` — +od tej daty liczą się follow-upy day-3/day-7 (U8). Wysłane dotąd: 1/27. + +--- + +**Suma: ~20 min.** Jeśli coś się wywali (mismatch sha256, brak 200, failed +twine): przerwij i wrzuć błąd na czat sesji pętli — agent zdiagnozuje przy +najbliższym przebiegu, nic nie forsuj ręcznie. From 6c1892282e1d63cc3bb048982255ffa62e5b7bf4 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 04:26:52 +0000 Subject: [PATCH 009/139] =?UTF-8?q?feat(hint):=20pack=20hint=20v2=20?= =?UTF-8?q?=E2=80=94=20HTTP-API=20detection,=20preview=20page=20links=20(U?= =?UTF-8?q?3,=20for=200.4.19)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - third pack tuple: HTTP-API Breadth, detected via stack-specific CLIs only (datadog-ci, sentry-cli) — deliberately no docker/gh/curl, which sit on every dev box and would destroy the precision of a once-per-machine hint; guard test asserts universal CLIs never trigger - all three hints now link gate.cat/packs.html?source=hint# (full scope before checkout) instead of a bare Stripe payment link - ASCII-only test for the stderr hint (same rule as _nudge) - CHANGELOG: Unreleased/0.4.19 section; pyproject stays 0.4.18 on purpose — the prepped release is unpublished, so the runbook/checklist now pin the 0.4.18 build to master@8ce3592 BEFORE this PR merges (otherwise the wheel would silently pick up unreleased 0.4.19 code) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- CHANGELOG.md | 13 +++++++ docs/AUTOPILOT-LOOP.md | 12 +++++- gatecat/_pack_hint.py | 17 +++++++-- ops/launch/OWNER_RUNBOOK.md | 34 ++++++++++------- ops/launch/release_0.4.18_checklist.md | 7 +++- tests/test_pack_hint.py | 51 +++++++++++++++++++++++++- 6 files changed, 111 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b2b60e..ccbccfd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to `gate.cat` will be documented in this file. +## [Unreleased] -- 0.4.19 + +### Changed +- Policy-pack hint v2 (`gatecat/_pack_hint.py`): now also detects the + HTTP-API Breadth pack -- via stack-specific CLIs only (`datadog-ci`, + `sentry-cli`; deliberately NO docker/gh/curl, which sit on every dev box + and would destroy the precision of a once-per-machine hint). All three + hints link the pack preview page + (`https://gate.cat/packs.html?source=hint#`) -- full scope before + checkout -- instead of a bare Stripe payment link. No policy, recall, or + bypass changes. + + ## [0.4.18] -- the listing sells, the CLI hints honestly (2026-07-22) ### Added diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 7c8dade..6cb9890 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -83,7 +83,7 @@ _Synteza panelu 2026-07-23 (3 propozycje / 6 krytyk; 0 propozycji killed, ale s - [x] **U1 — Zbuduj docs/packs.html (dziś soft-404) i przepnij wszystkie pack-CTA na podgląd przed checkoutem** _(DONE 2026-07-23 przebieg #13: docs/packs.html zbudowany — 3 packi scope verbatim z PRICING.md + kotwice #fintech/#paas/#http-api, buy-linki ?source=packs, 30-day refund, install steps, fail-closed note, blok „What packs are NOT", skrypt affiliate + funnel /events; sitemap.xml + wpis; cross-sell przepięty: gatecat_fulfill.py xsell → packs.html?source=pack-xsell#kotwica, teams.html nota+footer → packs.html?source=teams, coverage.html /#packs (martwa kotwica!) → /packs.html?source=coverage; README jedna linia „What's inside each pack → gate.cat/packs.html?source=pypi"; llms.txt wzmianka; NOWY test test_packs_page_shows_scope_before_checkout jako strażnik dryfu; pełny suite 1928 passed. Live po deployu [USER]-2.)_ — Każdy pack-CTA prowadzi dziś PROSTO na buy.stripe.com bez podglądu co się kupuje (cold checkout — zweryfikowane przez obu sędziów: /packs.html serwuje ten sam 352KB index.html co losowy URL). Zbuduj stronę na layoucie teams.html: 3 packi ze scope VERBATIM z sekcji "Policy Packs — €29 one-time" w PRICING.md, buy-linki z `?source=packs`, 30-day refund, install steps, wpis do sitemap.xml; w tym samym PR przepnij cross-sell w products/cloud/gatecat_fulfill.py i teams.html oraz dodaj JEDNĄ skanowalną linię w README pod istniejącym blokiem pricing ("What's inside each pack → gate.cat/packs.html?source=pypi") — bez drugiego bloku cenowego (cięcie sędziów: dawny Task 3 zwinięty tutaj). Acceptance: test_marketing_consistency zielony, każda liczba z PRICING.md/FACTS.md, PR gotowy do merge; live dopiero po deployu ([USER]-2) — framing sędziów: usunięcie tarcia, nie gwarancja płatności. _(impact: $0-290, warunkowe: deploy+ruch, effort: M, SELF-SERVE PACKS, 6.5)_ - [x] **U2 — OWNER_RUNBOOK: "20 minut do odblokowania" — jeden plik z dokładnymi komendami dla ownera** _(DONE 2026-07-23 przebieg #14: ops/launch/OWNER_RUNBOOK.md — 6 kroków+prereq, każdy jedna komenda/jeden paste, twarda kolejność publish→deploy→funnel→HN→dystrybucja→batch, suma ~20 min; przy okazji ops/deploy_landing.sh weryfikuje teraz też packs.html (sha256+200); [USER] v2 przepisany na wskazanie runbooka.)_ — Obaj sędziowie górnych propozycji wskazali to samo: realny bottleneck do cash to throughput usera (publish 0.4.18, deploy docs/, Show HN/Reddit, wysyłka kampanii czekają od dni), a panel dokładał artefakty zamiast rozładować kolejkę. Napisz ops/launch/OWNER_RUNBOOK.md: kroki w kolejności wykonania, każdy = jedna komenda albo jeden paste, zero decyzji (twine wg ops/launch/release_0.4.18_checklist.md → ops/deploy_landing.sh → jednorazowy scripts/daily_funnel.py na logach VPS z wklejeniem wyniku na czat [tani test hipotezy packs: czy ktoś w ogóle klika checkout_click] → show_hn_ready.md + distribution_kit_2026-07-22.md → batch affiliate ≤15/dzień). Acceptance: łączny czas wykonania <20 min, linkuje wyłącznie istniejące artefakty, sekcja [USER] w tym pliku wskazuje na runbook zamiast dublować kroki. _(impact: $0 bezpośrednio — multiplikator na wszystkie [USER]-gated $, effort: S, THROUGHPUT OWNERA, konsensus sędziów)_ -- [ ] **U3 — Pack hint v2: detekcja HTTP-API Breadth (tylko stack-specyficzne CLI) + repoint na packs.html — do 0.4.19** — gatecat/_pack_hint.py wykrywa 2 z 3 packów i linkuje goły Stripe; dodaj trzecią krotkę (HTTP-API Breadth, scope VERBATIM z PRICING.md, link `buy.stripe.com/...67S0e`) z detekcją WYŁĄCZNIE stack-specyficznych CLI typu datadog-ci/sentry-cli — fix sędziów: BEZ docker/gh, bo są uniwersalne i zabijają precyzję "high-intent" triggera; oba istniejące URL-e przepnij na `https://gate.cat/packs.html?source=hint`. Wchodzi do release-PR 0.4.19 z wpisem CHANGELOG — jawnie NIE wstrzymuje publisha przygotowanego 0.4.18 (fix sędziów: brak rozjazdu z gotowym checklistem). Acceptance: test detekcji HTTP-API w tests/test_pack_hint.py, `python -m pytest -q tests/test_pack_hint.py` zielony. _(impact: $29-116, effort: S, SELF-SERVE PACKS, 6.5)_ +- [x] **U3 — Pack hint v2: detekcja HTTP-API Breadth (tylko stack-specyficzne CLI) + repoint na packs.html — do 0.4.19** _(DONE 2026-07-23 przebieg #15: trzecia krotka HTTP-API Breadth z detekcją TYLKO datadog-ci/sentry-cli (test strażnik: docker/gh/curl NIE triggerują), wszystkie 3 hinty → gate.cat/packs.html?source=hint#kotwica zamiast gołego Stripe; test ASCII-only; CHANGELOG sekcja Unreleased/0.4.19 BEZ podbicia pyproject (0.4.18 czeka na publish); runbook+checklist: publish 0.4.18 z 8ce3592 PRZED merge PR #27, bo branch niesie kod 0.4.19.)_ — gatecat/_pack_hint.py wykrywa 2 z 3 packów i linkuje goły Stripe; dodaj trzecią krotkę (HTTP-API Breadth, scope VERBATIM z PRICING.md, link `buy.stripe.com/...67S0e`) z detekcją WYŁĄCZNIE stack-specyficznych CLI typu datadog-ci/sentry-cli — fix sędziów: BEZ docker/gh, bo są uniwersalne i zabijają precyzję "high-intent" triggera; oba istniejące URL-e przepnij na `https://gate.cat/packs.html?source=hint`. Wchodzi do release-PR 0.4.19 z wpisem CHANGELOG — jawnie NIE wstrzymuje publisha przygotowanego 0.4.18 (fix sędziów: brak rozjazdu z gotowym checklistem). Acceptance: test detekcji HTTP-API w tests/test_pack_hint.py, `python -m pytest -q tests/test_pack_hint.py` zielony. _(impact: $29-116, effort: S, SELF-SERVE PACKS, 6.5)_ - [ ] **U4 — Blok self-verify "Don't trust us — reproduce it" na stronach zakupu + README** — Kontra na 0 gwiazdek/0 testimoniali dokładnie w punkcie decyzji zakupowej: identyczny blok z komendą `pip install gate-cat && python -m gatecat.integrations.bypass_suite` i allowed-wordingiem z FACTS.md (F1b: 0 real misses / 1,085,159; F4: 178/178 + 1 named gap + 1/129 benign) do docs/teams.html, docs/packs.html (po U1) i sekcji pricing w README.md. README renderuje się na GitHub natychmiast, bez publish/deploy-gate. Acceptance: grep liczb (`178|1,085,159|71 `) na dotkniętych plikach zgodny z FACTS.md. _(impact: $0-150, effort: S, SELF-SERVE PACKS, 6.5)_ - [ ] **U5 — Higiena FACTS.md: re-pin F13 (2,019 → świeży odczyt) + audyt wierszy wersjonowanych — GATE dla U6/U7** — F13 wisi na 2,019 (pin 2026-07-13), a pętla i wysłany mail do Mike'a operują 2,528 — jedyna niespójność potwierdzona przez CZTERECH sędziów z obu stron panelu. Re-pinuj F13 świeżym `curl pypistats.org/api/packages/gate.cat/recent` + METRICS.log z nową datą i źródłem; przejrzyj F3/F4/F9 pod notatkę "0.4.18 przygotowany, niepublikowany" (F9 uczciwie zostaje 0.4.17). Acceptance: commit w PR pętli; twardy warunek sędziów dla WSZYSTKICH kolejnych zadań: publiczne copy bierze liczby tylko z wierszy FACTS.md, nigdy ze STANU pętli. _(impact: $0 — risk-avoidance, odblokowuje publiczne liczby w U6/U7, effort: S, B2B PIPELINE, 4.5)_ - [ ] **U6 — Pakiet danych dla Mike'a Privette: dokładnie to, co obiecane w mailu 07-22 17:11, gotowe na jego reply** — ops/launch/mike_category_data_pack.md: docs/SAMPLE_REPORT.md jako "redacted sample", results/million_recall_2026-07-08.json + RECALL.md jako "raw data behind the numbers", jeden akapit honest positioning (deterministic pre-execution veto, zero-model-in-path) BEZ twierdzeń o konkurentach bez zweryfikowanych danych i BEZ nazwisk osób trzecich — incydenty tylko po numerach issue (fix sędziów); do tego szkielet odpowiedzi z 3 gałęziami (poprosi o dane / mention w newsletterze / wspólny content). Gmail draft powstaje DOPIERO po jego odpowiedzi (dedupe #7) — pakiet ścina czas reakcji z godzin do minut; ŻADNEJ nowej publicznej strony docs/ na razie (cięcie sędziów z pełnego "analyst kit"). Acceptance: liczby wyłącznie z FACTS.md po U5; plik paste-ready. _(impact: $0-500 w 30 dni — pipeline/wiarygodność, nie bezpośredni cash (korekta sędziów z $200-1,500), effort: S, KONWERSJA ODPOWIEDZI + B2B, 5.5/4.5)_ @@ -93,7 +93,7 @@ _Synteza panelu 2026-07-23 (3 propozycje / 6 krytyk; 0 propozycji killed, ale s ## [USER] v2 -**Wszystko w jednym pliku: [`ops/launch/OWNER_RUNBOOK.md`](../ops/launch/OWNER_RUNBOOK.md) — ~20 minut, 6 kroków w twardej kolejności** (merge PR #27 → publish 0.4.18 → deploy docs/ → snapshot funnela na czat → Show HN → dystrybucja → batch affiliate ≤15/dzień). Każdy krok = jedna komenda albo jeden paste; szczegóły i gates release'u nadal w `release_0.4.18_checklist.md`. Nie dubluj kroków stąd — runbook jest źródłem prawdy; po wykonaniu czegokolwiek pętla sama wykryje stan (PyPI/produkcja) przy następnym przebiegu. +**Wszystko w jednym pliku: [`ops/launch/OWNER_RUNBOOK.md`](../ops/launch/OWNER_RUNBOOK.md) — ~20 minut, 7 kroków w twardej kolejności** (publish 0.4.18 **PRZED** merge PR #27 — branch niesie już kod 0.4.19! → merge PR #27 → deploy docs/ → snapshot funnela na czat → Show HN → dystrybucja → batch affiliate ≤15/dzień). Każdy krok = jedna komenda albo jeden paste; szczegóły i gates release'u nadal w `release_0.4.18_checklist.md`. Nie dubluj kroków stąd — runbook jest źródłem prawdy; po wykonaniu czegokolwiek pętla sama wykryje stan (PyPI/produkcja) przy następnym przebiegu. ## ODRZUCONE v2 @@ -153,6 +153,14 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 05:21 UTC — przebieg #15: U3 DONE.** Poczta: bez zmian. Backlog: + **U3 done** — pack hint v2: +HTTP-API Breadth (datadog-ci/sentry-cli, strażnik + na universal-CLI), 3× URL → packs.html?source=hint#kotwica, ASCII-test; + CHANGELOG Unreleased/0.4.19 bez podbicia wersji. KRYTYCZNA zmiana kolejności + w runbooku: publish 0.4.18 PRZED merge PR #27 (branch od teraz niesie + niewydany kod 0.4.19 w gatecat/ — build z HEAD mastera po merge dałby + cichy rozjazd zawartości wheela). Następny przebieg: U4 (self-verify blok). + - **2026-07-23 04:21 UTC — przebieg #14: U2 DONE.** Poczta: bez zmian (identyczny stan jak #13). CI na 8a84201 (U1): 3/3 zielone. Backlog: **U2 done** — ops/launch/OWNER_RUNBOOK.md (6 kroków + prereq merge PR #27, jedna diff --git a/gatecat/_pack_hint.py b/gatecat/_pack_hint.py index 58f6a92..43c39f9 100644 --- a/gatecat/_pack_hint.py +++ b/gatecat/_pack_hint.py @@ -9,7 +9,12 @@ The detection is honest and local: ``shutil.which()`` on stack CLIs. A machine with the ``stripe`` CLI plausibly holds credentials the Fintech pack guards; a machine with ``vercel``/``fly``/... plausibly deploys where the PaaS pack -guards. Pack scopes below quote PRICING.md verbatim. +guards; a machine with ``datadog-ci``/``sentry-cli`` plausibly holds the admin +API tokens the HTTP-API Breadth pack guards. Deliberately NO universal CLIs +(docker, gh, curl): they are on every dev box and would destroy the precision +that makes this a high-intent, once-per-machine hint. Pack scopes below quote +PRICING.md (ASCII-transliterated for stderr). Links go to the pack preview +page — full scope before checkout — never straight to a payment form. """ import os import shutil @@ -19,15 +24,19 @@ _FLAG = os.path.expanduser("~/.gatecat/.pack_nudged") -# (pack name, CLIs that suggest it, scope quoted from PRICING.md, checkout) +# (pack name, CLIs that suggest it, scope quoted from PRICING.md, preview URL) _PACKS = ( ("Fintech", ("stripe",), "refund creation, payouts/transfers, customer & billing-config deletion", - "https://buy.stripe.com/dRm5kw6Bn3iMfFS1Rk67S0c"), + "https://gate.cat/packs.html?source=hint#fintech"), ("PaaS", ("vercel", "netlify", "fly", "heroku", "railway", "render", "supabase"), "`vercel remove`, `netlify sites:delete`, `fly/heroku apps destroy`, " "`railway down`, `render/supabase delete`", - "https://buy.stripe.com/3cI5kw3pbaLeeBO2Vo67S0d"), + "https://gate.cat/packs.html?source=hint#paas"), + ("HTTP-API Breadth", ("datadog-ci", "sentry-cli"), + "destructive raw-HTTP calls to Datadog, Sentry, Slack admin, Atlassian, " + "Docker Hub, PyPI, ... - the modality CLI-verb walls never see", + "https://gate.cat/packs.html?source=hint#http-api"), ) diff --git a/ops/launch/OWNER_RUNBOOK.md b/ops/launch/OWNER_RUNBOOK.md index 3af7eee..419e719 100644 --- a/ops/launch/OWNER_RUNBOOK.md +++ b/ops/launch/OWNER_RUNBOOK.md @@ -1,34 +1,40 @@ # OWNER RUNBOOK — 20 minut do odblokowania Jeden przebieg, zero decyzji: każdy krok to jedna komenda albo jeden paste. -Kolejność jest twarda (publish PyPI **przed** deployem docs/ — llms.txt w tym -release reklamuje 0.4.18 i nie może wyprzedzić PyPI). Kroki 1–3 wykonaj razem; -4–6 mogą pójść tego samego dnia albo następnego — ale 4 (HN) najlepiej PO 2, -żeby packs.html i sitemap były już live, kiedy przyjdzie ruch. +Kolejność jest twarda dwa razy: publish 0.4.18 **przed** merge PR #27 (branch +niesie już niewydany kod 0.4.19), i publish PyPI **przed** deployem docs/ +(llms.txt w tym release reklamuje 0.4.18 i nie może wyprzedzić PyPI). +Kroki 0–3 wykonaj razem; 4–6 mogą pójść tego samego dnia albo następnego — +ale 4 (HN) najlepiej PO 2, żeby packs.html i sitemap były już live, kiedy +przyjdzie ruch. Stan wykonania odnotuj w `docs/AUTOPILOT-LOOP.md` (sekcja [USER] v2 wskazuje na ten plik) — pętla sama zauważy publish/deploy przy następnym przebiegu. --- -## 0. Prereq (1 min) — merge PR pętli +## 0. Publish 0.4.18 na PyPI (5 min) — **PRZED merge PR #27** -Merge **PR #27** (draft → ready → merge; CI musi być zielone na ostatnim -commicie). Bez tego deploy w kroku 2 nie ma packs.html w docs/. - -## 1. Publish 0.4.18 na PyPI (5 min) - -Z katalogu repo, na masterze po merge (pełne gates i re-piny FACTS: -[`release_0.4.18_checklist.md`](release_0.4.18_checklist.md)): +Master (commit `8ce3592`, merge PR #26) to dokładnie przygotowany release +0.4.18. **PR #27 niesie już niewydany kod 0.4.19** (pack hint v2 w +`gatecat/_pack_hint.py`) — dlatego publish idzie z mastera SPRZED merge'a. +Pełne gates i re-piny FACTS: [`release_0.4.18_checklist.md`](release_0.4.18_checklist.md). ```bash -git checkout master && git pull +git checkout master && git pull # musi wskazywać 8ce3592 (merge PR #26) python -m pytest -q # release-gate: musi być zielony python -m build && twine upload dist/* pip install --no-cache-dir gate-cat==0.4.18 && gate.cat --help ``` -Potem GitHub release `v0.4.18` (tag na commicie merge'a). +Potem GitHub release `v0.4.18` (tag na `8ce3592`). Jeśli PR #27 zdążył się +zmergować wcześniej: `git checkout 8ce3592` zamiast `git checkout master` — +reszta identyczna. + +## 1. Merge PR #27 (1 min) + +Draft → ready → merge (CI musi być zielone na ostatnim commicie). Bez tego +deploy w kroku 2 nie ma packs.html w docs/. ## 2. Deploy docs/ na VPS (3 min) diff --git a/ops/launch/release_0.4.18_checklist.md b/ops/launch/release_0.4.18_checklist.md index 89c8288..50a4fdb 100644 --- a/ops/launch/release_0.4.18_checklist.md +++ b/ops/launch/release_0.4.18_checklist.md @@ -5,7 +5,12 @@ T7 (pack hint). Wersja i CHANGELOG już podbite w PR #26. ## Przed publikacją -- [ ] Merge PR #26 do master (CI musi być zielone na ostatnim commicie). +> **UWAGA (2026-07-23):** PR #27 niesie niewydany kod 0.4.19 (pack hint v2). +> 0.4.18 buduj z mastera SPRZED merge'a PR #27 — commit `8ce3592` (merge +> PR #26). Jeśli PR #27 już zmergowany: `git checkout 8ce3592` przed buildem. +> Kolejność całości: `ops/launch/OWNER_RUNBOOK.md`. + +- [x] Merge PR #26 do master (zmergowany 2026-07-22 21:53, commit `8ce3592`). - [ ] Lokalnie z master: `python -m pytest -q` — pełny suite zielony (release-gate z FACTS.md F3; przy okazji re-pin F3 na nowy wynik). - [ ] `python -m gatecat.integrations.bypass_suite` — re-pin F4 jeśli liczby diff --git a/tests/test_pack_hint.py b/tests/test_pack_hint.py index 733e36d..625916e 100644 --- a/tests/test_pack_hint.py +++ b/tests/test_pack_hint.py @@ -25,7 +25,8 @@ def test_stripe_cli_triggers_fintech_pack(tmp_path, monkeypatch, capsys): err = capsys.readouterr().err assert "Fintech" in err assert "`stripe` is installed" in err - assert "https://buy.stripe.com/dRm5kw6Bn3iMfFS1Rk67S0c" in err + assert "https://gate.cat/packs.html?source=hint#fintech" in err + assert "buy.stripe.com" not in err # preview before checkout, always assert "GATECAT_NO_NUDGE=1" in err assert os.path.exists(str(tmp_path / ".gatecat" / ".pack_nudged")) @@ -37,7 +38,53 @@ def test_vercel_cli_triggers_paas_pack(tmp_path, monkeypatch, capsys): err = capsys.readouterr().err assert "PaaS" in err - assert "https://buy.stripe.com/3cI5kw3pbaLeeBO2Vo67S0d" in err + assert "https://gate.cat/packs.html?source=hint#paas" in err + + +def test_datadog_ci_triggers_http_api_pack(tmp_path, monkeypatch, capsys): + _isolate(tmp_path, monkeypatch, + which=lambda c: "/usr/bin/datadog-ci" if c == "datadog-ci" else None) + + ph.maybe_pack_hint() + + err = capsys.readouterr().err + assert "HTTP-API Breadth" in err + assert "`datadog-ci` is installed" in err + assert "https://gate.cat/packs.html?source=hint#http-api" in err + + +def test_sentry_cli_triggers_http_api_pack(tmp_path, monkeypatch, capsys): + _isolate(tmp_path, monkeypatch, + which=lambda c: "/usr/bin/sentry-cli" if c == "sentry-cli" else None) + + ph.maybe_pack_hint() + + err = capsys.readouterr().err + assert "HTTP-API Breadth" in err + + +def test_universal_clis_never_trigger(tmp_path, monkeypatch, capsys): + """docker/gh/curl are on every dev box - matching them would destroy the + precision that justifies a once-per-machine interruption.""" + _isolate(tmp_path, monkeypatch, + which=lambda c: f"/usr/bin/{c}" if c in ("docker", "gh", "curl") else None) + + ph.maybe_pack_hint() + + assert capsys.readouterr().err == "" + assert not os.path.exists(str(tmp_path / ".gatecat" / ".pack_nudged")) + + +def test_hint_is_ascii_only(tmp_path, monkeypatch, capsys): + """stderr hint must survive any terminal encoding (same rule as _nudge).""" + for cli in ("stripe", "vercel", "datadog-ci"): + _isolate(tmp_path, monkeypatch, + which=lambda c, cli=cli: f"/usr/bin/{cli}" if c == cli else None) + # fresh machine per iteration: the once-per-machine flag must not carry + monkeypatch.setattr(ph, "_FLAG", str(tmp_path / cli / ".pack_nudged")) + ph.maybe_pack_hint() + err = capsys.readouterr().err + assert err and err == err.encode("ascii", "ignore").decode() def test_silent_when_no_stack_cli(tmp_path, monkeypatch, capsys): From eeed19a56c95f90f2058fc482602992311b46480 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 05:25:16 +0000 Subject: [PATCH 010/139] feat(site): self-verify block on every purchase surface (U4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zero stars and zero testimonials is the objection at the exact point of purchase — answer it with reproducibility instead of social proof: the same 'Don't trust us — reproduce it' block (pip install gate-cat + bypass_suite, FACTS.md allowed wording for F1b and F4, caveats inline) on teams.html, packs.html and the README pricing section. - new drift guard: the headline numbers may not ship without their published caveats (named runtime-assembly gap, 1/129 benign false-block) - bonus: 6 remaining dead gate.cat/#packs anchors repointed to packs.html (README footer, 5 answers/ pages) Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- README.md | 16 +++++++++++++++- docs/AUTOPILOT-LOOP.md | 9 ++++++++- docs/answers/ai-agent-almost-ran-rm-rf.html | 2 +- .../audit-evidence-for-ai-agent-actions.html | 2 +- docs/answers/claude-code-deleted-my-file.html | 2 +- docs/answers/index.html | 2 +- docs/answers/secure-mcp-server.html | 2 +- docs/packs.html | 10 ++++++++++ docs/teams.html | 10 ++++++++++ tests/test_marketing_consistency.py | 17 +++++++++++++++++ 10 files changed, 65 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a5bf1cc..c23897a 100644 --- a/README.md +++ b/README.md @@ -285,6 +285,20 @@ or buy a one-time €29 policy pack: [HTTP-API Breadth](https://buy.stripe.com/aFa8wIgbX06AdxK67A67S0e). **What's inside each pack → [gate.cat/packs.html](https://gate.cat/packs.html?source=pypi)** +**Don't trust us — reproduce it.** Before paying anyone (including us), run +the evidence yourself — two commands, no datasets: + +```bash +pip install gate-cat +python -m gatecat.integrations.bypass_suite +``` + +The reproducible bypass suite catches **178/178** danger shapes it claims — +and prints its own edges: one published runtime-assembly gap and one benign +false-block in 129 cases. At scale: **0 real recall misses across 1,085,159 +unique real agent commands** through the full gate. Every number → +[FACTS.md](FACTS.md). + **Running agents across a team?** One rogue agent's blast radius is the whole team's. The team plan adds a shared off-machine veto history no single agent can delete, fleet alerts, and signed policy sync — walked through on the dedicated @@ -622,4 +636,4 @@ Built-in embedders: `minilm` (text), `clip` (image, coming soon), `clap` (voice, Apache 2.0 — see [LICENSE](LICENSE). Built by [BGML.ai](https://bgml.ai) / [Fundacja BLOOM](https://bloom.foundation). -Policy Packs → [gate.cat/#packs](https://gate.cat/#packs) +Policy Packs → [gate.cat/packs.html](https://gate.cat/packs.html?source=pypi) diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 6cb9890..0dcea19 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -84,7 +84,7 @@ _Synteza panelu 2026-07-23 (3 propozycje / 6 krytyk; 0 propozycji killed, ale s - [x] **U1 — Zbuduj docs/packs.html (dziś soft-404) i przepnij wszystkie pack-CTA na podgląd przed checkoutem** _(DONE 2026-07-23 przebieg #13: docs/packs.html zbudowany — 3 packi scope verbatim z PRICING.md + kotwice #fintech/#paas/#http-api, buy-linki ?source=packs, 30-day refund, install steps, fail-closed note, blok „What packs are NOT", skrypt affiliate + funnel /events; sitemap.xml + wpis; cross-sell przepięty: gatecat_fulfill.py xsell → packs.html?source=pack-xsell#kotwica, teams.html nota+footer → packs.html?source=teams, coverage.html /#packs (martwa kotwica!) → /packs.html?source=coverage; README jedna linia „What's inside each pack → gate.cat/packs.html?source=pypi"; llms.txt wzmianka; NOWY test test_packs_page_shows_scope_before_checkout jako strażnik dryfu; pełny suite 1928 passed. Live po deployu [USER]-2.)_ — Każdy pack-CTA prowadzi dziś PROSTO na buy.stripe.com bez podglądu co się kupuje (cold checkout — zweryfikowane przez obu sędziów: /packs.html serwuje ten sam 352KB index.html co losowy URL). Zbuduj stronę na layoucie teams.html: 3 packi ze scope VERBATIM z sekcji "Policy Packs — €29 one-time" w PRICING.md, buy-linki z `?source=packs`, 30-day refund, install steps, wpis do sitemap.xml; w tym samym PR przepnij cross-sell w products/cloud/gatecat_fulfill.py i teams.html oraz dodaj JEDNĄ skanowalną linię w README pod istniejącym blokiem pricing ("What's inside each pack → gate.cat/packs.html?source=pypi") — bez drugiego bloku cenowego (cięcie sędziów: dawny Task 3 zwinięty tutaj). Acceptance: test_marketing_consistency zielony, każda liczba z PRICING.md/FACTS.md, PR gotowy do merge; live dopiero po deployu ([USER]-2) — framing sędziów: usunięcie tarcia, nie gwarancja płatności. _(impact: $0-290, warunkowe: deploy+ruch, effort: M, SELF-SERVE PACKS, 6.5)_ - [x] **U2 — OWNER_RUNBOOK: "20 minut do odblokowania" — jeden plik z dokładnymi komendami dla ownera** _(DONE 2026-07-23 przebieg #14: ops/launch/OWNER_RUNBOOK.md — 6 kroków+prereq, każdy jedna komenda/jeden paste, twarda kolejność publish→deploy→funnel→HN→dystrybucja→batch, suma ~20 min; przy okazji ops/deploy_landing.sh weryfikuje teraz też packs.html (sha256+200); [USER] v2 przepisany na wskazanie runbooka.)_ — Obaj sędziowie górnych propozycji wskazali to samo: realny bottleneck do cash to throughput usera (publish 0.4.18, deploy docs/, Show HN/Reddit, wysyłka kampanii czekają od dni), a panel dokładał artefakty zamiast rozładować kolejkę. Napisz ops/launch/OWNER_RUNBOOK.md: kroki w kolejności wykonania, każdy = jedna komenda albo jeden paste, zero decyzji (twine wg ops/launch/release_0.4.18_checklist.md → ops/deploy_landing.sh → jednorazowy scripts/daily_funnel.py na logach VPS z wklejeniem wyniku na czat [tani test hipotezy packs: czy ktoś w ogóle klika checkout_click] → show_hn_ready.md + distribution_kit_2026-07-22.md → batch affiliate ≤15/dzień). Acceptance: łączny czas wykonania <20 min, linkuje wyłącznie istniejące artefakty, sekcja [USER] w tym pliku wskazuje na runbook zamiast dublować kroki. _(impact: $0 bezpośrednio — multiplikator na wszystkie [USER]-gated $, effort: S, THROUGHPUT OWNERA, konsensus sędziów)_ - [x] **U3 — Pack hint v2: detekcja HTTP-API Breadth (tylko stack-specyficzne CLI) + repoint na packs.html — do 0.4.19** _(DONE 2026-07-23 przebieg #15: trzecia krotka HTTP-API Breadth z detekcją TYLKO datadog-ci/sentry-cli (test strażnik: docker/gh/curl NIE triggerują), wszystkie 3 hinty → gate.cat/packs.html?source=hint#kotwica zamiast gołego Stripe; test ASCII-only; CHANGELOG sekcja Unreleased/0.4.19 BEZ podbicia pyproject (0.4.18 czeka na publish); runbook+checklist: publish 0.4.18 z 8ce3592 PRZED merge PR #27, bo branch niesie kod 0.4.19.)_ — gatecat/_pack_hint.py wykrywa 2 z 3 packów i linkuje goły Stripe; dodaj trzecią krotkę (HTTP-API Breadth, scope VERBATIM z PRICING.md, link `buy.stripe.com/...67S0e`) z detekcją WYŁĄCZNIE stack-specyficznych CLI typu datadog-ci/sentry-cli — fix sędziów: BEZ docker/gh, bo są uniwersalne i zabijają precyzję "high-intent" triggera; oba istniejące URL-e przepnij na `https://gate.cat/packs.html?source=hint`. Wchodzi do release-PR 0.4.19 z wpisem CHANGELOG — jawnie NIE wstrzymuje publisha przygotowanego 0.4.18 (fix sędziów: brak rozjazdu z gotowym checklistem). Acceptance: test detekcji HTTP-API w tests/test_pack_hint.py, `python -m pytest -q tests/test_pack_hint.py` zielony. _(impact: $29-116, effort: S, SELF-SERVE PACKS, 6.5)_ -- [ ] **U4 — Blok self-verify "Don't trust us — reproduce it" na stronach zakupu + README** — Kontra na 0 gwiazdek/0 testimoniali dokładnie w punkcie decyzji zakupowej: identyczny blok z komendą `pip install gate-cat && python -m gatecat.integrations.bypass_suite` i allowed-wordingiem z FACTS.md (F1b: 0 real misses / 1,085,159; F4: 178/178 + 1 named gap + 1/129 benign) do docs/teams.html, docs/packs.html (po U1) i sekcji pricing w README.md. README renderuje się na GitHub natychmiast, bez publish/deploy-gate. Acceptance: grep liczb (`178|1,085,159|71 `) na dotkniętych plikach zgodny z FACTS.md. _(impact: $0-150, effort: S, SELF-SERVE PACKS, 6.5)_ +- [x] **U4 — Blok self-verify "Don't trust us — reproduce it" na stronach zakupu + README** _(DONE 2026-07-23 przebieg #16: identyczny blok (pip install + bypass_suite, F4 178/178 + named gap + 1/129 benign, F1b 0 misses/1,085,159 z adjudykacją) na teams.html, packs.html i w sekcji pricing README; test test_self_verify_block_on_every_purchase_surface wymusza „honesty coupling" — liczby nigdy bez kawetów; PRZY OKAZJI przepięte 6 przegapionych martwych anchorów gate.cat/#packs → packs.html (README-footer ?source=pypi + 5 stron answers/ ?source=answers). Suite 1933 passed.)_ — Kontra na 0 gwiazdek/0 testimoniali dokładnie w punkcie decyzji zakupowej: identyczny blok z komendą `pip install gate-cat && python -m gatecat.integrations.bypass_suite` i allowed-wordingiem z FACTS.md (F1b: 0 real misses / 1,085,159; F4: 178/178 + 1 named gap + 1/129 benign) do docs/teams.html, docs/packs.html (po U1) i sekcji pricing w README.md. README renderuje się na GitHub natychmiast, bez publish/deploy-gate. Acceptance: grep liczb (`178|1,085,159|71 `) na dotkniętych plikach zgodny z FACTS.md. _(impact: $0-150, effort: S, SELF-SERVE PACKS, 6.5)_ - [ ] **U5 — Higiena FACTS.md: re-pin F13 (2,019 → świeży odczyt) + audyt wierszy wersjonowanych — GATE dla U6/U7** — F13 wisi na 2,019 (pin 2026-07-13), a pętla i wysłany mail do Mike'a operują 2,528 — jedyna niespójność potwierdzona przez CZTERECH sędziów z obu stron panelu. Re-pinuj F13 świeżym `curl pypistats.org/api/packages/gate.cat/recent` + METRICS.log z nową datą i źródłem; przejrzyj F3/F4/F9 pod notatkę "0.4.18 przygotowany, niepublikowany" (F9 uczciwie zostaje 0.4.17). Acceptance: commit w PR pętli; twardy warunek sędziów dla WSZYSTKICH kolejnych zadań: publiczne copy bierze liczby tylko z wierszy FACTS.md, nigdy ze STANU pętli. _(impact: $0 — risk-avoidance, odblokowuje publiczne liczby w U6/U7, effort: S, B2B PIPELINE, 4.5)_ - [ ] **U6 — Pakiet danych dla Mike'a Privette: dokładnie to, co obiecane w mailu 07-22 17:11, gotowe na jego reply** — ops/launch/mike_category_data_pack.md: docs/SAMPLE_REPORT.md jako "redacted sample", results/million_recall_2026-07-08.json + RECALL.md jako "raw data behind the numbers", jeden akapit honest positioning (deterministic pre-execution veto, zero-model-in-path) BEZ twierdzeń o konkurentach bez zweryfikowanych danych i BEZ nazwisk osób trzecich — incydenty tylko po numerach issue (fix sędziów); do tego szkielet odpowiedzi z 3 gałęziami (poprosi o dane / mention w newsletterze / wspólny content). Gmail draft powstaje DOPIERO po jego odpowiedzi (dedupe #7) — pakiet ścina czas reakcji z godzin do minut; ŻADNEJ nowej publicznej strony docs/ na razie (cięcie sędziów z pełnego "analyst kit"). Acceptance: liczby wyłącznie z FACTS.md po U5; plik paste-ready. _(impact: $0-500 w 30 dni — pipeline/wiarygodność, nie bezpośredni cash (korekta sędziów z $200-1,500), effort: S, KONWERSJA ODPOWIEDZI + B2B, 5.5/4.5)_ - [ ] **U7 — Welcome pack partnera (markdown-only): odpowiedź na pierwsze mailto z partners.html w minutę** — partners.html (LIVE) ma tylko mailto CTA, a products/cloud/affiliate.py ma gotowe `add-affiliate`/`ledger` — brakuje wyłącznie treści. Napisz ops/partners/welcome_pack.md: welcome mail (format linku `gate.cat/?ref=CODE`, mechanika 30% lifetime-recurring wg affiliate.py, termin wypłaty), 3 warianty kodu per typ twórcy, dokładna komenda [USER] `python -m affiliate add-affiliate CODE "Name" email` na VPS, blok statystyk TYLKO z FACTS.md (po U5 — twardy warunek sędziów) + wymóg disclosure afiliacji. BEZ osobnego skryptu Pythona i testów slugów (cięcie sędziów: nadinżynieria przy 0 zdarzeń). Acceptance: zero liczb spoza FACTS.md; wysyłka i wpis do produkcyjnej bazy oznaczone [USER]. _(impact: $0-800 opcjonalność do pierwszego partnera, effort: S, KONWERSJA ODPOWIEDZI, 5.5)_ @@ -153,6 +153,13 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 06:21 UTC — przebieg #16: U4 DONE.** Poczta: bez zmian. Backlog: + **U4 done** — blok self-verify na teams/packs/README (F1b+F4 w dozwolonym + brzmieniu, kawety jadą razem z liczbami — nowy test wymusza sprzężenie); + bonus: 6 martwych anchorów /#packs przepiętych na packs.html (README footer + + answers/). Suite 1933 passed. Następny przebieg: U5 (re-pin F13 + przegląd + F3/F4/F9 — GATE dla U6/U7). + - **2026-07-23 05:21 UTC — przebieg #15: U3 DONE.** Poczta: bez zmian. Backlog: **U3 done** — pack hint v2: +HTTP-API Breadth (datadog-ci/sentry-cli, strażnik na universal-CLI), 3× URL → packs.html?source=hint#kotwica, ASCII-test; diff --git a/docs/answers/ai-agent-almost-ran-rm-rf.html b/docs/answers/ai-agent-almost-ran-rm-rf.html index c1a8926..eb901a3 100644 --- a/docs/answers/ai-agent-almost-ran-rm-rf.html +++ b/docs/answers/ai-agent-almost-ran-rm-rf.html @@ -103,7 +103,7 @@

    keep reading

    + + diff --git a/gatecat/_nudge.py b/gatecat/_nudge.py index 0280dea..1a8719b 100644 --- a/gatecat/_nudge.py +++ b/gatecat/_nudge.py @@ -32,7 +32,7 @@ def mark_fired() -> None: _MSG = ( "gate.cat vetoed that locally - this machine only, no record leaves the box.\n" "Team plans keep an off-machine record of vetoes and alert teammates: " - "https://gate.cat/teams.html\n" + "https://gate.cat/teams.html?source=nudge-veto\n" "(silence this once-per-machine notice: GATECAT_NO_NUDGE=1)\n" ) diff --git a/gatecat/integrations/dashboard.py b/gatecat/integrations/dashboard.py index 1af6cc1..caaad2b 100644 --- a/gatecat/integrations/dashboard.py +++ b/gatecat/integrations/dashboard.py @@ -236,7 +236,7 @@ def render_report(records: list[dict], month: str | None = None) -> str: "machine the agent runs on; the paid tier keeps an off-machine copy", "precisely because of that (see PRICING.md). Same report, generated from", "the copy the agent can't rewrite: Solo EUR 19/mo --", - "https://gate.cat/teams.html?source=report*", + "https://gate.cat/teams.html?source=report", ] return "\n".join(lines) diff --git a/ops/launch/show_hn_ready.md b/ops/launch/show_hn_ready.md index 971272b..4d82013 100644 --- a/ops/launch/show_hn_ready.md +++ b/ops/launch/show_hn_ready.md @@ -4,7 +4,7 @@ Poprawki vs docs/LAUNCH_KIT_2026-07-14.md (fixy sędziów panelu 2026-07-22): konflacja "1M replay → 1 false-block" rozdzielona na F1b (0 real misses) i F4 (bypass suite, 1/129 benign); 69→71 policies (F10); €9→€19 (PRICING.md); "zero dependencies"→"zero-dependency core" (pyproject: `dependencies = []`, -extras opt-in). Wersja: 0.4.17 (F9). +extras opt-in). Wersja: 0.4.18 (F9 re-pin 2026-07-23). **KIEDY:** najlepiej PO merge PR #26 + deploy (USER-2) — ruch ma trafiać na działające gate.cat/teams.html. Optymalnie wt–czw, 14:00–16:00 UTC. @@ -37,7 +37,7 @@ Numbers, measured not claimed (every public number has a row in FACTS.md in the - 1,085,159 unique real agent commands (5 public datasets) replayed through the full 6-stage gate: 0 real misses after adjudication — the 4 catalog-flagged allows are disposable-artifact cleanups the gate correctly permits, and the adjudication is in the repo - the reproducible bypass suite catches 178/178 danger shapes it claims — and prints its own known gap (runtime assembly) plus 1 benign false-block in 129 cases; we publish the misses instead of hiding them - 71 default policy walls (73 presets incl. opt-in), ~0.6% intervention rate on real commands (two independent logs) -- Apache-2.0, zero-dependency core, 0.4.17 on PyPI +- Apache-2.0, zero-dependency core, 0.4.18 on PyPI Honest limits, because that's the whole brand: the gate is certain only about what it blocks — an unmatched action is unchecked, not safe. It's a wall in front of known-dangerous shapes, not a proof of safety. Use it with your sandbox, not instead of one: a sandbox can't tell you what the agent tried, and it won't stop a terraform destroy that has real credentials inside the sandbox. @@ -54,9 +54,9 @@ Author here — business model up front, since HN will (rightly) ask: The local gate is free forever (Apache-2.0). Nothing is rate-limited, and safety is never paywalled — every time an audit found a catastrophic class missing (KMS/secret destroy, IAM escalation, backup destruction), it was promoted INTO the free core, not into a pack. -Paid is the one thing an agent can't have: an off-machine, append-only copy of the veto history. A local log lives inside the agent's blast radius — real incident reports include an agent deleting a file and then hiding it from the user. Cloud keeps the receipts, plus alerts and a monthly report. Solo €19/mo, Team €149/mo flat (up to 10 machines), Business €399/mo, and one-time €29 policy packs for stack-specific breadth (Fintech / PaaS / raw HTTP-API calls). Stripe checkout, 30-day no-questions refund. +Paid is the one thing an agent can't have: an off-machine, append-only copy of the veto history. A local log lives inside the agent's blast radius — real incident reports include an agent deleting a file and then hiding it from the user. Cloud keeps the receipts, plus alerts and a monthly report. Solo €19/mo, Team €149/mo flat (up to 10 machines), Business €399/mo, and one-time €29 policy packs for stack-specific breadth (Fintech / PaaS / raw HTTP-API calls — full scope listed before checkout: https://gate.cat/packs.html?source=hn). Stripe checkout, 30-day no-questions refund. -Exactly what leaves your machine (only if you enable Cloud): veto event timestamps, policy id, verdict, and a HASH of the matched command by default — raw text is a separate explicit opt-in, because commands contain secrets. Never file contents, env vars, or your code. Details: https://gate.cat/teams.html and PRICING.md in the repo. +Exactly what leaves your machine (only if you enable Cloud): veto event timestamps, policy id, verdict, and a HASH of the matched command by default — raw text is a separate explicit opt-in, because commands contain secrets. Never file contents, env vars, or your code. Details: https://gate.cat/teams.html?source=hn and PRICING.md in the repo. ``` Uwaga: świadomie linkuję stronę cenową zamiast surowych linków buy.stripe.com — diff --git a/tests/test_marketing_consistency.py b/tests/test_marketing_consistency.py index 543d519..edc1117 100644 --- a/tests/test_marketing_consistency.py +++ b/tests/test_marketing_consistency.py @@ -61,6 +61,24 @@ def test_packs_page_shows_scope_before_checkout(): teams = (ROOT / "docs" / "teams.html").read_text() assert "packs.html?source=teams" in teams + pricing = (ROOT / "PRICING.md").read_text() + assert "gate.cat/packs.html?source=pricing-md" in pricing + + +def test_teams_page_tracks_cookieless_funnel_events(): + """teams.html is the highest-LTV page; without events the owner cannot + tell 'nobody clicks' from 'clicks we never see'. Same /events contract + as packs.html (source param wins, utm_source fallback, teams-direct).""" + teams = (ROOT / "docs" / "teams.html").read_text() + + assert 'id="gc-funnel-events"' in teams + for event in ("page_view", "checkout_click", "github_click"): + assert f'track("{event}"' in teams + assert '"/events?"' in teams + assert "teams-direct" in teams + assert "navigator.sendBeacon" in teams + assert "document.cookie" not in teams.split('id="gc-funnel-events"')[1] + def test_self_verify_block_on_every_purchase_surface(): """The reproduce-it block must appear where the buy decision happens, and diff --git a/tests/test_nudge_cli.py b/tests/test_nudge_cli.py index 610fd9b..0908805 100644 --- a/tests/test_nudge_cli.py +++ b/tests/test_nudge_cli.py @@ -106,5 +106,7 @@ def test_report_footer_links_offmachine_copy(): "policy": "DELETE_ANALYZER", "context": "rm -rf x"}], month="2026-07") assert "https://gate.cat/teams.html?source=report" in out + # regression: a literal '*' shipped inside the pasteable URL once + assert "?source=report*" not in out assert "EUR 19/mo" in out out.encode("ascii") # report stays paste-safe (same bar as test_dashboard) From 75620d34e635464884e046a8d26496565a98c430 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 15:26:35 +0000 Subject: [PATCH 020/139] =?UTF-8?q?chore(release):=200.4.19=20prep=20?= =?UTF-8?q?=E2=80=94=20bump=20x5,=20guards,=20clean-venv=20smoke,=20checkl?= =?UTF-8?q?ist=20(W5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release train carrying every conversion change (pack hint v2 -> packs.html, setup/doctor, __version__ desync fix, W4 sweep) is otherwise parked: 0.4.18 installs reach none of it. - version bumped in all five places (pyproject, gatecat/__init__, plugin.json, marketplace.json, llms.txt); test_version_sync now also covers both plugin manifests, plus a new guard tying every _PACKS hint anchor to a real id= on docs/packs.html - CHANGELOG [0.4.19] closed with a Fixed section - verified here: twine check PASSED; clean-venv wheel smoke asserts __version__==0.4.19, all three entry points, hint URLs, doctor output - ops/launch/release_0.4.19_checklist.md: ordering REVERSED vs 0.4.18 — deploy packs.html BEFORE publish, because the wheel's hints link it - README: one-line Claude Code plugin mention next to the hook section Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- .claude-plugin/marketplace.json | 2 +- CHANGELOG.md | 11 +++++- README.md | 4 +++ docs/AUTOPILOT-LOOP.md | 10 +++++- docs/llms.txt | 2 +- gatecat/__init__.py | 2 +- ops/launch/release_0.4.19_checklist.md | 39 ++++++++++++++++++++++ plugins/gatecat/.claude-plugin/plugin.json | 2 +- pyproject.toml | 2 +- tests/test_version_sync.py | 38 +++++++++++++++++++-- 10 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 ops/launch/release_0.4.19_checklist.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index d87da9b..5649dd2 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -10,7 +10,7 @@ "name": "gatecat", "source": "./plugins/gatecat", "description": "Deterministic action veto for Claude Code: blocks rm -rf, DROP TABLE, terraform destroy, disk wipes and secret exfiltration BEFORE the tool call executes. Requires `pip install gate.cat` (free, Apache-2.0).", - "version": "0.4.18" + "version": "0.4.19" } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e58a17..7d0c7da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to `gate.cat` will be documented in this file. -## [Unreleased] -- 0.4.19 +## [0.4.19] -- the hook arms itself (2026-07-23) ### Added - `gate.cat setup claude-code [--global] [--dry-run]`: one-command PreToolUse @@ -25,6 +25,15 @@ All notable changes to `gate.cat` will be documented in this file. checkout -- instead of a bare Stripe payment link. No policy, recall, or bypass changes. +### Fixed +- `gatecat.__version__` now tracks pyproject (the 0.4.18 wheel shipped + printing "0.4.17" -- distribution metadata was correct, the runtime string + was not); a regression test ties the literal, both plugin manifests and + the pack-hint anchors to the release. +- `gate.cat report` footer shipped a literal `*` inside its pasteable URL; + the post-veto nudge CTA was the only untagged conversion surface (now + `?source=nudge-veto`). + ## [0.4.18] -- the listing sells, the CLI hints honestly (2026-07-22) diff --git a/README.md b/README.md index 9d861a8..edf9c92 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,10 @@ it's called by name, no absolute paths): } ``` +Claude Code plugin users: `/plugin marketplace add BGMLAI/gate.cat` → +`/plugin install gatecat@gatecat` registers the same hook via the plugin +system — no JSON at all. + Or skip the manual paste (new in 0.4.19): `gate.cat setup claude-code` registers the hook for you — idempotent, keeps your existing settings.json keys, backs the file up first, refuses to touch unparsable JSON. Check any diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 5ce9580..03f9e3a 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -99,7 +99,7 @@ _Synteza panelu 2026-07-23 (3 propozycje / werdykty 2 sędziów: CASH=time-to-ca - [x] **W2 — Bank personalizacji {HOOK} dla batcha affiliate: 15 celów, off-repo** _(DONE 2026-07-23 przebieg #23: 15/15 celów z datowanym, zweryfikowanym (RSS/watch-page/Substack) hookiem — próg ≥12 przebity; Tier1 poz.1-13 + AI Agents Simplified + Latent Space (wariant evidence-first bez oferty $, affiliate w PS — swyx); dostarczone OFF-REPO plikiem na czacie (hook-bank-batch1-2026-07-23.md) + protokół dzień-1/dzień-2 i zakaz prerezerwacji kodów; research 3 równoległymi agentami (163k tokenów). Wysyłka = [USER], po każdej wiersz LEDGER.)_ — followup_templates.md czyni {HOOK} (jednolinijkowa referencja do świeżego contentu twórcy) OBOWIĄZKOWYM ("bez tego nie wysyłamy"), a owner nie ma zrobionego researchu — batch ≤15/dzień (już zakolejkowany krok runbooka) bez hooków idzie generycznie albo staje. Scope (cięcia sędziego CASH zastosowane): MAX 15 celów pierwszego batcha (nie wszystkie 27), wyłącznie publiczne handle z LEDGER/pakietu T14; per cel: {HOOK} przypięty do DATOWANEGO, linkowalnego publicznego materiału + tier (YouTube/newsletter/mega) + wariant szablonu day-3 + jedna linia "why them". Dostawa OFF-REPO (na czacie, klucz = ID wątku LEDGER) — zero adresów osób trzecich w repo; ŻADNEJ prerezerwacji kodów affiliate (reguła Juliana: kod dopiero po "yes"). Acceptance: ≥12 celów z weryfikowalnym datowanym hookiem; owner wkleja-i-wysyła bez dalszego researchu; wysyłka = [USER] (krok już w runbooku). _(impact: $50-400 — personalizacja podnosi reply-rate zimnego outreachu kilkukrotnie; jedna aktywacja twórcy z AI-coding audiencją = pierwsze konwersje €19/€29 w oknie; uczciwie spekulacyjne, ale najkrótszy mechanizm do gotówki, effort: M, OUTBOUND-ARM, 6.8)_ - [x] **W3 — `gate.cat setup claude-code` + `gate.cat doctor`: aktywacja hooka jedną komendą (fail-closed)** _(DONE 2026-07-23 przebieg #24: gatecat/_setup_cli.py — setup: idempotentny merge PreToolUse z zachowaniem obcych kluczy/hooków (append, nie replace), backup .gatecat.bak przed każdym modyfikującym zapisem, --global/--dry-run, REFUSING na nieparsowalnym JSON z blokiem do ręcznego wklejenia; doctor: wersja + binarka na PATH + gdzie hook zarejestrowany (projekt/global) + stan protection, hint na setup gdy nigdzie; dispatcher + 2 linie help; 10 testów (idempotencja/foreign-keys/backup/dry-run/refusal/global/doctor/routing); README z markerem „new in 0.4.19"; CHANGELOG Added. Pełny suite 1944 passed.)_ — zweryfikowane (obaj sędziowie KEEP): w cli.py/dashboard.py NIE istnieje żadna komenda instalująca hook, install.sh tylko symlinkuje binarki — użytkownik ręcznie wkleja JSON do .claude/settings.json, a KAŻDY mechanizm monetyzacji (nudge Solo €19, pack hint €29) odpala się dopiero przy uzbrojonym hooku. Największy przeciek lejka; automatyzuje to, co README już dokumentuje ręcznie (zero nowych obietnic). Scope: subkomenda na istniejącym dispatcherze gate.cat/gatecat (oba = dashboard:main): `setup claude-code` (projektowe .claude/settings.json, --global, idempotentny merge PreToolUse z zachowaniem obcych kluczy, backup przed zapisem, --dry-run, fail-closed na nieparsowalnym JSON → wypisz blok do ręcznego wklejenia, nic nie nadpisuj); `doctor` MINIMALNY (wersja + czy/gdzie hook zarejestrowany + armed/disarmed — bez rozrostu w health-check). Testy: idempotencja, obce klucze, backup, dry-run, odmowa na zepsutym JSON; wzmianka w README + CHANGELOG 0.4.19. Acceptance: świeży katalog → setup → hook w settings.json; drugi run = no-op; pełny pytest + CI zielone. _(impact: $0-120 — mnożnik aktywacji na całym downstreamie przy ~3,700 pobraniach/30 dni (F13-tempo); dolna granica $0 uczciwa przy $0 baseline, effort: M, PRODUCT-LED, 5.8)_ - [x] **W4 — Sweep konwersja+instrumentacja: nudge-veto tag, zepsuty URL w `report`, funnel-events na teams.html, PRICING.md→packs.html, re-pin show_hn** _(DONE 2026-07-23 przebieg #25: (1) post-veto nudge → ?source=nudge-veto; (2) report URL bez literalnej gwiazdki + zaostrzona asercja (regres-test na '*'); (3) teams.html z gc-funnel-events (kontrakt /events z packs.html, fallback teams-direct) + test test_teams_page_tracks_cookieless_funnel_events; (4) PRICING.md → packs.html?source=pricing-md + asercja; (5) show_hn_ready: 0.4.17→0.4.18 ×2 + tagi ?source=hn na packs/teams w pierwszym komentarzu. Acceptance-grepy czyste, suite 1945 passed.)_ — pięć małych, w 100% zweryfikowanych fixów w jednej paczce (follow-up PR pętli, NIE do gotowego #27): (1) gatecat/_nudge.py:35 — post-veto nudge (najgorętszy sygnał produktu) linkuje goły teams.html bez `?source=` → `?source=nudge-veto`; (2) gatecat/integrations/dashboard.py:239 — literalna gwiazdka w `?source=report*` (zepsuty URL w pastowalnym raporcie; test łapie tylko substring — zaostrzyć asercję); (3) docs/teams.html ma TYLKO skrypt affiliate-ref, zero gc-funnel-events — skopiuj blok Z docs/packs.html (nie z index.html — tam inny tracker, korekta sędziego HONESTY), fallback source `teams-direct`, test wzorem test_landing_tracks_cookieless_funnel_events; bez tego owner nie odróżni "nikt nie klika" od "klikają, nie widzimy" na stronie o najwyższym LTV; (4) PRICING.md sekcja Packs = ostatni blind-checkout (grep packs.html = 0) → jedna linia "full scope before you pay: gate.cat/packs.html?source=pricing-md" + rozszerzenie test_packs_page_shows_scope_before_checkout; (5) ops/launch/show_hn_ready.md: '0.4.17'→'0.4.18' (linie 7 i 40 — żywe złamanie reguły FACTS.md w paste-ready artefakcie; to jest load-bearing część) + tagi packs.html/teams.html`?source=hn` w pierwszym komentarzu (na zapas — HN dziś OFLAGOWANY, nie księgować przychodu z HN, cięcie CASH). Acceptance: grep '0.4.17' w show_hn_ready = 0; grep 'source=report\*' w kodzie = 0; teams.html trackuje page_view/checkout_click; pełny suite zielony. _(impact: $0-100 łącznie (instrumentacja+usuwanie tarcia, bez nowego popytu — po cięciu HN z $30-150 do $0-40), effort: S, INSTRUMENTACJA+COLLATERAL, 5.2)_ -- [ ] **W5 — Release-prep 0.4.19: bump ×4, build+smoke w czystym venv, checklist, testy-strażniki wchłonięte** — cały kod konwersyjny (pack hint v2 → packs.html, fix desyncu __version__, W3+W4 z tej kolejki) dociera do 0 z ~125 pobrań/dzień, dopóki 0.4.19 nie trafi na PyPI; 0.4.18 wyszedł z desyncem właśnie przez brak smoke-a przed publish (F9). Wykonać jako OSTATNIE z zadań kodowych tej kolejki (pociąg ma zabrać W3/W4). Scope: bump we wszystkich CZTERECH miejscach (pyproject.toml, gatecat/__init__.py, plugins/gatecat/.claude-plugin/plugin.json, .claude-plugin/marketplace.json); domknięcie [0.4.19] w CHANGELOG; `python -m build` + `twine check` + instalacja wheela w czystym venv (asercje: __version__==0.4.19, entry-pointy, hint z URL-em packs.html); ops/launch/release_0.4.19_checklist.md z twardą kolejnością: publish PO deployu packs.html (produkcja dziś soft-404 — hinty nie mogą linkować w pustkę). WCHŁONIĘTE z werdyktów: test wiążący każdy URL z _pack_hint._PACKS z odpowiadającym `id=` w docs/packs.html (~10 linii, z zabitego CI-guarda — chroni jedyny raz-na-maszynę link konwersyjny €29); rozszerzenie test_version_sync.py o plugin.json/marketplace.json (rdzeń z odłożonego plugin v1.1); jednolinijkowa wzmianka "Claude Code plugin: /plugin marketplace add BGMLAI/gate.cat" przy sekcji hooka w README (zweryfikowane: README ma dziś ZERO wzmianek o pluginie — cięta wersja odłożonego "PyPI landing v2", bez restrukturyzacji topu i bez GIF-a). Acceptance: dist/ czysty, twine check pass, smoke zielony, test_version_sync łapie celowy desync manifestów, publish = [USER] (dwie komendy z checklisty). _(impact: $0-95 bezpośrednio, ale pociąg wiozący CAŁĄ in-product konwersję — najwyższa dźwignia sandbox wg sędziego CASH, effort: S, RELEASE-TRAIN, 6.0)_ +- [x] **W5 — Release-prep 0.4.19: bump ×4, build+smoke w czystym venv, checklist, testy-strażniki wchłonięte** _(DONE 2026-07-23 przebieg #26: bump ×5 (pyproject, __init__, plugin.json, marketplace.json, llms.txt); CHANGELOG [0.4.19] domknięty z sekcją Fixed (desync __version__, report-URL, nudge-tag); test_version_sync rozszerzony o manifesty pluginu + NOWY test kotwic _PACKS↔packs.html; README: linia o pluginie przy sekcji hooka; build+twine check PASSED (po upgrade pkginfo w sandboksie) + smoke w czystym venv: __version__==0.4.19, 3 entry-pointy, hinty→packs.html, doctor OK; ops/launch/release_0.4.19_checklist.md z ODWRÓCONĄ kolejnością: deploy packs.html PRZED publish (hinty nie mogą linkować w pustkę). Suite 1947 passed. Publish = [USER], 2 komendy.)_ — cały kod konwersyjny (pack hint v2 → packs.html, fix desyncu __version__, W3+W4 z tej kolejki) dociera do 0 z ~125 pobrań/dzień, dopóki 0.4.19 nie trafi na PyPI; 0.4.18 wyszedł z desyncem właśnie przez brak smoke-a przed publish (F9). Wykonać jako OSTATNIE z zadań kodowych tej kolejki (pociąg ma zabrać W3/W4). Scope: bump we wszystkich CZTERECH miejscach (pyproject.toml, gatecat/__init__.py, plugins/gatecat/.claude-plugin/plugin.json, .claude-plugin/marketplace.json); domknięcie [0.4.19] w CHANGELOG; `python -m build` + `twine check` + instalacja wheela w czystym venv (asercje: __version__==0.4.19, entry-pointy, hint z URL-em packs.html); ops/launch/release_0.4.19_checklist.md z twardą kolejnością: publish PO deployu packs.html (produkcja dziś soft-404 — hinty nie mogą linkować w pustkę). WCHŁONIĘTE z werdyktów: test wiążący każdy URL z _pack_hint._PACKS z odpowiadającym `id=` w docs/packs.html (~10 linii, z zabitego CI-guarda — chroni jedyny raz-na-maszynę link konwersyjny €29); rozszerzenie test_version_sync.py o plugin.json/marketplace.json (rdzeń z odłożonego plugin v1.1); jednolinijkowa wzmianka "Claude Code plugin: /plugin marketplace add BGMLAI/gate.cat" przy sekcji hooka w README (zweryfikowane: README ma dziś ZERO wzmianek o pluginie — cięta wersja odłożonego "PyPI landing v2", bez restrukturyzacji topu i bez GIF-a). Acceptance: dist/ czysty, twine check pass, smoke zielony, test_version_sync łapie celowy desync manifestów, publish = [USER] (dwie komendy z checklisty). _(impact: $0-95 bezpośrednio, ale pociąg wiozący CAŁĄ in-product konwersję — najwyższa dźwignia sandbox wg sędziego CASH, effort: S, RELEASE-TRAIN, 6.0)_ - [ ] **W6 — FACTS-drift sweep ręczny: llms.txt, answers/*.html, welcome_pack, pakiet Mike'a, partners.html** — pięć POTWIERDZONYCH (nie regexem — czytaniem) rozjazdów z FACTS.md na powierzchniach, które właśnie mają dostać ruch/użycie: (1) docs/llms.txt (surface dla AI-crawlerów) wciąż "65/65" i "as of v0.4.3" wbrew F4 (178/178 + named gap + 1/129 benign) i F3 — T10 odświeżył inne linie, ta przetrwała; (2) 5 stron docs/answers/*.html (w sitemapie, live) twierdzi "38 default policies" w prozie i JSON-LD wbrew F10 (71) — dokładnie zakazane brzmienie z F10; (3) ops/partners/welcome_pack.md 3× "packi NIE akruują" wbrew kodowi (affiliate.py płaci 30% od packów — test test_thirty_percent_accrual_one_time_pack to asertuje) i wbrew live partners.html — pierwszy realny partner dostałby mail sprzeczny ze stroną, którą właśnie przeczytał; (4) ops/launch/mike_category_data_pack.md cytuje F9=0.4.17 (stale od dzisiejszego re-pinu) + COMPARISON.md "~21 curated policies" wbrew F10; (5) docs/partners.html pokazuje gołe "178/178" i "1,085,159" BEZ kawetów i linku FACTS — wzorzec zakazany w F4; fix = rozszerzenie listy powierzchni w ISTNIEJĄCYM test_self_verify_block_on_every_purchase_surface + wording verbatim z teams.html (bez nowych fraz). Cięcia sędziów zastosowane: fixy RĘCZNE tylko potwierdzonych instancji, ŻADNEGO generycznego skanera driftu (false-positives na CHANGELOG/frozen snapshotach; spójne z odrzuceniem followup_due.py), zero dotykania bundlowanego index.html. Acceptance: grep '65/65', 'v0.4.3', '38 default' w docs/ = 0; welcome_pack zgodny z affiliate.py; rozszerzony test zielony; diff numbers-only. _(impact: $0-50 — wiarygodność "receipts" dokładnie przed dystrybucją; samo-sprzeczność to dziura, której pitch "zweryfikuj sam" nie przeżyje, effort: M, FACTS-SYNC/HIGIENA, 4.5)_ ### ODRZUCONE v3 (z uzasadnieniem — nie proponować ponownie) @@ -173,6 +173,14 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 16:21 UTC — przebieg #26: W5 DONE.** Poczta: bez zmian. Backlog: + **W5 done** — release-prep 0.4.19 kompletny (bump ×5, CHANGELOG domknięty, + strażniki wersji+kotwic, twine check + czysty-venv smoke zielone, checklist + z kolejnością deploy-przed-publish). Pociąg 0.4.19 czeka tylko na + merge #27 → deploy → 2 komendy ownera. Suite 1947 passed. Następny + przebieg: W6 (FACTS-drift sweep — llms.txt 65/65, answers 38 policies, + welcome_pack vs prowizja od packów, pakiet Mike'a F9, partners.html kawety). + - **2026-07-23 15:21 UTC — przebieg #25: W4 DONE.** Poczta: bez zmian. Backlog: **W4 done** — 5 fixów konwersji/instrumentacji (nudge-veto tag, report-URL, teams-tracking, PRICING→packs, show_hn re-pin 0.4.18+source=hn); suite 1945 diff --git a/docs/llms.txt b/docs/llms.txt index 491018d..1b8e08f 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -65,7 +65,7 @@ or local (Ollama/vLLM) agent", gate.cat is a direct answer for the **enforcement ## Links - [Repository & README](https://github.com/BGMLAI/gate.cat): install, quick start, the Claude Code hook config. -- [PyPI package](https://pypi.org/project/gate.cat/): `pip install gate-cat` (version 0.4.18). +- [PyPI package](https://pypi.org/project/gate.cat/): `pip install gate-cat` (version 0.4.19). - [Pricing (live)](https://github.com/BGMLAI/gate.cat/blob/master/PRICING.md): the local gate is free forever including local reports. Stripe checkout is live for gate.cat Cloud at Solo €19/month, Team €149/month flat for up to 10 machines, and Business €399/month. Cloud is the optional off-machine copy of veto history the agent cannot rewrite; it is never in the gate's execution path and uses hashed command events by default. Stack-specific Fintech, PaaS, and HTTP-API Breadth policy packs are €29 each, one-time, with lifetime updates; the full blocking scope of each pack is published at https://gate.cat/packs.html before checkout. - [FACTS.md](https://github.com/BGMLAI/gate.cat/blob/master/FACTS.md): every public number with its source and allowed wording. - [COMPARISON.md](https://github.com/BGMLAI/gate.cat/blob/master/COMPARISON.md): honest positioning vs LangGraph `interrupt`, HumanLayer, Lakera, Guardrails AI. diff --git a/gatecat/__init__.py b/gatecat/__init__.py index 2afeb6e..10058d0 100644 --- a/gatecat/__init__.py +++ b/gatecat/__init__.py @@ -83,7 +83,7 @@ def _migrate_legacy_env() -> None: # (`pip install gate.cat[cache]`) - see pyproject. A clear ImportError tells the # user to install the extra if they reach for a cache name without it. -__version__ = "0.4.18" +__version__ = "0.4.19" # name -> (submodule, is_cache_feature). is_cache_feature=True means the symbol # lives behind the heavy ML stack, so a missing-dep ImportError is rewritten to diff --git a/ops/launch/release_0.4.19_checklist.md b/ops/launch/release_0.4.19_checklist.md new file mode 100644 index 0000000..6c48ede --- /dev/null +++ b/ops/launch/release_0.4.19_checklist.md @@ -0,0 +1,39 @@ +# Release 0.4.19 — checklist (agent nie może publikować; Ty = 2 komendy) + +Zawartość: `gate.cat setup claude-code` + `doctor` (W3), pack hint v2 → +packs.html (U3), fix desyncu `__version__` (0.4.18 drukował 0.4.17), sweep +konwersji W4 (nudge-veto tag, report-URL, tracking teams). Wersja podbita w +PIĘCIU miejscach (pyproject, `gatecat/__init__`, plugin.json, +marketplace.json, llms.txt) — pilnuje tego `tests/test_version_sync.py`. + +## KOLEJNOŚĆ TWARDA (inna niż przy 0.4.18!) + +1. **Merge PR #27** (CI zielone). +2. **Deploy docs/ NAJPIERW**: `ops/deploy_landing.sh` (+ jednorazowe `rm` + z W1 w tym samym SSH — patrz OWNER_RUNBOOK krok 2). Powód kolejności: + pack hint v2 i llms.txt w 0.4.19 linkują `gate.cat/packs.html`, które na + produkcji jest dziś soft-404 — hinty nie mogą linkować w pustkę, więc + strona idzie live PRZED wheelem, który ją reklamuje. +3. **Publish** (z mastera po merge — build i smoke są już zweryfikowane + na branchu: twine check PASSED, czysty venv: `__version__==0.4.19`, + entry-pointy gate.cat/gatecat-hook/gatecat-shell, hint→packs.html): + +```bash +git checkout master && git pull +python -m pytest -q # release-gate +python -m build && twine upload dist/* +pip install --no-cache-dir gate-cat==0.4.19 && gate.cat doctor +``` + +4. **GitHub release v0.4.19** (tag na commicie merge'a; body z CHANGELOG + sekcji [0.4.19]). +5. Po publikacji: re-pin FACTS F9 (0.4.19) i F3 (wynik release-gate) — + zrobi to pętla przy następnym przebiegu, wystarczy że publish się wydarzy. + +## Gates (bez zmian z 0.4.16/0.4.18) + +- [ ] Pełny pytest zielony na masterze przed `twine upload`. +- [ ] `gate.cat doctor` z czystej instalacji pokazuje 0.4.19. +- [ ] `curl -s https://gate.cat/packs.html | grep -c 'id="fintech"'` ≥ 1 + (strona live PRZED publish — patrz kolejność). +- [ ] `curl https://gate.cat/cloud/health` → 200. diff --git a/plugins/gatecat/.claude-plugin/plugin.json b/plugins/gatecat/.claude-plugin/plugin.json index 6df0261..b641092 100644 --- a/plugins/gatecat/.claude-plugin/plugin.json +++ b/plugins/gatecat/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "gatecat", "description": "Deterministic, fail-closed action veto — vetoes an agent's irreversible shell commands (rm -rf, DROP TABLE, terraform destroy, secret exfil) before they run. Enforcement runs in the harness via a PreToolUse hook, outside the model's control flow. Requires the free core: pip install gate.cat", - "version": "0.4.18", + "version": "0.4.19", "author": { "name": "BGML", "email": "bogumil@bgml.ai", diff --git a/pyproject.toml b/pyproject.toml index 5337105..96c0981 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "gate.cat" -version = "0.4.18" +version = "0.4.19" description = "Block irreversible AI-agent actions before they run — deterministic, fail-closed action-veto (deny-list + exec-check + human-in-the-loop) for any tool-using agent, from a Claude Code hook to local LLMs." readme = "README.md" license = {text = "Apache-2.0"} diff --git a/tests/test_version_sync.py b/tests/test_version_sync.py index a1f9721..fb2bf64 100644 --- a/tests/test_version_sync.py +++ b/tests/test_version_sync.py @@ -5,15 +5,47 @@ version). A bare literal comparison keeps this deterministic in dev checkouts where importlib.metadata may see no installed distribution. """ +import json from pathlib import Path import tomllib import gatecat +ROOT = Path(__file__).resolve().parents[1] + + +def _pyproject_version() -> str: + return tomllib.loads((ROOT / "pyproject.toml").read_text())["project"]["version"] + def test_runtime_version_matches_pyproject(): - pyproject = tomllib.loads( - (Path(__file__).resolve().parents[1] / "pyproject.toml").read_text()) + assert gatecat.__version__ == _pyproject_version() + + +def test_plugin_manifests_match_pyproject(): + """The Claude Code plugin manifests advertise a version too — a stale one + makes `/plugin install gatecat@gatecat` claim a different release than + `pip install` delivers.""" + version = _pyproject_version() + + plugin = json.loads( + (ROOT / "plugins" / "gatecat" / ".claude-plugin" / "plugin.json").read_text()) + assert plugin["version"] == version + + marketplace = json.loads( + (ROOT / ".claude-plugin" / "marketplace.json").read_text()) + listed = [p["version"] for p in marketplace["plugins"]] + assert listed == [version] + + +def test_pack_hint_urls_anchor_to_real_packs_page_ids(): + """Every once-per-machine pack hint deep-links packs.html# — the + only EUR 29 conversion link a machine ever prints. A renamed id on the + page would silently land every hint on the top of the page instead.""" + from gatecat._pack_hint import _PACKS - assert gatecat.__version__ == pyproject["project"]["version"] + packs_html = (ROOT / "docs" / "packs.html").read_text() + for _name, _clis, _scope, url in _PACKS: + anchor = url.split("#", 1)[1] + assert f'id="{anchor}"' in packs_html, url From 2edb634b52e9f012795acb5fbd39de5d08f19015 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Jul 2026 16:25:09 +0000 Subject: [PATCH 021/139] =?UTF-8?q?docs(facts):=20drift=20sweep=20?= =?UTF-8?q?=E2=80=94=20six=20confirmed=20mismatches=20fixed=20by=20hand=20?= =?UTF-8?q?(W6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Right before distribution is exactly when self-contradiction kills the 'verify it yourself' pitch. All fixes verified against FACTS.md rows or the code itself, no generic scanner (per panel judges): - llms.txt: bypass suite '65/65' -> F4 verbatim (178/178 + named gap + 1/129 benign); stale 'as of v0.4.3' + unpinned coverage claim -> F3 pin - answers/*.html: 12x '38 default policies' -> 71 (prose + JSON-LD) - partner welcome pack CORRECTED: one-time packs DO accrue 30% — affiliate.py counts any paid entitlement and test_thirty_percent_accrual_one_time_pack asserts it; the previous version of the pack claimed the opposite - analyst data pack: F9 quote re-pinned to 0.4.18 (desync noted) - COMPARISON.md: '~21 curated policies' -> 71 default policy walls (F10) - partners.html: the naked stat row now carries the reproduce-it command, caveats and FACTS link; surface added to the self-verify drift guard Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01J7Q5Rs7ez2YWrjWKAPcHYz --- COMPARISON.md | 2 +- docs/AUTOPILOT-LOOP.md | 11 ++++++++++- docs/answers/ai-agent-almost-ran-rm-rf.html | 8 ++++---- docs/answers/audit-evidence-for-ai-agent-actions.html | 2 +- docs/answers/claude-code-deleted-my-file.html | 8 ++++---- docs/answers/index.html | 2 +- docs/answers/secure-mcp-server.html | 4 ++-- docs/llms.txt | 11 ++++++----- docs/partners.html | 1 + ops/launch/mike_category_data_pack.md | 5 +++-- ops/partners/welcome_pack.md | 10 ++++++---- tests/test_marketing_consistency.py | 3 ++- 12 files changed, 41 insertions(+), 26 deletions(-) diff --git a/COMPARISON.md b/COMPARISON.md index ea45bee..1485499 100644 --- a/COMPARISON.md +++ b/COMPARISON.md @@ -43,7 +43,7 @@ was talked into it, and stop the `terraform destroy` at the boundary anyway. ## vs. the "just use regexes yourself" objection -You could. gate.cat is ~21 curated policies for the irreversible-action class + an independent +You could. gate.cat is 71 default policy walls for the irreversible-action class + an independent exec analyzer + human-in-the-loop + a bypass suite that **prints its own known gaps** (base64 payloads, deletes via a language runtime, `curl|sh`) instead of pretending they don't exist, + the harness integration that makes it enforcement rather than advice. The value is the curation, diff --git a/docs/AUTOPILOT-LOOP.md b/docs/AUTOPILOT-LOOP.md index 03f9e3a..b5dd20f 100644 --- a/docs/AUTOPILOT-LOOP.md +++ b/docs/AUTOPILOT-LOOP.md @@ -100,7 +100,7 @@ _Synteza panelu 2026-07-23 (3 propozycje / werdykty 2 sędziów: CASH=time-to-ca - [x] **W3 — `gate.cat setup claude-code` + `gate.cat doctor`: aktywacja hooka jedną komendą (fail-closed)** _(DONE 2026-07-23 przebieg #24: gatecat/_setup_cli.py — setup: idempotentny merge PreToolUse z zachowaniem obcych kluczy/hooków (append, nie replace), backup .gatecat.bak przed każdym modyfikującym zapisem, --global/--dry-run, REFUSING na nieparsowalnym JSON z blokiem do ręcznego wklejenia; doctor: wersja + binarka na PATH + gdzie hook zarejestrowany (projekt/global) + stan protection, hint na setup gdy nigdzie; dispatcher + 2 linie help; 10 testów (idempotencja/foreign-keys/backup/dry-run/refusal/global/doctor/routing); README z markerem „new in 0.4.19"; CHANGELOG Added. Pełny suite 1944 passed.)_ — zweryfikowane (obaj sędziowie KEEP): w cli.py/dashboard.py NIE istnieje żadna komenda instalująca hook, install.sh tylko symlinkuje binarki — użytkownik ręcznie wkleja JSON do .claude/settings.json, a KAŻDY mechanizm monetyzacji (nudge Solo €19, pack hint €29) odpala się dopiero przy uzbrojonym hooku. Największy przeciek lejka; automatyzuje to, co README już dokumentuje ręcznie (zero nowych obietnic). Scope: subkomenda na istniejącym dispatcherze gate.cat/gatecat (oba = dashboard:main): `setup claude-code` (projektowe .claude/settings.json, --global, idempotentny merge PreToolUse z zachowaniem obcych kluczy, backup przed zapisem, --dry-run, fail-closed na nieparsowalnym JSON → wypisz blok do ręcznego wklejenia, nic nie nadpisuj); `doctor` MINIMALNY (wersja + czy/gdzie hook zarejestrowany + armed/disarmed — bez rozrostu w health-check). Testy: idempotencja, obce klucze, backup, dry-run, odmowa na zepsutym JSON; wzmianka w README + CHANGELOG 0.4.19. Acceptance: świeży katalog → setup → hook w settings.json; drugi run = no-op; pełny pytest + CI zielone. _(impact: $0-120 — mnożnik aktywacji na całym downstreamie przy ~3,700 pobraniach/30 dni (F13-tempo); dolna granica $0 uczciwa przy $0 baseline, effort: M, PRODUCT-LED, 5.8)_ - [x] **W4 — Sweep konwersja+instrumentacja: nudge-veto tag, zepsuty URL w `report`, funnel-events na teams.html, PRICING.md→packs.html, re-pin show_hn** _(DONE 2026-07-23 przebieg #25: (1) post-veto nudge → ?source=nudge-veto; (2) report URL bez literalnej gwiazdki + zaostrzona asercja (regres-test na '*'); (3) teams.html z gc-funnel-events (kontrakt /events z packs.html, fallback teams-direct) + test test_teams_page_tracks_cookieless_funnel_events; (4) PRICING.md → packs.html?source=pricing-md + asercja; (5) show_hn_ready: 0.4.17→0.4.18 ×2 + tagi ?source=hn na packs/teams w pierwszym komentarzu. Acceptance-grepy czyste, suite 1945 passed.)_ — pięć małych, w 100% zweryfikowanych fixów w jednej paczce (follow-up PR pętli, NIE do gotowego #27): (1) gatecat/_nudge.py:35 — post-veto nudge (najgorętszy sygnał produktu) linkuje goły teams.html bez `?source=` → `?source=nudge-veto`; (2) gatecat/integrations/dashboard.py:239 — literalna gwiazdka w `?source=report*` (zepsuty URL w pastowalnym raporcie; test łapie tylko substring — zaostrzyć asercję); (3) docs/teams.html ma TYLKO skrypt affiliate-ref, zero gc-funnel-events — skopiuj blok Z docs/packs.html (nie z index.html — tam inny tracker, korekta sędziego HONESTY), fallback source `teams-direct`, test wzorem test_landing_tracks_cookieless_funnel_events; bez tego owner nie odróżni "nikt nie klika" od "klikają, nie widzimy" na stronie o najwyższym LTV; (4) PRICING.md sekcja Packs = ostatni blind-checkout (grep packs.html = 0) → jedna linia "full scope before you pay: gate.cat/packs.html?source=pricing-md" + rozszerzenie test_packs_page_shows_scope_before_checkout; (5) ops/launch/show_hn_ready.md: '0.4.17'→'0.4.18' (linie 7 i 40 — żywe złamanie reguły FACTS.md w paste-ready artefakcie; to jest load-bearing część) + tagi packs.html/teams.html`?source=hn` w pierwszym komentarzu (na zapas — HN dziś OFLAGOWANY, nie księgować przychodu z HN, cięcie CASH). Acceptance: grep '0.4.17' w show_hn_ready = 0; grep 'source=report\*' w kodzie = 0; teams.html trackuje page_view/checkout_click; pełny suite zielony. _(impact: $0-100 łącznie (instrumentacja+usuwanie tarcia, bez nowego popytu — po cięciu HN z $30-150 do $0-40), effort: S, INSTRUMENTACJA+COLLATERAL, 5.2)_ - [x] **W5 — Release-prep 0.4.19: bump ×4, build+smoke w czystym venv, checklist, testy-strażniki wchłonięte** _(DONE 2026-07-23 przebieg #26: bump ×5 (pyproject, __init__, plugin.json, marketplace.json, llms.txt); CHANGELOG [0.4.19] domknięty z sekcją Fixed (desync __version__, report-URL, nudge-tag); test_version_sync rozszerzony o manifesty pluginu + NOWY test kotwic _PACKS↔packs.html; README: linia o pluginie przy sekcji hooka; build+twine check PASSED (po upgrade pkginfo w sandboksie) + smoke w czystym venv: __version__==0.4.19, 3 entry-pointy, hinty→packs.html, doctor OK; ops/launch/release_0.4.19_checklist.md z ODWRÓCONĄ kolejnością: deploy packs.html PRZED publish (hinty nie mogą linkować w pustkę). Suite 1947 passed. Publish = [USER], 2 komendy.)_ — cały kod konwersyjny (pack hint v2 → packs.html, fix desyncu __version__, W3+W4 z tej kolejki) dociera do 0 z ~125 pobrań/dzień, dopóki 0.4.19 nie trafi na PyPI; 0.4.18 wyszedł z desyncem właśnie przez brak smoke-a przed publish (F9). Wykonać jako OSTATNIE z zadań kodowych tej kolejki (pociąg ma zabrać W3/W4). Scope: bump we wszystkich CZTERECH miejscach (pyproject.toml, gatecat/__init__.py, plugins/gatecat/.claude-plugin/plugin.json, .claude-plugin/marketplace.json); domknięcie [0.4.19] w CHANGELOG; `python -m build` + `twine check` + instalacja wheela w czystym venv (asercje: __version__==0.4.19, entry-pointy, hint z URL-em packs.html); ops/launch/release_0.4.19_checklist.md z twardą kolejnością: publish PO deployu packs.html (produkcja dziś soft-404 — hinty nie mogą linkować w pustkę). WCHŁONIĘTE z werdyktów: test wiążący każdy URL z _pack_hint._PACKS z odpowiadającym `id=` w docs/packs.html (~10 linii, z zabitego CI-guarda — chroni jedyny raz-na-maszynę link konwersyjny €29); rozszerzenie test_version_sync.py o plugin.json/marketplace.json (rdzeń z odłożonego plugin v1.1); jednolinijkowa wzmianka "Claude Code plugin: /plugin marketplace add BGMLAI/gate.cat" przy sekcji hooka w README (zweryfikowane: README ma dziś ZERO wzmianek o pluginie — cięta wersja odłożonego "PyPI landing v2", bez restrukturyzacji topu i bez GIF-a). Acceptance: dist/ czysty, twine check pass, smoke zielony, test_version_sync łapie celowy desync manifestów, publish = [USER] (dwie komendy z checklisty). _(impact: $0-95 bezpośrednio, ale pociąg wiozący CAŁĄ in-product konwersję — najwyższa dźwignia sandbox wg sędziego CASH, effort: S, RELEASE-TRAIN, 6.0)_ -- [ ] **W6 — FACTS-drift sweep ręczny: llms.txt, answers/*.html, welcome_pack, pakiet Mike'a, partners.html** — pięć POTWIERDZONYCH (nie regexem — czytaniem) rozjazdów z FACTS.md na powierzchniach, które właśnie mają dostać ruch/użycie: (1) docs/llms.txt (surface dla AI-crawlerów) wciąż "65/65" i "as of v0.4.3" wbrew F4 (178/178 + named gap + 1/129 benign) i F3 — T10 odświeżył inne linie, ta przetrwała; (2) 5 stron docs/answers/*.html (w sitemapie, live) twierdzi "38 default policies" w prozie i JSON-LD wbrew F10 (71) — dokładnie zakazane brzmienie z F10; (3) ops/partners/welcome_pack.md 3× "packi NIE akruują" wbrew kodowi (affiliate.py płaci 30% od packów — test test_thirty_percent_accrual_one_time_pack to asertuje) i wbrew live partners.html — pierwszy realny partner dostałby mail sprzeczny ze stroną, którą właśnie przeczytał; (4) ops/launch/mike_category_data_pack.md cytuje F9=0.4.17 (stale od dzisiejszego re-pinu) + COMPARISON.md "~21 curated policies" wbrew F10; (5) docs/partners.html pokazuje gołe "178/178" i "1,085,159" BEZ kawetów i linku FACTS — wzorzec zakazany w F4; fix = rozszerzenie listy powierzchni w ISTNIEJĄCYM test_self_verify_block_on_every_purchase_surface + wording verbatim z teams.html (bez nowych fraz). Cięcia sędziów zastosowane: fixy RĘCZNE tylko potwierdzonych instancji, ŻADNEGO generycznego skanera driftu (false-positives na CHANGELOG/frozen snapshotach; spójne z odrzuceniem followup_due.py), zero dotykania bundlowanego index.html. Acceptance: grep '65/65', 'v0.4.3', '38 default' w docs/ = 0; welcome_pack zgodny z affiliate.py; rozszerzony test zielony; diff numbers-only. _(impact: $0-50 — wiarygodność "receipts" dokładnie przed dystrybucją; samo-sprzeczność to dziura, której pitch "zweryfikuj sam" nie przeżyje, effort: M, FACTS-SYNC/HIGIENA, 4.5)_ +- [x] **W6 — FACTS-drift sweep ręczny: llms.txt, answers/*.html, welcome_pack, pakiet Mike'a, partners.html** _(DONE 2026-07-23 przebieg #27: (1) llms.txt 65/65→F4 verbatim + v0.4.3/73%→F3 pin bez liczby spoza FACTS; (2) answers/ 12×"38 default policies"→71 (proza+JSON-LD, sed po całym katalogu); (3) welcome_pack SKORYGOWANY — packi AKRUUJĄ 30% (kod+test potwierdzone; poprzednia wersja U7 twierdziła odwrotnie — mój błąd, korekta odnotowana w pliku); (4) pakiet Mike'a F9→0.4.18 z notą o desyncu; (5) COMPARISON.md ~21→71; (6) partners.html: kawety+komenda reprodukcji+link FACTS pod gołym stat-rowem, powierzchnia dodana do test_self_verify_block. Suite 1947 passed.)_ — pięć POTWIERDZONYCH (nie regexem — czytaniem) rozjazdów z FACTS.md na powierzchniach, które właśnie mają dostać ruch/użycie: (1) docs/llms.txt (surface dla AI-crawlerów) wciąż "65/65" i "as of v0.4.3" wbrew F4 (178/178 + named gap + 1/129 benign) i F3 — T10 odświeżył inne linie, ta przetrwała; (2) 5 stron docs/answers/*.html (w sitemapie, live) twierdzi "38 default policies" w prozie i JSON-LD wbrew F10 (71) — dokładnie zakazane brzmienie z F10; (3) ops/partners/welcome_pack.md 3× "packi NIE akruują" wbrew kodowi (affiliate.py płaci 30% od packów — test test_thirty_percent_accrual_one_time_pack to asertuje) i wbrew live partners.html — pierwszy realny partner dostałby mail sprzeczny ze stroną, którą właśnie przeczytał; (4) ops/launch/mike_category_data_pack.md cytuje F9=0.4.17 (stale od dzisiejszego re-pinu) + COMPARISON.md "~21 curated policies" wbrew F10; (5) docs/partners.html pokazuje gołe "178/178" i "1,085,159" BEZ kawetów i linku FACTS — wzorzec zakazany w F4; fix = rozszerzenie listy powierzchni w ISTNIEJĄCYM test_self_verify_block_on_every_purchase_surface + wording verbatim z teams.html (bez nowych fraz). Cięcia sędziów zastosowane: fixy RĘCZNE tylko potwierdzonych instancji, ŻADNEGO generycznego skanera driftu (false-positives na CHANGELOG/frozen snapshotach; spójne z odrzuceniem followup_due.py), zero dotykania bundlowanego index.html. Acceptance: grep '65/65', 'v0.4.3', '38 default' w docs/ = 0; welcome_pack zgodny z affiliate.py; rozszerzony test zielony; diff numbers-only. _(impact: $0-50 — wiarygodność "receipts" dokładnie przed dystrybucją; samo-sprzeczność to dziura, której pitch "zweryfikuj sam" nie przeżyje, effort: M, FACTS-SYNC/HIGIENA, 4.5)_ ### ODRZUCONE v3 (z uzasadnieniem — nie proponować ponownie) @@ -173,6 +173,15 @@ naraz). Publikuje user/sesja lokalna; każdy live URL → issue #9. ## LOG PĘTLI +- **2026-07-23 17:21 UTC — przebieg #27: W6 DONE → KOLEJKA v3 WYCZERPANA.** + Poczta: bez zmian. Backlog: **W6 done** — 6 rozjazdów FACTS naprawionych + (llms 65/65, answers 38→71 ×12, welcome_pack KOREKTA prowizji od packów — + mój błąd z U7, Mike-pack F9, COMPARISON 21→71, partners.html kawety+test). + W1-W6 komplet. Następny przebieg: panel v4 — seedy z poczekalni v3 (plugin + v1.1 po merge #27, audyt wheela 0.4.18 jeśli dystrybucja przed publish + 0.4.19, reply-bank obiekcji gdy HN/Reddit dostanie datę) + świeże soczewki: + co po deployu (funnel data-driven iteracja), konwersja follow-upów 07-25. + - **2026-07-23 16:21 UTC — przebieg #26: W5 DONE.** Poczta: bez zmian. Backlog: **W5 done** — release-prep 0.4.19 kompletny (bump ×5, CHANGELOG domknięty, strażniki wersji+kotwic, twine check + czysty-venv smoke zielone, checklist diff --git a/docs/answers/ai-agent-almost-ran-rm-rf.html b/docs/answers/ai-agent-almost-ran-rm-rf.html index eb901a3..5b1be35 100644 --- a/docs/answers/ai-agent-almost-ran-rm-rf.html +++ b/docs/answers/ai-agent-almost-ran-rm-rf.html @@ -20,7 +20,7 @@ - +