From 0b69d2b91d2361845dcfd23a1659c6650a587a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Ign=C3=A1cio=20Fontoura=20Solla?= Date: Fri, 31 Jul 2026 12:53:12 -0300 Subject: [PATCH] =?UTF-8?q?chore:=20public=20release=20tip=20=E2=80=94=20A?= =?UTF-8?q?ll=20Rights=20Reserved,=20sanitize=20field=20material?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove interview audio/transcripts/sheets from the tree, add LICENSE (UNLICENSED), /private/ convention for local-only sensitive docs, and public-clean CUSTOMER + session summaries for cloud agents. --- .gitignore | 22 ++-- LICENSE | 11 ++ README.md | 4 + docs/AGENT-OPS.md | 13 ++- docs/CUSTOMER.md | 109 ++++++++++++++++++ docs/IMPROVE-APP-PLAN.md | 4 +- docs/plans/cenarios-estimativa-votos.md | 2 +- docs/plans/remodelagem-municipios.md | 2 +- ...servada-coordenador-2026-07-29-snapshot.md | 21 ++++ ...sessao-observada-coordenador-2026-07-30.md | 18 +++ ...sessao-observada-coordenador-cheatsheet.md | 32 +++++ ...-observada-coordenador-convite-whatsapp.md | 25 ++++ docs/plans/whatsapp-interno-campanha.md | 2 +- package.json | 5 +- private/README.md | 27 +++++ scripts/refresh-stage.mjs | 5 +- 16 files changed, 283 insertions(+), 19 deletions(-) create mode 100644 LICENSE create mode 100644 docs/CUSTOMER.md create mode 100644 docs/plans/sessao-observada-coordenador-2026-07-29-snapshot.md create mode 100644 docs/plans/sessao-observada-coordenador-2026-07-30.md create mode 100644 docs/plans/sessao-observada-coordenador-cheatsheet.md create mode 100644 docs/plans/sessao-observada-coordenador-convite-whatsapp.md create mode 100644 private/README.md diff --git a/.gitignore b/.gitignore index 127b9a96..1b4165ea 100644 --- a/.gitignore +++ b/.gitignore @@ -56,14 +56,16 @@ next-env.d.ts # IBGE demographics download cache (pnpm build:demographics) /data/demographics/ -# Transcription intermediates (source audio lives under docs/) -output/**/*.wav +# Local-only sensitive material (agents may read; never commit content) +/private/** +!/private/README.md -# Playwright -node_modules/ -/test-results/ -/playwright-report/ -/blob-report/ -/playwright/.cache/ -/.playwright-cli/ -.aider* +# Former tracked sensitive locations — never re-add +/docs/general-coordinator-interview/ +/docs/sheets/ +/output/ + +# Audio / media field captures +*.m4a +*.mp3 +*.webm diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..02400438 --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +Copyright (c) 2026 Francisco Ignácio Fontoura Solla. All Rights Reserved. + +This software and associated documentation files (the "Software") are the +proprietary property of the copyright holder. + +No permission is granted to use, copy, modify, merge, publish, distribute, +sublicense, and/or sell copies of the Software without prior written +permission from the copyright holder. + +For licensing inquiries: fsolla@pm.me +Governing law / venue: Brazil. diff --git a/README.md b/README.md index 00d6194d..5a26e74e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # Teqo +> **License:** proprietary — **All Rights Reserved** (© Francisco Ignácio Fontoura Solla). Portfolio / demonstration only. **Not** open source. Use, copy, or redistribution requires prior written permission (`fsolla@pm.me`). See [`LICENSE`](LICENSE). +> +> **Sensitive field material** belongs in `/private/` on local checkouts (gitignored). Cloud agents: use public-clean docs; report sensitive deliverables in chat — do not commit them. + > **Cheatsheet de operação agentic (humanos)** — o fluxo em 5 linhas: > > 1. O agente roda `pnpm agent:claim` e pega a próxima Issue `ready` por prioridade (`prio:P0..P3`). diff --git a/docs/AGENT-OPS.md b/docs/AGENT-OPS.md index 47d1c508..762978fc 100644 --- a/docs/AGENT-OPS.md +++ b/docs/AGENT-OPS.md @@ -71,7 +71,7 @@ Fast gate local do agente (iteração): `pnpm gate:fast` (lint + typecheck + tes ## Stage DB — runbook de refresh (semanal, humano) -1. `export NEON_API_KEY=…` (console.neon.tech → API keys; projeto `jorgesolla` / `lively-math-34249863`). +1. `export NEON_API_KEY=…` (console.neon.tech → API keys; projeto Neon da campanha (id via `NEON_PROJECT_ID`; não hardcodar no repo público)). 2. `pnpm db:refresh:stage` — deleta a branch `stage` velha, cria nova do snapshot de prod, faz swap do secret `STAGE_DATABASE_URL` no Environment `stage`. `--dry-run` inspeciona. 3. Próximo `ci-stage` já usa o snapshot novo. Preview Vercel da branch `stage` (`jorgesolla-git-stage-solla.vercel.app`) aponta para o mesmo banco via envs `Preview (stage)` — **atenção**: o endpoint muda a cada refresh; rode também `vercel env add DATABASE_URL preview stage` com a URL nova (o script imprime a URL mascarada; pegue a completa no console Neon ou rode `vercel env pull`). @@ -92,3 +92,14 @@ Supervisor **remoto** que mantém até 5 Cursor Cloud Agents rodando `work-issue ## Leitura always-on (ordem) `AGENTS.md` (fatiado 2026-07-30) → `.cursor/rules/codebase-map.mdc` → `.cursor/rules/engineering-standards.mdc` → esta página → kernels [`PRODUCT.md`](../PRODUCT.md) / [`DESIGN.md`](../DESIGN.md) / [`CUSTOMER.md`](CUSTOMER.md) (kernel no topo). Histórico: [`CHANGELOG-AGENTS.md`](CHANGELOG-AGENTS.md). Referência Payload sob demanda: [`PAYLOAD-REFERENCE.md`](PAYLOAD-REFERENCE.md). + +## Material sensível: `/private/` (local) vs cloud + +O repo GitHub é **público** e proprietário (All Rights Reserved). Discovery de campo com áudio, transcrição bruta, nomes reais, deltas operacionais de voto e planilhas de projeção **não** sobem no tip público. + +| Quem | Onde grava | O que faz | +|------|------------|-----------| +| **Agente local** | `/private/` (gitignored; só `private/README.md` versionado) | Lê/escreve notas sensíveis aí. Publica em `docs/` só uma **versão limpa** (JTBD/insights sem PII operacional). Nunca `git add` de áudio/transcribe/sheets/notas verbatim. | +| **Agente cloud** (Cursor Cloud, Devin, etc.) | Clone **sem** `/private/` | Baseia-se em `docs/CUSTOMER.md` e planos públicos limpos. Se o entregável for sensível, **informa no chat** e **não commitá** — o humano salva em `/private/` no checkout local. | + +Regra de ouro: o que um cloud agent não deveria ver no GitHub público também não deve ser commitado por um agente local. diff --git a/docs/CUSTOMER.md b/docs/CUSTOMER.md new file mode 100644 index 00000000..da082217 --- /dev/null +++ b/docs/CUSTOMER.md @@ -0,0 +1,109 @@ +# Customer + +> **Public-clean version.** Field recordings, raw transcripts, named actors, and operational vote deltas live only under `/private/` on local checkouts (gitignored). Cloud agents: use this document; if a task would produce sensitive deliverables, report them in chat and do not commit them. + +## Kernel (day-to-day) + +- **Who:** the General Coordinator of a federal-deputy campaign in Bahia (~45 days, scarce resources, information scattered across WhatsApp / spreadsheets / memory). Job: one shared, current operational picture so limited effort goes to the right territories and people. +- **Mental model (observed use):** **Action → Place → Who** — never entity-first. The coordinator does not scroll by instinct; an invisible confirmation (Save / Approve) means the action was not completed; a fragmented form means abandonment. +- **Relative reading of the board:** **% of the candidate’s own vote** (concentration of own capture) is the hard priority criterion — absolute statewide % is an anti-metric. Projected floor is on the order of prior-cycle performance with a stretch target above it. +- **Threat #1:** friendly fire inside the same party (a co-religionist ahead). Real team channel: WhatsApp 1:1 without dated audit trail. +- **Dominant constraint:** “legs” / field structure, not money. +- **Competence anxiety** (“I can’t handle the tool”) is the worst emotional problem — the product must give a sense of control, not only data. + +--- + +## Job Statement + +When I am coordinating a statewide federal-deputy campaign across dozens of Bahia municipalities in roughly 45 days, with scarce resources and information scattered across advisors and local leaderships, I want a shared, current operational picture so I can put limited effort into precise mobilization instead of reconciling WhatsApp, spreadsheets, and memory. + +(PT, field language:) +Quando preciso coordenar uma campanha de deputado federal pelo estado da Bahia — votos e estrutura em dezenas de municípios, ~45 dias, pouco recurso, informação espalhada entre assessores e lideranças — quero enxergar o mesmo quadro operacional e agir no território/pessoas certas sem caçar atualizações, para transformar esforço limitado em mobilização precisa. + +## Job Dimensions + +| Dimension | Description | Where the app underdelivers today | +| ---------- | ----------- | --------------------------------- | +| Functional | See municipalities (predefined territories), base, declared-vs-estimated votes, and agenda in one place; record updates and decide the next action | Entity-first screens invert the **Action → Place → Who** model; discovery requires scroll; confirmations invisible; fragmented forms. Hit: filtered “no advisor” lists × prior-cycle votes. Jargon still blocks. | +| Emotional | Feel in control and trust that the picture is current | **Worst today.** Competence anxiety (“I can’t see / handle it”), not only stale data. Without action-first flows, Little Hire does not start. | +| Social | Be seen as serious, aligned coordination | Real work still “wins” on WhatsApp; tool users can look bureaucratic while informal channels set the pace | + +## Competing Alternatives + +| Alternative | Why hired today | Weakness | +| ----------- | --------------- | -------- | +| WhatsApp groups / 1:1 | Fast, everyone is already there | Fragments; no analysis; useful history disappears | +| Spreadsheets (projection maps) | Flexible; one advisor’s “source of truth” | Divergent versions; weak on phone | +| Notebook / memory / phone calls | Zero tool friction | Doesn’t scale; doesn’t share | +| Other campaign platforms (past attempts) | Promise of a single system | Team stops updating → stale data → abandonment | +| Non-consumption | Avoids another login | Burns the 45-day window | + +## Big Hire vs Little Hire + +| Moment | What it is here | Status / intervention | +| ------ | --------------- | --------------------- | +| Big Hire | First login, trust the system enough to start | Mitigated offline: in-person onboarding; seed initial data when needed | +| Little Hire | Come back and update so the shared picture stays alive | **Primary leak.** Past tools died here. Reduce emotional cost of “updating again today” | + +## Forces of Progress + +| Force | Notes | +| ----- | ----- | +| Push | Fragmentation; statewide scope; 45-day crunch; cannot follow dynamics by hand | +| Pull | One operational picture; smarter targeting; instrument the team can update; territory dossier before agenda | +| Habit | WhatsApp + spreadsheet as default — “Zap is the field”; projection sheet is the morning ritual | +| Anxiety | “If others don’t update, I’m wasting time”; competence anxiety; LGPD / real-data hold; “legs” constraint | + +## Opportunity Solution Tree (sanitized) + +``` +Outcome: weekly Little Hire +├── O1 I don’t trust others updated → anxiety / abandonment +├── O2 Day’s delta (call/Zap) does not enter the decision queue +├── O3 Jargon + opaque AI block action +├── O4 Updating on phone is slower than voice on Zap +├── O5 “Truth” still lives in the projection spreadsheet +├── O6 Arrive in territory without a dossier +├── O7 Vote gains/losses lack dated / auditable record +├── O8 Team in isolated islands — information does not circulate +├── O9 Action-first mental model vs entity-first UI +├── O10 Discovery must be above-the-fold — no instinctive scroll +└── O11 Invisible confirmation / commit (Save / Approve / Done) +``` + +**Product direction:** tables = bulk bank management; redesign daily UX as **continuous linear flows**. Observed-session originals: `private/plans/` (local only). + +## Leap-of-Faith Assumptions + +| Assumption | Type | Cheap test | Success if | +| ---------- | ---- | ---------- | ---------- | +| Seeded picture + onboarding → returns within 7 days | Desirability / Little Hire | Count logins + ≥1 real update after action-first redesign | ≥1 spontaneous update in 7 days | +| Action queues answer “where do I start?” | Usability | Filtered “no advisor” × prior-cycle votes | Finds queue/action without help | +| Entity-first “edit where you see” is discoverable | Usability | Observed: editable cells not discovered in free exploration | Opens vote adjust without demo — **FAILED**; pivot O9 | +| Inline glossary / plain language cuts confusion | Usability | Field jargon needed live translation | Zero “what is…?” in 2nd session after copy | + +## Discovery method (no raw evidence here) + +Field discovery used Mom Test story blocks + observed product use. Full verbatim transcripts, audio, and named operational deltas are **not** in this public tree. Local agents: see `private/customer/CUSTOMER.md`, `private/transcribe/`, `private/general-coordinator-interview/`. Cloud agents: stay on this clean doc; escalate sensitive outputs in chat. + +### Validated patterns (safe to build on) + +- Priority is **share of the candidate’s own capture**, not local electorate %. +- Leadership value is often political representativeness, not raw vote count. +- Friendly fire (same-party competitor) is the named #1 threat class. +- Channel of truth for day deltas is voice/Zap without dated tool trail — until the product wins Little Hire. +- Dominant constraint named in field: structure/“legs”, with money as instrument — not always the binding constraint. +- Map is briefing/panel, not the daily operating surface; filtered lists for “who is unmonitored” are the observed value hit. +- Tables remain for bulk; day-delta work needs action-first chassis. + +## Segments & Best-Fit Customer + +- Primary: `coordinator` ("Coordenador Geral"), `candidate` ("Candidato"), and `advisor` ("Assessor") operating `/campanha` under time pressure — advisor scoped to administered municipalities. +- Secondary: `leader` ("Liderança") in the field (PWA) — phone-first supporter contact tool only. +- Out of scope for this improve cycle: public site visitors / donors. + +## Links + +- Architecture / campaign model: [`ARCHITECTURE.md`](ARCHITECTURE.md) +- Agent ops (incl. `/private/` rules): [`AGENT-OPS.md`](AGENT-OPS.md) +- Local sensitive originals: `private/` (gitignored; local checkouts only) diff --git a/docs/IMPROVE-APP-PLAN.md b/docs/IMPROVE-APP-PLAN.md index 380cb4e4..b38b6d39 100644 --- a/docs/IMPROVE-APP-PLAN.md +++ b/docs/IMPROVE-APP-PLAN.md @@ -63,8 +63,8 @@ Statuses: pending · in-progress · awaiting-evidence · done · deferred: \ **Public-clean.** Full notes, transcript, and named operational detail: `private/plans/` and `private/transcribe/` on local checkouts only. + +## Goal + +Hands-on observed use (Bloco B): coordinator drives Teqo as on a normal coordination day; team notes where discovery and commit fail. + +## Safe learnings (build on these) + +- Mental model is **Action → Place → Who**, not entity-first edit-in-place. +- Discovery must be **above-the-fold** — no instinctive scroll. +- Invisible Save/Approve/Done = action not completed. +- Filtered “no advisor × prior-cycle votes” lists were the value hit; map was not the daily operating surface. +- Competence anxiety (“I can’t see / handle it”) blocked Little Hire more than stale data. +- Product direction: tables for bulk bank management; day-to-day = linear action-first flows. + +## For agents + +- Cloud: use this summary + [`docs/CUSTOMER.md`](../CUSTOMER.md). Do not invent named municipalities, vote deltas, or verbatim quotes from the private session. +- Local: full snapshot under `private/plans/sessao-observada-coordenador-2026-07-29-snapshot.md`. diff --git a/docs/plans/sessao-observada-coordenador-2026-07-30.md b/docs/plans/sessao-observada-coordenador-2026-07-30.md new file mode 100644 index 00000000..431ef9b9 --- /dev/null +++ b/docs/plans/sessao-observada-coordenador-2026-07-30.md @@ -0,0 +1,18 @@ +# Observed session — General Coordinator (2026-07-30) — public summary + +> **Public-clean.** Full session notes: `private/plans/` on local checkouts only. + +## Goal + +Follow-up observed / planning session after the 2026-07-29 hands-on; refine action-first home flows and next product bets. + +## Safe learnings + +- Reinforces Action → Place → Who and above-the-fold discovery from 29/07. +- Prefer continuous linear flows for day deltas; keep list/table chassis for bulk portfolio work. +- Details that name people, municipalities with operational numbers, or interview verbatim stay offline. + +## For agents + +- Cloud: [`docs/CUSTOMER.md`](../CUSTOMER.md) + this summary. +- Local: `private/plans/sessao-observada-coordenador-2026-07-30.md`. diff --git a/docs/plans/sessao-observada-coordenador-cheatsheet.md b/docs/plans/sessao-observada-coordenador-cheatsheet.md new file mode 100644 index 00000000..b1fbd04d --- /dev/null +++ b/docs/plans/sessao-observada-coordenador-cheatsheet.md @@ -0,0 +1,32 @@ +# Notary cheatsheet — CG observed session (public template) + +> **Public template only.** Filled sheets with real names/events: `private/plans/` (local). + +One-page notary sheet for observed-use sessions. Print or keep on tablet. One line per relevant event. + +**Date:** ____/____/2026 · **Start:** __:__ · **End:** __:__ +**Facilitator:** ________ · **Notary:** ________ · **Recording:** [ ] screen+audio OK + +## Quick codes + +| Symbol | Meaning | +| ------ | ------- | +| `?` | hesitated / asked what something is | +| `✗` | wrong path / backed out | +| `✓` | found alone | +| `Z` | talked about going back to WhatsApp | +| `P` | talked about going back to spreadsheet | +| `J` | jargon (note the word) | +| `→` | navigated to | + +**Screens (generic):** Home · Map · Municipality list · Municipality detail · Dossier · Leaderships · Suggestions · Territories · Phone + +## Block 1 — Free exploration (10–12′) + +First click: ________ · Within ≤2′ reached municipality/map? [ ] yes [ ] no + +Notes: … + +## For agents + +Do not commit filled cheatsheets with real participant data — save under `private/plans/`. diff --git a/docs/plans/sessao-observada-coordenador-convite-whatsapp.md b/docs/plans/sessao-observada-coordenador-convite-whatsapp.md new file mode 100644 index 00000000..7d869b85 --- /dev/null +++ b/docs/plans/sessao-observada-coordenador-convite-whatsapp.md @@ -0,0 +1,25 @@ +# WhatsApp invite — Teqo hands-on session (public template) + +> **Public template.** Do not commit messages that name a real coordinator or private logistics beyond placeholders. Filled copies: `private/plans/` (local). + +Tone: direct, no product pitch. Adjust day/time/place. + +## Short version (recommended) + +Oi, [Nome] — amanhã a gente tem a sessão prática do Teqo (~1h15). + +Não é apresentação: você usa a ferramenta como num dia normal de coordenação e a gente só observa onde trava. + +Pode ser no seu notebook. Dados sensíveis de apoiadores reais ainda não entram (jurídico); o mapa e a projeção seedada já estão. + +**Quando:** [dia], [hora] +**Onde:** [local] +Confirma? + +## Even shorter + +[Nome], amanhã [hora] — ~1h15 de uso prático do Teqo (você dirige, a gente anota). Sem slide. Confirma em [local]? + +## If they ask what to bring + +Só você e o celular (se der). Conta e senha a gente já deixa prontas. Se puder, traz na cabeça o último município que mudou de número esta semana — a gente recria esse caso com dado seedado. diff --git a/docs/plans/whatsapp-interno-campanha.md b/docs/plans/whatsapp-interno-campanha.md index d3d1e690..7affd72c 100644 --- a/docs/plans/whatsapp-interno-campanha.md +++ b/docs/plans/whatsapp-interno-campanha.md @@ -84,7 +84,7 @@ flowchart TD ## Referências - `docs/roadmap.md` — Trilha D; Fora de escopo (Business API / massa) -- Entrevista CG 2026-07-23 (`output/transcribe/general-coordinator-interview-20260723/`) — “ZAP é o campo” +- Entrevista CG 2026-07-23 (`private/transcribe/general-coordinator-interview-20260723/`) — “ZAP é o campo” - `docs/IMPROVE-APP-PLAN.md` — Little Hire / leak WhatsApp - `PRODUCT.md` §1 soberania + atalho pragmático; §5 humano no loop - `docs/plans/notifications.md` (D2) — complementar diff --git a/package.json b/package.json index 1db3e053..a852728d 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "url": "https://github.com/fsolla/teqo/issues" }, "author": "Francisco Solla", - "license": "MIT", + "license": "UNLICENSED", "type": "module", "scripts": { "build": "cross-env NODE_OPTIONS=\"--no-deprecation --conditions=react-server\" payload migrate && cross-env NODE_OPTIONS=\"--no-deprecation --max-old-space-size=8000\" next build", @@ -173,5 +173,6 @@ "unrs-resolver" ] }, - "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977" + "packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977", + "private": true } diff --git a/private/README.md b/private/README.md new file mode 100644 index 00000000..ee542fb3 --- /dev/null +++ b/private/README.md @@ -0,0 +1,27 @@ +# private/ (local only) + +This directory is gitignored except for this README. + +Put field recordings, transcripts, session notes, operational spreadsheets, +and other campaign-sensitive material here so **local** agents can collaborate +without publishing them to the public GitHub repository. + +## Rules + +- **Local agents:** write sensitive discovery/field docs under `/private/`. Never + commit audio, raw transcripts, operational spreadsheets, or notes with real + names / vote deltas / interview verbatim into the public tree. Publish only a + cleaned public version under `docs/` when cloud agents need the context. +- **Cloud agents:** clones do **not** include `/private/`. Base work on the + public-clean docs (e.g. `docs/CUSTOMER.md`). If a task would produce a + sensitive deliverable, **report it in chat** and do **not** commit it — ask + the human to save it under `/private/` on a local checkout. +- Do not `git add` anything under this folder other than this README. + +## Layout (examples) + +- `private/customer/` — full customer/discovery notes +- `private/plans/` — observed-session notes +- `private/general-coordinator-interview/` — interview audio +- `private/transcribe/` — transcripts / diarization +- `private/sheets/` — operational vote-projection spreadsheets diff --git a/scripts/refresh-stage.mjs b/scripts/refresh-stage.mjs index c8037a99..547e21c3 100644 --- a/scripts/refresh-stage.mjs +++ b/scripts/refresh-stage.mjs @@ -24,7 +24,10 @@ import { dieWithLabel } from './lib/cli.mjs' const LABEL = 'refresh:stage' const die = dieWithLabel(LABEL) -const PROJECT_ID = process.env.NEON_PROJECT_ID ?? 'lively-math-34249863' +const PROJECT_ID = process.env.NEON_PROJECT_ID +if (!PROJECT_ID) { + die('Set NEON_PROJECT_ID (Neon console → project id).') +} const DATABASE_NAME = 'neondb' const ROLE_NAME = 'neondb_owner' const API = 'https://console.neon.tech/api/v2'