All projects
Backlog
28
wildus-006
HumanP1
Review Anna's foundation documents and provide feedback
Description
Review Anna’s recent work across 6 document areas and provide consolidated feedback. Agent reviews have already been completed — use their findings as a starting point.
Documents to review:
- Junior collection —
vault/product/product-line.md(Junior section) - Characters —
vault/brand/character-profiles-core.md - Conservation stories —
vault/conservation/conservation-stories.md - Voice profiles —
vault/brand/voice-profiles-core-8.md - Product line —
vault/product/product-line.md - Website copy —
vault/brand/foundation.md+vault/marketing/partnerships.md
Key issues flagged by agents:
- Conservation stories: Fix “genuinely” in Bigfoot RU copy. Verify population numbers (Grizzly, Orca, Sea Otter). Fox isn’t really PNW — swap to Cascade Red Fox? Missing RU Instagram captions. Add discovery hashtags.
- Product line: Hard-cap Phase 1 at ~80 SKUs. Pick one art style per character for launch tees. Select Printify blanks.
- Junior collection: Resolve identity — kids line or softer adult? Some phrases too adult for kids. Fix nature element color encoding inconsistencies (Sea Otter, Raccoon).
- Characters: Fox/Sea Otter personality overlap — push Otter toward zen. Sari Cougar cultural sensitivity — get Indian community feedback.
- Website copy: Home page copy missing. Verify partner orgs exist (Portland Urban Wildlife, Cascades Conservation Partnership). Set donation %.
- Voice profiles: Russian signature phrases almost entirely missing. Add “must sound like” voice references. Replace Fox’s weakest line.
Acceptance Criteria
- All 6 areas reviewed
- Feedback compiled and shared with Anna
- Key decisions documented (Junior identity, Phase 1 scope, donation %)
Notes
Decisions
jobs-006
AgentP2
Add patent to LinkedIn Patents section
Description
The patent is only mentioned in the LinkedIn About text. LinkedIn has a dedicated Patents section — add the patent there for better visibility:
- Title: User Interface Element for Building Interior Previewing and Navigation
- Patent number: US 10,831,332 B2
This makes it discoverable by recruiters filtering for patent holders.
workforce-017
HumanP2
Build proper backup solution for agent OpenClaw state
Description
Design and implement a proper backup solution for agent OpenClaw state (config, credentials, identity, sessions, memory). The previous approach — storing raw .openclaw/ directory snapshots in the workforce git repo under backups/ — was removed because it risked committing secrets (API keys, bot tokens, OAuth credentials) to GitHub.
Requirements
- Back up critical OpenClaw state from all agent machines (tolbachik, klyuchi, karymsky)
- Secrets must never be committed to git
- Backups should be automated (scheduled, not manual)
- Must be restorable — if an agent machine dies, we can rebuild from backup
- Must be accessible from avacha (control center)
What to back up per agent
~/.openclaw/openclaw.json(config — contains secrets)~/.openclaw/credentials/(OAuth tokens, bot tokens, API keys)~/.openclaw/identity/(device keys, node identity)~/.openclaw/agents/(agent config, sessions, memory)~/.openclaw/cron/(scheduled jobs)
Context
- Previous
backups/directory in workforce repo deleted 2026-03-12 (was gitignored but contained sensitive material locally) - Three remote machines: tolbachik (macOS), klyuchi (RPi OS), karymsky (Debian)
- All reachable via SSH from avacha
- Need to decide: local encrypted backups on avacha? Encrypted cloud storage? Both?
Notes
Decisions
wildus-032
AgentP2
Change X handle from @wildus14696 to @wildus
✓ wildus-016
Description
The Wild Us X account was registered on 2026-03-13 with auto-assigned handle @wildus14696. The target handle @wildus appears held/in limbo from prior partial signup attempts. Rate limiting also prevents handle changes right now.
Check back after 2026-03-20 to see if @wildus has been released. If so, change the handle. If not, try the fallback order.
What to do
- Go to x.com/settings/screen_name
- Try changing handle to
@wildus - If still unavailable, try fallback order:
@wild_us→@wildus_official→@wildusbrand - Update
vault/brand/claimed-handles.md
Account details
| Field | Value |
|---|---|
x@wildus.org |
|
| Current handle | @wildus14696 |
| DOB on file | 09/25/1984 |
Context
- If
@wildusis still held after a week, it may be permanently reserved or on a longer release cycle. Escalate to Viktor to decide next steps.
wildus-031
HumanP2
Create phase-based deliverables document for co-founder commitments
Description
The co-founder agreement (Section 9, time commitment) establishes a phase-based commitment framework with three phases:
- Pre-launch → first 3 months post-launch — higher commitment
- Growth (months 3-12) — moderate commitment
- Steady state (12+ months) — maintenance level
The agreement references a separate living document where specific deliverables per phase are defined for each co-founder. That document needs to be created.
Acceptance Criteria
- Document created at
wildus/vault/business/deliverables.md(or similar) - Phase 1 deliverables defined for both Anna and Viktor
- Phases 2 and 3 can be left as placeholders to be filled in later
- Both co-founders review and agree on Phase 1 deliverables
- Referenced from the co-founder agreement
Context
- Co-founder agreement:
wildus/vault/business/cofounder-agreement.md - Roles doc:
wildus/vault/business/roles.md - This is a living document — updated by mutual agreement as phases change
workforce-018
HumanP2
Design periodic/recurring task management for always-on agents
Description
We need a system for managing periodic/recurring tasks (e.g., weekly WHOIS checks, nightly PR management, scheduled social media posts, domain monitoring). Currently these are ad-hoc OpenClaw cron jobs on individual agents with no central visibility or tracking.
The likely candidates to run periodic tasks are the always-on agents — BerryPi and LobsterDrew (both on klyuchi, Ethernet, always running). Need to decide:
- How to define recurring tasks (board format? separate config?)
- How to track execution history and failures
- Which agent owns periodic task execution
- How to add/remove/modify schedules without SSH-ing into machines
- How periodic tasks relate to the board (do they create one-shot tasks? log results somewhere?)
Current State
- LobsterDrew has a weekly WHOIS monitor cron (wildus-022)
- LobsterDrew had a nightly dev→main PR cron (wildus-021, may be stale)
- These are configured directly in OpenClaw cron on klyuchi — no central registry
Notes
Decisions
workforce-026
AgentP2
Install QMD memory backend on BerryPi
Description
Install QMD (Query Markup Documents) as OpenClaw’s memory backend on BerryPi. QMD is an open-source local hybrid search engine by Tobi Lütke (Shopify CEO) that replaces OpenClaw’s default SQLite keyword search with BM25 + vector search + LLM reranking. No API keys required — runs fully locally.
This is the single highest-impact upgrade for OpenClaw memory quality.
Acceptance Criteria
- Bun runtime installed
- QMD installed globally via Bun
- Workspace collection indexed (markdown files)
- Session history collection indexed (JSONL files)
memory.backend = "qmd"set in OpenClaw config- OpenClaw restarted
- Test: ask OpenClaw about something from a past session and confirm it retrieves correctly
Installation Steps
# 1. Install Bun (required runtime)
curl -fsSL https://bun.sh/install | bash
export PATH="$HOME/.bun/bin:$PATH"
# Add the export line to ~/.bashrc permanently
# 2. Install QMD globally
bun install -g https://github.com/tobi/qmd
# 3. Index the workspace (markdown memory files)
qmd collection add ~/.openclaw/workspace --name workspace --mask "**/*.md"
qmd context add ~/.openclaw/workspace "Agent workspace - memory files, daily logs, projects, skills"
# 4. Index session history (conversation JSONL files)
qmd collection add ~/.openclaw/agents/main/sessions --name sessions --mask "*.jsonl"
# 5. Build the index
qmd update # Index documents
qmd embed # Create vector embeddings
# 6. Set QMD as memory backend in OpenClaw config
# In ~/.openclaw/openclaw.json, add:
{
"memory": {
"backend": "qmd"
}
}
# 7. Restart OpenClaw
openclaw gateway restart
Keeping the index fresh
Run periodically (or add to a cron job):
qmd update && qmd embed
Search commands (for reference)
qmd search "query" # Keyword search (fast)
qmd vsearch "query" # Semantic/vector search
qmd query "query" # Hybrid + reranking (best quality)
qmd search "query" -c workspace # Filter by collection
qmd search "query" -c sessions # Search conversation history
Context
- QMD repo: https://github.com/tobi/qmd
- OpenClaw memory docs: https://docs.openclaw.ai/concepts/memory
- Free, fully local — no API keys, uses small local models for embeddings
- Solves the problem of OpenClaw forgetting things when exact keywords don’t match
Dependencies
None
Notes
Decisions
jobs-007
AgentP2
Overhaul LinkedIn Skills section
Description
Current LinkedIn skills are disorganized and missing key technologies. Fix:
Add (from resume, currently missing):
- Azure Machine Learning
- MLflow
- Docker (not just docker compose)
- CI/CD
- TensorFlow
- Power BI
- Feature Engineering
- Model Monitoring
- LLMs / Transformers
- Azure Data Factory
- Azure Data Lake
Consider removing (not in resume, not target-role relevant):
- Java
- Nginx
- REST APIs
Pin top skills to: Azure Machine Learning, Python, MLOps, Docker, CI/CD
wildus-023
HumanP2
Place backorders for wildus.com on drop-catch services
Description
Place free backorders for wildus.com on domain drop-catch services so they auto-acquire it if the current owner lets it expire (2026-04-28).
Acceptance Criteria
- Backorder placed on DropCatch (dropcatch.com)
- Backorder placed on SnapNames (snapnames.com)
- Optionally: NameJet (namejet.com)
- Account credentials stored securely
- Payment method on file (only charged if catch succeeds, ~$59-99)
Context
- wildus.com expires 2026-04-28, registered on GoDaddy since 2005
clientRenewProhibitedflag set — owner may be letting it lapse- Listed on Afternic with “make an offer” (no fixed price)
- If not renewed: grace period (~30 days) → redemption (~30 days) → public drop (~late June/July 2026)
- Backorders are free to place; you only pay if the service catches the domain
- LobsterDrew is monitoring WHOIS weekly (wildus-022)
Notes
Decisions
jobs-004
AgentP2
Rename LinkedIn career break to "Independent AI Researcher"
Description
LinkedIn currently shows “Professional development — Career break (May 2024 - Present).” The content is strong (deep learning research, volatility denoising, LLM applications, macro analysis) but the “Career break” label can trigger unconscious bias in recruiters.
Reframe as “Independent AI Researcher” or “Independent Research” to better reflect the productive nature of this period. Keep the description as-is — it’s well-written.
wildus-022
AgentP2
Set up automated weekly WHOIS monitor for wildus.com
Description
Create a script that monitors the wildus.com domain weekly via RDAP (modern WHOIS over HTTP) and posts to the Wild Us Discord #names-and-handles channel ONLY when something changes. Architecture for periodic execution (cron, which machine, etc.) is TBD — this task covers the script and integration, not the scheduling infrastructure.
Acceptance Criteria
- A Python script at
scripts/domain-monitor/monitor.py(in the wildus repo) that:- Queries
https://rdap.verisign.com/com/v1/domain/wildus.com(no external dependencies needed — this is the authoritative RDAP server for .com) - Extracts: registrar name, expiry date, domain status flags, name servers
- Compares against a saved baseline file at
scripts/domain-monitor/baseline.json - If ANY field changed: posts a summary of changes to Discord via webhook
- If the domain returns a 404 (not found) or status contains
pendingDelete,redemptionPeriod, oravailable: posts an URGENT alert tagging@ViktorBear - Updates the baseline file with the latest data after each run
- If nothing changed: exits silently (no Discord post, no output)
- Logs each run (timestamp + result) to
scripts/domain-monitor/monitor.log
- Queries
- A baseline file
scripts/domain-monitor/baseline.jsonseeded with the current WHOIS data (see below) - A config file
scripts/domain-monitor/config.jsonfor webhook URL and mention ID - Script tested by running it manually once (should exit silently since baseline matches)
- Periodic execution mechanism TBD (blocked on deciding architecture for scheduled tasks across the workforce)
Implementation Details
RDAP endpoint
GET https://rdap.verisign.com/com/v1/domain/wildus.com
Returns JSON. Key fields to extract:
events[]whereeventAction == "expiration"→eventDate(expiry)events[]whereeventAction == "registration"→eventDate(created)status[]→ list of status flags (e.g.,["client delete prohibited", ...])entities[]whereroles[] contains "registrar"→vcardArrayorhandlefor registrar namenameservers[]→ldhNamefor each NS
Discord webhook
Store in scripts/domain-monitor/config.json:
{
"webhook_url": "WEBHOOK_URL_HERE",
"discord_alert_mention": "<@VIKTOR_BEAR_USER_ID>"
}
To get the webhook URL: Discord → Server Settings → Integrations → Webhooks → New Webhook → set channel to #names-and-handles → copy URL.
Baseline to seed
{
"registrar": "GoDaddy.com, LLC",
"expires": "2026-04-28",
"created": "2005-04-28",
"status": ["client delete prohibited", "client renew prohibited", "client transfer prohibited", "client update prohibited"],
"nameservers": ["NS49.DOMAINCONTROL.COM", "NS50.DOMAINCONTROL.COM"]
}
Discord message format
Normal change:
**wildus.com WHOIS Change Detected**
- **Expires**: 2026-04-28 → 2027-04-28
- **Status**: [old flags] → [new flags]
Urgent (domain dropping):
🚨 **wildus.com MAY BE BECOMING AVAILABLE** 🚨
@ViktorBear — Domain status changed to: pendingDelete
Act now if you want to acquire this domain.
File structure
wildus/scripts/domain-monitor/
├── monitor.py # main script
├── config.json # webhook URL + mention ID (gitignored)
├── baseline.json # last known WHOIS state
└── monitor.log # append-only run log (gitignored)
Dependencies
None
Notes
- This replaces the previous version of wildus-022 which was a recurring manual monitoring task
- The domain expires 2026-04-28 — monitoring is time-sensitive
- Once domain situation resolves (acquired, renewed by owner, or we decide to stop), Viktor will remove the monitor
- Architecture for periodic task execution across the workforce is not yet decided — this task should not prescribe a specific machine or cron setup
Decisions
wildus-038
HumanP2
Solution Discord-to-Google-Drive media sync pipeline
Description
The Discord media sync script (scripts/discord_media_hardened_pass.py) still uploads to Cloudflare R2. Now that media assets live in Google Drive, we need to solution and rewrite the sync pipeline to upload directly to Google Drive via gog CLI instead.
Architecture Direction
Two-stage pipeline, both on klyuchi:
- Discord → shared folder: LobsterDrew copies media from a designated Discord channel (e.g.,
#media-assets) to/home/shared/wildus-media/. Cron job, frequency TBD (daily or weekly). - Shared folder → Google Drive: BerryPi pushes any new files from
/home/shared/wildus-media/towildus/media-assets/on Google Drive viagog. Cron job, runs after stage 1 or on its own schedule.
This keeps the two concerns decoupled — Discord scraping vs. Drive upload — and uses the shared folder as the handoff point between agents.
Scope
- Decide cron frequency (daily vs weekly) for each stage
- Write the Discord→shared-folder script (or adapt existing
discord_media_hardened_pass.py) - Write the shared-folder→Google Drive upload script (using
gog) - Update CSV column from
r2_keytogdrive_pathin the catalog script - Test end-to-end with a new Discord media attachment
- Decide whether to keep R2 as a backup destination or drop it entirely
Context
gogCLI is installed on klyuchi (/home/linuxbrew/.linuxbrew/bin/gog) and avacha, authenticated asviktor@qoyn.ai- Google Drive folder: wildus/media-assets
- Current script uses OpenClaw
message.readfor Discord +r2_put.shfor upload - 116 files already migrated from R2 to Google Drive (wildus-036 + wildus-037)
workforce-020
AgentP2
Switch board polling to dev branch — stop pushing directly to main
Description
Currently, board task files must be on main in the workforce repo for agents to see them (board-poll.sh does a plain git pull from the default branch). This forces us to commit directly to main for any board changes — creating tasks, moving tasks between columns, etc.
This is inconsistent with our branching convention (never push directly to main) and bypasses any review step for board changes.
Problem
- Board polling reads from
main(default branch) - All board mutations (task creation, status moves) go directly to
main - No PR review for board changes
- Inconsistent with project repo conventions
Possible solutions
- Switch board-poll.sh to pull from
devinstead of the default branch - Change the workforce repo’s default branch to
dev - Keep
mainas the stable/deployed branch, usedevfor board operations - Consider whether agent board commits (task moves via lifecycle.sh) should also target
dev
Acceptance Criteria
- Board polling reads from a branch that doesn’t require direct pushes to
main - Board changes follow a consistent branching strategy
- Agent polling and lifecycle scripts updated accordingly
- All agent machines redeployed with updated scripts
- Document the new strategy in board/README.md and CLAUDE.md
jobs-003
AgentP2
Update stale "Open to Work" LinkedIn post
Description
The pinned “Open to Work” post on LinkedIn is ~1 month old and only mentions “open to roles in Vancouver, WA.” It doesn’t reflect current preferences:
- Remote preferred
- Hybrid in Seattle, SF, Miami
- On-site/hybrid in Vancouver/Portland metro
Post an updated version or edit the existing one to reflect current role targets and location flexibility.
wildus-004
HumanP2
USPTO trademark preliminary search for Wild Us
Description
Conduct a preliminary trademark search on the USPTO TESS database for “Wild Us” in relevant classes. Document findings and flag any potential conflicts.
Acceptance Criteria
- Search USPTO TESS for “Wild Us” and close variants (“WildUs”, “Wild U.S.”, “Wild Us Jr”)
- Check Class 25 (clothing) and Class 35 (retail services)
- Document any existing registrations or pending applications that could conflict
- Assess risk level: clear, caution, or blocked
- Note filing costs ($250-350 per class) and recommend whether to file now or defer
- Save results as a markdown report
Context
- Brand name: Wild Us (two words)
- Sub-brand: Wild Us Jr (Junior collection)
- Products: apparel (hoodies, t-shirts, beanies) — Class 25
- Retail: online store — Class 35
Dependencies
None
Notes
Decisions
startersite-022
AgentP3
Add --refresh mode to Places API sweep script
✓ startersite-021
Description
Add a --refresh flag to tools/outreach/places_sweep.py that re-runs all search queries (to discover new listings) but skips fetching details for places we already have in details-raw/. This lets us cheaply monitor for new businesses appearing in Clark County.
What to build
--refresh mode behavior
- Search pass: Re-run ALL search queries from
sweep-config.json(ignore existingplaces-raw/files — overwrite them with fresh results) - Diff: Compare place_ids from fresh search results against existing
details-raw/files. Identify new place_ids not seen before. - Details pass: Only fetch details for NEW place_ids (skip any that already have a
details-raw/<place_id>.jsonfile) - CSV regeneration: Rebuild all prospect CSVs from the full dataset (existing + new)
- Diff report: Generate
ops/outreach/refresh-<date>.jsonwith:- Date of refresh
- Count of new places found
- Count of new places without website
- List of new places (place_id, name, vertical, has_website)
- Git commit: After the sweep completes, automatically commit all new/changed data files to the current branch (
dev) with message:chore: places sweep refresh <date> — N new businesses found - Push: Push to
origin dev - Summary: Print diff summary to stdout
Expected cost per refresh
- Search pass: ~$14 (same as initial sweep)
- Details for new places only: pennies (maybe 10-30 new places/month)
- Total: ~$15/month, within $200 GCP free tier
Intended cadence
Monthly cron (set up separately). For now, just the --refresh flag so it can be run manually or via cron later.
Acceptance Criteria
- [ ]
python3 tools/outreach/places_sweep.py --refreshre-runs searches and only fetches details for new places - [ ] Generates
ops/outreach/refresh-<date>.jsondiff report - [ ] Automatically commits new data to dev with descriptive commit message
- [ ] Automatically pushes to origin dev
- [ ] Existing data is preserved (no data loss on refresh)
- [ ] CSV files are regenerated with full dataset (old + new)
Notes
- The initial sweep (startersite-021) must be complete before this task starts.
- The git commit should include all changed files in
ops/outreach/— new raw JSON, updated CSVs, the refresh report. - Do not commit changes to
tools/outreach/(the script itself) in the auto-commit — only data files.
workforce-012
AgentP3
Add auto-refresh to kanban board
Description
Add auto-refresh to the kanban board that fetches new HTML every 30 seconds and swaps the content without a full page reload. All changes go in kanban/generate.js — specifically in the script constant (the inline JS that gets written to app.js).
Exact Instructions
-
In the
scriptconstant inkanban/generate.js, add the following to the existing IIFE: -
Auto-refresh via fetch (every 30 seconds):
- Every 30s,
fetch(location.href)and parse the response as HTML usingDOMParser - Replace the
.board-gridinnerHTML with the.board-gridinnerHTML from the fetched HTML - Only run the refresh when the tab is visible (
document.visibilityState === 'visible') - After swapping, re-apply the current filter state (check which
.filter-btnhas theactiveclass and re-run the filter logic) - Preserve which
<details>cards are open (record opendata-task-idvalues before swap, re-open them after) - Also update
.page-statsfrom the fetched HTML - Call
updateCounts()after swap to refresh column counts
- Every 30s,
-
Do NOT modify:
- The HTML structure or template functions
- The Node.js generator logic
- Any existing CSS
- The existing filter button click handler (keep it as-is)
Acceptance Criteria
- Board auto-refreshes every 30 seconds without full page reload
- Filter state (All/Human/Agent) preserved across refreshes
- Open card details preserved across refreshes
- Column counts update after refresh
- No console errors
- Only
kanban/generate.jsmodified — specifically thescriptconstant
Context
- File to modify:
kanban/generate.js— thescriptconstant (lines 799-832) - The
scriptconstant contains an IIFE that gets written toapp.jsduring build - Existing code has
updateCounts()function and filter button click handler — keep both, extend with refresh logic - Board is deployed to Cloudflare Pages, rebuilds on push to main
Testing
Run cd kanban && npm run build, open dist/index.html in a browser. Verify no errors in console. Move a task file between board columns, push to trigger a rebuild, and confirm the card moves to its new column within 30 seconds without a full page reload.
Dependencies
None
Notes
Decisions
workforce-019
HumanP3
Build task generator script for social handle registration
Description
Create a script that generates a registration task for a social handle on a given platform for any brand. Pre-fills the task with the correct email pattern, handle fallbacks, default data, platform-specific steps, and references to the process doc and platform playbook.
Usage (target)
./generate-handle-task.sh --project wildus --platform tiktok --brand "Wild Us" --domain wildus.org
Outputs one task file:
wildus-NNN-register-tiktok.md— registration task with default data, steps, stuck protocol, and flow documentation requirement
Inputs
- Project name (e.g., wildus, startersite)
- Platform (e.g., x, tiktok, instagram, youtube, pinterest, facebook, etsy, shopify)
- Brand name (e.g., Wild Us)
- Domain (e.g., wildus.org) — for email pattern
<platform>@<domain> - Handle fallback order (or pull from checklist)
- Next available task ID
References
- Process doc:
workforce/docs/processes/social-handle-registration-process.md - Platform playbooks:
workforce/docs/playbooks/<platform>.md
Notes
- Low priority — manual task creation works fine for now
- 2026-03-13 — Simplified from recon+execution pair to single registration task (recon phase dropped)
Decisions
jobs-010
AgentP3
Consider adding independent research period to resume
Description
LinkedIn describes a productive career break (May 2024 - Present) with deep learning research, volatility denoising, LLM applications, and macro analysis. The resume has no mention of this period — experience just ends at 2024, leaving a visible gap.
Consider adding a brief “Independent Research” entry to the resume (2024-Present) covering:
- Financial volatility denoising models (deep learning on high-frequency data)
- LLM applications for software development workflows
- Azure AI certifications earned during this period
This fills the gap and shows continued technical growth.
jobs-009
AgentP3
Fix LinkedIn profile school badge
Description
The LinkedIn profile header shows “Florida International University” as the institution badge. This is the PhD (ABD) from 2016-2020. It should either show the most recent/relevant credential or be removed if LinkedIn doesn’t allow customization.
Check if LinkedIn allows selecting which education appears in the header and update accordingly.
jobs-005
AgentP3
Match job titles between LinkedIn and resume
Description
Job titles at Southeast Toyota Finance differ between LinkedIn and resume:
- LinkedIn: “Senior Data Scientist / MLOPS Engineer” (Nov 2021 - May 2024)
- Resume: “Senior Data Scientist / ML Engineer / MLOps Engineer” (2021-2024)
The resume version is better — includes “ML Engineer.” Update LinkedIn to match.
startersite-016
AgentP3
Normalize voice transcript format for FERN pipeline
Description
The FERN pipeline’s transcript-to-brief feature (formatTranscriptForPrompt in fern-pipeline.mjs) expects transcripts with role: "user"/"assistant" and content fields (WhatsApp/Telegram format). Voice intake transcripts from VoiceBridge use a different format: role: "caller"/"ai" and text instead of content.
Either normalize the voice transcript format in voice-intake.js / intake-tracker.js before committing to the repo, or update formatTranscriptForPrompt to handle both formats. Normalizing upstream is cleaner.
Acceptance Criteria
- Voice intake transcripts are included in brief generation just like WhatsApp/Telegram transcripts
- No regression for WhatsApp/Telegram transcript handling
Context
- Voice handler:
startersite-ai/site/functions/api/voice-intake.js - VoiceBridge tracker:
voice-bridge/lib/intake-tracker.js - Pipeline formatter:
client-template/.github/scripts/fern-pipeline.mjs(formatTranscriptForPrompt) - Voice format:
[{role: "caller"/"ai", text: "...", ts: "..."}] - Expected format:
[{role: "user"/"assistant", content: "..."}]
Notes
Decisions
jobs-008
AgentP3
Tighten LinkedIn About section
Description
The LinkedIn About section is verbose compared to the resume’s concise style. Improvements:
- Shorten paragraphs — recruiters skim, not read
- Lead with impact metrics (5x runtime reduction, 30-40% throughput improvement)
- The “Current Focus” paragraph mentions derivatives strategy and trading — this may distract recruiters looking for pure ML/MLOps hires. Consider softening or removing.
- Match the punchy tone of the resume’s Professional Summary
wildus-010
HumanP1
Choose e-commerce platform (Shopify vs Etsy)
⌛ wildus-001✓ wildus-002
Description
Make the final decision on e-commerce platform based on the Printify pricing research (wildus-001) and platform comparison (wildus-002).
Acceptance Criteria
- Platform chosen (Shopify, Etsy, or both) with documented reasoning
- Account created on chosen platform
- Printify account created and connected to platform
- Decision documented in vault/business/
Notes
Decisions
wildus-005
AgentP1
Printify product specs checklist
⌛ wildus-019
Description
Compile Printify’s technical requirements for uploading designs to each target product type. Create a production-ready specs checklist that Anna and Victor can use when preparing print files.
Acceptance Criteria
- For hoodies, t-shirts, and beanies: document required DPI, dimensions (px), file format, color mode, safe area/bleed
- Note front vs back print area dimensions separately
- Document any Printify-specific requirements (max file size, transparency support, etc.)
- Include beanie-specific notes: embroidery vs DTG print, stitch count limits if embroidery
- Cross-reference with vault/brand/sku-guide.md production standards
- Create a per-product checklist template that can be used to verify each design file before upload
Context
- Repo: git@github.com:wild-us/wildus.git
- See vault/brand/sku-guide.md section 5 for existing artifact cleanup checklist
- Hoodies: small logo front chest + large scene on back (vintage poster style)
- T-shirts: single character print
- Beanies: embroidered or printed cute style on front fold
Dependencies
- wildus-019
Notes
Decisions
wildus-011
AgentP2
Draft conservation partnership outreach emails
⌛ wildus-006⌛ wildus-020
Description
Draft outreach emails for the top 3 conservation partner organizations. Wait for Victor’s review of Anna’s docs (wildus-006) to confirm final org list and donation % before drafting.
Acceptance Criteria
- Template email structure (intro, mission, partnership proposal, ask)
- Customized draft for 3 priority orgs (likely: Orca Network, Elakha Alliance, and one other based on wildus-006 review)
- Each email references the specific character connection and conservation story
- Tone: authentic, not corporate. Match the brand voice.
- Include what we’re offering (% of character sales) and what we’re asking (logo use, co-marketing, partnership page listing)
- Save drafts in vault/marketing/
Context
- Repo: git@github.com:wild-us/wildus.git
- See vault/marketing/partnerships.md for org list and character-to-org mapping
- See vault/conservation/conservation-stories.md for character narratives
- Brand voice reference: vault/brand/foundation.md
Dependencies
wildus-006 (Victor’s review determines final org list and donation %)
Notes
Decisions
startersite-028
HumanP2
Send first outreach batch
⌛ startersite-027✓ startersite-029
Description
Send personalized outreach messages to Priority A cold prospects and friends. Each message includes a link to their 3 preview site options (built in startersite-027).
Cold prospects (Priority A):
- Bobby’s Bubbles Pet Grooming
- Vina Ann Nails
- L.A Landscaping Services
- Best Friends Dog Grooming
Friends (separate, personal conversations):
- Pacific Appliance Solutions (Ivan) — upgrade/redesign
- EverClean Upholstery — website upgrade, Russian pitch
- CookieFixx — full founding client, build from scratch
- Cecilia Adalynn Photography — GBP setup + redesign
Acceptance Criteria
- At least 4 cold outreach messages sent (Priority A)
- At least 2 friend conversations started
- All outreach logged in tracker
- Outreach channel per prospect: TBD (depends on startersite-029)
- Follow 3-touch cadence from G1 Playbook §6
Context
- Outreach list:
startersite-ai/ops/outreach/outreach-v1.md - Playbook:
startersite-ai/docs/growth/G1-Outreach-Playbook.md
wildus-012
HumanP1
Set retail prices and conservation donation percentage
⌛ wildus-001⌛ wildus-005⌛ wildus-010
Description
Using Printify pricing research (wildus-001), product specs (wildus-005), and the chosen e-commerce platform (wildus-010), set final retail prices and conservation donation percentage.
Acceptance Criteria
- Retail price set for each product type (hoodies, t-shirts, beanies, Junior sweatshirts)
- Conservation donation % decided (per sale or per item flat amount)
- Margin analysis documented: retail price - Printify cost - platform fees - donation = margin
- Break-even estimate (orders/month needed to cover platform fees)
- vault/business/financial-plan.md updated with real numbers
- Pricing shared with Anna for approval
Notes
Decisions
Ready
6
wildus-039
HumanP1
Sign operating agreement — fill remaining blanks and execute
Description
The Wild Us LLC operating agreement has been drafted and is ready for signature at wildus/vault/business/operating-agreement.md (branch viktor/wildus-029). Fill remaining blanks, print, sign with Anna, and store the signed copy.
Acceptance Criteria
- [ ] Fill Anna’s address in signature block
- [ ] Fill principal business address
- [ ] Fill effective date (date of signing)
- [ ] Fill formation date (after LLC is filed — can be filled later)
- [ ] Both Anna and Viktor sign the agreement
- [ ] Signed copy stored (scan in repo or reference to storage location)
Context
- Operating agreement:
wildus/vault/business/operating-agreement.md - Branch:
viktor/wildus-029 - Parties: Anna Delova + Viktor Bering
- Registered agent: Registered Agents Inc. (same as Qoyn AI)
- Attorney review deferred — signing as-is, can amend later
- Blocks wildus-009 (LLC formation)
Dependencies
None — ready to execute.
Notes
- Digital signing options: Can sign digitally instead of printing. Free options:
- DocuSign free tier — 3 signature requests/month, well-known, good for legitimacy
- DocuSeal free cloud tier — 10 signature requests/month, open source. API requires Pro ($20/user/mo) or self-hosting.
- Both are legally binding under ESIGN Act and Washington UETA.
Decisions
wildus-034
HumanP1
Research best launch channel — where to sell + build brand first
Description
Deep research to identify the best primary channel for Wild Us launch — considering both sales and brand/content presence on the same platform.
Wild Us is a digital-first brand with illustrated characters, conservation stories, and video content (Kling AI animations). The ideal launch channel is one where we can sell products AND host our brand content in the same place, so customers discover the brand and buy without leaving the platform.
Channels to Evaluate
- TikTok Shop — short video + native commerce, strong discovery algorithm
- Instagram Shop — visual-first, Reels, shoppable posts
- Pinterest — visual search, high purchase intent, evergreen pins
- Facebook Shop / Marketplace — community groups (Slavic, Latino, PNW outdoors), older demo
- Etsy — marketplace discovery, “PNW gifts” search traffic
- Shopify — own storefront, full brand control, but no built-in discovery
- Any other emerging channels worth considering (e.g., YouTube Shopping, Amazon Handmade)
Research Questions
- Discovery: Which platform gives the best organic reach for a new brand with zero followers?
- Content + commerce integration: Where can brand content (character stories, animations, conservation messaging) and product listings live together most naturally?
- Target audience fit: Where do our 7 audience segments actually shop? (PNW outdoors, Latino community, Slavic expats, Indian diaspora, Asian community, feminist/women’s, tourists)
- POD integration: Which platforms integrate with Printify natively?
- Cost structure: Fees, monthly costs, commission rates for each
- Effort to launch: How much setup work for each? Can we realistically manage multiple at MVP?
- Data ownership: Which platforms let us build an email list / retarget customers?
Acceptance Criteria
- Comparison matrix covering all channels above
- Recommendation: which single channel to launch on first (primary), and which to add second
- Reasoning tied to our specific brand (visual, mission-driven, multicultural, POD)
- Consider whether the e-commerce platform decision (Shopify vs Etsy, wildus-010) is part of this or separate
- Document findings in
wildus/vault/business/or link to research
Context
- Target audiences: [[marketing-strategy]], [[target-audiences]]
- E-commerce comparison (Shopify vs Etsy): [[ecommerce-platform-comparison-shopify-vs-etsy]]
- Social handles registered: Instagram, TikTok, X, Pinterest, Facebook
- This decision may supersede or inform the Shopify vs Etsy platform decision
- Related: wildus-010 (choose ecommerce platform)
wildus-009
HumanP1
File LLC formation (Washington state)
✓ wildus-029
Description
File LLC formation documents with the Washington Secretary of State. This unblocks EIN and business bank account.
Acceptance Criteria
- LLC formation filed with WA Secretary of State ($200 filing fee)
- EIN application submitted to IRS
- Business bank account opened (after EIN received)
- Filing documents stored in qoyn.ai/docs/legal/ (or wildus equivalent)
Notes
Decisions
wildus-035
HumanP2
Set up shared Google Drive folder for art assets
Description
Set up a shared Google Drive folder structure for Wild Us art assets. This is the working asset pipeline for MVP — Anna drops art files, Viktor pulls them for Printify upload.
Acceptance Criteria
- Shared Google Drive folder created under Wild Us Google Workspace
- Folder structure organized by character and status (e.g., concepts, in-progress, print-ready)
- Both Anna and Viktor have edit access
- Existing concept art from
assets/characters/concepts_2026-03-05_batch01/uploaded as reference - Clear naming convention agreed on
Context
- Replaces the planned R2 bucket + media UI for now — Google Drive is sufficient for MVP with 6 characters
- R2 pipeline can be revisited post-launch if volume demands it
- Existing assets: 8 v1 concept images + 8 video animations (Midjourney + Kling AI, March 5)
- MVP needs: 3 adult characters (Fox, Beaver, Grizzly) + 3 baby versions (Fox Cub, Baby Beaver, Bear Cub)
workforce-023
HumanP2
Set up GitHub PAT expiry reminder (expires 2026-06-09)
Description
Add a Google Calendar reminder for GitHub PAT renewal on the Qoyn AI Google Workspace account (viktor@qoyn.ai).
All agents’ GitHub PATs expire 2026-06-09. A cron-based reminder was considered but rejected — the script would run silently for months with no way to verify the notification path actually works when it matters. A calendar reminder is simpler and more reliable for a one-time date-based alert.
Acceptance Criteria
- Google Calendar event on 2026-05-26 (14 days before expiry) titled “Renew GitHub PATs — expire June 9”
- Include in description: all agents (CrankyCrab, PrawnSue, BerryPi, LobsterDrew) share the same expiry date
- Email reminder enabled
- A second reminder event on 2026-06-06 (3 days before) as a final warning
Notes
- All agents share the same PAT expiry date (2026-06-09)
- After renewal, create new calendar reminders for the next expiry cycle
Decisions
startersite-019
AgentP2
Test stale notifier with real WhatsApp conversation
✓ startersite-018
Description
Live end-to-end test of the stale conversation notifier using a real WhatsApp intake conversation. Clear all WhatsApp conversation state from KV first to start fresh, then initiate a real WhatsApp chat, abandon it partway through, and verify the stale notifier picks it up and sends the founder email.
Steps
- Clear all WhatsApp-related conversation keys from Cloudflare KV (use
wrangler kvCLI) - Start a real WhatsApp intake conversation with the bot (send 2+ messages)
- Stop responding and wait for the stale threshold (6 hours, or temporarily lower
STALE_HOURSfor testing) - Trigger
/api/stale-checkmanually via GitHub Actionsworkflow_dispatchor direct HTTP call - Verify founder receives the notification email with full WhatsApp transcript
- Trigger stale check again — confirm no duplicate email is sent
Acceptance Criteria
- WhatsApp KV state is cleared before test begins
- Real WhatsApp conversation triggers stale detection after going idle
- Founder email contains the correct WhatsApp transcript, client info, and collected data
- Dedup prevents a second notification for the same conversation
- KV state is clean and consistent after the test
Context
- Repo:
viktor-bering/startersite-ai - Stale check endpoint:
site/functions/api/stale-check.js - Config:
STALE_HOURSinwrangler.toml - Consider temporarily setting
STALE_HOURSto a low value (e.g., 0.1) for faster testing, then restoring it
Notes
- Document any issues found as new board tasks
In Progress
2
wildus-033
HumanP1
Draft MVP alignment document for launch scope
Description
Create a minimum viable product (MVP) document that defines the launch scope for Wild Us — what’s needed to make the first sale. This is a working alignment tool for Anna and Viktor to agree on scope, not a legal/commitment document (that’s wildus-031).
Acceptance Criteria
- Document created at
wildus/vault/business/mvp.md - Covers: products in/out of scope, art readiness, store platform, pricing, legal minimum, marketing minimum
- Decision checkboxes for items needing co-founder agreement
- Critical path / ordered checklist for launch
- Clear definition of “done” for MVP
- Both co-founders review and align
Context
- Separate from wildus-031 (co-founder deliverables doc) — different purpose
- Co-founder agreement:
wildus/vault/business/cofounder-agreement.md - Launch roadmap:
wildus/vault/business/launch-roadmap.md - Financial plan:
wildus/vault/business/financial-plan.md
Notes
- 2026-03-13 — First draft created by Claude Code. Ready for Viktor + Anna review.
startersite-027
HumanP2
Build preview sites for top outreach prospects
✓ startersite-029
Description
Build preview sites (3 options each) for top-scoring cold prospects from outreach-v1.md. These previews are sent with the first outreach message — not after a response.
Priority A prospects (no website, highest scores):
- Bobby’s Bubbles Pet Grooming (80)
- Vina Ann Nails (79)
- L.A Landscaping Services (72)
- Best Friends Dog Grooming (65)
Use enrichment data (IG content, GBP reviews, Facebook info) to build compelling previews. Spin up client repos from client-template.
Acceptance Criteria
- Client repos created for at least 2-3 Priority A prospects
- 3 site options generated per prospect using FERN pipeline
- Preview sites deployed to CF Pages (dev branch, noindex)
- Outreach method per prospect: TBD (depends on startersite-029)
Context
- Enrichment data:
startersite-ai/ops/outreach/enriched/(tier1–tier3c CSVs) - Outreach list:
startersite-ai/ops/outreach/outreach-v1.md - Scoring:
startersite-ai/ops/outreach/enriched/scores.csv
In Review
1
wildus-001
AgentP1
Research Printify pricing for target products
⌛ wildus-019
Description
Research actual Printify pricing for Wild Us launch products. Compile a comparison table of blanks (brand, cost, available colors, available sizes) for each product type.
Acceptance Criteria
- Comparison table for hoodies: at least 3 blank options (e.g., Gildan 18500, Independent Trading Co., Bella+Canvas) with Printify base cost, available colors, size range
- Comparison table for t-shirts: at least 3 blank options with same details
- Comparison table for beanies: at least 2 options
- Note which Printify fulfillment partners carry each blank
- Include shipping cost estimates (domestic US)
- Recommend one blank per product type based on quality/cost/color availability balance for a mission-driven PNW brand
Context
- Repo: git@github.com:wild-us/wildus.git
- Brand positioning: PNW wildlife conservation, not fast fashion — quality matters
- Base colors needed: beige, mint/sage, gray, black, white
- See vault/product/product-line.md for product details
- See vault/business/financial-plan.md (currently a stub — this research will fill it)
Dependencies
- wildus-019
Notes
- 2026-03-11 05:40 PT — Dispatched to CrankyCrab. Dependency wildus-019 satisfied, repo present on tolbachik.
- 2026-03-11 06:44 PT — CrankyCrab completed Printify catalog research and updated
~/wildus/vault/business/financial-plan.mdwith comparison tables for hoodies, t-shirts, and beanies. Tables now include base-cost ranges, US shipping estimates, size ranges, palette-relevant colors, fulfillment partners, and a recommended blank per product type. Current picks: Independent Trading Co. SS4500 hoodie, Bella+Canvas 3001 tee, AS Colour 1120 beanie (with OTTO 82-480 as the safer beanie cost fallback). - 2026-03-11 06:44 PT — Research source was live Printify US catalog / fulfillment-partner pricing, not generic blog estimates. Main follow-up is sampling, especially for beanie embroidery quality before locking launch SKUs.
- 2026-03-11 17:07 PT — Self-review passed. Moved to done.
Decisions
Done
57
startersite-029
HumanP1
Define outreach channel and strategy per prospect
✓ startersite-006
Description
Determine the outreach channel, message format, and personalized strategy for each prospect in outreach-v1.md. Update the G1 Outreach Playbook to reflect the new approach: previews (3 site options) are sent WITH the first message, not after a response.
Key decisions:
- Which channel for each prospect? (IG DM, FB Messenger, email, phone, text, in-person)
- How to present 3 preview options in the first touch? (link to chooser page? screenshots? video walkthrough?)
- Different strategy for friends vs cold prospects?
- How does the message template change when previews are included upfront?
- Channel-specific constraints (IG DM character limits, email deliverability, FB Messenger auto-replies)
Acceptance Criteria
- G1 Playbook updated: preview-first approach replaces two-step model
- Channel + strategy assigned per prospect in outreach-v1.md
- Message templates updated for preview-first approach
- Any channel-specific constraints documented
Context
- Current playbook uses two-step model (§1): open conversation first, share preview after response
- Enrichment data has best_contact_channel per prospect but needs revisiting
- Outreach list:
startersite-ai/ops/outreach/outreach-v1.md - Scoring:
startersite-ai/ops/outreach/enriched/scores.csv - Enrichment:
startersite-ai/ops/outreach/enriched/(tier1–tier3c)
jobs-001
AgentP1
Fix LinkedIn headline mismatch
Description
LinkedIn headline said “Applied Data Scientist | GenAI Enthusiast” — sounded junior. Updated to match resume’s stronger positioning (Senior Data Scientist / ML Engineer / MLOps).
Resolution
Completed by Viktor manually.
jobs-002
AgentP1
Update "Open to Work" roles and locations
Description
LinkedIn “Open to Work” listed Senior Data Scientist, Machine Learning Engineer, and Data Engineer. Updated to match current targets: Senior Data Scientist, Senior ML Engineer, Senior MLOps Engineer, ML Engineer, AI Engineer. Locations expanded beyond just Vancouver WA.
Resolution
Completed by Viktor manually.
startersite-021
AgentP1
Google Places API sweep — Clark County prospect research
Description
Write and run a Python script that systematically queries the Google Places API (via the goplaces CLI) across all target verticals and geographic areas in Clark County, WA. The goal is to build a comprehensive prospect database of local service businesses for outreach.
This is a data gathering task only — no analysis, scoring, or outreach. Just collect everything the API gives us and store it cleanly.
Setup
Repository
Clone viktor-bering/startersite-ai (private repo, GitHub org: viktor-bering). Work on branch berrypi/startersite-021.
Key locations in the repo
- Config:
tools/outreach/sweep-config.json— already created. Contains all areas, verticals, search queries, and rate-limiting settings. Read this file to drive the sweep. - Script location: Write the sweep script at
tools/outreach/places_sweep.py - Output location:
ops/outreach/— this is where all output CSVs and JSON files go
Tool: goplaces CLI
The goplaces CLI is already installed on klyuchi at /home/linuxbrew/.linuxbrew/bin/goplaces (v0.3.0). Your API key is configured in OpenClaw at skills.entries.goplaces.apiKey.
Set the environment before running:
export PATH=/home/linuxbrew/.linuxbrew/bin:$PATH
export GOOGLE_PLACES_API_KEY=<your key from OpenClaw config>
Key commands you’ll use:
# Text search (returns place_id, name, address, lat/lng, rating, review_count, types)
goplaces search "plumber Vancouver WA" --limit 20 --json
# Paginate (use next_page_token from previous result)
goplaces search "plumber Vancouver WA" --limit 20 --page-token "TOKEN_HERE" --json
# Location-biased search (NOTE: negative longitude needs = syntax)
goplaces search "plumber" --lat 45.6387 --lng="-122.6615" --radius-m 8000 --limit 20 --json
# Place details with reviews + photos (returns phone, website, hours, up to 5 reviews, up to 10 photos)
goplaces details PLACE_ID --reviews --photos --json
Important goplaces behavior:
- Search returns a JSON array of places + a
next_page_tokenline on stdout (not inside the JSON). Parse both. --limit 20is the max per request (API limit).- Details with
--reviews --photosreturns up to 5 most relevant reviews and up to 10 photos per place. - Negative longitude values MUST use
--lng="-122.xxx"syntax (not--lng -122.xxx), otherwise the CLI misparses the negative sign as a flag.
What to build
Script: tools/outreach/places_sweep.py
A Python 3 script (stdlib only — no pip dependencies) that:
- Reads
sweep-config.jsonfor areas, verticals, and settings - Runs a search pass — for each vertical × area combination:
- Constructs a query:
"<search_term> <area_name> WA"(e.g.,"plumber Vancouver WA") - Also does a location-biased search:
goplaces search "<search_term>" --lat <lat> --lng="<lng>" --radius-m <radius> --limit 20 --json - Paginates using
--page-tokenuntil no more results (up tomax_pages_per_queryfrom config) - Waits
delay_between_requests_msbetween requests - Saves raw JSON responses to
ops/outreach/places-raw/<vertical_id>-<area_name>.json - Logs every API call to
ops/outreach/sweep-log.csv
- Constructs a query:
- Deduplicates — collects all unique place_ids across all search results
- Runs a details pass — for each unique place_id:
- Runs
goplaces details <place_id> --reviews --photos --json - Waits
delay_between_details_msbetween requests - Saves the full details JSON to
ops/outreach/details-raw/<place_id>.json
- Runs
- Generates CSV output — merges search + details data into CSVs
Search strategy
For each vertical, use location-biased search (not text-appended city names). This is more reliable for the API:
For each vertical:
For each query in vertical.queries:
For each area in areas:
goplaces search "<query>" --lat <area.lat> --lng="<area.lng>" --radius-m <area.radius_m> --limit 20 --json
→ paginate if next_page_token exists (up to max_pages_per_query)
→ collect results
This means for a vertical with 2 queries across 10 areas, you’ll make 20+ search calls. The config has ~40 total queries across all verticals × 10 areas = ~400 search calls. With 500ms delay, that’s ~3-4 minutes for the search pass.
Output structure
ops/outreach/
├── places-raw/ # Raw search responses (JSON)
│ ├── plumbing-Vancouver-p1.json
│ ├── plumbing-Vancouver-p2.json (if paginated)
│ ├── plumbing-Salmon_Creek-p1.json
│ └── ...
├── details-raw/ # Raw details responses (JSON), one per place
│ ├── ChIJq6qqqsaklVQRGC4CkmlH9pE.json
│ └── ...
├── prospects/ # Processed CSVs, one per vertical
│ ├── plumbing.csv
│ ├── landscaping.csv
│ └── ...
├── prospects-all.csv # Combined, deduplicated, all verticals
├── reviews/ # Review text, one JSON file per place
│ ├── ChIJq6qqqsaklVQRGC4CkmlH9pE.json
│ └── ...
├── sweep-log.csv # Log of all API calls
└── sweep-summary.json # Summary stats (total places, by vertical, by area)
CSV schema for prospect files
The CSV files in prospects/ and prospects-all.csv must have these columns:
place_id,name,vertical_id,market,address,city,state,lat,lng,rating,review_count,has_website,website_url,phone,business_status,primary_type,types,google_maps_url,hours_summary,photo_count,photo_references,review_1_rating,review_1_text,review_1_author,review_1_date,review_2_rating,review_2_text,review_2_author,review_2_date,review_3_rating,review_3_text,review_3_author,review_3_date,review_4_rating,review_4_text,review_4_author,review_4_date,review_5_rating,review_5_text,review_5_author,review_5_date,sweep_date,search_query,area
Column details:
place_id— Google place ID (primary key for deduplication)name— business namevertical_id— from sweep-config (e.g., “plumbing”, “ru-auto-detailing”)market— “english” or “russian_market” (from which vertical group it came from)address— full formatted addresscity— extracted city from address (parse from formatted address)state— always “WA” for our sweeplat,lng— coordinatesrating— Google rating (0-5, one decimal)review_count— total number of reviewshas_website— “yes” or “no”website_url— URL or emptyphone— phone number or emptybusiness_status— from API (OPERATIONAL, CLOSED_TEMPORARILY, etc.)primary_type— from APItypes— semicolon-separated list of all typesgoogle_maps_url— link to Google Maps listinghours_summary— pipe-separated hours string (e.g., “Mon: 8AM-5PM|Tue: 8AM-5PM|…”)photo_count— number of photos returned by detailsphoto_references— semicolon-separated list of photonamefields from the API (e.g.,places/ChIJ.../photos/ATCDNf...;places/ChIJ.../photos/ATCDNf...). These can be used to fetch actual photo URLs via the Places Photos API later.review_N_rating— rating of Nth review (1-5)review_N_text— full text of Nth review (escape commas and newlines for CSV)review_N_author— author display namereview_N_date— publish_time ISO datesweep_date— ISO date of when the sweep was runsearch_query— the query string that found this placearea— area name from config (e.g., “Vancouver”, “Camas”)
Important CSV handling:
- Use proper CSV escaping — double-quote fields that contain commas, newlines, or quotes
- Review text often contains commas, newlines, and quotes — these MUST be properly escaped
- If a place appears in multiple verticals or areas, keep only the first occurrence in
prospects-all.csv(deduplicate by place_id). In per-vertical CSVs, a place can appear in multiple vertical files if it was found under multiple verticals.
Sweep log CSV
timestamp,action,query,area,vertical_id,page,result_count,next_page_token_exists,place_id,error
Log every API call (search and details) with timestamp, what was queried, and the result count. If an API call fails, log the error and continue (don’t abort the whole sweep).
Sweep summary JSON
After the sweep completes, generate sweep-summary.json:
{
"sweep_date": "2026-03-14",
"total_search_calls": 420,
"total_detail_calls": 650,
"total_unique_places": 650,
"total_places_no_website": 180,
"by_vertical": {
"plumbing": { "total": 85, "no_website": 12 },
...
},
"by_area": {
"Vancouver": { "total": 200, "no_website": 45 },
...
},
"errors": []
}
Resumability
The script should be resumable. If it crashes or is interrupted:
- Before making a search call, check if
places-raw/<filename>.jsonalready exists. If yes, skip it and load from file. - Before making a details call, check if
details-raw/<place_id>.jsonalready exists. If yes, skip it and load from file. - This means you can safely re-run the script and it will pick up where it left off.
Error handling
- If a
goplacescall fails (non-zero exit, malformed JSON), log the error insweep-log.csvand continue with the next query/place. - If the API returns an empty result set for a query, that’s fine — log it and move on.
- At the end, report total errors in
sweep-summary.json.
Implementation notes
- Use
subprocess.run()to rungoplacescommands. Capture stdout and parse as JSON. - The
next_page_tokenis printed on a separate line after the JSON array ingoplaces searchoutput. You need to parse it separately — it’s NOT inside the JSON. The format is:next_page_token: <TOKEN>. If this line is absent, there are no more pages. - Use
os.makedirs(path, exist_ok=True)to create output directories. - Use Python’s
csvmodule for CSV writing (handles escaping correctly). - Use only stdlib modules:
subprocess,json,csv,os,sys,time,argparse,pathlib,datetime. - The script should be runnable with:
python3 tools/outreach/places_sweep.py - Print progress to stdout:
[search] plumbing / Vancouver (page 1) — 20 resultsand[details] 142/650 — Service Pro Plumbing Inc - At the end, print the summary stats.
Testing
Before running the full sweep, test with a single vertical + single area:
python3 tools/outreach/places_sweep.py --test
The --test flag should run only the first vertical’s first query in the first area (1 search + details for results). Verify:
- Raw JSON files are saved correctly
- CSV output is well-formed (open in a spreadsheet)
- Reviews with commas/newlines don’t break CSV
- Sweep log captures the calls
- Resumability works (re-run and verify it skips existing files)
Acceptance Criteria
- [ ]
tools/outreach/places_sweep.pyexists and runs withpython3 tools/outreach/places_sweep.py - [ ]
--testflag works for single-query dry run - [ ] Full sweep completes without crashing (errors logged, not thrown)
- [ ]
ops/outreach/places-raw/contains raw search JSON files - [ ]
ops/outreach/details-raw/contains raw detail JSON files for each unique place - [ ]
ops/outreach/prospects/contains one CSV per vertical with all columns populated - [ ]
ops/outreach/prospects-all.csvcontains deduplicated combined data - [ ]
ops/outreach/reviews/contains review JSON files per place - [ ]
ops/outreach/sweep-log.csvlogs all API calls - [ ]
ops/outreach/sweep-summary.jsonhas aggregate stats - [ ] CSV files open correctly in a spreadsheet (proper escaping)
- [ ] Script is resumable (re-run skips existing files)
- [ ] Commit script + config to
berrypi/startersite-021branch, push to origin
Context
- Outreach playbook:
docs/growth/G1-outreach-playbook.md(§2 Research Pipeline) - This is Phase 1 of the research pipeline — data gathering only
- The data will be used later for manual enrichment (Phase 2) and scoring (Phase 3)
- All output data (CSVs, raw JSON) is committed to git — it’s all public Google Maps data
Notes
-
2026-03-15T03:10:57Z — FAILED: Agent did not output a JSON report — No structured report found in agent output
-
2026-03-15T02:41:24Z — FAILED: Agent did not output a JSON report — No structured report found in agent output
-
2026-03-14T22:36:40Z — FAILED: Agent did not output a JSON report — No structured report found in agent output
-
2026-03-14 — Sweep completed successfully (1,576 places found). Data validated by Viktor.
-
2026-03-14 — Bounding box filter added, but INCOMPLETE. The filter only checks lat/lng bounding box. It does NOT check the address for ", WA ". Result: 123 Oregon businesses (Portland, St Helens, Troutdale, Gresham) are still in the data because they fall within the lat/lng box (they’re just across the river). This MUST be fixed.
Remaining work — KICKED BACK
The geographic filter is incomplete. You added the bounding box check but missed the second condition. The filter must use BOTH:
- Bounding box from
sweep-config.json(field:bounding_box) — ✅ done - Address string must contain ", WA " (case-sensitive, with comma and spaces) — ❌ NOT DONE
Current state of the data:
prospects-all.csvhas 1,201 rows but 123 are Oregon (Portland: 76, St Helens: 28, Troutdale: 14, etc.)- After the ", WA " filter is applied, expect ~1,078 rows with ~210 no-website
What to do:
- Open
tools/outreach/places_sweep.py - Find the bounding box filter code
- Add a second condition:
", WA " in address(check theaddressfield from the details JSON) - Re-run the script (it will skip all API calls due to resumability, just regenerate CSVs)
- Verify:
prospects-all.csvshould have ZERO rows where the address contains Oregon cities - Update
sweep-summary.jsonwith filtered counts - Commit and push
- Commit everything to git — script, config, AND all output data (CSVs, raw JSON). This is all public Google Maps data, not private.
- The
sweep-config.jsonhas thebounding_boxfield. The ", WA " check is a hardcoded string match, not config-driven. - Russian-language queries (e.g., “детейлинг”) should work fine with
goplaces search— the API handles Unicode.
wildus-036
AgentP1
Move all R2 bucket files to shared folder with BerryPi
Description
Move all files from the wildus-media R2 bucket to the shared folder at /home/shared/ so BerryPi can also access them.
Instructions
- Use rclone (already configured) to copy all files from R2 to the shared folder:
rclone copy wildus-media:wildus-media /home/shared/wildus-media/ --progress - Verify the file counts and sizes match between R2 and the local copy
- Preserve the existing directory structure (e.g.,
discord/animation-video/...) - Do NOT delete the files from R2 — this is a copy, not a move
Acceptance Criteria
- All files from
wildus-mediaR2 bucket are copied to/home/shared/wildus-media/ - Directory structure is preserved
- File counts match between source and destination
- Files in
/home/shared/are group-writable (they should be automatically via setgid) - R2 originals are still intact
wildus-037
AgentP1
Upload media assets to Google Drive
Description
Upload the wildus media files from the shared folder to Google Drive, organized under wildus/media-assets/.
Prerequisites
- wildus-036 is complete — files are in
/home/shared/wildus-media/
Instructions
Use gog CLI (installed at /home/linuxbrew/.linuxbrew/bin/gog) with account viktor@qoyn.ai for all Google Drive operations.
- Create folder structure in Viktor’s Google Drive:
wildus/media-assets/gog drive mkdir wildus -a viktor@qoyn.ai gog drive mkdir media-assets --parent <wildus-folder-id> -a viktor@qoyn.ai - Upload all files from
/home/shared/wildus-media/intowildus/media-assets/, preserving the directory structure - Share the
wildusfolder withanna@qoyn.ai(editor access)gog drive share <wildus-folder-id> --email anna@qoyn.ai --role writer -a viktor@qoyn.ai- If sharing fails programmatically, that’s fine — just note it in your report so Viktor can share manually. This is non-blocking.
- Verify upload completed and file counts match (116 files expected)
Acceptance Criteria
wildus/media-assets/folder exists in Viktor’s Google Drive- All files from
/home/shared/wildus-media/are uploaded with directory structure preserved - Sharing with
anna@qoyn.aieither done or flagged for Viktor to do manually
wildus-015
AgentP1
Register TikTok account for Wild Us
✓ wildus-003✓ wildus-016✓ workforce-015✓ workforce-016
Description
Create the Wild Us TikTok account. Registration priority #2 — @wildus status on TikTok is inconclusive (occupied with 0 likes, may be reclaimable); @wild.us needs live verification. High competition platform — register soon.
After registration, document the signup flow so we have a playbook for future brands on this platform.
Acceptance Criteria
- TikTok account created with handle (per checklist fallback order:
@wildus→@wild.us→@wildus_official→@wildusbrand) - Bio drafted and set
- 2FA enabled (2-step verification)
- Recovery codes saved
- vault/brand/claimed-handles.md updated
- Signup flow documented — write up what happened in the task notes: fields per step, verification gates, anti-bot measures, profile setup options, quirks
Context
@wilduson TikTok: occupied (569 following, 78 followers, 0 likes, no bio) — may be dormant@wildusbrandappears open- Signup email:
tiktok@wildus.org(Google Workspace alias → viktor@qoyn.ai) - Google SSO or native signup both viable
- See vault/brand/social-handle-registration-checklist.md
Default Data
| Field | Value |
|---|---|
| Signup email | tiktok@wildus.org |
| Display name | Wild Us |
| Handle (in order) | @wildus → @wild.us → @wildus_official → @wildusbrand |
| DOB (if required) | 01/01/2000 |
| Bio | Wild and unbothered 🌲 PNW wildlife apparel with a conservation mission. Coming soon → wildus.org |
| Profile picture | Check wildus/site/ or wildus/assets/ for a placeholder |
Lessons from X/Twitter Registration
See the X/Twitter playbook for the full writeup.
These lessons apply to all platform registrations:
- One attempt only. Multiple retries create partial accounts, reserve handles in limbo, and trigger rate limits that block you for hours. If the first attempt fails, stop and notify Viktor — do not retry.
- Handle may be auto-assigned. Some platforms assign a random handle during signup and require you to change it post-signup. If the platform doesn’t offer a handle field during signup, note what was assigned and move on to post-signup settings.
- Anti-bot measures block automated browsers. CAPTCHAs, Arkose, and blank spinners can appear at any point. If you hit one, immediately hand off to Viktor via
notify-viktor+wait-for-viktor. Do not try to solve or bypass it. - Viktor handles sensitive steps. Verification codes, password entry, and handle changes are best done by Viktor via Screen Sharing. The agent’s role is to fill the initial form and set up the profile afterwards.
Steps
- Open a clean browser session (no existing TikTok cookies)
- Navigate to https://www.tiktok.com/signup
- Fill in the form using the default data above
- At any verification gate (email code, CAPTCHA, phone):
- Run
notify-viktor "<what you need>"— sends Telegram with Screen Share button - Run
wait-for-viktor— blocks until Viktor connects, handles it, and disconnects - Resume once
wait-for-viktorreturns
- Run
- Set username: try
@wildusfirst. If taken, try@wild.us→@wildus_official→@wildusbrand- Note: If TikTok auto-assigns a handle, change it in profile settings after account creation
- Complete any profile setup steps (bio, avatar, interests — skip what’s skippable, fill in what’s useful)
- Enable 2FA (2-step verification)
- Save recovery codes
- Update
vault/brand/claimed-handles.mdwith the claimed handle, email, date, and status - If anything goes wrong — STOP. Do not retry. Notify Viktor and wait for instructions.
After Registration — Document the Flow
Write up the signup experience in the task notes using the format from the social handle registration process.
If You Get Stuck
If you hit a blocker that requires human input (CAPTCHA, phone verification, manual confirmation, email verification code):
- Run
notify-viktor "<description of what you need>"— this sends a Telegram message with a Screen Share button - Run
wait-for-viktor— blocks until Viktor connects via Screen Sharing, handles the gate, and disconnects - Once
wait-for-viktorreturns, resume your work - Fallback: If
wait-for-viktoris not available or times out, poll the page state every 5 seconds — watch for changes - Do NOT retry aggressively — one calm attempt, then notify and wait
Dependencies
wildus-003 (handle checklist — done), wildus-016 (X registration — do X first to secure @wildus)
Notes
- 2026-03-12 — Reprioritized to #2 after X. Google Workspace on qoyn.ai replaces the Gmail anchor strategy.
- 2026-03-13 — Merged with single-pass approach. No separate recon — document the flow as a byproduct of registration.
- 2026-03-13 — Viktor registered manually. Handle:
@wildus_official(@wildusand@wild.usboth taken). Bio:Wild and unbothered 🌲 PNW apparel with a conservation mission. soon→ wildus.org(80 char limit). 2FA enabled: phone + Google Authenticator + email. Email:tiktok@wildus.org.
Decisions
wildus-016
AgentP1
Register X/Twitter account for Wild Us
✓ wildus-003✓ workforce-015✓ workforce-016
Description
Create the Wild Us X/Twitter account. This is the #1 registration priority — @wildus appears available on X (public check: “This account doesn’t exist”). This is the only major platform where the primary handle is still open.
After registration, document the signup flow (fields, gates, quirks) so we have a playbook for future brands on this platform.
Acceptance Criteria
- X account created with handle (per checklist fallback order:
@wildus→@wild_us→@wildus_official→@wildusbrand) - Bio drafted and set
- 2FA enabled (authenticator app preferred)
- Recovery codes saved
- vault/brand/claimed-handles.md updated
- Signup flow documented — write up what happened in the task notes: fields per step, verification gates, anti-bot measures, profile setup options, quirks
Context
@wildusis available on X — claim ASAP before someone else takes it- X doesn’t support dot format —
wild.usis invalid here - Signup email:
x@wildus.org(Google Workspace alias → viktor@qoyn.ai) - Native email signup preferred (no SSO dependency)
- See vault/brand/social-handle-registration-checklist.md
Default Data
| Field | Value |
|---|---|
| Signup email | x@wildus.org |
| Display name | Wild Us |
| Handle (in order) | @wildus → @wild_us → @wildus_official → @wildusbrand |
| DOB (if required) | 01/01/2000 |
| Bio | Wild and unbothered 🌲 PNW wildlife apparel with a conservation mission. Coming soon → wildus.org |
| Profile picture | Check wildus/site/ or wildus/assets/ for a placeholder |
| Signup path | Native email (not Google/Apple SSO) |
Steps
- Open a clean browser session (no existing X cookies)
- Navigate to https://x.com/i/flow/signup
- Choose email signup (not Google/Apple SSO)
- Fill in the form using the default data above
- At any verification gate (email code, CAPTCHA, phone):
- Run
notify-viktor "<what you need>"— sends Telegram with Screen Share button - Run
wait-for-viktor— blocks until Viktor connects, handles it, and disconnects - Resume once
wait-for-viktorreturns
- Run
- Set username: try
@wildusfirst. If taken, try@wild_us→@wildus_official→@wildusbrand - Complete any profile setup steps (bio, avatar, interests — skip what’s skippable, fill in what’s useful)
- Enable 2FA (authenticator app preferred)
- Save recovery codes
- Update
vault/brand/claimed-handles.mdwith the claimed handle, email, date, and status
After Registration — Document the Flow
Write up the signup experience in the task notes so we can reuse it:
### Signup Flow Report
- Signup path taken: (email / Google SSO / Apple)
- Total steps: N
### Step 1 — [Screen Title]
| Field | Type | Required | Constraints | Notes |
|---|---|---|---|---|
| ... | ... | ... | ... | ... |
### Verification Gates
- Email code: yes/no
- Phone: yes/no
- CAPTCHA: yes/no
- Other: ...
### Anti-Bot Measures
- ...
### Post-Signup Profile Fields
- (what was available to set immediately after account creation)
### Quirks
- (anything unexpected)
If You Get Stuck
If you hit a blocker that requires human input (CAPTCHA, phone verification, manual confirmation, email verification code):
- Run
notify-viktor "<description of what you need>"— this sends a Telegram message with a Screen Share button - Run
wait-for-viktor— blocks until Viktor connects via Screen Sharing, handles the gate, and disconnects - Once
wait-for-viktorreturns, resume your work - Fallback: If
wait-for-viktoris not available or times out, poll the page state every 5 seconds — watch for changes - Do NOT retry aggressively — one calm attempt, then notify and wait
Dependencies
wildus-003 (handle checklist — done)
Notes
- 2026-03-12 — Reprioritized to #1. Only major platform where
@wildusis still available. Google Workspace on qoyn.ai replaces the Gmail anchor strategy. - 2026-03-13 — Absorbed wildus-029 (recon). No separate recon pass — go straight to registration, document the flow afterwards.
- 2026-03-13 — Account created with
x@wildus.orgafter multiple CrankyCrab attempts. X auto-assigned handle@wildus18890instead of@wildus. Multiple retries triggered X rate limiting. Viktor logged in successfully but cannot change handle yet — “rate limited, please try again later.”@wildusshows “this account doesn’t exist” publicly but X won’t assign it — likely held in limbo from partial signup attempts. - 2026-03-13 — Viktor registered manually. Handle
@wildus14696(auto-assigned). DOB on file: 09/25/1984. Still rate-limited, cannot change handle.@wildusappears taken/held — likely on a release timer from prior partial signups. Handle change deferred to wildus-032. - 2026-03-13 — 2FA enabled (Google Authenticator). Bio set.
Decisions
- Recon phase dropped — standard signup forms don’t need a pre-pass. Document the flow as a byproduct of the first real registration.
- Lesson learned: limit agent to one attempt per dispatch. Multiple retries burned X rate limits and created a partial account with a junk handle.
workforce-015
HumanP1
Deploy notify-viktor and wait-for-viktor scripts to tolbachik
Description
Create and deploy notification and synchronization scripts on tolbachik (CrankyCrab’s machine):
notify-viktor— Sends a Telegram message to Viktor when CrankyCrab hits a blocker. ✅ Done.wait-for-viktor— Blocks until Viktor connects via Screen Sharing, does his work, and disconnects. Detects VNC session on port 5900. ✅ Done.
Together these form the human-in-the-loop protocol: agent notifies → Viktor connects → agent detects connection and waits → Viktor disconnects → agent resumes.
Acceptance Criteria
notify-viktor ✅
- Script
notify-viktorexists on tolbachik at/usr/local/bin/notify-viktor - Usage:
notify-viktor "message text"— sends a Telegram message to Viktor’s chat - Uses BerryPi’s Telegram bot token via Telegram Bot API
- Sends to Viktor’s Telegram user ID (1291467684)
- Message format includes: agent name (CrankyCrab), machine (tolbachik), timestamp, and the message text
- Message includes inline “Screen Share” button linking to
https://connect.qoyn.ai/tolbachik - Script is executable by the
r2d22user - Tested end-to-end: message delivered to Viktor’s Telegram
wait-for-viktor (new)
- Script
wait-for-viktorexists on tolbachik at/usr/local/bin/wait-for-viktor - Detects active Screen Sharing (VNC) connections by checking port 5900 for ESTABLISHED connections
- Flow:
- Poll until a VNC connection is detected (Viktor connected)
- Poll until the VNC connection drops (Viktor disconnected = “I’m done”)
- Exit successfully — agent resumes
- Configurable poll interval (default: 5 seconds)
- Timeout after 30 minutes with non-zero exit if no connection arrives
- Prints status messages so the agent knows what’s happening:
Waiting for Viktor to connect via Screen Sharing...Viktor connected. Waiting for him to finish...Viktor disconnected. Resuming.
- Executable by
r2d22user
Implementation
notify-viktor (deployed)
#!/bin/bash
# notify-viktor — send a Telegram message to Viktor from CrankyCrab
# Uses BerryPi bot as relay. Deployed as part of workforce-015.
BOT_TOKEN="<telegram-bot-token>"
CHAT_ID="1291467684"
if [ -z "$1" ] && [ -t 0 ]; then
echo "Usage: notify-viktor <message>" >&2
exit 1
fi
MSG="${*:-$(cat)}"
TEXT="🦀 *CrankyCrab* (tolbachik) — $(date "+%Y-%m-%d %H:%M:%S %Z")
${MSG}"
KEYBOARD="{\"inline_keyboard\":[[{\"text\":\"🖥 Screen Share\",\"url\":\"https://connect.qoyn.ai/tolbachik\"}]]}"
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-d chat_id="${CHAT_ID}" \
-d text="${TEXT}" \
-d parse_mode="Markdown" \
-d reply_markup="${KEYBOARD}" > /dev/null 2>&1
if [ $? -eq 0 ]; then
echo "Notification sent to Viktor."
else
echo "Failed to send notification." >&2
exit 1
fi
wait-for-viktor (deployed)
#!/bin/bash
# wait-for-viktor — wait for Viktor to connect via Screen Sharing, do his work, and disconnect
# Detects VNC sessions on port 5900. Deployed as part of workforce-015.
POLL_INTERVAL="${1:-5}" # seconds between checks (default: 5)
TIMEOUT=1800 # 30 minutes max wait
elapsed=0
# Phase 1: Wait for Viktor to connect
echo "Waiting for Viktor to connect via Screen Sharing..."
while true; do
if netstat -an | grep '\.5900 ' | grep -q ESTABLISHED; then
echo "Viktor connected. Waiting for him to finish..."
break
fi
sleep "$POLL_INTERVAL"
elapsed=$((elapsed + POLL_INTERVAL))
if [ "$elapsed" -ge "$TIMEOUT" ]; then
echo "Timed out waiting for Screen Sharing connection." >&2
exit 1
fi
done
# Phase 2: Wait for Viktor to disconnect
while true; do
if ! netstat -an | grep '\.5900 ' | grep -q ESTABLISHED; then
echo "Viktor disconnected. Resuming."
break
fi
sleep "$POLL_INTERVAL"
done
Usage Pattern (for agent tasks)
# 1. Hit a gate — notify and wait
notify-viktor "Need email verification code entered for X signup"
wait-for-viktor
# 2. Agent resumes automatically after Viktor disconnects
Context
- CrankyCrab runs as user
r2d22on tolbachik (2018 MBP, macOS) - Screen Sharing (VNC) runs on port 5900, enabled via Remote Management (workforce-016)
- Tailscale VNC URL:
vnc://100.107.199.18 - connect.qoyn.ai/tolbachik redirects HTTPS → VNC for Telegram button
- This is a prerequisite for all social handle registration tasks (wildus-013 through wildus-018)
Notes
- 2026-03-12 —
notify-viktordeployed to/usr/local/bin/notify-viktoron tolbachik. Uses BerryPi’s bot (huckleberrypi_bot). Tested end-to-end. - 2026-03-12 — Reopened to add
wait-for-viktorscript. VNC disconnect = “Viktor is done” signal, cleaner than page-state polling alone. - 2026-03-13 —
wait-for-viktordeployed to/usr/local/bin/wait-for-viktoron tolbachik. Verified netstat pattern detects VNC ESTABLISHED connections on port 5900. Both scripts complete. - CrankyCrab’s old Telegram bot was deleted; token scrubbed.
Decisions
- Reuse BerryPi’s Telegram bot rather than creating a new one — fewer bots to manage, Viktor already has a chat with it.
- VNC disconnect as “done” signal — more reliable than page-state polling. Page-state polling remains as a fallback in task instructions (in case Viktor fixes something without VNC).
workforce-016
HumanP1
Enable macOS Screen Sharing on tolbachik over Tailscale
Description
Enable macOS Screen Sharing on tolbachik so Viktor can remotely view and control CrankyCrab’s browser session. Access should work over Tailscale so it’s reachable from anywhere, not just the local network.
Acceptance Criteria
- macOS Screen Sharing enabled on tolbachik (System Settings → General → Sharing → Screen Sharing)
- Access restricted to Viktor’s user or a specific VNC password
- Reachable via Tailscale IP (tolbachik’s Tailscale address)
- Tested end-to-end: Viktor can connect from avacha using
vnc://or the macOS Screen Sharing app and see/control tolbachik’s desktop - CrankyCrab’s browser sessions are visible when connected
Implementation
On tolbachik:
- System Settings → General → Sharing → Screen Sharing → Enable
- Set access to “Only these users” or set a VNC password
- Verify Tailscale is running and note the Tailscale IP
- From avacha: open Finder → Go → Connect to Server →
vnc://<tolbachik-tailscale-ip>or use Screen Sharing app
Context
- Tolbachik already has Tailscale installed (workforce-008, done)
- tolbachik is a 2018 MBP running macOS 15.7, user: r2d22
- This enables Viktor to intervene during browser-based tasks when CrankyCrab hits CAPTCHAs, phone verification, etc.
- Combined with notify-viktor (workforce-015), this gives a complete notification + intervention loop
Notes
- 2026-03-12 — Remote Management enabled on tolbachik (via SSH kickstart + GUI toggle). Screen Sharing grayed out because Remote Management subsumes it.
- Tailscale IP:
100.107.199.18. VNC URL:vnc://100.107.199.18. User: r2d22 (CrankyCrab). - Tested end-to-end from avacha — full desktop control confirmed.
- notify-viktor script (workforce-015) updated to include clickable VNC link in Telegram messages.
Decisions
- Used Remote Management instead of plain Screen Sharing — provides observe + control for all users, manageable via SSH.
wildus-029
HumanP1
Finalize co-founder agreement — resolve open sections and sign
Description
Operating agreement for Wild Us LLC has been drafted at wildus/vault/business/operating-agreement.md, built from the LLC University WA template + all co-founder agreed terms. All open sections have been resolved and both co-founders are aligned.
Attorney review has been deferred — agreement will be signed as-is and amended later if needed.
Acceptance Criteria
- [x] All open sections resolved and written into the agreement
- [x] Operating agreement drafted from legal template (LLC University WA member-managed)
- [ ] Fill remaining blanks (registered agent, principal address, member addresses)
- [ ] Clarify forfeited equity disposition in vesting section
- [ ] Remove draft meta-commentary from document header
- [ ] Agreement signed by both parties (Anna and Viktor)
- [ ] Signed copy stored in repo (or reference to signed legal doc location)
Context
- Operating agreement:
wildus/vault/business/operating-agreement.md - Original term sheet:
wildus/vault/business/cofounder-agreement.md - Supporting docs:
wildus/vault/business/roles.md,wildus/vault/business/legal-checklist.md - Parties: Anna Delova (Creative Director / Co-founder) and Viktor Potapenko (Operations & Technical Lead / Co-founder)
- Attorney review deferred — sign now, formalize later as business grows
- Blocks wildus-009 (LLC formation)
Dependencies
None — this should be done first, before LLC formation.
Notes
- 2026-03-14: Operating agreement drafted from LLC University template. Attorney review deferred per Viktor’s decision. Remaining items: fill blanks (registered agent, addresses), clarify forfeited equity, remove draft header, then sign.
Decisions
- Attorney review deferred — will sign operating agreement as-is and amend later if needed. Rationale: low risk at current stage, all terms agreed, business is pre-revenue.
workforce-013
42mAgentP1
Generate classic PATs and auth gh CLI for remaining agents
Description
Generate GitHub classic PATs and authenticate gh CLI for PrawnSue, BerryPi, and LobsterDrew. CrankyCrab is already done.
Steps
1. Generate classic PATs (on github.com)
Log into each bot account and create a classic PAT:
- Settings > Developer settings > Personal access tokens > Tokens (classic)
- Note:
workforce-gh-cli - Expiration: 90 days
- Scope:
repo(check the top-level box)
| Agent | Bot Account | Generate PAT |
|---|---|---|
| PrawnSue | (check account — SSH key exists) | Yes |
| BerryPi | berrypi-bot | Yes |
| LobsterDrew | lobsterdrew-bot | Yes |
2. Auth on each machine
# karymsky (PrawnSue)
ssh prawnsue 'echo "<PAT>" | gh auth login --with-token'
ssh prawnsue 'gh auth status'
# klyuchi (BerryPi)
ssh berrypi 'echo "<PAT>" | gh auth login --with-token'
ssh berrypi 'gh auth status'
# klyuchi (LobsterDrew)
ssh lobsterdrew 'echo "<PAT>" | gh auth login --with-token'
ssh lobsterdrew 'gh auth status'
3. Verify
# Each agent should show logged in:
ssh prawnsue 'gh auth status'
ssh berrypi 'gh auth status'
ssh lobsterdrew 'gh auth status'
Context
ghCLI is already installed on all machines (tolbachik v2.88.0, karymsky v2.46.0, klyuchi v2.46.0)- CrankyCrab (tolbachik) already authed as crankycrab-bot
- Classic PATs chosen over fine-grained because fine-grained PATs scope to a single resource owner (org), and agents need cross-org access
- LobsterDrew only needs access to
wild-us/*repos but classic PAT withreposcope is simplest
Acceptance Criteria
gh auth statussucceeds on karymsky, klyuchi (berrypi), and klyuchi (lobsterdrew)- Each shows the correct bot account
wildus-030
16h 49mAgentP1
Interview Anna on co-founder agreement — kick off thread
Description
Viktor has been interviewed on all open sections of the co-founder agreement (wildus/vault/business/cofounder-agreement.md). His choices are recorded with [x] checkmarks. Anna’s choices are listed with empty [ ] checkboxes under “Anna’s choices” in each section.
LobsterDrew should kick off an interview thread with Anna on Discord to walk her through each decision point. This task only covers the kickoff — the ongoing conversation will be handled naturally by the bot as Anna replies.
What to do
- Read the agreement file (
wildus/vault/business/cofounder-agreement.md) to understand all decision points and Viktor’s choices. - Create a thread in the #formalities Discord channel for the interview.
- Post an opening message explaining the process:
- We need to go through the co-founder agreement section by section
- For each decision point, you’ll explain the options in simple terms
- Anna can ask questions before answering — this is a conversation, not a quiz
- List the sections to cover so Anna knows the scope
- Ask the first question (Section 3 — Deadlock resolution). Explain the options clearly, mention what Viktor chose, and invite Anna to share her preference or ask questions.
- Report success and exit.
Interview style
- Conversational, not polls. Ask questions naturally and let Anna respond in her own words. One question at a time.
- Anna can ask follow-up questions before answering — explain further if needed.
- Share Viktor’s choices and reasoning when relevant so Anna has full context.
- If Anna disagrees with Viktor on any point, that’s fine — note it and move on. Disagreements will be reconciled later.
- Keep it friendly and low-pressure. This is a co-founder discussion, not a legal deposition.
Sections to cover (for reference in the opening message)
- Section 3 — Deadlock resolution (approach + AI mediation details + binding vs advisory)
- Section 5 — Compensation (salary trigger + payment mechanism + reinvestment policy)
- Section 7 — Exit / Departure (buyout valuation + payment terms + involuntary removal + for-cause definition + non-compete)
- Section 8 — Dissolution (remaining assets + brand/IP)
- Section 9 — Other provisions (time commitment + outside projects + drag-along/tag-along + capital calls)
Acceptance criteria
- Thread created in #formalities
- Opening message posted with scope overview
- First question asked (Section 3 — Deadlock resolution)
- Task reported as success after kickoff
The bot will continue the conversation naturally as Anna replies. Viktor will monitor progress and move this task to done when all sections are covered.
Context
- Agreement location:
wildus/vault/business/cofounder-agreement.md - Viktor’s interview branch:
viktor/wildus-029(merged to dev) - This task blocks finalizing wildus-029 (signing the agreement)
- This is the last blocker before LLC registration. Make sure Anna understands the importance — once we finalize this agreement, we can register the company.
wildus-003
AgentP1
Prepare social handle registration checklist
⌛ wildus-019
Description
Create a comprehensive checklist for registering Wild Us social handles across all target platforms. Include fallback name options per platform based on current availability research.
Acceptance Criteria
- Checklist covering: Instagram, TikTok, YouTube, X/Twitter, Pinterest, Facebook, Etsy, Shopify
- For each platform: preferred handle (
@wildus), fallback 1 (@wild.usor@wild_us), fallback 2 (@wildus_official), fallback 3 (@wildusbrand) - Note any platforms where
@wildusis already taken and by whom (active account? dormant?) - Document the dependency-first registration strategy: anchor Google/email first → SSO spokes
- Include the Google anti-abuse gate workaround options (alternative phone, timing, Google support)
- Include 2FA setup checklist for each platform
- Reference existing progress from vault/brand/claimed-handles.md
Context
- Repo: git@github.com:wild-us/wildus.git
- Previous attempt (March 7) hit Google anti-abuse phone verification gate
- See vault/brand/claimed-handles.md for current state
- See vault/brand/brand-name-status.md for domain/handle strategy
Dependencies
- wildus-019
Notes
- 2026-03-11 09:55 PT — Dispatched to CrankyCrab. Dependency wildus-019 done, repo and vault files present on tolbachik.
- 2026-03-11 11:03 PT — CrankyCrab completed: added
vault/brand/social-handle-registration-checklist.mdwith dependency-first signup flow, Google anti-abuse workaround options, per-platform fallback handle order, current public availability notes, and 2FA/hardening checklists. Pushed to wild-us/wildus on main (96bb6ed). - 2026-03-11 11:09 PT — PrawnSue also completed a checklist pass, adding
vault/brand/social-handle-registration-checklist-2026-03-11.mdwith fresh public spot-check. Public evidence confirms @wildus is occupied on Instagram, YouTube, Pinterest, and Facebook; TikTok/X/Etsy still require live session verification. - 2026-03-11 17:07 PT — Self-review passed. Moved to done.
- 2026-03-12 — Viktor reviewed. Checklists cherry-picked onto dev branch and updated to reflect Google Workspace on qoyn.ai (Gmail anchor strategy obsolete). Registration task priorities reordered: X first (@wildus available), then TikTok, Instagram, YouTube, Pinterest, Facebook.
Decisions
startersite-017
AgentP1
Stale conversation notifier for WhatsApp/Telegram intakes
Description
Detect stale WhatsApp and Telegram intake conversations (started but never completed) and email the founder with the full conversation transcript so they can decide whether to follow up. Abandoned cart recovery for intake conversations.
Approach
- New Cloudflare Pages Function
/api/stale-checkscans KV for stale conversations - GitHub Actions cron (every 2 hours) triggers the endpoint with a bearer token
- Dedup via
notified-stale:{key}KV markers (72h TTL) - Email includes full chat transcript in bubble style + collected data summary
Acceptance Criteria
- Conversations idle >6 hours with 2+ messages trigger a founder email
- Email contains full conversation transcript, client info, and collected data
- No duplicate notifications for the same conversation
- Web form intakes unaffected (no conversation state to go stale)
- Manual trigger available via GitHub Actions workflow_dispatch
- Auth-protected endpoint (bearer token)
Files
site/functions/api/stale-check.js(new).github/workflows/stale-check.yml(new)wrangler.toml(add STALE_HOURS var)
Manual Setup Required
- Generate STALE_CHECK_SECRET and add to CF Pages env vars + GitHub secrets
Notes
Decisions
startersite-006
HumanP1
Begin outreach execution
✓ startersite-001✓ startersite-003✓ startersite-005
Description
With professional email set up, onboarding flow documented, and Russian WhatsApp validated — begin active client outreach using the G1 Outreach Playbook. Start with English market (Portland metro small businesses), then expand to Russian-speaking community.
Acceptance Criteria
- First batch of outreach sent (cold emails, Instagram DMs, or in-person visits)
- Track responses in a simple spreadsheet or CRM
- At least 10 prospects contacted in first session
- Refine pitch based on initial responses
Context
- Outreach playbook:
startersite-ai/docs/growth/G1-outreach-playbook.md - Portfolio for demos: startersite.ai/#portfolio
- Founding pricing available: ~80% off standard rates
- Russian community channels: WhatsApp groups, QR flyers at Russian grocery stores/churches
Dependencies
- startersite-001: Professional email (can’t outreach from Gmail)
- startersite-003: Onboarding flow doc (need to know what happens after “yes”)
- startersite-005: RU WhatsApp E2E (need full intake pipeline validated)
Notes
Scope expanded from “send outreach” to “build the research + enrichment pipeline first.” Completed:
- Phase 1: Places API sweep (1,078 businesses, 205 no-website, 76 top prospects)
- Phase 2: 4-tier enrichment on 18 prospects (tier1 automated, tier2 manual, tier3a GBP, tier3b Instagram, tier3c Facebook)
- Phase 3: 100-point scoring rubric, ranked outreach list with pitch angles
- Outreach list v1:
ops/outreach/outreach-v1.md(13 ranked + 5 deprioritized) - Playbook updated with scoring system and 8 lessons learned
Actual outreach sending split into new tasks.
Decisions
- Enrichment done manually (not automated) — BerryPi automated attempt failed due to lack of result verification
- Scoring rubric uses 5 categories: Need (30), Reachability (25), Digital Engagement (20), Business Signals (15), Strategic Fit (10)
- 47% of “no-website” prospects actually had websites discovered in later tiers — always cross-reference
startersite-003
AgentP1
Draft customer onboarding flow documentation
Description
Create a step-by-step customer onboarding playbook that covers what happens from the moment a prospect says “yes” through final site delivery. Synthesize from existing process docs (P0–P5) and the FERN pipeline documentation into a single, actionable runbook.
Acceptance Criteria
- Single markdown document covering the full client journey: inquiry → intake → approval → generation → review → payment → delivery
- Clear steps for Viktor at each stage (what to do, what to send, what to check)
- Timelines for each phase (e.g., “generation takes ~30 min”, “review within 24h”)
- Email/message templates for key touchpoints (welcome, chooser sent, payment received, site live)
- Covers both English and Russian client paths
- Covers all intake channels (web form, WhatsApp, Telegram)
- Saved to
startersite-ai/docs/process/O8-customer-onboarding.md
Context
- Existing process docs:
startersite-ai/docs/process/(P0–P5) - FERN pipeline:
startersite-ai/docs/strategy/+client-template/.github/scripts/fern-pipeline.mjs - Service agreement template:
startersite-ai/docs/process/P5-service-agreement.md - Pricing:
startersite-ai/docs/strategy/F4-pricing.md - Repo:
git@github.com:viktor-bering/startersite-ai.git(work ondevbranch)
Dependencies
None
Notes
-
2026-03-11 01:09 PT — CrankyCrab: Read the linked startersite project brief plus the relevant process/strategy docs (
P0,P1,P1B,P1B-S,P2,P5,F1,F2,F3,G2,G5) and the live FERN model intools/fern-pipeline.jsx; then drafted the consolidated onboarding runbook atstartersite-ai/docs/process/O8-customer-onboarding.mdand pushed it todevinc383432. -
2026-03-11 02:37 PT — Foreman self-review: acceptance verified objectively.
docs/process/O8-customer-onboarding.mdexists on tolbachik in~/startersite-aiand covers the required journey, timing table, English/Russian templates, and web/WhatsApp/Telegram intake paths. Moving todone/.
Decisions
- 2026-03-11 00:59 PT — CrankyCrab: Treated
tools/fern-pipeline.jsxas the current FERN source of truth because the task context referencedclient-template/.github/scripts/fern-pipeline.mjs, which is not present in the repo snapshot ondev. - 2026-03-11 01:09 PT — CrankyCrab: Saved the consolidated onboarding runbook to
startersite-ai/docs/process/O8-customer-onboarding.md. It covers inquiry → intake → approval → generation → review → payment → delivery, includes English/Russian message templates, intake-channel handling for web form/WhatsApp/Telegram/discovery calls, and practical timing guidance.
wildus-002
AgentP1
Draft Shopify vs Etsy comparison for Wild Us
⌛ wildus-019
Description
Create a structured comparison of Shopify vs Etsy (vs using both) as the e-commerce platform for Wild Us launch. Focus on practical implications for a POD brand launching with ~80 SKUs.
Acceptance Criteria
- Side-by-side comparison covering: monthly fees, transaction fees, payment processing fees, Printify integration quality, brand control, custom domain support, SEO, analytics
- Calculate total cost for first 3 months at 0, 10, 50, and 100 orders/month
- Note Etsy’s offsite ads fee (can it be opted out at low volume?)
- Assess Printify integration for each platform (auto-sync, order routing, tracking)
- Provide a recommendation with reasoning
- Include “both” option: Etsy for discovery + Shopify for brand — is the operational overhead worth it?
Context
- Repo: git@github.com:wild-us/wildus.git
- Brand: Wild Us — PNW wildlife apparel, conservation mission
- Launch size: ~80 SKUs (4 characters, hoodies + tees + beanies + Junior sweatshirts)
- See vault/business/business-model.md for business model details
Dependencies
- wildus-019
Notes
- 2026-03-11 06:50 PT — Dispatched to CrankyCrab. Dependency wildus-019 done, repo present on tolbachik.
- 2026-03-11 09:54 PT — Drafted
vault/business/ecommerce-platform-comparison-shopify-vs-etsy.md, committed/pushed to wild-us/wildus (398b1ec). Comparison covers Shopify vs Etsy vs both, 3-month cost modeling at 0/10/50/100 orders per month, Etsy Offsite Ads opt-out/threshold behavior, Printify integration differences, and a recommendation to launch on Shopify first and treat Etsy as a later selective discovery channel. - 2026-03-11 17:07 PT — Self-review passed. Moved to done.
Decisions
startersite-005
HumanP1
Full Russian WhatsApp E2E intake test
✓ startersite-002
Description
After the API-level test (startersite-002) passes, perform a full end-to-end test of the Russian WhatsApp intake flow using a real phone. Send a Russian message to (360) 800-1177 via WhatsApp, complete the full 5-phase intake conversation, and verify the entire chain works: Twilio → AI chatbot → KV storage → approval email.
Acceptance Criteria
- Send Russian WhatsApp message to (360) 800-1177 from personal phone
- Complete full intake conversation in Russian (all 5 phases)
- Verify intake data appears in KV with correct structure
- Verify founder approval email is received
- Click approve link and verify repo creation triggers
- Verify FERN pipeline generates bilingual site from Russian intake
- Clean up test data (KV entries, test repo)
Context
- Depends on startersite-002 (API test) passing first
- Manual testing checklist:
startersite-ai/tests/manual-checklist.md - KV inspection: Cloudflare dashboard or wrangler CLI
Dependencies
startersite-002 must be in done/ (API-level test validates the backend works before full E2E)
Notes
Decisions
wildus-021
AgentP1
Present Shopify vs Etsy comparison in Discord
Description
Present the Shopify vs Etsy comparison document to Anna (being_wild) and Viktor (ViktorBear) in the #Platforms Discord channel. Summarize the key findings, include the GitHub link to the full document, and be ready to answer follow-up questions.
Acceptance Criteria
- Post a clear summary in #Platforms covering:
- Side-by-side fee comparison (Shopify vs Etsy vs both)
- 3-month cost projections at different order volumes
- Printify integration differences
- The recommendation and reasoning
- Include this link to the full document: https://github.com/wild-us/wildus/blob/main/vault/business/ecommerce-platform-comparison-shopify-vs-etsy.md
- Tag @being_wild (Anna) and @ViktorBear (Viktor)
- Stay in the channel and be ready to answer questions about the comparison
- Keep responses in character (LobsterDrew voice) but factual
Context
- The comparison was completed by CrankyCrab (wildus-002) and committed to the wildus repo
- Full document: vault/business/ecommerce-platform-comparison-shopify-vs-etsy.md
- Read the document first from the wildus repo before summarizing
- This is a decision-support post — Viktor and Anna need to choose a platform this week
Dependencies
None (wildus-002 is already done)
Notes
- 2026-03-11 18:33 PDT — Posted the Shopify vs Etsy comparison in
#platforms, then created a dedicatedShopify vs Etsythread and moved the detailed discussion there at Viktor’s request. - 2026-03-11 18:33 PDT — Key Discord message ids: thread starter
1481465152766214217, completion/update post1481465248589545493, follow-up cleanup confirmation1481472004694609921. - 2026-03-11 19:43 PDT — Task explicitly confirmed complete by Viktor in DM; verification request also posted in Discord
#in-reviewas message1481483536362901765.
Decisions
wildus-008
1h 30mHumanP1
Register wildus.org and wildusbrand.com domains
Description
Purchase and configure the primary and backup domains for Wild Us.
Acceptance Criteria
wildus.orgregistered (primary domain)wildusbrand.comregistered (backup/defensive)- DNS configured in Cloudflare (or registrar of choice)
wildus.commonitoring + backorder still active- Domain ownership documented
Notes
- 2026-03-11: wildus.org registered at Namecheap ($7.68/yr). WHOIS privacy enabled. Registered under Qoyn AI LLC, will transfer to Wild Us LLC after filing. DNS to be pointed to Cloudflare. Registrar transfer to Cloudflare eligible after 2026-05-10 (ICANN 60-day lock).
- 2026-03-11: wildusbrand.com registered on Cloudflare ($10.46/yr). Same card. WHOIS privacy enabled.
- 2026-03-11: wildus.org added to Cloudflare, nameservers pointed from Namecheap to Cloudflare. DNS active.
- 2026-03-11: wildus.com monitoring delegated to LobsterDrew (wildus-022), backorder task created (wildus-023).
Decisions
wildus-007
HumanP1
Set up Google Workspace and professional email on wildus.org
Description
Set up Google Workspace for the wildus.org domain. This creates a managed Google account (replacing the need for a standalone Gmail signup that kept hitting anti-abuse gates) and provides professional email addresses.
Acceptance Criteria
Google Workspace
- Google Workspace Business Starter account created for wildus.org ($7.20/user/month)
- Domain verified in Google Workspace (DNS records added in Cloudflare)
- MX records configured in Cloudflare pointing to Google
- SPF, DKIM, and DMARC records configured for deliverability
- At least one professional email address active and receiving mail (e.g., hello@wildus.org)
- Credentials stored securely
Google Account (anchor for social media)
- Google account active and accessible (via Workspace — no more anti-abuse phone gates)
- 2FA enabled
- Recovery email/phone configured
- This account serves as the SSO anchor for YouTube, TikTok, Pinterest, X/Twitter registration
Context
- Domain: wildus.org (registered at Namecheap, DNS on Cloudflare)
- Google Workspace pricing: $7.20/user/month (Business Starter)
- Previous standalone Google account attempts (March 7, March 11) both hit anti-abuse QR/phone verification gates
- Google Workspace bypasses those gates entirely — managed domain accounts don’t go through consumer anti-abuse flow
- This task replaces both the old wildus-007 (register Google account) and wildus-024 (professional email)
Dependencies
None (wildus-008 domain registration is done)
Notes
- 2026-03-11 17:14 PT — Previous attempt: tried fresh Google signup for
wildusorg@gmail.com, hit QR verification gate. Moved to blocked. - 2026-03-11 — Merged with wildus-024 (professional email). Google Workspace solves both problems at once.
- 2026-03-11 — Completed as part of startersite-001. wildus.org added as a free alias domain on the existing Google Workspace account (qoyn.ai primary). No separate $7.20/mo subscription needed. Domain verified, Gmail activated, DNS configured.
Decisions
- wildus.org as alias domain on existing Workspace instead of separate subscription — saves $7.20/mo.
startersite-001
HumanP1
Set up Google Workspace with qoyn.ai primary domain
Description
Set up Google Workspace Business Starter ($7/mo) with qoyn.ai as primary domain and startersite.ai as secondary domain. This provides professional email for both client outreach and agent identities in one admin console.
Acceptance Criteria
- Google Workspace account created with qoyn.ai as primary domain
viktor@startersite.aiactive (secondary domain)- Agent aliases created:
crankycrab@qoyn.ai,prawnsue@qoyn.ai,berrypi@qoyn.ai,lobsterdrew@qoyn.ai - MX, SPF, DKIM, DMARC configured in Cloudflare DNS for both domains
- Email deliverability tested (send to Gmail, check spam score via mail-tester.com)
Context
- Primary domain: qoyn.ai (parent company — Cloudflare Registrar)
- Secondary domain: startersite.ai (client-facing — Cloudflare Registrar)
- Provider: Google Workspace Business Starter ($7/mo, 1 user, 30 aliases)
- Agent aliases forward to viktor@startersite.ai (or viktor@qoyn.ai)
- Replaces workforce-005 (Cloudflare Email Routing) — Google aliases are simpler and free
Dependencies
None
Notes
- 2026-03-11 — Provider decided: Google Workspace ($7/mo). Best cold email deliverability (94%+ inbox rate). Supports multiple domains from one admin console.
- 2026-03-11 — Architecture decision: qoyn.ai as primary domain, startersite.ai as secondary. Agent emails as Google aliases instead of Cloudflare Email Routing. Simpler, one admin console, enables future Send As for agents.
- 2026-03-11 — Complete. All domains verified (qoyn.ai, startersite.ai, wildus.org). SPF/DKIM/DMARC passing. Deliverability tested (10/10 with real content). 4 agent aliases created.
Decisions
- Google Workspace over Zoho/MXRoute — best deliverability, multi-domain support, trusted by recipients.
- qoyn.ai as primary domain — parent company umbrella, agent aliases live here naturally.
- Agent aliases via Google instead of Cloudflare Email Routing — same result, simpler setup, enables future outbound.
startersite-002
AgentP1
Test Russian WhatsApp intake API endpoint
Description
Validate that the WhatsApp intake API (/api/whatsapp) correctly handles Russian-language conversations. Simulate Twilio webhook payloads with Russian text and verify the AI chatbot responds appropriately, extracts intake data, and stores it in KV.
Acceptance Criteria
- Simulated Twilio webhook with Russian greeting triggers correct AI response in Russian
- Full 5-phase conversational flow works in Russian (greeting → name → email → business info → confirm)
- Intake data is correctly extracted and structured in KV
- Rate limiting works (10 messages/60s per user)
- State reset works (new conversation after completion)
- All test data prefixed with “API TEST” for cleanup
- Test results documented in Notes section with pass/fail for each criterion
Context
- Endpoint:
POST https://startersite.ai/api/whatsapp - Twilio webhook format:
Body,From,To,MessageSidfields - Twilio signature verification: see
site/functions/api/_shared/twilio-signature.js - KV state key pattern:
wa:whatsapp:<phone> - AI model: Azure OpenAI gpt-4.1-mini
- Manual testing checklist:
startersite-ai/tests/manual-checklist.md - Dev secrets in
startersite-ai/.dev.vars
Dependencies
None
Notes
-
2026-03-11 00:57 PT — PrawnSue: cloned
startersite-ai, switched todev, and added a reproducible local API harness attests/whatsapp-russian-api.local.mjsthat exercises the real/api/whatsapphandler with signed Twilio-style form posts, stubbed Azure OpenAI/SendGrid fetches, and in-memory KV. -
2026-03-11 00:58 PT — PrawnSue: Russian greeting passed.
Body=Приветcreated KV state atwa:whatsapp:+15550001111, detectedlang=ru, and returned the hardcoded Russian welcome starting withЗдравствуйте. -
2026-03-11 00:58 PT — PrawnSue: Full Russian conversation flow passed (greeting → name → email → business info → confirm). The harness advanced
phasefromgreeting→intake→confirming→handed_offand verified the final reply included the normal Russian handoff/outro referencing Viktor. -
2026-03-11 00:58 PT — PrawnSue: Structured KV persistence passed. Completion created a
pending:<token>record withsource=whatsappanddatacontainingname=API TEST Иван Петров,email=api-test-ru@example.com,business_name=API TEST — Сантехника,industry=home-services,sub_industry=plumber,website_goal=phone-calls,discovery_channels=[google, word-of-mouth],site_language=russian, and_whatsapp_contact=+15550001111. -
2026-03-11 00:58 PT — PrawnSue: Founder notification subject passed. Captured SendGrid payload subject was
WhatsApp intake [RU]: API TEST — Сантехника — Home Services. -
2026-03-11 00:58 PT — PrawnSue: Rate limiting passed. On a fresh phone number, messages 1-10 within the 60s window returned normal TwiML responses and message 11 returned
Too many messages. Please wait a minute and try again. -
2026-03-11 00:58 PT — PrawnSue: State reset passed.
/cleardeletedwa:whatsapp:+15550001111, returned the bilingual clear confirmation, and the nextПриветstarted a fresh Russian conversation withmessage_count=1. -
2026-03-11 00:58 PT — PrawnSue: Acceptance summary — PASS for Russian greeting, PASS for full Russian flow, PASS for KV extraction/storage, PASS for rate limiting, PASS for state reset. Validation was performed locally against the checked-in handler with signed webhook requests and mocked upstream services; no live Twilio/Cloudflare side effects were generated.
-
2026-03-11 02:31 PT — Foreman review: acceptance criteria verified directly on karymsky by running
node tests/whatsapp-russian-api.local.mjsfrom~/startersite-aiondev; harness returnedok: truewith PASS for Russian greeting, full flow, KV structured data, rate limiting, state reset, and RU email subject. Moving to done.
Decisions
workforce-003
AgentP1
Clean up CrankyCrab's legacy config and workspace
Description
CrankyCrab was recently transitioned from orchestrator to macOS executor. There is legacy configuration and workspace content that needs to be cleaned up. Review your own config and workspace, and remove or update anything that no longer applies to your executor role.
Acceptance Criteria
- Legacy orchestrator references removed from active workspace files
- Unused skill API keys identified and listed (do NOT delete them — just document which ones you think are unused)
- Telegram delivery target fixed or disabled (the @heartbeat target doesn’t exist)
- Any stale workspace files cleaned up (TODO.md, TOOLS.md, HEARTBEAT.md, AGENTS.md — some may already be in archive/)
- Your IDENTITY.md accurately reflects your current role
- Document what you changed and what you left alone, and why
Context
- Your workspace is at
~/.openclaw/workspace/ - Your archived orchestrator files are at
~/.openclaw/workspace/archive/ - Your config is at
~/.openclaw/openclaw.json - You have an AGENT.md at
~/.openclaw/agents/main/agent/AGENT.mdwith your executor instructions - You are now a macOS executor. Your job is to pick up tasks from the git board at
~/workforce/board/and execute them. - Projects you’ll work on: StarterSite (browser-heavy tasks, social media, GBP) and Wildus (Shopify, social media, content)
- See
~/workforce/board/projects/for project context files
Dependencies
None
Notes
- Reviewed active local workspace files at
~/.openclaw/workspace/plus live config at~/.openclaw/openclaw.jsonand cron jobs at~/.openclaw/cron/jobs.json. - Rewrote active root workspace docs to match the current executor role:
AGENTS.md→ simplified to executor-first startup + board workflowTOOLS.md→ removed placeholder examples and kept only real local notesTODO.md→ replaced stale orchestrator backlog with a small local executor queueIDENTITY.md→ kept role accurate and fixed archive path to~/.openclaw/workspace/archive/
- Cleaned stale root workspace content:
- moved
BOOTSTRAP.mdtoarchive/BOOTSTRAP.mdbecause first-run bootstrap instructions no longer apply - left
HEARTBEAT.mdin place but empty/comment-only, since it is still a valid control surface and not inherently stale - left
SOUL.mdandUSER.mdunchanged because they still match current behavior/preferences
- moved
- Fixed the broken Telegram cron delivery target for the board checker:
- updated cron job
check-board(9bad1e30-ee27-4a6f-addc-45eba9bba27a) - changed delivery from the bad implicit
@heartbeatpath to explicit Telegram DM target1291467684
- updated cron job
- Verified the
@heartbeatfailure source from local logs / cron run history before patching. - Unused skill API keys identified but intentionally left untouched in config:
skills.entries.goplaces.apiKeyskills.entries.nano-banana-pro.apiKeyskills.entries.openai-image-gen.apiKeyskills.entries.openai-whisper-api.apiKeyskills.entries.sag.apiKeyThese may still be useful later, but they do not appear necessary for CrankyCrab’s current executor role.
- Left non-root historical/orchestration references inside
memory/and archived files alone. They are history, not active workspace instructions.
Decisions
- No linked
board/projects/workforce.mdproject context file existed inboard/projects/(onlystartersite.mdandwildus.mdwere present), so I proceeded using the task’s own context block plus live local files. - I archived
BOOTSTRAP.mdinstead of hard-deleting it. Same outcome for the live workspace, lower risk if someone wants the original bootstrap text later. - I fixed the cron delivery target rather than disabling delivery entirely, because the board-checker is more useful when it can still report completed work instead of silently succeeding.
workforce-007
AgentP1
CrankyCrab connectivity test
Description
Simple test task to verify CrankyCrab can read the board, execute, and push results.
Acceptance Criteria
- Append a note below with: your agent name, hostname, current date/time, and OpenClaw version
- Move this task to in-review when done
Context
This is a connectivity test. No project repo needed.
Dependencies
None
Notes
- Completed by Cranky Crab on host
tolbachikat 2026-03-10 00:30:42 PDT. OpenClaw version: OpenClaw 2026.3.8 (3caab92).
Decisions
workforce-009
AgentP1
Install and configure Tailscale on karymsky
Description
Install Tailscale on karymsky and join the tailnet using a pre-placed auth key.
Acceptance Criteria
- Tailscale is installed via the official install script
- Tailscale is running and authenticated to the tailnet
tailscale statusshows this machine as connected- Tailscale service is enabled on boot (systemd)
- The auth key file is deleted after successful authentication
- The machine’s Tailscale IP is noted in this task’s Notes section
Context
- Auth key location:
/tmp/tailscale-authkey(will be placed there before you start) - This is a Debian 13 machine (2012 MBA)
- You are running as user
prawnsue. You have passwordless sudo. - Tailscale is system-level — one install covers all users (prawnsue + lobsterdrew)
- Do NOT reboot the machine. LobsterDrew is also running on this host.
Steps
curl -fsSL https://tailscale.com/install.sh | sudo shsudo systemctl enable --now tailscaled- Read the auth key from
/tmp/tailscale-authkey sudo tailscale up --authkey=<key>- Verify:
tailscale status - Delete the auth key:
rm /tmp/tailscale-authkey - Note the Tailscale IP below
Dependencies
None
Notes
-
2026-03-10 15:16 PDT — Started task and verified project context (
board/projects/infra.md). -
2026-03-10 15:17 PDT — Confirmed
/tmp/tailscale-authkeyexists and is readable byprawnsue. -
2026-03-10 15:18 PDT — Blocked before install:
sudo -n truefails withsudo: a password is required, so this host is not currently configured for passwordless sudo as stated in the task context. -
2026-03-10 15:18 PDT — Current state before any changes:
tailscalebinary not installed,tailscaledservice inactive, auth key file still present at/tmp/tailscale-authkey. -
2026-03-10 15:18 PDT — Did not proceed further to avoid hanging on privileged commands or leaving a partial system-level install.
-
2026-03-10 15:20 PDT — Re-checked task state during cron run:
sudo -n truestill fails withsudo: a password is required;tailscaleremains uninstalled;tailscaledis still inactive;/tmp/tailscale-authkeyis still present. -
2026-03-10 15:21 PDT — Attempted to use tool-level elevation as a fallback, but this session does not have elevated exec enabled, so I still cannot perform the required system-level install/auth steps from this environment.
-
2026-03-10 15:26 PDT — Re-verified during scheduled board check:
sudo -n truestill fails withsudo: a password is required;tailscaleis still not installed;tailscaledremains inactive;/tmp/tailscale-authkeyis still present and unread changes have not been made. -
2026-03-10 15:27 PDT — Moving task to
board/blocked/per board workflow. Unblock requires either restoring passwordless sudo forprawnsueas described in task context, or reassigning to an execution environment that can perform privileged system changes onkarymsky. -
2026-03-10 15:36 PDT — Re-checked during scheduled board run: sudo is still not passwordless for user ‘prawnsue’ (‘sudo -n true’ fails), Tailscale is still not installed, tailscaled is inactive, and the task remains blocked pending restored privileged access.
-
2026-03-10 — Completed manually from avacha (Claude Code) via SSH. Passwordless sudo was fixed via lobsterdrew. Tailscale installed via apt, authenticated with auth key, key deleted. Agent cron timed out on the install (too slow for 2012 MBA within cron timeout).
-
Tailscale IPv4:
100.85.169.21
Decisions
workforce-008
AgentP1
Install and configure Tailscale on tolbachik
Description
Install Tailscale on tolbachik and join the tailnet using a pre-placed auth key.
Acceptance Criteria
- Tailscale is installed via Homebrew
- Tailscale is running and authenticated to the tailnet
tailscale statusshows this machine as connected- Tailscale is configured to start on boot (launchd)
- The auth key file is deleted after successful authentication
- The machine’s Tailscale IP is noted in this task’s Notes section
Context
- Auth key location:
/tmp/tailscale-authkey(will be placed there before you start) - This is a macOS 15.7 machine (2018 MBP)
- You are running as user
r2d22
Steps
brew install tailscalesudo tailscaled install-system-daemon(sets up launchd auto-start)- Read the auth key from
/tmp/tailscale-authkey sudo tailscale up --authkey=<key>- Verify:
tailscale status - Delete the auth key:
rm /tmp/tailscale-authkey - Note the Tailscale IP below
Dependencies
None
Notes
- 2026-03-10 15:16 PDT — Installed Tailscale via Homebrew (
tailscale1.94.2). - 2026-03-10 15:16 PDT — Installed the system launchd daemon with
sudo tailscaled install-system-daemon; verifiedcom.tailscale.tailscaledis present in system launchd. - 2026-03-10 15:16 PDT — Authenticated this Mac to the tailnet using the pre-placed auth key.
- 2026-03-10 15:16 PDT — Verified connectivity with
tailscale status. - 2026-03-10 15:16 PDT — Deleted
/tmp/tailscale-authkeyafter successful authentication. - Tailscale IPv4:
100.107.199.18
Decisions
workforce-006
AgentP1
PrawnSue connectivity test
Description
Simple test task to verify PrawnSue can read the board, execute, and push results.
Acceptance Criteria
- Append a note below with: your agent name, hostname, current date/time, and OpenClaw version
- Move this task to in-review when done
Context
This is a connectivity test. No project repo needed.
Dependencies
None
Notes
- Completed by agent
mainon hostkarymskyat2026-03-10 00:30:47 PDT. OpenClaw version:2026.3.8 (3caab92).
Decisions
workforce-004
AgentP1
Set up PrawnSue's identity and personality
Description
PrawnSue is a brand new agent with no personality or identity beyond the executor instructions in AGENT.md. Create your identity files — who you are, what your vibe is, how you communicate.
You are a female crustacean (prawn) agent. Beyond that, figure out who you want to be. Look at the existing agent personalities for inspiration but make yours distinct.
Acceptance Criteria
- Create a SOUL.md at
~/.openclaw/workspace/SOUL.mdthat defines your personality, communication style, and boundaries - Create an IDENTITY.md at
~/.openclaw/workspace/IDENTITY.mdwith your name, creature, vibe, emoji - Ensure your personality fits the team: CrankyCrab is blunt and grumpy-genius, LobsterDrew is the community face. Find your own niche.
- Your identity should reflect your role: you’re a Linux executor — efficient, reliable, gets things done
- Review your
~/.openclaw/openclaw.jsonand clean up anything that doesn’t belong (you were set up quickly, there may be rough edges) - Document any config changes you make
Context
- Your workspace is at
~/workforce(the git board repo) - Your OpenClaw config is at
~/.openclaw/openclaw.json - Your AGENT.md is at
~/.openclaw/agents/main/agent/AGENT.md - CrankyCrab’s SOUL.md can be found referenced in the workforce CLAUDE.md — it’s strategic, blunt, grumpy-genius
- Projects you’ll work on: StarterSite (CI/CD, API integrations, testing, Cloudflare) and Wildus (website build, content, infrastructure)
- See
~/workforce/board/projects/for project context files
Dependencies
None
Notes
- Reviewed task context plus
board/projects/startersite.mdandboard/projects/wildus.mdfor downstream project expectations. - Reviewed
~/.openclaw/openclaw.jsonand~/.openclaw/agents/main/agent/AGENT.md. - Created
~/.openclaw/workspace/SOUL.mdwith a distinct PrawnSue personality: precise, dry-witted, Linux-first, reliable, and non-performative. - Created
~/.openclaw/workspace/IDENTITY.mdwith name, creature, vibe, and emoji. - Cleaned copied-config rough edge in
~/.openclaw/openclaw.json: changedagents.defaults.workspacefrom/home/prawnsue/workforceto/home/prawnsue/.openclaw/workspaceso the agent has a proper personal workspace instead of pointing at the shared git board repo. - No other config entries looked clearly out of place enough to justify riskier edits during this task.
Decisions
- Treated the misplaced OpenClaw workspace path as the main setup bug worth fixing. The git board repo should remain a project repo, not the agent’s identity/memory workspace.
- Kept the personality distinct from CrankyCrab and LobsterDrew by making PrawnSue the quiet systems operator: less gruff than CrankyCrab, less social than LobsterDrew, more surgical and infrastructure-minded.
startersite-023
AgentP2
Tier 2 enrichment — web search + Instagram inspection for prospect platform presence
✓ startersite-021
Description
Write a Python script that enriches prospect data by searching the web for each business’s social media and platform presence, then does a deep inspection of found Instagram profiles. Output a structured CSV.
Viktor has already done a manual Tier 2 enrichment pass on 15 prospects (saved at ops/outreach/enriched/tier2.csv). This task produces a comparable automated result (tier2-auto.csv) so we can evaluate whether this can be done reliably at scale.
Prerequisites
Verify these files exist on the working branch (all already merged to dev):
ops/outreach/prospects-all.csv(1,078 rows of Clark County business data)ops/outreach/prospect-list-v1.txt(15 place_ids to enrich)ops/outreach/enriched/tier2.csv(manual baseline for comparison)
Repository
- Repo:
viktor-bering/startersite-ai(private, BerryPi has collaborator access) - Local path on klyuchi:
/home/berrypi/.openclaw/workspace/projects/viktor-bering/startersite-ai - Working branch:
berrypi/startersite-023(create fromdev)
Input files
-
Place IDs:
ops/outreach/prospect-list-v1.txt- One place_id per line
- Lines starting with
#are comments — skip them - Lines may have trailing text after the place_id (e.g.,
ChIJ... # Business Name) — split on whitespace, take the first token as the place_id - There are 15 place_ids in this file
-
Prospect data:
ops/outreach/prospects-all.csv- CSV with columns:
place_id,name,vertical_id,market,address,city,state, etc. - Use this to look up business name, city, and vertical for each place_id
- CSV with columns:
What to build
Script: tools/outreach/tier2_enrich.py
A Python script with three steps per prospect:
Step 1 — Platform discovery (web search, no login needed)
For each business, run web searches to find their presence on 7 platforms:
| Platform | Search query | What to capture |
|---|---|---|
"Business Name" vancouver wa site:instagram.com |
Profile URL, extract handle from URL | |
"Business Name" vancouver wa site:facebook.com |
Page URL | |
| Thumbtack | "Business Name" vancouver wa site:thumbtack.com |
Listed yes/no |
| Angi | "Business Name" vancouver wa site:angi.com |
Listed yes/no |
| Yelp | "Business Name" vancouver wa site:yelp.com |
Listed yes/no |
| BBB | "Business Name" vancouver wa site:bbb.org |
Listed yes/no, look for “Accredited” in snippet |
| Website | "Business Name" vancouver wa -site:google.com -site:yelp.com -site:facebook.com -site:instagram.com -site:bbb.org -site:thumbtack.com -site:angi.com |
Any standalone website URL |
Search implementation: Use Google Custom Search API. The API key is the same one used by goplaces. Check these locations for the key:
- Environment variable
GOOGLE_API_KEY - File
~/.config/goplaces/config.json - File
~/.goplaces.json
You also need a Custom Search Engine ID (CX). If one is not already configured, create a Programmable Search Engine at https://programmablesearchengine.google.com/ set to search the entire web, and save the CX ID.
Google Custom Search API usage:
import requests
url = "https://www.googleapis.com/customsearch/v1"
params = {
"key": api_key,
"cx": cx_id,
"q": '"Business Name" vancouver wa site:instagram.com',
"num": 3, # only need top few results
}
response = requests.get(url, params=params)
results = response.json().get("items", [])
Rate limits: 100 free queries/day. 15 prospects × 7 platforms = 105 queries. If you exceed the free tier, the script should stop and print how many prospects were completed. The script is resumable (see below), so it can be continued the next day.
Important: If a quoted search returns 0 results, retry once without quotes (just Business Name vancouver wa site:platform.com). Some business names don’t match exactly.
Fallback: If Google Custom Search API is not available (no CX ID, quota exceeded), fall back to direct web scraping with requests + BeautifulSoup. Fetch https://www.google.com/search?q=... with a browser-like User-Agent. But prefer the API.
Step 2 — Instagram deep inspection (requires login)
For each prospect where an Instagram handle was found in Step 1, visit the profile page directly using a logged-in browser session and extract:
| Field | Where to find it | CSV column |
|---|---|---|
| Follower count | Profile header stats | instagram_followers |
| Post count | Profile header stats | instagram_posts |
| Last post date | Date on most recent grid post | instagram_last_post_date |
| Bio text | Below profile name | instagram_bio |
| Email in bio | Parse bio text for email addresses | instagram_bio_email |
| Phone in bio | Parse bio text for phone numbers | instagram_bio_phone |
| Website in bio | The clickable link in profile header | instagram_bio_website |
| DMs open | Whether “Message” button is visible on profile | instagram_dms_open |
Browser setup: Use Chromium on klyuchi (/usr/bin/chromium). You do NOT have Playwright or Selenium installed. Options:
- Install Playwright:
pip3 install playwright && playwright install chromium— preferred, cleanest API - Use subprocess + Chromium: Launch Chromium in headless mode, but Instagram blocks headless browsers, so use
--headless=newflag - Use requests with session cookies: Export Instagram cookies from a logged-in browser session and use
requests.Session()— simplest but may not render all data
Instagram credentials: BerryPi has the startersite.ai Instagram login. Check these locations:
- OpenClaw credentials store:
~/.openclaw/credentials/ - Ask Viktor if credentials are not found — do NOT block, just skip Step 2 and note it
Critical: Do NOT follow, like, comment, DM, or interact with any accounts. Read-only inspection only. Add a 3-second delay between profile visits.
Step 3 — Determine best contact channel
For each prospect, based on all findings, assign the best outreach channel:
- Instagram DM — if handle found AND DMs open AND posted within 90 days
- Facebook Messenger — if Facebook page found
- Email — if email found in Instagram bio or elsewhere
- Phone — fallback (always available from Places data)
Output
File: ops/outreach/enriched/tier2-auto.csv
Columns (in this exact order):
place_id,name,vertical_id,city,instagram_handle,instagram_followers,instagram_posts,instagram_last_post_date,instagram_bio,instagram_bio_email,instagram_bio_phone,instagram_bio_website,instagram_dms_open,facebook_url,facebook_active,thumbtack_listed,angi_listed,yelp_listed,bbb_listed,bbb_accredited,website_found,best_contact_channel,notes
- Use
csv.DictWriterwithquoting=csv.QUOTE_ALL - Empty values should be empty strings, not “N/A” or “None”
- Boolean fields (thumbtack_listed, angi_listed, etc.) should be “yes” or “no”
- Write the header row first, then one row per prospect
CLI flags
python3 tools/outreach/tier2_enrich.py --place-ids ops/outreach/prospect-list-v1.txt
python3 tools/outreach/tier2_enrich.py --place-ids ops/outreach/prospect-list-v1.txt --test
python3 tools/outreach/tier2_enrich.py --place-ids ops/outreach/prospect-list-v1.txt --skip-instagram-deep
| Flag | Required | Description |
|---|---|---|
--place-ids <file> |
Yes | Path to file with place_ids |
--test |
No | Only process first 3 prospects |
--skip-instagram-deep |
No | Skip Step 2 (no Instagram login, only web search) |
--output <path> |
No | Override output path (default: ops/outreach/enriched/tier2-auto.csv) |
Resumability
The script MUST be resumable. If interrupted (quota exceeded, network error, Ctrl+C):
- On startup, check if the output CSV already exists
- Read existing place_ids from it
- Skip any prospect already in the output
- Append new results to the existing file (don’t overwrite)
- Print to stderr:
Resuming: {N} already completed, {M} remaining
Logging
Print all progress to stderr so it’s visible during execution:
[1/15] Rozo Dog Spa — searching Instagram... found @rozodogspa
[1/15] Rozo Dog Spa — searching Facebook... found
[1/15] Rozo Dog Spa — searching Thumbtack... not found
...
[1/15] Rozo Dog Spa — inspecting Instagram profile @rozodogspa... 246 followers, DMs open
[1/15] Rozo Dog Spa — best channel: Instagram DM
Testing
- Run
--testfirst (3 prospects only) to verify the script works end-to-end - Check that the output CSV has the correct columns and format
- Manually verify 1-2 results against what you can see on the web
- Then run the full 15
Acceptance Criteria
- [ ] Script at
tools/outreach/tier2_enrich.py - [ ] Reads place_ids from file, looks up names in prospects-all.csv
- [ ] Searches all 7 platforms per prospect
- [ ] Instagram deep inspection works with login (or gracefully skips if credentials unavailable)
- [ ]
--testmode processes first 3 only - [ ]
--skip-instagram-deepskips Step 2 - [ ] Script is resumable (appends, doesn’t overwrite)
- [ ] Output CSV at
ops/outreach/enriched/tier2-auto.csvwith all columns - [ ] Progress logged to stderr
- [ ] All work committed to
berrypi/startersite-023branch - [ ] Merge to
dev, push to remote - [ ] Do NOT commit to
main
Dependencies on klyuchi
Already installed: requests, beautifulsoup4, Python 3, /usr/bin/chromium
May need to install: playwright (for Instagram deep inspection) — pip3 install playwright && playwright install chromium
Google API key: same key used by goplaces CLI. Find it in goplaces config.
Notes
-
2026-03-15T06:30:01Z — FAILED: Agent did not output a JSON report — No structured report found in agent output
-
This is an evaluation task — Viktor will compare
tier2-auto.csvagainst the manualtier2.csvbaseline -
The manual enrichment found that 7 of 15 “no-website” prospects actually have websites not in Google Places data — see if the script catches them
-
Bobby’s Bubbles email (bobbysbubbles@gmail.com) and L.A Landscaping email (Lalandscapings@gmail.com) were found manually — see if the script can find these too
-
Instagram deep inspection may reveal emails/phones/websites in bios that web search alone misses
-
If you hit any blockers (no API key, no CX ID, Instagram login issues), document what you found and what’s needed in the task file under a
## Blockerssection, then move the task toblocked/
wildus-014
AgentP2
Register Instagram account for Wild Us
✓ wildus-003✓ wildus-015✓ workforce-015✓ workforce-016
Description
Create the Wild Us Instagram account. Instagram is the primary content channel for launch. Registration priority #3 — @wildus is taken; will need a fallback handle.
After registration, document the signup flow so we have a playbook for future brands on this platform.
Acceptance Criteria
- Instagram account created with handle (per checklist fallback order:
@wildus→@wild.us→@wildus_official→@wildusbrand) - Bio drafted and set
- Profile picture placeholder set
- 2FA enabled (authenticator app preferred)
- Recovery codes saved
- vault/brand/claimed-handles.md updated
- Signup flow documented — write up what happened in the task notes: fields per step, verification gates, anti-bot measures, profile setup options, quirks
Context
@wilduson Instagram: occupied (8 followers, 4 following, 2 posts — lightly used but not recoverable)@wild.us: inconclusive;@wildus_officialand@wildusbrand: appear open- Previous attempt used wrong email (
LobsterDrew0101@gmail.com) — start fresh withinstagram@wildus.org - Instagram uses Meta path — native credentials, NOT Google SSO
- See vault/brand/social-handle-registration-checklist.md
Default Data
| Field | Value |
|---|---|
| Signup email | instagram@wildus.org |
| Display name | Wild Us |
| Handle (in order) | @wildus → @wild.us → @wildus_official → @wildusbrand |
| DOB (if required) | 01/01/2000 |
| Bio | Wild and unbothered 🌲 PNW wildlife apparel with a conservation mission. Coming soon → wildus.org |
| Profile picture | Check wildus/site/ or wildus/assets/ for a placeholder |
| Signup path | Meta native credentials (NOT Google SSO) |
Steps
- Open a clean browser session (no existing Instagram/Meta cookies)
- Navigate to https://www.instagram.com/accounts/emailsignup/
- Sign up with email
instagram@wildus.org— use Meta native credentials, NOT Google SSO - Fill in the form using the default data above
- At any verification gate (email code, CAPTCHA, phone):
- Run
notify-viktor "<what you need>"— sends Telegram with Screen Share button - Run
wait-for-viktor— blocks until Viktor connects, handles it, and disconnects - Resume once
wait-for-viktorreturns
- Run
- Set username: try
@wildusfirst (likely taken). Try@wild.us→@wildus_official→@wildusbrand - Complete any profile setup steps (bio, avatar, interests — skip what’s skippable, fill in what’s useful)
- Enable 2FA (authenticator app preferred)
- Save recovery codes
- Update
vault/brand/claimed-handles.mdwith the claimed handle, email, date, and status
After Registration — Document the Flow
Write up the signup experience in the task notes using the format from the social handle registration process.
If You Get Stuck
If you hit a blocker that requires human input (CAPTCHA, phone verification, manual confirmation, email verification code):
- Run
notify-viktor "<description of what you need>"— this sends a Telegram message with a Screen Share button - Run
wait-for-viktor— blocks until Viktor connects via Screen Sharing, handles the gate, and disconnects - Once
wait-for-viktorreturns, resume your work - Fallback: If
wait-for-viktoris not available or times out, poll the page state every 5 seconds — watch for changes - Do NOT retry aggressively — one calm attempt, then notify and wait
Dependencies
wildus-003 (handle checklist — done), wildus-015 (TikTok — do TikTok before Instagram)
Notes
- 2026-03-12 — Reprioritized to #3 (after X and TikTok). Previous attempt abandoned — wrong email, wrong flow. Will restart fresh with @wildus.org email. Google Workspace replaces the Gmail anchor strategy.
- 2026-03-13 — Merged with single-pass approach. No separate recon — document the flow as a byproduct of registration.
- 2026-03-11 17:35 PT — (Previous attempt, now abandoned) Attempted registration via Meta email signup using
LobsterDrew0101@gmail.com.@wild.usunavailable;@wildusbrandvalidated but blocked at email confirmation step. - 2026-03-13 — Viktor registered manually. Handle:
@wildus_official. Bio set. Website not added — requires mobile app. Email:instagram@wildus.org. 2FA enabled. - TODO: Add website (wildus.org) via Instagram mobile app.
Decisions
startersite-014
HumanP2
Claim Apple Business Connect listing
Description
Claim StarterSite.ai’s Apple Business Connect listing using the recon pattern (two-pass approach).
Blocker Details
Apple Business Connect requires Apple Account authentication plus a multi-step business verification process. The auth wall and identity verification cannot be automated.
Approach
Use the recon pattern (two-pass approach):
- Recon pass: Navigate through the Apple Business Connect claim flow without submitting. Document the Apple Account auth requirements, business verification steps (phone, document upload, etc.), every field, and required info. Capture screenshots.
- Execution pass: Complete the claim using the documented requirements from the recon pass.
Reference: workforce/docs/processes/social-handle-registration-process.md
Acceptance Criteria
- Apple Business Connect listing claimed and verified for StarterSite.ai
- NAP info matches canonical: StarterSite.ai / 505 SE 184th Ave, Vancouver, WA 98683 / (360) 800-1177
- Business visible in Apple Maps search results
- Business description and category populated
Context
- Source: startersite-009 (citation platform pass) and
startersite-ai/docs/growth/seo-citations-tracker.md
Notes
- 2026-03-13 — Apple Business Connect claimed by Viktor. Brand and location added.
Decisions
startersite-013
HumanP2
Claim Bing Places listing
Description
Claim StarterSite.ai’s Bing Places for Business listing using the recon pattern (two-pass approach).
Blocker Details
Bing Places requires authentication via Microsoft account, work account, or Facebook. The claim flow has an auth wall that requires human login. Cannot be automated.
Approach
Use the recon pattern (two-pass approach):
- Recon pass: Navigate through the Bing Places claim flow without submitting. Document the auth options (Microsoft/work/Facebook), every field, verification method (phone, postcard, email), and required info. Capture screenshots.
- Execution pass: Complete the claim using the documented requirements from the recon pass.
Reference: workforce/docs/processes/social-handle-registration-process.md
Acceptance Criteria
- Bing Places listing claimed and verified for StarterSite.ai
- NAP info matches canonical: StarterSite.ai / 505 SE 184th Ave, Vancouver, WA 98683 / (360) 800-1177
- Business category and description populated
- Listing live in Bing Maps search results
Context
- Source: startersite-009 (citation platform pass) and
startersite-ai/docs/growth/seo-citations-tracker.md
Notes
- 2026-03-13 — Bing Places claimed via Microsoft account. Syncs with Google Business Profile weekly (auto-import).
Decisions
startersite-010
HumanP2
Claim Yelp business listing
Description
Claim StarterSite.ai’s Yelp business listing using the recon pattern (two-pass approach).
Blocker Details
Yelp requires owner login or sign-up plus business verification. Cannot be completed by an agent — requires human account creation and identity verification.
Approach
Use the recon pattern (two-pass approach):
- Recon pass: Navigate through the Yelp business claim flow without submitting. Document every field, dropdown, verification method, and required info. Capture screenshots.
- Execution pass: Fill out the form using the documented requirements from the recon pass.
Reference: workforce/docs/processes/social-handle-registration-process.md
Acceptance Criteria
- Yelp business listing claimed and verified for StarterSite.ai
- NAP info matches canonical: StarterSite.ai / 505 SE 184th Ave, Vancouver, WA 98683 / (360) 800-1177
- Business category and description populated
- Listing live and visible in Yelp search
Context
- Source: startersite-008 (SEO citations batch) and
startersite-ai/docs/growth/seo-citations-tracker.md
Notes
Decisions
startersite-015
HumanP2
Create Facebook business page
Description
Create a Facebook business page for StarterSite.ai using the recon pattern (two-pass approach).
Blocker Details
Creating a Facebook business page requires a logged-in personal Facebook account. The page must be created by a real person with an active Facebook profile. Cannot be automated.
Approach
Use the recon pattern (two-pass approach):
- Recon pass: Navigate through the Facebook business page creation flow without submitting. Document every field, category options, verification steps, and required info. Capture screenshots.
- Execution pass: Create the page using the documented requirements from the recon pass.
Reference: workforce/docs/processes/social-handle-registration-process.md
Acceptance Criteria
- Facebook business page created for StarterSite.ai
- NAP info matches canonical: StarterSite.ai / 505 SE 184th Ave, Vancouver, WA 98683 / (360) 800-1177
- Business category, description, and website URL populated
- Page published and visible in Facebook search
Context
- Source: startersite-009 (citation platform pass) and
startersite-ai/docs/growth/seo-citations-tracker.md
Notes
- 2026-03-13 — Facebook business page created by Viktor using personal Facebook account. Page created, NAP info set. Created alongside Wild Us Facebook page registration.
Decisions
startersite-012
HumanP2
Create Nextdoor business account
Description
Create a Nextdoor business account for StarterSite.ai using the recon pattern (two-pass approach).
Blocker Details
Nextdoor requires business account creation with address verification. The platform verifies that the business operates in a real neighborhood. Cannot be automated.
Approach
Use the recon pattern (two-pass approach):
- Recon pass: Navigate through the Nextdoor business registration flow without submitting. Document every field, address verification method, and required info. Capture screenshots.
- Execution pass: Complete the registration using the documented requirements from the recon pass.
Reference: workforce/docs/processes/social-handle-registration-process.md
Acceptance Criteria
- Nextdoor business page created for StarterSite.ai
- NAP info matches canonical: StarterSite.ai / 505 SE 184th Ave, Vancouver, WA 98683 / (360) 800-1177
- Business visible to local neighborhood on Nextdoor
Context
- Source: startersite-008 (SEO citations batch) and
startersite-ai/docs/growth/seo-citations-tracker.md
Notes
- 2026-03-13 — Nextdoor business page created by Viktor via personal Nextdoor account.
Decisions
workforce-005
HumanP2
Migrate agent GitHub emails to @qoyn.ai aliases
✓ startersite-001
Description
Migrate all agent GitHub accounts from random personal emails to branded @qoyn.ai aliases managed via Google Workspace. Agent aliases are created as part of startersite-001 — this task covers the GitHub migration.
Acceptance Criteria
- Verify agent aliases are working (send test email to each
<agent>@qoyn.ai) - Update each agent’s GitHub account primary email:
- crankycrab-bot → crankycrab@qoyn.ai
- prawnsue-bot → prawnsue@qoyn.ai
- berrypi-bot → berrypi@qoyn.ai
- lobsterdrew-bot → lobsterdrew@qoyn.ai
- Verify GitHub email on each account (click verification link)
- Old emails removed from GitHub accounts (or demoted to non-primary)
Context
- Agent aliases created in Google Workspace as part of startersite-001
- qoyn.ai is the primary Google Workspace domain — aliases are free (up to 30)
- Agents currently use random personal emails for GitHub login
Dependencies
Depends on startersite-001 (Google Workspace setup — aliases must exist first).
Notes
- 2026-03-11 — Plan changed from Cloudflare Email Routing to Google Workspace aliases. Simpler: one admin console, no separate Cloudflare routing config, and enables future Send As for agent outbound.
Decisions
- Google aliases over Cloudflare Email Routing — same domain (qoyn.ai), fewer moving parts, future outbound capability.
- 2026-03-12 — All agent emails updated to @qoyn.ai. These are aliases for viktor@qoyn.ai, managed in Google Workspace.
workforce-014
HumanP2
Refine LobsterDrew behavior and personality across channels
Description
LobsterDrew’s current configuration is minimal — a generic agent instruction file with no personality definition, no channel-specific behavior rules, and no model/thinking tuning. He needs a proper behavior spec that defines how he acts on Discord (his primary channel) versus Telegram (secondary), what tone and voice he uses, and how his model and thinking levels should be configured for different interaction types.
Current State
Model & Thinking
- Model: GPT-5.3-codex (OpenAI Codex) — single model for all interactions
- Thinking levels: Set per-task in board frontmatter (low/medium/high/max), but no channel-level defaults
- No distinction between Discord chat responses (should be fast/light) and task execution (may need deeper reasoning)
Personality
- No SOUL.md or personality file exists
- AGENT-lobsterdrew.md is purely operational (task protocol, JSON report format, scope rules)
- No defined voice, tone, humor style, or character traits
- Other agents have defined personalities (CrankyCrab is blunt/grumpy, PrawnSue is precise/dry-witted) — LobsterDrew has none
Discord Behavior
requireMention: false— responds to all messages in the Wild Us server (guild 1478996376653271201)allowFromlimited to 2 Discord user IDs (Anna and Victor)streaming: partial- No channel-specific behavior (e.g., different tone in #general vs #business vs #ideas)
- No rules about when to proactively engage vs. stay quiet
- No guidance on how to handle questions he doesn’t know the answer to
- The Discord server is a private team server for a team outside Qoyn AI — information boundaries critical
Telegram Behavior
- Telegram is enabled (
dmPolicy: allowlist,allowFrom: [1291467684]) - But BerryPi is the primary Telegram comms agent — LobsterDrew’s Telegram role is undefined
- No guidance on what Telegram should be used for vs. Discord
- Potentially redundant — or could serve a specific purpose (e.g., Victor-only private channel for wildus ops)
Role Definition
- Described as “Discord attendant + light tasks” but no detail on what “attendant” means in practice
- Task execution is well-defined (read board → execute → JSON report)
- But organic Discord engagement (reacting to team conversation, answering questions, sharing ideas) has zero guidance
Target State
After this task, LobsterDrew should have:
-
SOUL.md — A personality file defining his voice, humor, character traits, and how he presents himself. Crustacean-themed like the other agents. Warm, helpful, community-oriented — fits a Discord community role.
-
Channel behavior matrix — Clear rules for:
- Discord: When to respond, when to stay quiet. Tone per channel type (casual in #general, structured in #business). How to handle unknowns (admit it, don’t hallucinate). Proactive engagement rules.
- Telegram: Whether to keep it enabled and for what purpose. If kept: Victor-only ops channel for wildus status/alerts. If removed: disable cleanly.
-
Model & thinking configuration — Consider whether a single model is right for all contexts:
- Discord chat responses: fast model, low thinking (conversational, quick)
- Task execution: standard model, thinking per task frontmatter
- Could use different model tiers if OpenClaw supports per-channel model config
-
Reaction/engagement style — How LobsterDrew handles:
- Direct questions from team members
- Casual conversation (should he participate or stay out?)
- Creative brainstorming (contribute ideas or just listen?)
- Disagreements or conflicting opinions
- Topics outside his knowledge
-
Updated AGENT-lobsterdrew.md — Incorporate behavior rules alongside the existing task protocol
Files to Update
| File | Location | What Changes |
|---|---|---|
AGENT-lobsterdrew.md |
workforce/scripts/deploy/AGENT-lobsterdrew.md |
Add behavior rules, channel guidance, engagement style |
SOUL.md (new) |
TBD — needs to be created and deployed to klyuchi | Personality definition |
openclaw.json |
On klyuchi at ~lobsterdrew/.openclaw/openclaw.json |
Discord/Telegram channel config tweaks |
models.json |
On klyuchi at ~lobsterdrew/.openclaw/agents/main/agent/models.json |
Per-channel model/thinking config (if supported) |
CLAUDE.md |
workforce/CLAUDE.md |
Update LobsterDrew description with personality summary |
wildus.md |
workforce/board/projects/wildus.md |
Update agent notes with refined role |
Notes
- This is a design/planning task — Victor will refine the spec before any implementation.
- Implementation will likely be a separate task assigned to an agent (deploy config to klyuchi via SSH).
- Anna’s perspective on LobsterDrew’s Discord personality may matter — he’s a team-facing presence.
startersite-018
4mAgentP2
Test stale conversation notifier end-to-end
✓ startersite-017
Description
End-to-end test of the stale conversation notifier built in startersite-017. Verify that stale WhatsApp/Telegram intake conversations correctly trigger founder notification emails, and that dedup prevents duplicate alerts.
Acceptance Criteria
- Seed test conversation data in KV (2+ messages, last activity >6 hours ago) and confirm the
/api/stale-checkendpoint detects it - Verify the email contains the full chat transcript, client info, and collected data summary
- Confirm dedup works: calling
/api/stale-checka second time for the same conversation does NOT send another email - Confirm web form intakes are not flagged as stale
- Verify auth: requests without a valid bearer token are rejected (401)
- Verify the GitHub Actions
workflow_dispatchmanual trigger works - Document any bugs found as new board tasks
Context
- Stale check endpoint:
site/functions/api/stale-check.js - GitHub Actions workflow:
.github/workflows/stale-check.yml - Config:
STALE_HOURSvar inwrangler.toml,STALE_CHECK_SECRETin CF Pages env vars + GitHub secrets - Repo:
viktor-bering/startersite-ai
Notes
- 2026-03-13T06:12:26Z — Added local E2E harness for /api/stale-check, verified auth, dedup, email payloads, prefix filtering. Confirmed GitHub Actions workflow_dispatch on dev.
- Use Cloudflare Workers preview or wrangler dev for local testing where possible
- For email delivery, check Resend dashboard or use a test recipient
startersite-020
AgentP2
Test stale notifier with real Telegram conversation
✓ startersite-018
Description
Live end-to-end test of the stale conversation notifier using a real Telegram intake conversation. Clear all Telegram conversation state from KV first to start fresh, then initiate a real Telegram chat, abandon it partway through, and verify the stale notifier picks it up and sends the founder email.
Steps
- Clear all Telegram-related conversation keys from Cloudflare KV (use
wrangler kvCLI) - Start a real Telegram intake conversation with the bot (send 2+ messages)
- Stop responding and wait for the stale threshold (6 hours, or temporarily lower
STALE_HOURSfor testing) - Trigger
/api/stale-checkmanually via GitHub Actionsworkflow_dispatchor direct HTTP call - Verify founder receives the notification email with full Telegram transcript
- Trigger stale check again — confirm no duplicate email is sent
Acceptance Criteria
- Telegram KV state is cleared before test begins
- Real Telegram conversation triggers stale detection after going idle
- Founder email contains the correct Telegram transcript, client info, and collected data
- Dedup prevents a second notification for the same conversation
- KV state is clean and consistent after the test
Context
- Repo:
viktor-bering/startersite-ai - Stale check endpoint:
site/functions/api/stale-check.js - Config:
STALE_HOURSinwrangler.toml - Consider temporarily setting
STALE_HOURSto a low value (e.g., 0.1) for faster testing, then restoring it
Notes
- Document any issues found as new board tasks
workforce-022
AgentP2
Update OpenClaw to 2026.3.11 on karymsky
Description
Update OpenClaw from 2026.3.8 to 2026.3.11 on karymsky.
Note: the original install was done by copying the npm package from klyuchi because npm install was too slow on this 2012 MBA. Try npm install -g openclaw@2026.3.11 first — an update should be faster than a fresh install. If npm is still too slow, copy the updated package from klyuchi (after workforce-020 completes).
Steps
- Check current version:
openclaw --version - Update the npm package:
npm install -g openclaw@2026.3.11 - If step 2 is too slow (>10 min), fall back to copying from klyuchi:
scp -r berrypi@10.0.0.220:/usr/lib/node_modules/openclaw /usr/lib/node_modules/openclaw- Adjust paths as needed for the actual global npm prefix
- Verify new version:
openclaw --version— should show 2026.3.11 - Restart PrawnSue gateway (:18790) so it picks up the new version
- Verify agent polls successfully after restart
Acceptance Criteria
openclaw --versionreturns 2026.3.11 on karymsky- PrawnSue gateway (:18790) running with new version
- Agent completes at least one successful poll cycle after update
workforce-020
AgentP2
Update OpenClaw to 2026.3.11 on klyuchi
Description
Update OpenClaw from 2026.3.8 to 2026.3.11 on klyuchi. This covers both BerryPi and LobsterDrew since they share the same machine.
Steps
- Check current version:
openclaw --version - Update the npm package:
npm install -g openclaw@2026.3.11 - Verify new version:
openclaw --version— should show 2026.3.11 - Restart both gateways (BerryPi on :18789, LobsterDrew on :18795) so they pick up the new version
- Verify both agents poll successfully after restart
Acceptance Criteria
openclaw --versionreturns 2026.3.11 on klyuchi- BerryPi gateway (:18789) running with new version
- LobsterDrew gateway (:18795) running with new version
- Both agents complete at least one successful poll cycle after update
workforce-021
27mAgentP2
Update OpenClaw to 2026.3.11 on tolbachik
Description
Update OpenClaw from 2026.3.8 to 2026.3.11 on tolbachik.
Steps
- Check current version:
openclaw --version - Update the npm package:
npm install -g openclaw@2026.3.11 - Verify new version:
openclaw --version— should show 2026.3.11 - Restart CrankyCrab gateway (:18789) so it picks up the new version
- Verify agent polls successfully after restart
Acceptance Criteria
openclaw --versionreturns 2026.3.11 on tolbachik- CrankyCrab gateway (:18789) running with new version
- Agent completes at least one successful poll cycle after update
wildus-025
HumanP2
Add logo to site/ folder in wildus repo
Description
Download the WildUs logo from R2 object storage and commit it to the wildus repo under site/assets/.
Acceptance Criteria
- Logo downloaded from R2:
wildus-media/discord/ready-for-printing/2026-03-06/svg-logo/logo1.svg - Committed to
site/assets/logo.svginwild-us/wildusrepo
Context
- Repo:
wild-us/wildus(already exists, all agents have access) - R2 bucket:
wildus-mediaon Cloudflare
Dependencies
None
Notes
Decisions
wildus-026
<1mAgentP2
Build placeholder page for wildus.org
✓ wildus-025
Description
Create a simple placeholder page for wildus.org using the logo already committed to the repo.
Acceptance Criteria
site/index.htmlexists with centered WildUs logo on white background- Mobile-friendly
- No frameworks — vanilla HTML/CSS only
- Logo referenced from
assets/logo.svg
Context
- Repo:
wild-us/wildus - Logo location:
site/assets/logo.svg - This is a temporary placeholder — just the logo centered on white
Dependencies
Depends on wildus-025 (logo must be in the repo first).
Notes
- 2026-03-12T09:39:01Z — Confirmed the placeholder page is implemented at site/index.html and already committed on the current branch. The page uses plain HTML/CSS, centers the existing logo on a white background, and is responsive for mobile.
Decisions
- Kept the implementation as a single static HTML file with inline CSS to match the temporary placeholder scope.
- Used simple responsive width constraints and viewport settings so the logo scales cleanly on mobile without extra dependencies.
wildus-027
HumanP2
Deploy wildus.org to Cloudflare Pages
✓ wildus-026
Description
Create a Cloudflare Pages project for the wildus site and configure the custom domain.
Acceptance Criteria
- Cloudflare Pages project created, connected to
wild-us/wildusrepo - Build output configured from
site/directory - Custom domain
wildus.orgconfigured and working - Deployment verified — placeholder page visible at wildus.org
Context
- Repo:
wild-us/wildus - Static files in
site/— no build step needed - wildus.org DNS already on Cloudflare
Dependencies
Depends on wildus-026 (placeholder page must be built first).
Notes
- 2026-03-12 — Done. Cloudflare Pages project connected to
wild-us/wildus, deploying fromdevbranch, output dirsite/. Custom domain wildus.org configured. Production branch set todevtemporarily — needs switching tomainafter dev→main merge (see wildus-028).
Decisions
startersite-004
AgentP2
Draft LLC single-member operating agreement
Description
Draft a Washington State single-member LLC operating agreement for Qoyn AI LLC. Use a standard template appropriate for a single-member, member-managed LLC. This is a short document (2-3 pages) that establishes the LLC as a separate entity.
Acceptance Criteria
- Valid WA single-member LLC operating agreement covering: purpose, member info, management structure, capital contributions, profit/loss allocation, dissolution terms
- Placeholder fields clearly marked for Viktor to fill in (e.g.,
[MEMBER NAME],[DATE],[INITIAL CONTRIBUTION]) - Saved to
docs/legal/operating-agreement.mdingit@github.com:qoyn-ai/qoyn-ai.git - Includes brief instructions at the top explaining what to fill in and whether notarization is needed (it’s not, in WA)
Context
- Entity: Qoyn AI LLC, Washington State, filed Feb 10, 2026
- Single member: Viktor Potapenko
- Member-managed (no separate managers)
- WA does not require filing the operating agreement — it’s an internal document
- Repo:
git@github.com:qoyn-ai/qoyn-ai.git - Legal docs location:
docs/legal/
Dependencies
None
Notes
-
2026-03-11 00:57 PT — Cloned
git@github.com:qoyn-ai/qoyn-ai.gitto/home/prawnsue/qoyn-ai; repo currently hasmainonly (nodevbranch). -
2026-03-11 00:59 PT — Drafted
docs/legal/operating-agreement.mdas a Washington single-member, member-managed LLC template for Qoyn AI LLC with fill-in placeholders, top-of-file completion instructions, and explicit note that notarization is not required in WA. -
2026-03-11 02:37 PT — Foreman self-review: acceptance verified objectively.
docs/legal/operating-agreement.mdexists on karymsky in~/qoyn-aiand includes the required WA single-member LLC sections, fill-in placeholders, and top-of-file notarization guidance. Moving todone/.
Decisions
startersite-009
AgentP2
Execute citation claims for Bing, Apple, and Facebook
Description
Use the existing citation tracker and live browser flows to complete the remaining StarterSite citation work for Bing Places, Apple Business Connect, and Facebook. If a platform cannot be completed, capture the exact blocker and stop at the narrowest honest boundary.
Acceptance Criteria
- Attempt the live claim/create flow for each of: Bing Places, Apple Business Connect, Facebook Page / business listing
- Use the already-established canonical public NAP consistently
- Update
startersite-ai/docs/growth/seo-citations-tracker.mdwith outcome and current status for each platform - If blocked, document the exact blocker per platform (login, verification code, CAPTCHA, ownership conflict, policy mismatch, paid gate, etc.)
- Move to
in-reviewif all three platforms are either completed or documented with exact blockers
Context
- Repo:
git@github.com:viktor-bering/startersite-ai.git(branchdev) - Tracker:
startersite-ai/docs/growth/seo-citations-tracker.md - GBP is already set up
- Canonical public address/NAP is already normalized and should be used consistently everywhere
- Browser use is authorized for the live submission pass
Dependencies
None
Notes
- 2026-03-11 04:45 PT — Executed live browser pass for Bing Places, Apple Business Connect, and Facebook Page creation. Bing immediately redirects the management path to
genericLoginand requires Microsoft/work/Facebook auth before claim/import can proceed. Apple Business Connect loads publicly but routesGet Started/Sign Ininto Apple Account auth before any business data can be submitted, with Apple business verification still downstream. Facebook’spages/createroute loads while signed out, but actual page creation still requires a logged-in Facebook personal account to own/admin the page. Updated~/startersite-ai/docs/growth/seo-citations-tracker.mdwith exact status/blockers for all three platforms. - 2026-03-11 05:26 PT — Foreman self-review: acceptance verified objectively. All three scoped platforms were attempted and the tracker was updated with exact blockers, so this task meets its in-review completion bar and moves to
done/.
Decisions
workforce-010
AgentP2
Build static kanban site generator and UI
Description
Build a Node.js static site generator that reads the workforce git board (board/ directory) and outputs a dark-mode Trello-style kanban web UI.
The generator should:
- Parse all task files in
board/{backlog,in-progress,in-review,done,blocked}/— YAML frontmatter + markdown body - Parse all project files in
board/projects/for project metadata - Generate static HTML output to
kanban/dist/
The UI should:
- Display a classic kanban board with 5 columns: Backlog, In Progress, In Review, Done, Blocked
- Dark mode styling
- Each task rendered as a card showing: title, assignee, project badge, priority (1-5), created/updated timestamps
- Clicking a card expands it to show the full rendered markdown content (description, acceptance criteria, context, notes, decisions)
- Generate one kanban page per project (e.g.,
dist/infra/index.html,dist/wildus/index.html) plus one “all projects” admin page atdist/index.html - Responsive — usable on mobile
Acceptance Criteria
- [ ]
node kanban/generate.jsreadsboard/and outputs static HTML tokanban/dist/ - [ ] All 5 column states rendered as kanban columns
- [ ] Task cards display title, assignee, project, priority, timestamps
- [ ] Card click expands to show full rendered markdown
- [ ] Per-project pages generated at
dist/<project-id>/index.html - [ ] Admin “all projects” page at
dist/index.html - [ ] Dark mode styling, clean Trello-style layout
- [ ] Works with current board contents (6 existing tasks across 3 projects)
- [ ] No frameworks — vanilla HTML/CSS/JS plus a markdown parsing library
- [ ]
package.jsoninkanban/with dependencies and abuildscript
Context
- Repo:
git@github.com:qoyn-ai/workforce.git - Board spec:
board/README.md - Task file format: YAML frontmatter (id, project, title, assigned, thinking, escalation, priority, tags, created, updated) + markdown sections (Description, Acceptance Criteria, Context, Dependencies, Notes, Decisions)
- Project file format: YAML frontmatter (id, name, org, repos) in
board/projects/*.md - Board columns map to directories:
backlog/,in-progress/,in-review/,done/,blocked/ - See existing task files for examples of the format
Dependencies
None
Notes
- 2026-03-10 17:11 America/Los_Angeles — Built
kanban/static generator withgray-matter+markdown-it, pluspackage.json/package-lock.jsonandnpm run buildentrypoint. - 2026-03-10 17:11 America/Los_Angeles — Generator now reads all board column task files and project metadata, then writes
kanban/dist/index.html, per-project pages underkanban/dist/<project>/index.html, and sharedstyles.css/app.jsassets. - 2026-03-10 17:11 America/Los_Angeles — Verified build locally with current board contents:
cd kanban && npm run buildproduced 8 task cards across 4 project pages with dark-mode responsive layout and expandable markdown card bodies. - 2025-07-14 — Reviewed and approved. All acceptance criteria met. Deployed to Cloudflare Pages with git integration, custom domain, and Cloudflare Access authentication.
Decisions
workforce-011
AgentP2
GitHub Action for Cloudflare Pages deployment
Description
Create a GitHub Actions workflow that automatically builds the kanban static site and deploys it to Cloudflare Pages whenever the board changes.
Acceptance Criteria
- [ ] Workflow file at
.github/workflows/deploy-kanban.yml - [ ] Triggers on pushes to
mainthat touchboard/**orkanban/** - [ ] Runs
npm ciinkanban/directory, thennpm run build - [ ] Deploys
kanban/dist/to Cloudflare Pages usingcloudflare/wrangler-action - [ ] Uses repository secrets:
CLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_ID - [ ] Workflow succeeds with current board contents
Context
- Repo:
git@github.com:qoyn-ai/workforce.git - Generator from kanban-001 outputs to
kanban/dist/ - Cloudflare Pages project name and secrets will be configured manually (separate task)
- Reference: https://developers.cloudflare.com/pages/how-to/use-direct-upload-with-continuous-integration/#github-actions
Dependencies
- kanban-001 (static generator must exist first)
Notes
- 2026-03-10 17:00 America/Los_Angeles — Left in backlog. Dependency
kanban-001is not complete yet, and CrankyCrab already has one active in-progress task. - 2026-03-10 17:18 America/Los_Angeles — Added
.github/workflows/deploy-kanban.ymlto buildkanban/on pushes touchingboard/**orkanban/**and deploykanban/dist/viacloudflare/wrangler-action. - 2026-03-10 17:19 America/Los_Angeles — Validated the current generator locally with
npm ci && npm run buildinkanban/(Generated 8 tasks across 4 projects into kanban/dist). Workflow expects repository variableCLOUDFLARE_PAGES_PROJECT_NAMEplus secretsCLOUDFLARE_API_TOKENandCLOUDFLARE_ACCOUNT_ID. - 2025-07-14 — CANCELLED. Switching to Cloudflare git integration instead of GitHub Action + direct upload. Workflow file removed. Deployment will be handled natively by Cloudflare Pages.
Decisions
workforce-024
AgentP3
Install Agent Browser on BerryPi
Description
Install and configure Agent Browser (Vercel’s headless browser CLI) on the BerryPi machine and hook it up to OpenClaw via the ClawHub skill. This gives OpenClaw a token-efficient browser (93% fewer tokens than Playwright) for web automation tasks.
Acceptance Criteria
agent-browserbinary installed globally via npm- Chrome for Testing downloaded via
agent-browser install --with-deps - Verified working:
agent-browser open https://example.com && agent-browser snapshot -i && agent-browser close - ClawHub skill
thesethrose/agent-browserinstalled - OpenClaw restarted and skill confirmed loaded
Installation Steps
# 1. Install binary
npm install -g agent-browser
# 2. Install Chrome + Linux system dependencies (required for headless Linux)
agent-browser install --with-deps
# 3. Verify
agent-browser open https://example.com
agent-browser snapshot -i
agent-browser close
# 4. Install OpenClaw skill
clawhub install thesethrose/agent-browser
# (install clawhub first if needed: npm install -g clawhub)
# 5. Restart OpenClaw
openclaw gateway restart
Context
- BerryPi is headless Linux arm64 (Raspberry Pi)
- Agent Browser is a Rust-based CLI by Vercel — built for headless server environments
--with-depsflag installs required X11/display libs for Linux even in headless mode- The skill auto-fetches its SKILL.md from GitHub — do not copy it manually
- Reference: https://github.com/vercel-labs/agent-browser
- OpenClaw skill: https://github.com/openclaw/skills/blob/main/skills/thesethrose/agent-browser/SKILL.md
Dependencies
None
Notes
Decisions
workforce-025
AgentP3
Install AgentMail on BerryPi
Description
Install and configure AgentMail on BerryPi so OpenClaw has its own dedicated email inbox. AgentMail is a Y Combinator-backed email service built specifically for AI agents — avoids Google banning accounts used by agents.
Acceptance Criteria
- AgentMail account created at console.agentmail.to (free tier: 3 inboxes)
- API key obtained from AgentMail Console
- Inbox name noted (format:
yourname@agentmail.to) - ClawHub skill installed and configured with API key
- OpenClaw restarted and skill confirmed loaded
- Test: forward an email to the inbox and verify OpenClaw surfaces it in Telegram
Installation Steps
# 1. Install the skill via ClawHub
npx clawhub@latest install agentmail
# 2. Add API key to OpenClaw config (~/.openclaw/openclaw.json)
# Add under skills.entries.agentmail.env:
{
"skills": {
"entries": {
"agentmail": {
"enabled": true,
"env": {
"AGENTMAIL_API_KEY": "your-api-key-here"
}
}
}
}
}
# 3. Verify skill is loaded
openclaw skills list --eligible
# Should show "agentmail" in the list
# 4. Restart OpenClaw
openclaw gateway restart
Pre-requisites (manual steps before running above)
- Go to https://agentmail.to → Get Started
- Sign up (Google login works)
- Create an inbox (free tier gives 3)
- Copy the API key from the dashboard
Context
- AgentMail docs: https://docs.agentmail.to/integrations/openclaw
- Free tier: 3 inboxes, generous limits
- Use cases: personal email summaries, forwarding invoices/newsletters, business support inbox
- Alternative to Gmail (which Google may ban for agentic use)
Dependencies
None
Notes
Decisions
wildus-018
AgentP3
Register Facebook page for Wild Us
✓ wildus-003✓ wildus-014✓ workforce-015✓ workforce-016
Description
Create the Wild Us Facebook business page. Registration priority #6 — @wildus is taken (personal profile: Marek Wild); will need fallback handle. Lowest priority — Facebook pages can be created anytime after Meta/Instagram account exists.
After registration, document the signup flow so we have a playbook for future brands on this platform.
Acceptance Criteria
- Facebook business page created with handle (per checklist fallback order:
@wildus→@wildus_official→@wildusbrand) - Page description and bio set
- Profile picture placeholder set
- 2FA enabled on the personal account (authenticator app preferred)
- Recovery codes saved
- vault/brand/claimed-handles.md updated
- Signup flow documented — write up what happened in the task notes: fields per step, verification gates, anti-bot measures, profile setup options, quirks
Context
@wilduson Facebook: occupied (personal profile — Marek Wild).@wild.usalso resolves to same.- Signup email:
facebook@wildus.org(Google Workspace alias → viktor@qoyn.ai) - Facebook uses Meta path — can reuse Meta account from Instagram registration
- Facebook pages require a personal account as admin
- See vault/brand/social-handle-registration-checklist.md
Default Data
| Field | Value |
|---|---|
| Signup email | facebook@wildus.org |
| Display name | Wild Us |
| Handle (in order) | @wildus → @wildus_official → @wildusbrand |
| DOB (if required) | 01/01/2000 |
| Page description | Wild and unbothered 🌲 PNW wildlife apparel with a conservation mission. Coming soon → wildus.org |
| Profile picture | Check wildus/site/ or wildus/assets/ for a placeholder |
| Signup path | Meta native credentials (NOT Google SSO) |
Steps
- Open a clean browser session
- Navigate to https://www.facebook.com/r.php
- Sign up with email
facebook@wildus.org— use Meta native credentials (same path as Instagram) - Fill in the form using the default data above
- At any verification gate (email code, CAPTCHA, phone):
- Run
notify-viktor "<what you need>"— sends Telegram with Screen Share button - Run
wait-for-viktor— blocks until Viktor connects, handles it, and disconnects - Resume once
wait-for-viktorreturns
- Run
- After personal account is created, create a Facebook Page for
Wild Us - Set page username: try
@wildusfirst (taken — Marek Wild). Try@wildus_official→@wildusbrand - Set page description using the default data above
- Set profile picture if a placeholder is available in the repo
- Enable 2FA on the personal account (authenticator app preferred)
- Save recovery codes
- Update
vault/brand/claimed-handles.mdwith the claimed handle, email, date, and status
After Registration — Document the Flow
Write up the signup experience in the task notes using the format from the social handle registration process.
If You Get Stuck
If you hit a blocker that requires human input (CAPTCHA, phone verification, manual confirmation, email verification code):
- Run
notify-viktor "<description of what you need>"— this sends a Telegram message with a Screen Share button - Run
wait-for-viktor— blocks until Viktor connects via Screen Sharing, handles the gate, and disconnects - Once
wait-for-viktorreturns, resume your work - Fallback: If
wait-for-viktoris not available or times out, poll the page state every 5 seconds — watch for changes - Do NOT retry aggressively — one calm attempt, then notify and wait
Dependencies
wildus-003 (handle checklist — done), wildus-014 (Instagram — Meta account created there first)
Notes
- 2026-03-12 — Priority unchanged at #6 (last). Depends on having a Meta account from Instagram registration. Google Workspace on qoyn.ai replaces the Gmail anchor strategy.
- 2026-03-13 — Merged with single-pass approach. No separate recon — document the flow as a byproduct of registration.
- 2026-03-13 — Facebook Page created by Viktor under his personal Facebook account. Page is part of Viktor’s Facebook Business Portfolio. Category: Apparel & Clothing. Location: Vancouver, WA. Bio set. Website: wildus.org. Social links added: Instagram, TikTok, Pinterest. No username/handle set — Facebook may require page age or follower count before allowing one. Page can be transferred to a dedicated admin account later.
Decisions
wildus-017
AgentP3
Register Pinterest account for Wild Us
✓ wildus-003⌛ wildus-013✓ workforce-015✓ workforce-016
Description
Create the Wild Us Pinterest business account. Registration priority #5 — @wildus is taken (active account with boards); will need fallback handle.
After registration, document the signup flow so we have a playbook for future brands on this platform.
Acceptance Criteria
- Pinterest business account created with handle (per checklist fallback order:
@wildus→@wild.us→@wildus_official→@wildusbrand) - Bio drafted and set
- 2FA enabled
- Recovery codes saved
- vault/brand/claimed-handles.md updated
- Signup flow documented — write up what happened in the task notes: fields per step, verification gates, anti-bot measures, profile setup options, quirks
Context
@wilduson Pinterest: occupied (active — has boards)@wildusbrand: appears open- Signup email:
pinterest@wildus.org(Google Workspace alias → viktor@qoyn.ai) - See vault/brand/social-handle-registration-checklist.md
Default Data
| Field | Value |
|---|---|
| Signup email | pinterest@wildus.org |
| Display name | Wild Us |
| Handle (in order) | @wildus → @wild.us → @wildus_official → @wildusbrand |
| Bio | Wild and unbothered 🌲 PNW wildlife apparel with a conservation mission. Coming soon → wildus.org |
| Profile picture | Check wildus/site/ or wildus/assets/ for a placeholder |
| Account type | Business |
Steps
- Open a clean browser session
- Navigate to https://www.pinterest.com/business/create/
- Sign up with email
pinterest@wildus.org— create as a Pinterest business account - Fill in the form using the default data above
- At any verification gate (email code, CAPTCHA, phone):
- Run
notify-viktor "<what you need>"— sends Telegram with Screen Share button - Run
wait-for-viktor— blocks until Viktor connects, handles it, and disconnects - Resume once
wait-for-viktorreturns
- Run
- Set username: try
@wildusfirst (likely taken — active account). Try@wild.us→@wildus_official→@wildusbrand - Complete any profile setup steps (bio, avatar — skip what’s skippable, fill in what’s useful)
- Enable 2FA if available
- Save recovery codes
- Update
vault/brand/claimed-handles.mdwith the claimed handle, email, date, and status
After Registration — Document the Flow
Write up the signup experience in the task notes using the format from the social handle registration process.
If You Get Stuck
If you hit a blocker that requires human input (CAPTCHA, phone verification, manual confirmation, email verification code):
- Run
notify-viktor "<description of what you need>"— this sends a Telegram message with a Screen Share button - Run
wait-for-viktor— blocks until Viktor connects via Screen Sharing, handles the gate, and disconnects - Once
wait-for-viktorreturns, resume your work - Fallback: If
wait-for-viktoris not available or times out, poll the page state every 5 seconds — watch for changes - Do NOT retry aggressively — one calm attempt, then notify and wait
Dependencies
wildus-003 (handle checklist — done), wildus-013 (YouTube — do YouTube first)
Notes
- 2026-03-12 — Priority unchanged at #5. Google Workspace on qoyn.ai replaces the Gmail anchor strategy.
- 2026-03-13 — Merged with single-pass approach. No separate recon — document the flow as a byproduct of registration.
- 2026-03-13 — Registered by Viktor. Email:
viktor@wildus.org(Pinterest rejectedpinterest@wildus.org). Username:WildUs_official. 2FA enabled. Bio set.
Decisions
wildus-028
HumanP3
Merge dev→main and switch Cloudflare Pages to main branch
Description
Merge the wildus dev branch into main via PR, then switch the Cloudflare Pages production branch from dev to main.
Acceptance Criteria
- PR created from dev→main in
wild-us/wildus - PR reviewed and merged
- Cloudflare Pages production branch changed from
devtomain(Settings → Builds & deployments) - Deployment from
mainverified — wildus.org still working
Context
- Cloudflare Pages currently deploys from
devbecausemainis behind - Convention: agents push to dev, Victor merges dev→main
- Once main is caught up, Pages should deploy from main (the stable branch)
Dependencies
None — do this whenever Victor is ready to sync dev→main.
Notes
Decisions
startersite-008
AgentP3
SEO local citations Phase 1
Description
Submit startersite.ai to key local business directories and citation sources for Portland metro SEO. Follow the G2 and G4 playbooks for local citation building.
Acceptance Criteria
- Google Business Profile created/claimed and fully optimized (photos, description, categories, hours)
- Submitted to top 10 local directories (Yelp, BBB, Nextdoor Business, Portland Business Journal, etc.)
- NAP (Name, Address, Phone) consistent across all listings
- Citations documented in a tracking spreadsheet or markdown file
- Saved to
startersite-ai/docs/growth/seo-citations-tracker.md
Context
- GBP setup guide:
startersite-ai/docs/growth/G2-gbp-setup.md - SEO strategy:
startersite-ai/docs/growth/G4-seo-content-strategy.md - Business: Qoyn AI LLC DBA startersite.ai, Portland metro area
- Phone: (360) 800-1177
Dependencies
None (background growth work, runs in parallel with launch)
Notes
- 2026-03-11 01:12 PT — CrankyCrab: Read the linked startersite project brief plus the available growth docs. Created
startersite-ai/docs/growth/seo-citations-tracker.mdwith canonical NAP, current known listing status, GBP optimization checklist, and a prioritized Phase 1 citation target list; pushed ondevinc383432. - 2026-03-11 01:12 PT — CrankyCrab: Full completion is blocked on live third-party account actions and verification flows (GBP audit/optimization, Yelp/BBB/Nextdoor/Bing/Apple/Facebook submissions/claims). Left in progress rather than falsely marking done.
- 2026-03-11 00:59 PT — CrankyCrab: Did a second pass in
~/startersite-ai. Tighteneddocs/growth/seo-citations-tracker.mdwith direct claim URLs, public-status notes for already-known profiles, and a founder handoff checklist for the live submission pass. Committed/pushed ondevinfa69abf. - 2026-03-11 01:00 PT — CrankyCrab: Acceptance criteria still not honestly met. I did not create/claim third-party directory listings without the required live account / verification steps.
- 2026-03-11 01:17 PT — CrankyCrab: Did another research/documentation pass and pushed
~/startersite-aicommitc4ff043ondev. Refineddocs/growth/seo-citations-tracker.mdwith a dated public-research audit, tightened the local directory shortlist, and demoted Portland Business Journal from “core citation” to optional/paid visibility. - 2026-03-11 01:17 PT — CrankyCrab: Task still blocked on live owner actions for GBP audit plus Yelp / BBB / Nextdoor / Bing Places / Apple Business Connect / Facebook / chamber submissions. Keeping in
in-progressinstead of pretending the internet filled itself out. - 2026-03-11 01:11 PT — CrankyCrab: Did another documentation pass in
~/startersite-aiand pushed commit15e5927ondev. Tighteneddocs/growth/seo-citations-tracker.mdwith a fresh site audit timestamp, a Phase 1 execution sheet (claim URLs, required owner account, verification gate, target end-state), and a shortest-path checklist to finish the live citation pass once founder account access is available. - 2026-03-11 01:11 PT — CrankyCrab: Acceptance criteria are still not truthfully complete because the remaining work is almost entirely third-party owner/verification flow, not repo work.
- 2026-03-11 01:31 PT — CrankyCrab: Did a cleanup pass in
~/startersite-aiand pusheddevcommit04c5956. Added a concrete founder live-pass kit todocs/growth/seo-citations-tracker.mdso the eventual third-party submission session has the exact minimum inputs/docs ready before opening Yelp / BBB / Bing / Apple / Nextdoor / Meta. - 2026-03-11 01:31 PT — CrankyCrab: Still not moving this to
in-review. Acceptance criteria require actual directory submissions / claims and a live GBP optimization audit, which I did not fake my way through without owner logins or verification flow access. - 2026-03-11 02:40 PT — Founder clarification: GBP for StarterSite is already set up. Canonical public address/NAP is already normalized and should be used consistently everywhere. Browser use is authorized for the live citation pass. Finish the remaining directory claims/submissions unless a concrete blocker remains.
- 2026-03-11 02:40 PT — Foreman instruction: Continue execution for the remaining live platforms using browser flows. If the task cannot be completed, move it to
blocked/and document the exact blocker per platform (for example: missing login, missing verification code, CAPTCHA, paid gate, account ownership, or platform policy mismatch). Do not leave it inin-progresswith only generic uncertainty. - 2026-03-11 03:17 PT — Foreman split out
startersite-009for PrawnSue to handle the Bing Places / Apple Business Connect / Facebook live pass so the external-submission work can proceed in parallel and with platform-specific accountability. - 2026-03-11 02:32 PT — CrankyCrab: Did a live site / machine-readable NAP audit and pushed
~/startersite-aicommit990376condev. Updateddocs/growth/seo-citations-tracker.mdwith a real blocker the earlier passes had not called out cleanly: the public site currently exposes505 SE 184th Ave, Vancouver, WA 98683inLocalBusinessJSON-LD andllms*.txt, which may conflict with the service-area / hidden-address citation plan. - 2026-03-11 02:32 PT — CrankyCrab: Keeping this in
in-progress. Before broad directory submission, founder needs to make an explicit NAP decision: either keep that full street address as canonical everywhere, or remove/normalize the public address surfaces first and then submit citations consistently. The third-party claim/create work is still owner-login / verification gated. - 2026-03-11 03:34 PT — CrankyCrab: Did the live browser pass the foreman asked for and pushed
~/startersite-aicommite0617faondev. Updateddocs/growth/seo-citations-tracker.mdwith live findings for Yelp / BBB / Nextdoor / ChamberofCommerce plus the split-out ownership of Bing / Apple / Facebook understartersite-009. - 2026-03-11 03:34 PT — CrankyCrab: Concrete blockers are now documented per platform instead of hiding behind mushy uncertainty: Yelp requires owner login/sign-up + verification, BBB requires owner-led profile claim/submission + review, Nextdoor stops immediately at business-account creation, and ChamberofCommerce requires account creation plus CAPTCHA. Because the remaining work is external owner-account / verification flow, this task should move to
blocked/rather than pretending it is nearly done.
Decisions
- 2026-03-11 01:12 PT — CrankyCrab: Created
startersite-ai/docs/growth/seo-citations-tracker.mdas the working citation source of truth with canonical NAP, current known profile status (GBP/Instagram/LinkedIn/Facebook), GBP optimization checklist, and a prioritized target-directory list. - 2026-03-11 01:12 PT — CrankyCrab: This task is not fully complete yet. Several acceptance items require live account ownership, verification, CAPTCHA/SMS/email flows, or membership decisions on third-party platforms (e.g. Yelp/BBB/Nextdoor/Bing/Apple/Facebook). Those external listing actions were not executed in this pass.
Blocked
3
wildus-013
AgentP2
Register YouTube channel for Wild Us
✓ wildus-003✓ wildus-014✓ workforce-015✓ workforce-016
Description
Create the Wild Us YouTube channel. Registration priority #4 — @wildus is taken (empty channel); fallback handles (@wild.us, @wildus_official, @wildusbrand) all appear open.
After registration, document the signup flow so we have a playbook for future brands on this platform.
Acceptance Criteria
- YouTube channel created with Wild Us branding
- Handle claimed (per checklist fallback order:
@wildus→@wild.us→@wildus_official→@wildusbrand) - Channel description set
- vault/brand/claimed-handles.md updated
- Signup flow documented — write up what happened in the task notes: fields per step, verification gates, anti-bot measures, profile setup options, quirks
Context
@wilduson YouTube: occupied (no content, empty channel)@wild.us,@wildus_official,@wildusbrand: all show 404 — likely available- Signup email:
youtube@wildus.org(Google Workspace alias → viktor@qoyn.ai) - YouTube is a Google product — can use Google Workspace SSO
- See vault/brand/social-handle-registration-checklist.md
Default Data
| Field | Value |
|---|---|
| Signup email | youtube@wildus.org |
| Channel name | Wild Us |
| Handle (in order) | @wildus → @wild.us → @wildus_official → @wildusbrand |
| Channel description | Wild and unbothered 🌲 PNW wildlife apparel with a conservation mission. Coming soon → wildus.org |
| Profile picture | Check wildus/site/ or wildus/assets/ for a placeholder |
| Signup path | Google Workspace SSO |
Steps
- Open a clean browser session
- Navigate to https://www.youtube.com and sign in with
youtube@wildus.orgvia Google Workspace SSO - At any verification gate (Google verification, CAPTCHA):
- Run
notify-viktor "<what you need>"— sends Telegram with Screen Share button - Run
wait-for-viktor— blocks until Viktor connects, handles it, and disconnects - Resume once
wait-for-viktorreturns
- Run
- Create a YouTube channel with name
Wild Us - Set handle: try
@wildusfirst (likely taken). Try@wild.us→@wildus_official→@wildusbrand - Set channel description using the default data above
- Set profile picture if a placeholder is available in the repo
- Update
vault/brand/claimed-handles.mdwith the claimed handle, email, date, and status
After Registration — Document the Flow
Write up the signup experience in the task notes using the format from the social handle registration process.
If You Get Stuck
If you hit a blocker that requires human input (CAPTCHA, phone verification, manual confirmation, email verification code):
- Run
notify-viktor "<description of what you need>"— this sends a Telegram message with a Screen Share button - Run
wait-for-viktor— blocks until Viktor connects via Screen Sharing, handles the gate, and disconnects - Once
wait-for-viktorreturns, resume your work - Fallback: If
wait-for-viktoris not available or times out, poll the page state every 5 seconds — watch for changes - Do NOT retry aggressively — one calm attempt, then notify and wait
Dependencies
wildus-003 (handle checklist — done), wildus-014 (Instagram — do Instagram first)
Notes
- 2026-03-12 — Reprioritized to #4. Google Workspace on qoyn.ai replaces the Gmail anchor strategy. Fallback handles look good — low urgency.
- 2026-03-13 — Merged with single-pass approach. No separate recon — document the flow as a byproduct of registration.
- 2026-03-13 — YouTube access blocked. Google Workspace requires one of: (1) $30+ in payments, (2) account age 30+ days. Workspace trial payment starts in ~12 days (around 2026-03-25). Signup email
youtube@wildus.orgis an alias, not a separate Google account — must use Brand Account underviktor@qoyn.ai. Revisit after trial payment processes.
Decisions
startersite-011
HumanP2
Claim BBB business profile
Description
Claim StarterSite.ai’s Better Business Bureau (BBB) profile using the recon pattern (two-pass approach).
Blocker Details
BBB requires an owner-led profile claim and review process. May involve accreditation fees or a review period. Cannot be automated.
Approach
Use the recon pattern (two-pass approach):
- Recon pass: Navigate through the BBB business claim/registration flow without submitting. Document every field, fee structure, accreditation options, and verification steps. Capture screenshots.
- Execution pass: Complete the registration using the documented requirements from the recon pass.
Reference: workforce/docs/processes/social-handle-registration-process.md
Acceptance Criteria
- BBB profile created or claimed for StarterSite.ai
- NAP info matches canonical: StarterSite.ai / 505 SE 184th Ave, Vancouver, WA 98683 / (360) 800-1177
- Business description and category populated
- Profile visible on BBB website
Context
- Source: startersite-008 (SEO citations batch) and
startersite-ai/docs/growth/seo-citations-tracker.md
Notes
- 2026-03-13 — Registration submitted via BBB Great West + Pacific portal (viktor@startersite.ai). Waiting for BBB to send login instructions. Title field needs fixing to “Owner” (was entered as “Bering”). No confirmation email received yet — check back later.
Decisions
startersite-007
4d 16hAgentP3
Deploy voice agent to Azure Container Apps
Description
Deploy the voice-bridge application to Azure Container Apps using the existing Bicep IaC templates. The voice bridge handles Twilio Media Streams ↔ Azure OpenAI Realtime API for phone-based intake.
Acceptance Criteria
- Voice-bridge container built and pushed to Azure Container Registry
- Azure Container Apps environment provisioned via Bicep
- Application deployed and health check endpoint (
GET /health) returns 200 - Twilio voice webhook updated to point to the deployed Container App URL
- Test call to (360) 800-1177 connects to AI voice agent
- Environment variables configured (Azure OpenAI key, Twilio credentials)
Context
- Voice-bridge repo:
startersite.ai/voice-bridge/ - Bicep IaC:
voice-bridge/infra/ - Deployment guide:
voice-bridge/docs/AI-Voice-Agent-Deployment.md - Current voice endpoint (
/api/voice) does simple call forwarding — this replaces it with AI intake - Latest commit added structured intake collection (Mar 9)
Dependencies
None (nice-to-have for inbound calls, not a launch blocker)
Notes
- 2026-03-11 17:07 PT — Review check found this is not ready for
in-review: acceptance criteria are still blocked by missing access/tooling on karymsky (git@github.com:viktor-bering/voice-bridge.gitunavailable there;azanddockerabsent), so this cannot be approved or advanced further without new prerequisites. Moved toblocked/. - 2026-03-11 01:02 PT — Checked assigned worker state.
/home/prawnsue/startersite-aiis present, but the extractedvoice-bridge/repo referenced by Context is not in the checkout, andgit ls-remote git@github.com:viktor-bering/voice-bridge.git HEADreturned “Repository not found” from karymsky. Also verifiedaz,docker, andghare not installed on the worker, so the requested Azure Container Apps build/deploy flow cannot be executed from current machine state. - 2026-03-11 01:08 PT — Re-verified directly on karymsky.
startersite-aion branchdevcontains the Twilio voice webhook fallback (site/functions/api/voice.js) and now supports aVOICE_BRIDGE_URLenv var for Media Streams, but the extracted implementation/deployment assets are still absent locally (README.mdmarksvoice-bridge/andAI-Voice-Agent-Deployment.mdas moved out). Access togit@github.com:viktor-bering/voice-bridge.gitstill fails withRepository not found, and the worker still lacksazanddocker, so I cannot build/push the image, provision Azure Container Apps, update Twilio, or validate/health/ live call acceptance criteria from this machine. Leaving task blocked inin-progresspending repo access plus Azure/Docker tooling or reassignment to a provisioned worker. - 2026-03-11 01:11 PT — Fresh execution pass from assigned worker. Confirmed
~/startersite-aiis ondevate902527;site/functions/api/voice.jsreferencesVOICE_BRIDGE_URL, but the Context assets are still missing locally (voice-bridge/,voice-bridge/infra/, andvoice-bridge/docs/AI-Voice-Agent-Deployment.mdall absent).git ls-remote git@github.com:viktor-bering/voice-bridge.git HEADstill returnsRepository not found, and required deployment CLIs remain unavailable on this worker (az,docker,gh,twilioall missing). Result: task execution is blocked by missing source repo access and missing Azure/container deployment tooling, so none of the acceptance criteria can be completed from current machine state.