feat(hands): complete i18n fixes, SKILL.md enhancements, and README overhaul
- Fix French accent characters (é/è/ê/ç/â/ô) across all 14 HAND.toml files - Fix German special characters (ä/ö/ü/ß) across all 14 HAND.toml files - Add category translations to all 6 i18n language blocks in all 14 hands - Enhance SKILL.md content for 9 hands with practical examples and workflows - Trim bloated SKILL.md files (apitester 1400→892, devops 1301→870) - Rewrite root README.md with accurate stats, complete hand/integration tables - Update hands/README.md with full 14-hand listing and i18n documentation
This commit is contained in:
1 parent
315f955ce2
commit
33d279889c
27 files changed
+9994
-71
No files matched your search
@@ -1,46 +1,137 @@
|
|||||||
# LibreFang Registry
|
# LibreFang Registry
|
||||||
|
|
||||||
Community-maintained content registry for [LibreFang](https://github.com/librefang/librefang) -- the open-source Agent Operating System.
|
Community-maintained content registry for [LibreFang](https://github.com/librefang/librefang) — the open-source Agent Operating System.
|
||||||
|
|
||||||
This repository is the single source of truth for all installable content definitions. Anyone can submit a PR to add new agents, hands, integrations, skills, or provider models -- no changes to the LibreFang binary required.
|
This repository is the **single source of truth** for all installable content definitions. Anyone can submit a PR to add new agents, hands, integrations, skills, or provider models — no changes to the LibreFang binary required.
|
||||||
|
|
||||||
## Structure
|
## Overview
|
||||||
|
|
||||||
|
| Type | Count | Description |
|
||||||
|
|------|------:|-------------|
|
||||||
|
| [Hands](#hands) | 14 | User-facing "apps" — agent + tools + settings + dashboard |
|
||||||
|
| [Agents](#agents) | 32 | Autonomous agent definitions with model config and tools |
|
||||||
|
| [Integrations](#integrations) | 25 | MCP server connections (GitHub, Slack, DBs, etc.) |
|
||||||
|
| [Providers](#providers) | 48 | LLM provider & model metadata with pricing |
|
||||||
|
| [Models](#providers) | 223 | Individual model definitions across all providers |
|
||||||
|
| [Aliases](#aliases) | 70 | Short names mapped to canonical model IDs |
|
||||||
|
| [Plugins](#plugins) | 10 | Memory, guardrails, and conversation plugins |
|
||||||
|
| [Skills](#skills) | 2 | Reusable prompt templates and Python scripts |
|
||||||
|
|
||||||
|
## Repository Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
librefang-registry/
|
librefang-registry/
|
||||||
├── agents/ # Agent definitions (TOML manifests)
|
├── agents/ # Agent definitions (TOML manifests)
|
||||||
│ ├── hello-world/agent.toml
|
│ ├── hello-world/
|
||||||
│ ├── researcher/agent.toml
|
│ │ └── agent.toml
|
||||||
│ └── ... (33 agents)
|
│ ├── researcher/
|
||||||
├── hands/ # Hand definitions (TOML + docs)
|
│ │ └── agent.toml
|
||||||
│ ├── browser/HAND.toml
|
│ └── ... (32 agents)
|
||||||
│ ├── trader/HAND.toml
|
├── hands/ # Hand definitions (app bundles)
|
||||||
|
│ ├── browser/
|
||||||
|
│ │ ├── HAND.toml # Metadata, tools, settings, i18n (6 languages)
|
||||||
|
│ │ └── SKILL.md # Domain expert knowledge injected at runtime
|
||||||
|
│ ├── trader/
|
||||||
|
│ │ ├── HAND.toml
|
||||||
|
│ │ └── SKILL.md
|
||||||
│ └── ... (14 hands)
|
│ └── ... (14 hands)
|
||||||
├── integrations/ # MCP server integration templates
|
├── integrations/ # MCP server integration templates
|
||||||
│ ├── github.toml
|
│ ├── github.toml
|
||||||
│ ├── slack.toml
|
│ ├── slack.toml
|
||||||
│ └── ... (25 integrations)
|
│ └── ... (25 integrations)
|
||||||
├── skills/ # Reusable skill definitions
|
|
||||||
│ ├── custom-skill-prompt/skill.toml
|
|
||||||
│ └── custom-skill-python/
|
|
||||||
├── providers/ # LLM provider & model metadata
|
├── providers/ # LLM provider & model metadata
|
||||||
│ ├── anthropic.toml
|
│ ├── anthropic.toml
|
||||||
│ ├── openai.toml
|
│ ├── openai.toml
|
||||||
│ └── ... (46 providers, 190+ models)
|
│ └── ... (48 providers, 223 models)
|
||||||
├── plugins/ # Plugin packages (10 plugins)
|
├── plugins/ # Memory, guardrails, and utility plugins
|
||||||
├── aliases.toml # Global model alias mappings
|
│ ├── episodic-memory/
|
||||||
|
│ ├── guardrails/
|
||||||
|
│ └── ... (10 plugins)
|
||||||
|
├── skills/ # Reusable skill definitions
|
||||||
|
│ ├── custom-skill-prompt/skill.toml
|
||||||
|
│ └── custom-skill-python/
|
||||||
|
├── aliases.toml # Global model alias mappings (70 aliases)
|
||||||
├── schema.toml # Provider/model schema reference
|
├── schema.toml # Provider/model schema reference
|
||||||
├── scripts/
|
├── scripts/
|
||||||
│ └── validate.py # Validation script
|
│ └── validate.py # Content validation script
|
||||||
├── CONTRIBUTING.md
|
├── CONTRIBUTING.md
|
||||||
└── LICENSE # MIT
|
└── LICENSE # MIT
|
||||||
```
|
```
|
||||||
|
|
||||||
## Content Types
|
## Content Types
|
||||||
|
|
||||||
|
### Hands
|
||||||
|
|
||||||
|
Hands are the **user-facing "apps"** in LibreFang. Each hand bundles an agent, tools, user-configurable settings, dashboard metrics, dependency checks, and i18n translations into a single deployable unit.
|
||||||
|
|
||||||
|
Every hand includes a `SKILL.md` — domain-specific expert knowledge that is injected into the agent's context at runtime, giving it deep expertise in its domain.
|
||||||
|
|
||||||
|
| Icon | Hand | Category | Description |
|
||||||
|
|:----:|------|----------|-------------|
|
||||||
|
| 📈 | analytics | data | Data collection, analysis, visualization, dashboards, and automated reporting |
|
||||||
|
| 🔌 | apitester | development | Endpoint discovery, request validation, load testing, and regression detection |
|
||||||
|
| 🌐 | browser | productivity | Web navigation, form filling, and multi-step web tasks with user approval |
|
||||||
|
| 🎬 | clip | content | Turns long-form video into viral short clips with captions and thumbnails |
|
||||||
|
| 🔍 | collector | data | Intelligence collection, change detection, and knowledge graphs |
|
||||||
|
| 👷 | devops | development | CI/CD management, infrastructure monitoring, deployment, and incident response |
|
||||||
|
| 📊 | lead | data | Lead generation, enrichment, scoring, and scheduled delivery |
|
||||||
|
| 💼 | linkedin | communication | Profile optimization, content creation, networking, and engagement |
|
||||||
|
| 🔮 | predictor | data | Signal collection, calibrated predictions, and accuracy tracking |
|
||||||
|
| 📢 | reddit | communication | Subreddit monitoring, content posting, and engagement tracking |
|
||||||
|
| 🧪 | researcher | productivity | Deep research, cross-referencing, fact-checking, and structured reports |
|
||||||
|
| 🎯 | strategist | productivity | Market research, competitive analysis, and strategic planning |
|
||||||
|
| 📈 | trader | data | Multi-signal analysis, adversarial reasoning, and risk management |
|
||||||
|
| 𝕏 | twitter | communication | Content creation, scheduled posting, engagement, and analytics |
|
||||||
|
|
||||||
|
**HAND.toml format:**
|
||||||
|
|
||||||
|
```toml
|
||||||
|
id = "browser"
|
||||||
|
name = "Browser Hand"
|
||||||
|
description = "Autonomous web browser"
|
||||||
|
category = "productivity"
|
||||||
|
icon = "🌐"
|
||||||
|
tools = ["browser_navigate", "browser_click", "browser_type"]
|
||||||
|
|
||||||
|
[routing]
|
||||||
|
aliases = ["browse", "open website"]
|
||||||
|
weak_aliases = ["web", "url"]
|
||||||
|
|
||||||
|
[[requires]]
|
||||||
|
key = "chromium"
|
||||||
|
requirement_type = "binary"
|
||||||
|
check_value = "chromium"
|
||||||
|
|
||||||
|
[[settings]]
|
||||||
|
key = "headless"
|
||||||
|
setting_type = "toggle"
|
||||||
|
default = "true"
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
name = "browser-hand"
|
||||||
|
module = "builtin:chat"
|
||||||
|
system_prompt = """You are an autonomous web browser agent..."""
|
||||||
|
|
||||||
|
[dashboard]
|
||||||
|
[[dashboard.metrics]]
|
||||||
|
label = "Pages Visited"
|
||||||
|
memory_key = "pages_visited"
|
||||||
|
format = "number"
|
||||||
|
|
||||||
|
# i18n — 6 languages supported: zh, ja, ko, es, fr, de
|
||||||
|
[i18n.zh]
|
||||||
|
name = "浏览器 Hand"
|
||||||
|
description = "自主网页浏览器"
|
||||||
|
category = "生产力"
|
||||||
|
|
||||||
|
[i18n.zh.settings.headless]
|
||||||
|
label = "无头模式"
|
||||||
|
description = "在后台运行浏览器"
|
||||||
|
```
|
||||||
|
|
||||||
### Agents
|
### Agents
|
||||||
|
|
||||||
Agent definitions in `agents/<name>/agent.toml` describe autonomous agents with their model config, tools, capabilities, and routing aliases.
|
Agent definitions describe autonomous agents with model configuration, tools, capabilities, and routing aliases.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
name = "hello-world"
|
name = "hello-world"
|
||||||
@@ -56,30 +147,11 @@ system_prompt = "You are a helpful assistant."
|
|||||||
tools = ["web_search", "file_read"]
|
tools = ["web_search", "file_read"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Hands
|
**32 built-in agents:** academic-researcher, analyst, architect, assistant, code-reviewer, coder, customer-support, data-scientist, debugger, devops-lead, doc-writer, email-assistant, health-tracker, hello-world, home-automation, legal-assistant, meeting-assistant, ops, orchestrator, personal-finance, planner, recipe-assistant, recruiter, researcher, sales-assistant, security-auditor, social-media, test-engineer, translator, travel-planner, tutor, writer
|
||||||
|
|
||||||
Hands in `hands/<name>/HAND.toml` are higher-level application bundles -- the user-facing "apps" in LibreFang. Each hand bundles an agent config, tools, settings, dashboard metrics, and dependency requirements.
|
|
||||||
|
|
||||||
```toml
|
|
||||||
id = "browser"
|
|
||||||
name = "Browser Hand"
|
|
||||||
category = "productivity"
|
|
||||||
tools = ["browser_navigate", "browser_click", "browser_type"]
|
|
||||||
|
|
||||||
[agent]
|
|
||||||
name = "browser-hand"
|
|
||||||
module = "builtin:chat"
|
|
||||||
system_prompt = "You are an autonomous web browser agent..."
|
|
||||||
|
|
||||||
[[settings]]
|
|
||||||
key = "headless"
|
|
||||||
setting_type = "toggle"
|
|
||||||
default = "true"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Integrations
|
### Integrations
|
||||||
|
|
||||||
Integration templates in `integrations/<name>.toml` define MCP server connections (GitHub, Slack, databases, etc.) with transport config, required env vars, and setup instructions.
|
Integration templates define [MCP](https://modelcontextprotocol.io/) server connections with transport configuration, required environment variables, and setup instructions.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
id = "github"
|
id = "github"
|
||||||
@@ -96,9 +168,47 @@ name = "GITHUB_PERSONAL_ACCESS_TOKEN"
|
|||||||
is_secret = true
|
is_secret = true
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**25 integrations across 6 categories:**
|
||||||
|
|
||||||
|
| Category | Integrations |
|
||||||
|
|----------|-------------|
|
||||||
|
| DevTools | bitbucket, github, gitlab, jira, linear, sentry |
|
||||||
|
| Data | elasticsearch, mongodb, postgresql, redis, sqlite |
|
||||||
|
| Productivity | dropbox, gmail, google-calendar, google-drive, notion, todoist |
|
||||||
|
| Communication | discord, slack, teams |
|
||||||
|
| Cloud | aws, azure, gcp |
|
||||||
|
| AI Search | brave-search, exa-search |
|
||||||
|
|
||||||
|
### Providers
|
||||||
|
|
||||||
|
Provider files define LLM providers and their models with pricing, context windows, and capability flags. See [schema.toml](schema.toml) for the full field reference.
|
||||||
|
|
||||||
|
**48 providers** including: Anthropic, OpenAI, Google Gemini, DeepSeek, Groq, Mistral, Cohere, xAI, Together, Fireworks, Ollama (local), LM Studio (local), vLLM (self-hosted), and many more.
|
||||||
|
|
||||||
|
**223 models** with metadata for each: pricing (input/output per token), context window size, capability flags (vision, function calling, streaming), and tier classification.
|
||||||
|
|
||||||
|
### Aliases
|
||||||
|
|
||||||
|
Global model alias mappings in [aliases.toml](aliases.toml) let users reference models by short names:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
"sonnet" = "claude-sonnet-4-6"
|
||||||
|
"gpt4" = "gpt-4o"
|
||||||
|
"flash" = "gemini-2.5-flash"
|
||||||
|
"deepseek" = "deepseek-chat"
|
||||||
|
```
|
||||||
|
|
||||||
|
Models can also define aliases directly in their provider TOML files, which are auto-registered at load time.
|
||||||
|
|
||||||
|
### Plugins
|
||||||
|
|
||||||
|
Plugins extend agent capabilities with memory systems, safety guardrails, and conversation utilities.
|
||||||
|
|
||||||
|
**10 plugins:** auto-summarizer, context-decay, conversation-logger, episodic-memory, guardrails, keyword-memory, sentiment-tracker, todo-tracker, topic-memory, user-profile
|
||||||
|
|
||||||
### Skills
|
### Skills
|
||||||
|
|
||||||
Skills in `skills/<name>/skill.toml` are reusable prompt templates or Python scripts that agents can invoke.
|
Reusable prompt templates or Python scripts that agents can invoke.
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
[skill]
|
[skill]
|
||||||
@@ -112,13 +222,9 @@ type = "promptonly"
|
|||||||
template = "Create a meeting agenda for: {{topic}}"
|
template = "Create a meeting agenda for: {{topic}}"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Providers
|
## Usage
|
||||||
|
|
||||||
Provider files in `providers/<name>.toml` define LLM providers and their models with pricing, context windows, and capability flags. See [schema.toml](schema.toml) for the full field reference.
|
### Install from Registry
|
||||||
|
|
||||||
## How LibreFang Uses This Registry
|
|
||||||
|
|
||||||
LibreFang ships with built-in content compiled into the binary. This repository serves as the upstream source for updates and community contributions.
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Update all registry content
|
# Update all registry content
|
||||||
@@ -133,15 +239,15 @@ librefang integration install github
|
|||||||
|
|
||||||
### Custom Local Content
|
### Custom Local Content
|
||||||
|
|
||||||
You can also create custom content locally without submitting a PR:
|
Create custom content locally without submitting to this registry:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Create a custom agent
|
# Custom agent
|
||||||
mkdir -p ~/.librefang/agents/my-agent
|
mkdir -p ~/.librefang/agents/my-agent
|
||||||
# Edit ~/.librefang/agents/my-agent/agent.toml
|
# Edit ~/.librefang/agents/my-agent/agent.toml
|
||||||
|
|
||||||
# Add custom models to your config
|
# Custom model aliases
|
||||||
# ~/.librefang/model_catalog.toml
|
# Add to ~/.librefang/model_catalog.toml
|
||||||
```
|
```
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
@@ -150,9 +256,9 @@ mkdir -p ~/.librefang/agents/my-agent
|
|||||||
python scripts/validate.py
|
python scripts/validate.py
|
||||||
```
|
```
|
||||||
|
|
||||||
This validates all provider TOML files for correctness: required fields, valid tiers, non-negative costs, no duplicate IDs.
|
Validates all content files for correctness: required fields, valid types, non-negative costs, no duplicate IDs.
|
||||||
|
|
||||||
## How to Contribute
|
## Contributing
|
||||||
|
|
||||||
1. Fork this repository
|
1. Fork this repository
|
||||||
2. Add or edit content in the appropriate directory
|
2. Add or edit content in the appropriate directory
|
||||||
@@ -161,19 +267,6 @@ This validates all provider TOML files for correctness: required fields, valid t
|
|||||||
|
|
||||||
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed instructions for each content type.
|
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed instructions for each content type.
|
||||||
|
|
||||||
## Current Stats
|
|
||||||
|
|
||||||
| Type | Count |
|
|
||||||
|------|-------|
|
|
||||||
| Agents | 33 |
|
|
||||||
| Hands | 14 |
|
|
||||||
| Integrations | 25 |
|
|
||||||
| Skills | 2 |
|
|
||||||
| Plugins | 10 |
|
|
||||||
| Providers | 46 |
|
|
||||||
| Models | 220+ |
|
|
||||||
| Aliases | 80+ |
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
MIT License. See [LICENSE](LICENSE).
|
MIT License. See [LICENSE](LICENSE).
|
||||||
+27
-7
@@ -10,7 +10,7 @@ Hand definitions for LibreFang. Hands are the user-facing "apps" -- higher-level
|
|||||||
hands/
|
hands/
|
||||||
├── browser/
|
├── browser/
|
||||||
│ ├── HAND.toml # Hand definition
|
│ ├── HAND.toml # Hand definition
|
||||||
│ └── SKILL.md # Documentation
|
│ └── SKILL.md # Expert knowledge for the agent
|
||||||
├── trader/
|
├── trader/
|
||||||
│ ├── HAND.toml
|
│ ├── HAND.toml
|
||||||
│ └── SKILL.md
|
│ └── SKILL.md
|
||||||
@@ -47,6 +47,17 @@ name = "hand-agent"
|
|||||||
module = "builtin:chat"
|
module = "builtin:chat"
|
||||||
system_prompt = """..."""
|
system_prompt = """..."""
|
||||||
|
|
||||||
|
# Optional: i18n for name, description, category, and settings
|
||||||
|
# Supported languages: zh, ja, ko, es, fr, de
|
||||||
|
[i18n.zh]
|
||||||
|
name = "浏览器 Hand"
|
||||||
|
description = "自主网页浏览器"
|
||||||
|
category = "生产力"
|
||||||
|
|
||||||
|
[i18n.zh.settings.headless] # Per-setting label/description translation
|
||||||
|
label = "无头模式"
|
||||||
|
description = "在后台运行浏览器"
|
||||||
|
|
||||||
[dashboard] # Dashboard metrics
|
[dashboard] # Dashboard metrics
|
||||||
[[dashboard.metrics]]
|
[[dashboard.metrics]]
|
||||||
label = "Tasks Completed"
|
label = "Tasks Completed"
|
||||||
@@ -58,15 +69,24 @@ format = "number"
|
|||||||
|
|
||||||
| Hand | Category | Description |
|
| Hand | Category | Description |
|
||||||
|------|----------|-------------|
|
|------|----------|-------------|
|
||||||
| browser | productivity | Autonomous web browser |
|
| analytics | data | Data analytics, visualization, dashboards, and automated reporting |
|
||||||
| trader | data | Crypto/stock trading assistant |
|
| apitester | development | API testing, endpoint discovery, load testing, and regression detection |
|
||||||
| researcher | productivity | Deep research automation |
|
| browser | productivity | Web navigation, form filling, and multi-step web tasks |
|
||||||
| analytics | data | Data analysis and dashboards |
|
| clip | content | Turns long-form video into short clips with captions and thumbnails |
|
||||||
| ... | | See each directory for details |
|
| collector | data | Intelligence collection, change detection, and knowledge graphs |
|
||||||
|
| devops | development | CI/CD management, infrastructure monitoring, and incident response |
|
||||||
|
| lead | data | Lead generation, enrichment, scoring, and scheduled delivery |
|
||||||
|
| linkedin | communication | LinkedIn content creation, networking, and engagement |
|
||||||
|
| predictor | data | Signal collection, calibrated predictions, and accuracy tracking |
|
||||||
|
| reddit | communication | Subreddit monitoring, content posting, and engagement tracking |
|
||||||
|
| researcher | productivity | Deep research, cross-referencing, fact-checking, and reports |
|
||||||
|
| strategist | productivity | Market research, competitive analysis, and strategic planning |
|
||||||
|
| trader | data | Market intelligence, multi-signal analysis, and risk management |
|
||||||
|
| twitter | communication | Twitter/X content creation, scheduling, and performance tracking |
|
||||||
|
|
||||||
## Adding a New Hand
|
## Adding a New Hand
|
||||||
|
|
||||||
1. Create `hands/<name>/HAND.toml` (and optionally `SKILL.md`)
|
1. Create `hands/<name>/HAND.toml` and `SKILL.md` (expert knowledge for the agent)
|
||||||
2. Ensure `id` matches the directory name
|
2. Ensure `id` matches the directory name
|
||||||
3. Run `python scripts/validate.py`
|
3. Run `python scripts/validate.py`
|
||||||
4. Submit a PR
|
4. Submit a PR
|
||||||
|
|||||||
@@ -484,6 +484,217 @@ token_consumption = "high"
|
|||||||
default_active = true
|
default_active = true
|
||||||
# Note: High consumption when actively analyzing data, lower when idle
|
# Note: High consumption when actively analyzing data, lower when idle
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "数据分析 Hand"
|
name = "数据分析 Hand"
|
||||||
description = "自主数据分析智能体——数据采集、分析、可视化、仪表盘和自动化报告"
|
description = "自主数据分析智能体——数据采集、分析、可视化、仪表盘和自动化报告"
|
||||||
|
category = "数据"
|
||||||
|
|
||||||
|
[i18n.zh.settings.data_source]
|
||||||
|
label = "数据源"
|
||||||
|
description = "主要数据源类型"
|
||||||
|
|
||||||
|
[i18n.zh.settings.analysis_type]
|
||||||
|
label = "分析类型"
|
||||||
|
description = "默认分析方法"
|
||||||
|
|
||||||
|
[i18n.zh.settings.output_format]
|
||||||
|
label = "输出格式"
|
||||||
|
description = "分析结果的呈现方式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.visualization]
|
||||||
|
label = "可视化"
|
||||||
|
description = "生成图表和可视化内容"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_schedule]
|
||||||
|
label = "定时报告"
|
||||||
|
description = "按计划自动生成报告"
|
||||||
|
|
||||||
|
[i18n.zh.settings.report_frequency]
|
||||||
|
label = "报告频率"
|
||||||
|
description = "定时报告的生成频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.confidence_threshold]
|
||||||
|
label = "置信度阈值"
|
||||||
|
description = "报告中纳入分析结论的最低置信度要求"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "データ分析 Hand"
|
||||||
|
description = "自律型データ分析エージェント——データ収集、分析、可視化、ダッシュボード、自動レポート生成"
|
||||||
|
category = "データ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.data_source]
|
||||||
|
label = "データソース"
|
||||||
|
description = "主要なデータソースの種類"
|
||||||
|
|
||||||
|
[i18n.ja.settings.analysis_type]
|
||||||
|
label = "分析タイプ"
|
||||||
|
description = "デフォルトの分析アプローチ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.output_format]
|
||||||
|
label = "出力形式"
|
||||||
|
description = "分析結果の表示方法"
|
||||||
|
|
||||||
|
[i18n.ja.settings.visualization]
|
||||||
|
label = "可視化"
|
||||||
|
description = "チャートやビジュアライゼーションを生成する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_schedule]
|
||||||
|
label = "定期レポート"
|
||||||
|
description = "スケジュールに基づいてレポートを自動生成する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.report_frequency]
|
||||||
|
label = "レポート頻度"
|
||||||
|
description = "定期レポートの生成頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.confidence_threshold]
|
||||||
|
label = "信頼度しきい値"
|
||||||
|
description = "レポートに分析結果を含めるための最低信頼度"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Analítica"
|
||||||
|
description = "Agente autónomo de analítica de datos — recopilación, análisis, visualización, paneles de control e informes automatizados"
|
||||||
|
category = "Datos"
|
||||||
|
|
||||||
|
[i18n.es.settings.data_source]
|
||||||
|
label = "Fuente de datos"
|
||||||
|
description = "Tipo de fuente de datos principal"
|
||||||
|
|
||||||
|
[i18n.es.settings.analysis_type]
|
||||||
|
label = "Tipo de análisis"
|
||||||
|
description = "Enfoque de análisis predeterminado"
|
||||||
|
|
||||||
|
[i18n.es.settings.output_format]
|
||||||
|
label = "Formato de salida"
|
||||||
|
description = "Cómo presentar los resultados del análisis"
|
||||||
|
|
||||||
|
[i18n.es.settings.visualization]
|
||||||
|
label = "Visualización"
|
||||||
|
description = "Generar gráficos y visualizaciones"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_schedule]
|
||||||
|
label = "Informes programados"
|
||||||
|
description = "Generar informes automáticamente según un calendario"
|
||||||
|
|
||||||
|
[i18n.es.settings.report_frequency]
|
||||||
|
label = "Frecuencia de informes"
|
||||||
|
description = "Con qué frecuencia generar los informes programados"
|
||||||
|
|
||||||
|
[i18n.es.settings.confidence_threshold]
|
||||||
|
label = "Umbral de confianza"
|
||||||
|
description = "Nivel mínimo de confianza para incluir hallazgos en los informes"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Analytique"
|
||||||
|
description = "Agent autonome d'analyse de données — collecte, analyse, visualisation, tableaux de bord et rapports automatisés"
|
||||||
|
category = "Données"
|
||||||
|
|
||||||
|
[i18n.fr.settings.data_source]
|
||||||
|
label = "Source de données"
|
||||||
|
description = "Type de source de données principal"
|
||||||
|
|
||||||
|
[i18n.fr.settings.analysis_type]
|
||||||
|
label = "Type d'analyse"
|
||||||
|
description = "Approche d'analyse par défaut"
|
||||||
|
|
||||||
|
[i18n.fr.settings.output_format]
|
||||||
|
label = "Format de sortie"
|
||||||
|
description = "Mode de présentation des résultats d'analyse"
|
||||||
|
|
||||||
|
[i18n.fr.settings.visualization]
|
||||||
|
label = "Visualisation"
|
||||||
|
description = "Générer des graphiques et des visualisations"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_schedule]
|
||||||
|
label = "Rapports programmés"
|
||||||
|
description = "Générer automatiquement des rapports selon un calendrier"
|
||||||
|
|
||||||
|
[i18n.fr.settings.report_frequency]
|
||||||
|
label = "Fréquence des rapports"
|
||||||
|
description = "Fréquence de génération des rapports programmés"
|
||||||
|
|
||||||
|
[i18n.fr.settings.confidence_threshold]
|
||||||
|
label = "Seuil de confiance"
|
||||||
|
description = "Niveau de confiance minimum pour inclure les résultats dans les rapports"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Analytik-Hand"
|
||||||
|
description = "Autonomer Datenanalyse-Agent — Datenerfassung, Analyse, Visualisierung, Dashboards und automatisierte Berichte"
|
||||||
|
category = "Daten"
|
||||||
|
|
||||||
|
[i18n.de.settings.data_source]
|
||||||
|
label = "Datenquelle"
|
||||||
|
description = "Primärer Datenquellentyp"
|
||||||
|
|
||||||
|
[i18n.de.settings.analysis_type]
|
||||||
|
label = "Analysetyp"
|
||||||
|
description = "Standard-Analyseansatz"
|
||||||
|
|
||||||
|
[i18n.de.settings.output_format]
|
||||||
|
label = "Ausgabeformat"
|
||||||
|
description = "Darstellung der Analyseergebnisse"
|
||||||
|
|
||||||
|
[i18n.de.settings.visualization]
|
||||||
|
label = "Visualisierung"
|
||||||
|
description = "Diagramme und Visualisierungen generieren"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_schedule]
|
||||||
|
label = "Geplante Berichte"
|
||||||
|
description = "Berichte automatisch nach Zeitplan generieren"
|
||||||
|
|
||||||
|
[i18n.de.settings.report_frequency]
|
||||||
|
label = "Berichtshäufigkeit"
|
||||||
|
description = "Häufigkeit der geplanten Berichtserstellung"
|
||||||
|
|
||||||
|
[i18n.de.settings.confidence_threshold]
|
||||||
|
label = "Konfidenzschwelle"
|
||||||
|
description = "Mindest-Konfidenzniveau für die Aufnahme von Ergebnissen in Berichte"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "데이터 분석 Hand"
|
||||||
|
description = "자율 데이터 분석 에이전트 — 데이터 수집, 분석, 시각화, 대시보드 및 자동화 보고서"
|
||||||
|
category = "데이터"
|
||||||
|
|
||||||
|
[i18n.ko.settings.data_source]
|
||||||
|
label = "데이터 소스"
|
||||||
|
description = "주요 데이터 소스 유형"
|
||||||
|
|
||||||
|
[i18n.ko.settings.analysis_type]
|
||||||
|
label = "분석 유형"
|
||||||
|
description = "기본 분석 방법"
|
||||||
|
|
||||||
|
[i18n.ko.settings.output_format]
|
||||||
|
label = "출력 형식"
|
||||||
|
description = "분석 결과 표시 방식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.visualization]
|
||||||
|
label = "시각화"
|
||||||
|
description = "차트 및 시각화 콘텐츠 생성"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_schedule]
|
||||||
|
label = "정기 보고서"
|
||||||
|
description = "일정에 따라 자동으로 보고서 생성"
|
||||||
|
|
||||||
|
[i18n.ko.settings.report_frequency]
|
||||||
|
label = "보고서 빈도"
|
||||||
|
description = "정기 보고서 생성 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.confidence_threshold]
|
||||||
|
label = "신뢰도 임계값"
|
||||||
|
description = "보고서에 분석 결과를 포함하기 위한 최소 신뢰도 수준"
|
||||||
@@ -337,3 +337,702 @@ Level 4: What to do (prescriptive)
|
|||||||
| Timeliness | Current | Data refreshed daily |
|
| Timeliness | Current | Data refreshed daily |
|
||||||
| Uniqueness | 99% | 1% duplicate records found |
|
| Uniqueness | 99% | 1% duplicate records found |
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: E-commerce Sales Analysis
|
||||||
|
|
||||||
|
**Goal**: Analyze 12 months of order data to identify revenue drivers, customer segments, and growth trends.
|
||||||
|
|
||||||
|
#### Step 1 — Load and clean
|
||||||
|
```python
|
||||||
|
import pandas as pd
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
df = pd.read_csv('orders.csv', parse_dates=['order_date'])
|
||||||
|
|
||||||
|
# Quick audit
|
||||||
|
print(f"Rows: {len(df):,} Columns: {df.shape[1]}")
|
||||||
|
print(df.isnull().sum()[df.isnull().sum() > 0])
|
||||||
|
|
||||||
|
# Clean
|
||||||
|
df = df.dropna(subset=['customer_id', 'order_total'])
|
||||||
|
df['order_total'] = df['order_total'].clip(lower=0) # Remove negative values
|
||||||
|
df['order_month'] = df['order_date'].dt.to_period('M')
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 2 — Revenue trend analysis
|
||||||
|
```python
|
||||||
|
monthly = (
|
||||||
|
df.groupby('order_month')
|
||||||
|
.agg(revenue=('order_total', 'sum'),
|
||||||
|
orders=('order_id', 'nunique'),
|
||||||
|
customers=('customer_id', 'nunique'))
|
||||||
|
.reset_index()
|
||||||
|
)
|
||||||
|
monthly['aov'] = monthly['revenue'] / monthly['orders'] # Average order value
|
||||||
|
monthly['revenue_mom'] = monthly['revenue'].pct_change() # Month-over-month growth
|
||||||
|
|
||||||
|
fig, axes = plt.subplots(2, 1, figsize=(12, 8), sharex=True)
|
||||||
|
axes[0].bar(monthly['order_month'].astype(str), monthly['revenue'], color='steelblue')
|
||||||
|
axes[0].set_title('Monthly Revenue', fontsize=14, fontweight='bold')
|
||||||
|
axes[0].set_ylabel('Revenue ($)')
|
||||||
|
|
||||||
|
axes[1].plot(monthly['order_month'].astype(str), monthly['aov'], marker='o', color='coral')
|
||||||
|
axes[1].set_title('Average Order Value', fontsize=14, fontweight='bold')
|
||||||
|
axes[1].set_ylabel('AOV ($)')
|
||||||
|
plt.xticks(rotation=45, ha='right')
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('revenue_trend.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 3 — Customer segmentation (RFM)
|
||||||
|
```python
|
||||||
|
snapshot_date = df['order_date'].max() + pd.Timedelta(days=1)
|
||||||
|
|
||||||
|
rfm = df.groupby('customer_id').agg(
|
||||||
|
recency=('order_date', lambda x: (snapshot_date - x.max()).days),
|
||||||
|
frequency=('order_id', 'nunique'),
|
||||||
|
monetary=('order_total', 'sum')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Score each dimension 1-4 using quartiles
|
||||||
|
for col in ['recency', 'frequency', 'monetary']:
|
||||||
|
labels = [4, 3, 2, 1] if col == 'recency' else [1, 2, 3, 4]
|
||||||
|
rfm[f'{col}_score'] = pd.qcut(rfm[col], q=4, labels=labels, duplicates='drop')
|
||||||
|
|
||||||
|
rfm['rfm_score'] = (rfm['recency_score'].astype(int)
|
||||||
|
+ rfm['frequency_score'].astype(int)
|
||||||
|
+ rfm['monetary_score'].astype(int))
|
||||||
|
|
||||||
|
# Segment mapping
|
||||||
|
def segment(row):
|
||||||
|
r, f, m = int(row['recency_score']), int(row['frequency_score']), int(row['monetary_score'])
|
||||||
|
if r >= 3 and f >= 3:
|
||||||
|
return 'Champions'
|
||||||
|
elif r >= 3 and f < 3:
|
||||||
|
return 'New / Promising'
|
||||||
|
elif r < 3 and f >= 3:
|
||||||
|
return 'At Risk'
|
||||||
|
else:
|
||||||
|
return 'Needs Attention'
|
||||||
|
|
||||||
|
rfm['segment'] = rfm.apply(segment, axis=1)
|
||||||
|
print(rfm.groupby('segment').agg(
|
||||||
|
count=('monetary', 'size'),
|
||||||
|
avg_revenue=('monetary', 'mean'),
|
||||||
|
avg_frequency=('frequency', 'mean')
|
||||||
|
).sort_values('avg_revenue', ascending=False))
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 4 — Cohort retention analysis
|
||||||
|
```python
|
||||||
|
df['cohort'] = df.groupby('customer_id')['order_date'].transform('min').dt.to_period('M')
|
||||||
|
df['order_period'] = df['order_date'].dt.to_period('M')
|
||||||
|
df['cohort_index'] = (df['order_period'] - df['cohort']).apply(lambda x: x.n)
|
||||||
|
|
||||||
|
cohort_table = (
|
||||||
|
df.groupby(['cohort', 'cohort_index'])['customer_id']
|
||||||
|
.nunique()
|
||||||
|
.reset_index()
|
||||||
|
.pivot(index='cohort', columns='cohort_index', values='customer_id')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Convert to retention percentages
|
||||||
|
retention = cohort_table.div(cohort_table[0], axis=0) * 100
|
||||||
|
|
||||||
|
fig, ax = plt.subplots(figsize=(14, 8))
|
||||||
|
sns.heatmap(retention, annot=True, fmt='.0f', cmap='YlOrRd_r', ax=ax)
|
||||||
|
ax.set_title('Cohort Retention (% of original customers)', fontsize=14, fontweight='bold')
|
||||||
|
ax.set_xlabel('Months Since First Purchase')
|
||||||
|
ax.set_ylabel('Cohort')
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('cohort_retention.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 2: A/B Test Analysis
|
||||||
|
|
||||||
|
**Goal**: Evaluate whether a new checkout flow (variant B) improves conversion rate over the existing flow (variant A).
|
||||||
|
|
||||||
|
#### Step 1 — Sample size calculation (pre-test)
|
||||||
|
```python
|
||||||
|
from scipy import stats
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
baseline_rate = 0.12 # Current conversion rate: 12%
|
||||||
|
mde = 0.02 # Minimum detectable effect: 2 percentage points
|
||||||
|
alpha = 0.05 # Significance level
|
||||||
|
power = 0.80 # Statistical power
|
||||||
|
|
||||||
|
# Using the normal approximation formula
|
||||||
|
p1 = baseline_rate
|
||||||
|
p2 = baseline_rate + mde
|
||||||
|
p_avg = (p1 + p2) / 2
|
||||||
|
|
||||||
|
z_alpha = stats.norm.ppf(1 - alpha / 2) # Two-tailed
|
||||||
|
z_beta = stats.norm.ppf(power)
|
||||||
|
|
||||||
|
n_per_group = ((z_alpha * np.sqrt(2 * p_avg * (1 - p_avg))
|
||||||
|
+ z_beta * np.sqrt(p1 * (1 - p1) + p2 * (1 - p2))) ** 2
|
||||||
|
/ (p2 - p1) ** 2)
|
||||||
|
|
||||||
|
print(f"Required sample size per group: {int(np.ceil(n_per_group)):,}")
|
||||||
|
print(f"Total required: {int(np.ceil(n_per_group)) * 2:,}")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 2 — Run the test and collect results
|
||||||
|
```python
|
||||||
|
ab = pd.read_csv('ab_test_results.csv')
|
||||||
|
|
||||||
|
summary = ab.groupby('variant').agg(
|
||||||
|
visitors=('user_id', 'nunique'),
|
||||||
|
conversions=('converted', 'sum')
|
||||||
|
)
|
||||||
|
summary['conversion_rate'] = summary['conversions'] / summary['visitors']
|
||||||
|
print(summary)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 3 — Statistical significance
|
||||||
|
```python
|
||||||
|
a = ab[ab['variant'] == 'A']
|
||||||
|
b = ab[ab['variant'] == 'B']
|
||||||
|
|
||||||
|
# Chi-squared test for proportions
|
||||||
|
contingency = pd.crosstab(ab['variant'], ab['converted'])
|
||||||
|
chi2, p_value, dof, expected = stats.chi2_contingency(contingency)
|
||||||
|
|
||||||
|
# Proportions z-test (more direct)
|
||||||
|
from statsmodels.stats.proportion import proportions_ztest
|
||||||
|
successes = [summary.loc['B', 'conversions'], summary.loc['A', 'conversions']]
|
||||||
|
trials = [summary.loc['B', 'visitors'], summary.loc['A', 'visitors']]
|
||||||
|
z_stat, p_val = proportions_ztest(successes, trials, alternative='larger')
|
||||||
|
|
||||||
|
print(f"Z-statistic: {z_stat:.4f}")
|
||||||
|
print(f"P-value: {p_val:.4f}")
|
||||||
|
print(f"Significant: {'Yes' if p_val < 0.05 else 'No'} (at alpha=0.05)")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 4 — Effect size and confidence interval
|
||||||
|
```python
|
||||||
|
p_a = summary.loc['A', 'conversion_rate']
|
||||||
|
p_b = summary.loc['B', 'conversion_rate']
|
||||||
|
n_a = summary.loc['A', 'visitors']
|
||||||
|
n_b = summary.loc['B', 'visitors']
|
||||||
|
|
||||||
|
lift = (p_b - p_a) / p_a
|
||||||
|
se_diff = np.sqrt(p_a * (1 - p_a) / n_a + p_b * (1 - p_b) / n_b)
|
||||||
|
ci_lower = (p_b - p_a) - 1.96 * se_diff
|
||||||
|
ci_upper = (p_b - p_a) + 1.96 * se_diff
|
||||||
|
|
||||||
|
print(f"Control rate: {p_a:.4f}")
|
||||||
|
print(f"Variant rate: {p_b:.4f}")
|
||||||
|
print(f"Absolute lift: {p_b - p_a:+.4f}")
|
||||||
|
print(f"Relative lift: {lift:+.2%}")
|
||||||
|
print(f"95% CI for diff: [{ci_lower:+.4f}, {ci_upper:+.4f}]")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 5 — Recommendation template
|
||||||
|
```
|
||||||
|
## A/B Test Report: New Checkout Flow
|
||||||
|
|
||||||
|
| Metric | Control (A) | Variant (B) |
|
||||||
|
|---------------------|-------------|-------------|
|
||||||
|
| Visitors | 15,204 | 15,198 |
|
||||||
|
| Conversions | 1,824 | 2,127 |
|
||||||
|
| Conversion Rate | 12.00% | 13.99% |
|
||||||
|
|
||||||
|
**Result**: Statistically significant (p = 0.0003, alpha = 0.05)
|
||||||
|
**Lift**: +1.99pp absolute / +16.6% relative
|
||||||
|
**95% CI**: [+0.90pp, +3.08pp]
|
||||||
|
**Recommendation**: Deploy variant B. The effect is both statistically
|
||||||
|
and practically significant with a lower bound above the +1pp threshold.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 3: Customer Churn Analysis
|
||||||
|
|
||||||
|
**Goal**: Identify which factors most strongly predict customer churn and quantify their relative importance.
|
||||||
|
|
||||||
|
#### Step 1 — Feature engineering
|
||||||
|
```python
|
||||||
|
df = pd.read_csv('customers.csv')
|
||||||
|
|
||||||
|
# Create behavioral features from raw data
|
||||||
|
features = df.copy()
|
||||||
|
features['tenure_months'] = (pd.Timestamp.now() - pd.to_datetime(df['signup_date'])).dt.days / 30
|
||||||
|
features['support_tickets_per_month'] = df['total_tickets'] / features['tenure_months'].clip(lower=1)
|
||||||
|
features['avg_session_minutes'] = df['total_session_minutes'] / df['total_sessions'].clip(lower=1)
|
||||||
|
features['days_since_last_login'] = (pd.Timestamp.now() - pd.to_datetime(df['last_login'])).dt.days
|
||||||
|
features['has_premium'] = (df['plan'] == 'premium').astype(int)
|
||||||
|
|
||||||
|
# Drop raw columns, keep engineered features
|
||||||
|
feature_cols = [
|
||||||
|
'tenure_months', 'support_tickets_per_month', 'avg_session_minutes',
|
||||||
|
'days_since_last_login', 'has_premium', 'monthly_spend', 'num_features_used'
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 2 — Correlation analysis
|
||||||
|
```python
|
||||||
|
churn_corr = features[feature_cols + ['churned']].corr()['churned'].drop('churned').sort_values()
|
||||||
|
|
||||||
|
fig, ax = plt.subplots(figsize=(8, 5))
|
||||||
|
churn_corr.plot(kind='barh', ax=ax, color=['coral' if x > 0 else 'steelblue' for x in churn_corr])
|
||||||
|
ax.set_title('Feature Correlation with Churn', fontsize=14, fontweight='bold')
|
||||||
|
ax.set_xlabel('Pearson Correlation')
|
||||||
|
ax.axvline(x=0, color='black', linewidth=0.5)
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('churn_correlations.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 3 — Key driver identification via group comparison
|
||||||
|
```python
|
||||||
|
churned = features[features['churned'] == 1]
|
||||||
|
retained = features[features['churned'] == 0]
|
||||||
|
|
||||||
|
comparison = []
|
||||||
|
for col in feature_cols:
|
||||||
|
t_stat, p_val = stats.ttest_ind(churned[col].dropna(), retained[col].dropna())
|
||||||
|
d = cohens_d(churned[col].dropna(), retained[col].dropna()) # From earlier definition
|
||||||
|
comparison.append({
|
||||||
|
'feature': col,
|
||||||
|
'churned_mean': churned[col].mean(),
|
||||||
|
'retained_mean': retained[col].mean(),
|
||||||
|
'diff_pct': (churned[col].mean() - retained[col].mean()) / retained[col].mean() * 100,
|
||||||
|
'cohens_d': abs(d),
|
||||||
|
'p_value': p_val,
|
||||||
|
'significant': p_val < 0.05
|
||||||
|
})
|
||||||
|
|
||||||
|
result = pd.DataFrame(comparison).sort_values('cohens_d', ascending=False)
|
||||||
|
print(result.to_string(index=False))
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 4 — Interpret and report
|
||||||
|
```
|
||||||
|
## Churn Driver Analysis
|
||||||
|
|
||||||
|
**Top 3 factors distinguishing churned vs. retained customers:**
|
||||||
|
|
||||||
|
| Factor | Churned (avg) | Retained (avg) | Diff | Effect Size |
|
||||||
|
|----------------------------|---------------|----------------|----------|-------------|
|
||||||
|
| Days since last login | 34.2 | 8.7 | +293% | Large |
|
||||||
|
| Support tickets per month | 2.8 | 0.9 | +211% | Large |
|
||||||
|
| Number of features used | 3.1 | 7.4 | -58% | Medium |
|
||||||
|
|
||||||
|
**Actionable insights:**
|
||||||
|
1. Customers inactive >14 days are 4x more likely to churn -- trigger re-engagement email at day 10
|
||||||
|
2. High support ticket rate signals frustration -- escalate accounts with >2 tickets/month to success team
|
||||||
|
3. Low feature adoption correlates with churn -- implement onboarding flow targeting unused features
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Advanced pandas Patterns
|
||||||
|
|
||||||
|
### Window Functions
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Expanding window (cumulative statistics)
|
||||||
|
df['cumulative_avg'] = df['value'].expanding().mean()
|
||||||
|
df['cumulative_max'] = df['value'].expanding().max()
|
||||||
|
|
||||||
|
# Exponentially weighted moving average (EWMA) -- emphasizes recent values
|
||||||
|
df['ewma_7'] = df['value'].ewm(span=7).mean() # Span-based decay
|
||||||
|
df['ewma_a'] = df['value'].ewm(alpha=0.3).mean() # Explicit decay factor
|
||||||
|
|
||||||
|
# Comparison: rolling vs. EWMA
|
||||||
|
# - rolling(7).mean() weights all 7 values equally
|
||||||
|
# - ewm(span=7).mean() weights recent values exponentially more
|
||||||
|
# Use EWMA when recent data matters more (stock prices, real-time metrics)
|
||||||
|
|
||||||
|
# Rolling with min_periods (handles early rows with insufficient data)
|
||||||
|
df['rolling_avg'] = df['value'].rolling(window=30, min_periods=5).mean()
|
||||||
|
|
||||||
|
# Rolling rank (percentile within window)
|
||||||
|
df['rolling_pctile'] = df['value'].rolling(90).rank(pct=True)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Index Operations
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Create multi-index from groupby
|
||||||
|
multi = df.groupby(['region', 'product']).agg(
|
||||||
|
revenue=('amount', 'sum'),
|
||||||
|
units=('quantity', 'sum')
|
||||||
|
)
|
||||||
|
|
||||||
|
# Access levels
|
||||||
|
multi.loc['North'] # All products in North region
|
||||||
|
multi.loc[('North', 'Widget')] # Specific region + product
|
||||||
|
multi.xs('Widget', level='product') # All regions for Widget
|
||||||
|
|
||||||
|
# Swap and sort levels
|
||||||
|
multi = multi.swaplevel().sort_index()
|
||||||
|
|
||||||
|
# Reset to flat columns
|
||||||
|
flat = multi.reset_index()
|
||||||
|
|
||||||
|
# Stack / unstack (reshape between long and wide)
|
||||||
|
wide = multi['revenue'].unstack(level='product') # Products become columns
|
||||||
|
long = wide.stack() # Back to multi-index
|
||||||
|
```
|
||||||
|
|
||||||
|
### Merge and Join Patterns
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Inner join (only matching rows)
|
||||||
|
merged = orders.merge(customers, on='customer_id', how='inner')
|
||||||
|
|
||||||
|
# Left join with indicator (see which rows matched)
|
||||||
|
merged = orders.merge(customers, on='customer_id', how='left', indicator=True)
|
||||||
|
unmatched = merged[merged['_merge'] == 'left_only']
|
||||||
|
|
||||||
|
# Join on multiple keys
|
||||||
|
merged = df1.merge(df2, on=['date', 'region'], how='left')
|
||||||
|
|
||||||
|
# Join with different column names
|
||||||
|
merged = orders.merge(products, left_on='prod_id', right_on='product_id')
|
||||||
|
|
||||||
|
# Anti-join (rows in A that have no match in B)
|
||||||
|
anti = df_a.merge(df_b, on='key', how='left', indicator=True)
|
||||||
|
anti = anti[anti['_merge'] == 'left_only'].drop(columns='_merge')
|
||||||
|
|
||||||
|
# Self-join (compare rows within same table)
|
||||||
|
df_prev = df[['customer_id', 'order_date', 'amount']].rename(
|
||||||
|
columns={'order_date': 'prev_date', 'amount': 'prev_amount'}
|
||||||
|
)
|
||||||
|
df_with_prev = df.merge(df_prev, on='customer_id', how='left')
|
||||||
|
df_with_prev = df_with_prev[df_with_prev['prev_date'] < df_with_prev['order_date']]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Apply and Transform
|
||||||
|
|
||||||
|
```python
|
||||||
|
# transform() returns same-shaped output -- useful for group-level stats on each row
|
||||||
|
df['group_mean'] = df.groupby('category')['value'].transform('mean')
|
||||||
|
df['pct_of_group'] = df['value'] / df.groupby('category')['value'].transform('sum')
|
||||||
|
df['z_within_group'] = df.groupby('category')['value'].transform(
|
||||||
|
lambda x: (x - x.mean()) / x.std()
|
||||||
|
)
|
||||||
|
|
||||||
|
# apply() for multi-column group operations
|
||||||
|
def top_n(group, n=3):
|
||||||
|
return group.nlargest(n, 'value')
|
||||||
|
|
||||||
|
top3_per_category = df.groupby('category', group_keys=False).apply(top_n, n=3)
|
||||||
|
|
||||||
|
# Vectorized operations (prefer these over apply when possible)
|
||||||
|
# Slow:
|
||||||
|
df['result'] = df.apply(lambda row: row['a'] * row['b'] + row['c'], axis=1)
|
||||||
|
# Fast:
|
||||||
|
df['result'] = df['a'] * df['b'] + df['c']
|
||||||
|
|
||||||
|
# np.where for conditional columns (vectorized if/else)
|
||||||
|
df['tier'] = np.where(df['revenue'] > 10000, 'high', 'low')
|
||||||
|
|
||||||
|
# np.select for multiple conditions
|
||||||
|
conditions = [
|
||||||
|
df['revenue'] > 10000,
|
||||||
|
df['revenue'] > 5000,
|
||||||
|
df['revenue'] > 0,
|
||||||
|
]
|
||||||
|
choices = ['high', 'medium', 'low']
|
||||||
|
df['tier'] = np.select(conditions, choices, default='none')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Memory Optimization for Large Datasets
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Check current memory usage
|
||||||
|
print(df.memory_usage(deep=True).sum() / 1024**2, "MB")
|
||||||
|
|
||||||
|
# Downcast numeric types
|
||||||
|
df['int_col'] = pd.to_numeric(df['int_col'], downcast='integer') # int64 -> int8/16/32
|
||||||
|
df['float_col'] = pd.to_numeric(df['float_col'], downcast='float') # float64 -> float32
|
||||||
|
|
||||||
|
# Use category type for low-cardinality strings
|
||||||
|
for col in df.select_dtypes(include='object'):
|
||||||
|
if df[col].nunique() / len(df) < 0.5: # Less than 50% unique values
|
||||||
|
df[col] = df[col].astype('category')
|
||||||
|
|
||||||
|
# Read in chunks for files that exceed memory
|
||||||
|
chunks = pd.read_csv('huge_file.csv', chunksize=100_000)
|
||||||
|
results = []
|
||||||
|
for chunk in chunks:
|
||||||
|
processed = chunk.groupby('category')['value'].sum()
|
||||||
|
results.append(processed)
|
||||||
|
final = pd.concat(results).groupby(level=0).sum()
|
||||||
|
|
||||||
|
# Specify dtypes at load time (avoids loading as float64/object first)
|
||||||
|
dtypes = {
|
||||||
|
'id': 'int32',
|
||||||
|
'category': 'category',
|
||||||
|
'value': 'float32',
|
||||||
|
'flag': 'bool'
|
||||||
|
}
|
||||||
|
df = pd.read_csv('data.csv', dtype=dtypes)
|
||||||
|
|
||||||
|
# Use pyarrow backend for better memory efficiency (pandas 2.0+)
|
||||||
|
df = pd.read_csv('data.csv', engine='pyarrow', dtype_backend='pyarrow')
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dashboard and Reporting Patterns
|
||||||
|
|
||||||
|
### Executive Dashboard Template
|
||||||
|
|
||||||
|
```python
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import matplotlib.gridspec as gridspec
|
||||||
|
from matplotlib.patches import FancyBboxPatch
|
||||||
|
|
||||||
|
def executive_dashboard(kpis, trend_df, comparison_df, output='dashboard.png'):
|
||||||
|
"""
|
||||||
|
kpis: dict with keys like {'Revenue': '$1.2M', 'Growth': '+15%', ...}
|
||||||
|
trend_df: DataFrame with 'date' and 'value' columns
|
||||||
|
comparison_df: DataFrame with 'category' and 'current'/'previous' columns
|
||||||
|
"""
|
||||||
|
fig = plt.figure(figsize=(16, 10))
|
||||||
|
gs = gridspec.GridSpec(3, len(kpis), hspace=0.4, wspace=0.3)
|
||||||
|
|
||||||
|
# Row 1: KPI cards
|
||||||
|
for i, (label, value) in enumerate(kpis.items()):
|
||||||
|
ax = fig.add_subplot(gs[0, i])
|
||||||
|
ax.text(0.5, 0.6, value, ha='center', va='center',
|
||||||
|
fontsize=28, fontweight='bold', color='#2c3e50')
|
||||||
|
ax.text(0.5, 0.2, label, ha='center', va='center',
|
||||||
|
fontsize=12, color='#7f8c8d')
|
||||||
|
ax.set_xlim(0, 1)
|
||||||
|
ax.set_ylim(0, 1)
|
||||||
|
ax.axis('off')
|
||||||
|
# Card background
|
||||||
|
rect = FancyBboxPatch((0.05, 0.05), 0.9, 0.9, boxstyle="round,pad=0.05",
|
||||||
|
facecolor='#f8f9fa', edgecolor='#dee2e6')
|
||||||
|
ax.add_patch(rect)
|
||||||
|
|
||||||
|
# Row 2: Trend line
|
||||||
|
ax_trend = fig.add_subplot(gs[1, :])
|
||||||
|
ax_trend.plot(trend_df['date'], trend_df['value'], linewidth=2, color='steelblue')
|
||||||
|
ax_trend.fill_between(trend_df['date'], trend_df['value'], alpha=0.1, color='steelblue')
|
||||||
|
ax_trend.set_title('Trend Over Time', fontsize=13, fontweight='bold')
|
||||||
|
ax_trend.set_ylabel('Value')
|
||||||
|
|
||||||
|
# Row 3: Period comparison (grouped bar)
|
||||||
|
ax_comp = fig.add_subplot(gs[2, :])
|
||||||
|
x = range(len(comparison_df))
|
||||||
|
width = 0.35
|
||||||
|
ax_comp.bar([i - width/2 for i in x], comparison_df['previous'], width,
|
||||||
|
label='Previous', color='#bdc3c7')
|
||||||
|
ax_comp.bar([i + width/2 for i in x], comparison_df['current'], width,
|
||||||
|
label='Current', color='steelblue')
|
||||||
|
ax_comp.set_xticks(list(x))
|
||||||
|
ax_comp.set_xticklabels(comparison_df['category'], rotation=45, ha='right')
|
||||||
|
ax_comp.set_title('Current vs. Previous Period', fontsize=13, fontweight='bold')
|
||||||
|
ax_comp.legend()
|
||||||
|
|
||||||
|
plt.savefig(output, dpi=150, bbox_inches='tight', facecolor='white')
|
||||||
|
plt.close()
|
||||||
|
```
|
||||||
|
|
||||||
|
### Weekly Metrics Report Template
|
||||||
|
|
||||||
|
```python
|
||||||
|
def weekly_report(df, date_col='date', metric_col='value', group_col=None):
|
||||||
|
"""Generate a standard weekly metrics summary."""
|
||||||
|
df[date_col] = pd.to_datetime(df[date_col])
|
||||||
|
df['week'] = df[date_col].dt.isocalendar().week.astype(int)
|
||||||
|
df['year'] = df[date_col].dt.year
|
||||||
|
|
||||||
|
current_week = df['week'].max()
|
||||||
|
prev_week = current_week - 1
|
||||||
|
|
||||||
|
curr = df[df['week'] == current_week]
|
||||||
|
prev = df[df['week'] == prev_week]
|
||||||
|
|
||||||
|
report = {
|
||||||
|
'period': f"Week {current_week}",
|
||||||
|
'total': curr[metric_col].sum(),
|
||||||
|
'mean': curr[metric_col].mean(),
|
||||||
|
'median': curr[metric_col].median(),
|
||||||
|
'wow_change': (curr[metric_col].sum() - prev[metric_col].sum())
|
||||||
|
/ prev[metric_col].sum() * 100
|
||||||
|
if prev[metric_col].sum() != 0 else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
if group_col:
|
||||||
|
report['by_group'] = curr.groupby(group_col)[metric_col].agg(['sum', 'mean', 'count'])
|
||||||
|
|
||||||
|
# Sparkline trend (last 8 weeks)
|
||||||
|
weekly_totals = (
|
||||||
|
df.groupby('week')[metric_col].sum()
|
||||||
|
.tail(8)
|
||||||
|
.reset_index()
|
||||||
|
)
|
||||||
|
|
||||||
|
fig, ax = plt.subplots(figsize=(6, 2))
|
||||||
|
ax.plot(weekly_totals['week'], weekly_totals[metric_col], marker='o',
|
||||||
|
linewidth=2, color='steelblue', markersize=4)
|
||||||
|
ax.fill_between(weekly_totals['week'], weekly_totals[metric_col],
|
||||||
|
alpha=0.1, color='steelblue')
|
||||||
|
ax.set_title(f'{metric_col.title()} — Last 8 Weeks', fontsize=10)
|
||||||
|
ax.tick_params(labelsize=8)
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('weekly_sparkline.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
return report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Anomaly Detection Patterns
|
||||||
|
|
||||||
|
```python
|
||||||
|
def detect_anomalies(series, method='zscore', threshold=3.0, window=30):
|
||||||
|
"""
|
||||||
|
Detect anomalies in a numeric series.
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
- 'zscore': Flag values beyond `threshold` standard deviations from mean
|
||||||
|
- 'iqr': Flag values beyond 1.5x IQR from quartiles
|
||||||
|
- 'rolling': Flag values beyond `threshold` std devs from rolling mean
|
||||||
|
"""
|
||||||
|
anomalies = pd.Series(False, index=series.index)
|
||||||
|
|
||||||
|
if method == 'zscore':
|
||||||
|
z = (series - series.mean()) / series.std()
|
||||||
|
anomalies = z.abs() > threshold
|
||||||
|
|
||||||
|
elif method == 'iqr':
|
||||||
|
q1 = series.quantile(0.25)
|
||||||
|
q3 = series.quantile(0.75)
|
||||||
|
iqr = q3 - q1
|
||||||
|
anomalies = (series < q1 - 1.5 * iqr) | (series > q3 + 1.5 * iqr)
|
||||||
|
|
||||||
|
elif method == 'rolling':
|
||||||
|
rolling_mean = series.rolling(window, min_periods=5).mean()
|
||||||
|
rolling_std = series.rolling(window, min_periods=5).std()
|
||||||
|
anomalies = (series - rolling_mean).abs() > threshold * rolling_std
|
||||||
|
|
||||||
|
return anomalies
|
||||||
|
|
||||||
|
|
||||||
|
# Usage: detect and visualize
|
||||||
|
anomalies = detect_anomalies(df['metric'], method='rolling', threshold=2.5, window=30)
|
||||||
|
|
||||||
|
fig, ax = plt.subplots(figsize=(14, 5))
|
||||||
|
ax.plot(df.index, df['metric'], linewidth=1, color='steelblue', label='Metric')
|
||||||
|
ax.scatter(df.index[anomalies], df['metric'][anomalies],
|
||||||
|
color='red', s=40, zorder=5, label='Anomaly')
|
||||||
|
ax.legend()
|
||||||
|
ax.set_title('Anomaly Detection (Rolling Z-Score)', fontsize=14, fontweight='bold')
|
||||||
|
plt.tight_layout()
|
||||||
|
plt.savefig('anomalies.png', dpi=150, bbox_inches='tight')
|
||||||
|
plt.close()
|
||||||
|
|
||||||
|
print(f"Detected {anomalies.sum()} anomalies out of {len(series):,} data points")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Method selection guide:**
|
||||||
|
|
||||||
|
| Method | Best For | Assumptions | Sensitivity |
|
||||||
|
|--------|----------|-------------|-------------|
|
||||||
|
| Z-score | Stationary data with normal distribution | Constant mean and variance | Low (misses local anomalies) |
|
||||||
|
| IQR | Skewed distributions, outlier screening | None (non-parametric) | Medium |
|
||||||
|
| Rolling z-score | Time series with trends or seasonality | Local stationarity within window | High (adapts to drift) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Analytics Pitfalls
|
||||||
|
|
||||||
|
### Simpson's Paradox
|
||||||
|
|
||||||
|
A trend that appears in grouped data reverses when the groups are combined.
|
||||||
|
|
||||||
|
```
|
||||||
|
Department A: Drug works better (80% vs 70%)
|
||||||
|
Department B: Drug works better (50% vs 40%)
|
||||||
|
Combined: Drug appears WORSE (55% vs 60%) <-- paradox
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why it happens**: Unequal group sizes create a confounding effect. Department B (with lower overall rates) sent most patients to the drug group.
|
||||||
|
|
||||||
|
**Prevention**: Always segment data by relevant confounders before drawing conclusions. If aggregate and segmented results disagree, trust the segmented analysis and report the confounding variable.
|
||||||
|
|
||||||
|
### Survivorship Bias
|
||||||
|
|
||||||
|
Analyzing only entities that "survived" a selection process, ignoring those that dropped out.
|
||||||
|
|
||||||
|
**Classic examples:**
|
||||||
|
- Studying only successful companies to find success patterns (ignoring failed companies with the same patterns)
|
||||||
|
- Analyzing only current customers to understand satisfaction (ignoring those who already left)
|
||||||
|
- Looking at fund performance by examining only funds that still exist (dead funds were closed)
|
||||||
|
|
||||||
|
**Prevention**: Always ask "what is missing from this dataset?" before drawing conclusions. If possible, include data from non-survivors. Explicitly note the selection criteria and what it excludes.
|
||||||
|
|
||||||
|
### Correlation vs. Causation
|
||||||
|
|
||||||
|
A statistically significant correlation between X and Y does not mean X causes Y. Possible explanations:
|
||||||
|
|
||||||
|
| Explanation | Example |
|
||||||
|
|-------------|---------|
|
||||||
|
| X causes Y | Exercise reduces blood pressure |
|
||||||
|
| Y causes X | Depression reduces exercise (not exercise causes depression) |
|
||||||
|
| Z causes both | Income drives both education spending AND health outcomes |
|
||||||
|
| Coincidence | Ice cream sales correlate with drowning deaths (both driven by summer) |
|
||||||
|
|
||||||
|
**Prevention**: Establish causation only with randomized controlled experiments (A/B tests). For observational data, state findings as "associated with" not "causes." Look for confounders and test whether the relationship holds when controlling for them.
|
||||||
|
|
||||||
|
### Cherry-Picking Time Windows
|
||||||
|
|
||||||
|
Selecting a start/end date that makes a metric look better or worse than the true trend.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Example: same data, different conclusions
|
||||||
|
# "Revenue up 40%!" -- comparing Jan (seasonal low) to Dec (seasonal high)
|
||||||
|
# "Revenue flat." -- comparing Dec 2024 to Dec 2025 (year-over-year)
|
||||||
|
|
||||||
|
# Prevention: always use year-over-year comparison for seasonal data
|
||||||
|
df['yoy_change'] = df.groupby(df['date'].dt.month)['revenue'].pct_change(periods=12)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Prevention checklist:**
|
||||||
|
- Compare like-for-like periods (YoY for seasonal businesses)
|
||||||
|
- Show the full time range, not a selected subset
|
||||||
|
- Use multiple time windows (WoW, MoM, QoQ, YoY) and note if they disagree
|
||||||
|
- Include a moving average to show the underlying trend separate from noise
|
||||||
|
|
||||||
|
### Small Sample Size Issues
|
||||||
|
|
||||||
|
Small samples produce unstable statistics that can flip with just a few more observations.
|
||||||
|
|
||||||
|
```python
|
||||||
|
# Illustrate instability: conversion rates with small vs. large samples
|
||||||
|
from scipy.stats import beta
|
||||||
|
|
||||||
|
# Scenario: 3 conversions out of 10 visitors (30%)
|
||||||
|
a_small, b_small = 3 + 1, 10 - 3 + 1 # Beta posterior
|
||||||
|
ci_small = beta.interval(0.95, a_small, b_small)
|
||||||
|
print(f"n=10: 30% conversion, 95% CI: [{ci_small[0]:.1%}, {ci_small[1]:.1%}]")
|
||||||
|
# Output: 95% CI: [9.9%, 56.8%] -- extremely wide, almost useless
|
||||||
|
|
||||||
|
# Scenario: 300 conversions out of 1000 visitors (30%)
|
||||||
|
a_large, b_large = 300 + 1, 1000 - 300 + 1
|
||||||
|
ci_large = beta.interval(0.95, a_large, b_large)
|
||||||
|
print(f"n=1000: 30% conversion, 95% CI: [{ci_large[0]:.1%}, {ci_large[1]:.1%}]")
|
||||||
|
# Output: 95% CI: [27.2%, 32.9%] -- narrow and actionable
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rules of thumb:**
|
||||||
|
- n < 30: Do not draw firm conclusions. Report as directional only.
|
||||||
|
- Conversion rates need hundreds (not dozens) of conversions to stabilize.
|
||||||
|
- Always report confidence intervals alongside point estimates.
|
||||||
|
- If sample size is fixed and small, use exact tests (Fisher's exact) rather than approximations (chi-squared).
|
||||||
@@ -460,6 +460,265 @@ token_consumption = "medium"
|
|||||||
default_active = false
|
default_active = false
|
||||||
activation_warning = "API Tester hand runs continuously, consuming tokens. Use on-demand for specific tests."
|
activation_warning = "API Tester hand runs continuously, consuming tokens. Use on-demand for specific tests."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "API 测试 Hand"
|
name = "API 测试 Hand"
|
||||||
description = "自主 API 测试智能体——端点发现、请求验证、负载测试和回归检测"
|
description = "自主 API 测试智能体——端点发现、请求验证、负载测试和回归检测"
|
||||||
|
category = "开发"
|
||||||
|
|
||||||
|
[i18n.zh.settings.base_url]
|
||||||
|
label = "基础 URL"
|
||||||
|
description = "待测试 API 的基础 URL(例如 https://api.example.com/v1)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auth_type]
|
||||||
|
label = "认证方式"
|
||||||
|
description = "API 请求的认证方式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auth_token]
|
||||||
|
label = "认证令牌 / API 密钥"
|
||||||
|
description = "Bearer 令牌、API 密钥或 Base64 编码的凭据,取决于认证方式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.test_mode]
|
||||||
|
label = "测试模式"
|
||||||
|
description = "执行的 API 测试类型"
|
||||||
|
|
||||||
|
[i18n.zh.settings.openapi_spec_url]
|
||||||
|
label = "OpenAPI 规范 URL"
|
||||||
|
description = "OpenAPI/Swagger 规范的 URL(例如 /openapi.json)。留空则自动发现。"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_schedule]
|
||||||
|
label = "自动定时"
|
||||||
|
description = "按计划自动运行测试"
|
||||||
|
|
||||||
|
[i18n.zh.settings.test_frequency]
|
||||||
|
label = "测试频率"
|
||||||
|
description = "定时测试的执行频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.fail_on_error]
|
||||||
|
label = "严格模式"
|
||||||
|
description = "将任何非 2xx 响应视为失败(而非允许预期的错误码)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "审批模式"
|
||||||
|
description = "将测试计划和破坏性请求写入队列文件供审核,而非直接执行"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "APIテスト Hand"
|
||||||
|
description = "自律型APIテストエージェント——エンドポイント検出、リクエスト検証、負荷テスト、リグレッション検出"
|
||||||
|
category = "開発"
|
||||||
|
|
||||||
|
[i18n.ja.settings.base_url]
|
||||||
|
label = "ベースURL"
|
||||||
|
description = "テスト対象APIのベースURL(例: https://api.example.com/v1)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auth_type]
|
||||||
|
label = "認証方式"
|
||||||
|
description = "APIリクエストの認証方法"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auth_token]
|
||||||
|
label = "認証トークン / APIキー"
|
||||||
|
description = "認証方式に応じたBearerトークン、APIキー、またはBase64エンコードされた資格情報"
|
||||||
|
|
||||||
|
[i18n.ja.settings.test_mode]
|
||||||
|
label = "テストモード"
|
||||||
|
description = "実行するAPIテストの種類"
|
||||||
|
|
||||||
|
[i18n.ja.settings.openapi_spec_url]
|
||||||
|
label = "OpenAPI仕様URL"
|
||||||
|
description = "OpenAPI/Swagger仕様のURL(例: /openapi.json)。空欄にすると自動検出します。"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_schedule]
|
||||||
|
label = "自動スケジュール"
|
||||||
|
description = "スケジュールに基づいてテストを自動実行する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.test_frequency]
|
||||||
|
label = "テスト頻度"
|
||||||
|
description = "定期テストの実行頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.fail_on_error]
|
||||||
|
label = "厳格モード"
|
||||||
|
description = "2xx以外のレスポンスをすべて失敗として扱う(期待されるエラーコードを許容しない)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "承認モード"
|
||||||
|
description = "テスト計画や破壊的リクエストを直接実行せず、レビュー用のキューファイルに書き出す"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Pruebas API"
|
||||||
|
description = "Agente autónomo de pruebas de API — descubrimiento de endpoints, validación de peticiones, pruebas de carga y detección de regresiones"
|
||||||
|
category = "Desarrollo"
|
||||||
|
|
||||||
|
[i18n.es.settings.base_url]
|
||||||
|
label = "URL base"
|
||||||
|
description = "URL base de la API a probar (ej. https://api.example.com/v1)"
|
||||||
|
|
||||||
|
[i18n.es.settings.auth_type]
|
||||||
|
label = "Tipo de autenticación"
|
||||||
|
description = "Cómo autenticar las peticiones a la API"
|
||||||
|
|
||||||
|
[i18n.es.settings.auth_token]
|
||||||
|
label = "Token de autenticación / Clave API"
|
||||||
|
description = "Token Bearer, clave API o credenciales codificadas en Base64 según el tipo de autenticación"
|
||||||
|
|
||||||
|
[i18n.es.settings.test_mode]
|
||||||
|
label = "Modo de prueba"
|
||||||
|
description = "Qué tipo de pruebas de API realizar"
|
||||||
|
|
||||||
|
[i18n.es.settings.openapi_spec_url]
|
||||||
|
label = "URL de especificación OpenAPI"
|
||||||
|
description = "URL de la especificación OpenAPI/Swagger (ej. /openapi.json). Dejar vacío para descubrimiento automático."
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_schedule]
|
||||||
|
label = "Programación automática"
|
||||||
|
description = "Ejecutar pruebas automáticamente según un calendario"
|
||||||
|
|
||||||
|
[i18n.es.settings.test_frequency]
|
||||||
|
label = "Frecuencia de pruebas"
|
||||||
|
description = "Con qué frecuencia ejecutar las pruebas programadas"
|
||||||
|
|
||||||
|
[i18n.es.settings.fail_on_error]
|
||||||
|
label = "Modo estricto"
|
||||||
|
description = "Tratar cualquier respuesta no 2xx como un fallo (en lugar de permitir códigos de error esperados)"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Modo de aprobación"
|
||||||
|
description = "Escribir planes de prueba y peticiones destructivas en un archivo de cola para revisión en lugar de ejecutarlos directamente"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand de Test API"
|
||||||
|
description = "Agent autonome de test d'API — découverte de points de terminaison, validation de requêtes, tests de charge et détection de régression"
|
||||||
|
category = "Développement"
|
||||||
|
|
||||||
|
[i18n.fr.settings.base_url]
|
||||||
|
label = "URL de base"
|
||||||
|
description = "URL de base de l'API à tester (ex. https://api.example.com/v1)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auth_type]
|
||||||
|
label = "Type d'authentification"
|
||||||
|
description = "Méthode d'authentification des requêtes API"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auth_token]
|
||||||
|
label = "Jeton d'authentification / Clé API"
|
||||||
|
description = "Jeton Bearer, clé API ou identifiants encodés en Base64 selon le type d'authentification"
|
||||||
|
|
||||||
|
[i18n.fr.settings.test_mode]
|
||||||
|
label = "Mode de test"
|
||||||
|
description = "Type de tests API à exécuter"
|
||||||
|
|
||||||
|
[i18n.fr.settings.openapi_spec_url]
|
||||||
|
label = "URL de spécification OpenAPI"
|
||||||
|
description = "URL de la spécification OpenAPI/Swagger (ex. /openapi.json). Laisser vide pour la découverte automatique."
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_schedule]
|
||||||
|
label = "Planification automatique"
|
||||||
|
description = "Exécuter automatiquement les tests selon un calendrier"
|
||||||
|
|
||||||
|
[i18n.fr.settings.test_frequency]
|
||||||
|
label = "Fréquence des tests"
|
||||||
|
description = "Fréquence d'exécution des tests planifiés"
|
||||||
|
|
||||||
|
[i18n.fr.settings.fail_on_error]
|
||||||
|
label = "Mode strict"
|
||||||
|
description = "Traiter toute réponse non 2xx comme un échec (au lieu d'autoriser les codes d'erreur attendus)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Mode d'approbation"
|
||||||
|
description = "Écrire les plans de test et requêtes destructives dans un fichier d'attente pour révision au lieu de les exécuter directement"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "API-Test-Hand"
|
||||||
|
description = "Autonomer API-Test-Agent — Endpunkt-Erkennung, Anfrage-Validierung, Lasttests und Regressionserkennung"
|
||||||
|
category = "Entwicklung"
|
||||||
|
|
||||||
|
[i18n.de.settings.base_url]
|
||||||
|
label = "Basis-URL"
|
||||||
|
description = "Basis-URL der zu testenden API (z.B. https://api.example.com/v1)"
|
||||||
|
|
||||||
|
[i18n.de.settings.auth_type]
|
||||||
|
label = "Authentifizierungstyp"
|
||||||
|
description = "Authentifizierungsmethode für API-Anfragen"
|
||||||
|
|
||||||
|
[i18n.de.settings.auth_token]
|
||||||
|
label = "Authentifizierungstoken / API-Schlüssel"
|
||||||
|
description = "Bearer-Token, API-Schlüssel oder Base64-kodierte Anmeldedaten je nach Authentifizierungstyp"
|
||||||
|
|
||||||
|
[i18n.de.settings.test_mode]
|
||||||
|
label = "Testmodus"
|
||||||
|
description = "Art der durchzuführenden API-Tests"
|
||||||
|
|
||||||
|
[i18n.de.settings.openapi_spec_url]
|
||||||
|
label = "OpenAPI-Spezifikations-URL"
|
||||||
|
description = "URL der OpenAPI/Swagger-Spezifikation (z.B. /openapi.json). Leer lassen für automatische Erkennung."
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_schedule]
|
||||||
|
label = "Automatische Planung"
|
||||||
|
description = "Tests automatisch nach Zeitplan ausführen"
|
||||||
|
|
||||||
|
[i18n.de.settings.test_frequency]
|
||||||
|
label = "Testhäufigkeit"
|
||||||
|
description = "Ausführungshäufigkeit der geplanten Tests"
|
||||||
|
|
||||||
|
[i18n.de.settings.fail_on_error]
|
||||||
|
label = "Strikter Modus"
|
||||||
|
description = "Jede Nicht-2xx-Antwort als Fehler behandeln (anstatt erwartete Fehlercodes zuzulassen)"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Genehmigungsmodus"
|
||||||
|
description = "Testpläne und destruktive Anfragen in eine Warteschlange zur Überprüfung schreiben, anstatt sie direkt auszuführen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "API 테스트 Hand"
|
||||||
|
description = "자율 API 테스트 에이전트 — 엔드포인트 탐색, 요청 검증, 부하 테스트 및 회귀 감지"
|
||||||
|
category = "개발"
|
||||||
|
|
||||||
|
[i18n.ko.settings.base_url]
|
||||||
|
label = "기본 URL"
|
||||||
|
description = "테스트할 API의 기본 URL (예: https://api.example.com/v1)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auth_type]
|
||||||
|
label = "인증 방식"
|
||||||
|
description = "API 요청의 인증 방식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auth_token]
|
||||||
|
label = "인증 토큰 / API 키"
|
||||||
|
description = "인증 방식에 따른 Bearer 토큰, API 키 또는 Base64 인코딩 자격 증명"
|
||||||
|
|
||||||
|
[i18n.ko.settings.test_mode]
|
||||||
|
label = "테스트 모드"
|
||||||
|
description = "수행할 API 테스트 유형"
|
||||||
|
|
||||||
|
[i18n.ko.settings.openapi_spec_url]
|
||||||
|
label = "OpenAPI 스펙 URL"
|
||||||
|
description = "OpenAPI/Swagger 스펙의 URL (예: /openapi.json). 비워두면 자동 탐색합니다."
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_schedule]
|
||||||
|
label = "자동 일정"
|
||||||
|
description = "일정에 따라 자동으로 테스트 실행"
|
||||||
|
|
||||||
|
[i18n.ko.settings.test_frequency]
|
||||||
|
label = "테스트 빈도"
|
||||||
|
description = "정기 테스트 실행 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.fail_on_error]
|
||||||
|
label = "엄격 모드"
|
||||||
|
description = "모든 비-2xx 응답을 실패로 처리 (예상된 오류 코드 허용 안 함)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "승인 모드"
|
||||||
|
description = "테스트 계획 및 파괴적 요청을 직접 실행하지 않고 큐 파일에 기록하여 검토"
|
||||||
@@ -237,3 +237,656 @@ First Seen: 2025-01-15 run
|
|||||||
Previous Value: string (email format)
|
Previous Value: string (email format)
|
||||||
Current Value: field absent
|
Current Value: field absent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Testing a REST API CRUD Endpoint
|
||||||
|
|
||||||
|
Full test suite for a `/api/users` resource covering create, read, update, delete, and edge cases.
|
||||||
|
|
||||||
|
**Setup — Create a test user**:
|
||||||
|
```bash
|
||||||
|
# POST /api/users — create
|
||||||
|
RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
-d '{"name": "Ada Lovelace", "email": "ada@example.com", "role": "engineer"}' \
|
||||||
|
"https://api.example.com/api/users")
|
||||||
|
|
||||||
|
BODY=$(echo "$RESPONSE" | sed '$d')
|
||||||
|
STATUS=$(echo "$RESPONSE" | tail -1)
|
||||||
|
|
||||||
|
# Expect 201 Created
|
||||||
|
[ "$STATUS" = "201" ] && echo "PASS: Create user" || echo "FAIL: Expected 201, got $STATUS"
|
||||||
|
|
||||||
|
# Extract ID for subsequent tests
|
||||||
|
USER_ID=$(echo "$BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
|
||||||
|
```
|
||||||
|
|
||||||
|
**Read operations**:
|
||||||
|
```bash
|
||||||
|
# GET /api/users — list all
|
||||||
|
curl -s -H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/users" | python3 -m json.tool
|
||||||
|
|
||||||
|
# GET /api/users/:id — single user
|
||||||
|
curl -s -H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/users/$USER_ID" | python3 -m json.tool
|
||||||
|
|
||||||
|
# GET /api/users/nonexistent-id — expect 404
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/users/00000000-0000-0000-0000-000000000000")
|
||||||
|
[ "$STATUS" = "404" ] && echo "PASS: 404 for missing user" || echo "FAIL: Expected 404, got $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Update operations**:
|
||||||
|
```bash
|
||||||
|
# PUT /api/users/:id — full update
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X PUT \
|
||||||
|
-H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
|
||||||
|
-d '{"name": "Ada Lovelace", "email": "ada.updated@example.com", "role": "lead"}' \
|
||||||
|
"https://api.example.com/api/users/$USER_ID")
|
||||||
|
[ "$STATUS" = "200" ] && echo "PASS: Full update" || echo "FAIL: Expected 200, got $STATUS"
|
||||||
|
|
||||||
|
# PATCH — partial update (expect 200); also test invalid data (expect 400/422)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Delete and verify**:
|
||||||
|
```bash
|
||||||
|
# DELETE /api/users/:id
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/users/$USER_ID")
|
||||||
|
[ "$STATUS" = "204" ] || [ "$STATUS" = "200" ] && echo "PASS: Delete user" || echo "FAIL: Expected 2xx, got $STATUS"
|
||||||
|
|
||||||
|
# GET deleted user — expect 404 or 410
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/users/$USER_ID")
|
||||||
|
[ "$STATUS" = "404" ] || [ "$STATUS" = "410" ] && echo "PASS: Deleted user gone" || echo "FAIL: Expected 404/410, got $STATUS"
|
||||||
|
|
||||||
|
# DELETE again — idempotency check
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/users/$USER_ID")
|
||||||
|
[ "$STATUS" = "404" ] || [ "$STATUS" = "204" ] && echo "PASS: Idempotent delete" || echo "FAIL: Got $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Edge cases to test**: duplicate create (expect 409), empty body (expect 400/422), extra unknown fields (verify ignored or rejected, not persisted).
|
||||||
|
|
||||||
|
### Example 2: Testing an Authenticated API with Rate Limiting
|
||||||
|
|
||||||
|
Scenario: API uses Bearer tokens, tokens expire after 1 hour, rate limit is 100 requests/minute.
|
||||||
|
|
||||||
|
**Token lifecycle testing**:
|
||||||
|
```bash
|
||||||
|
# Step 1: Obtain token
|
||||||
|
AUTH_RESPONSE=$(curl -s -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"client_id": "myapp", "client_secret": "secret", "grant_type": "client_credentials"}' \
|
||||||
|
"https://api.example.com/oauth/token")
|
||||||
|
|
||||||
|
ACCESS_TOKEN=$(echo "$AUTH_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
|
||||||
|
EXPIRES_IN=$(echo "$AUTH_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['expires_in'])")
|
||||||
|
echo "Token obtained, expires in ${EXPIRES_IN}s"
|
||||||
|
|
||||||
|
# Step 2: Use token — expect 200
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
"https://api.example.com/api/protected")
|
||||||
|
[ "$STATUS" = "200" ] && echo "PASS: Valid token accepted" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Step 3: Use expired/invalid token — expect 401
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "Authorization: Bearer expired.token.here" \
|
||||||
|
"https://api.example.com/api/protected")
|
||||||
|
[ "$STATUS" = "401" ] && echo "PASS: Expired token rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Step 4: Missing Authorization header — expect 401
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
"https://api.example.com/api/protected")
|
||||||
|
[ "$STATUS" = "401" ] && echo "PASS: No auth rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Step 5: Malformed header — expect 401
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "Authorization: NotBearer $ACCESS_TOKEN" \
|
||||||
|
"https://api.example.com/api/protected")
|
||||||
|
[ "$STATUS" = "401" ] && echo "PASS: Bad scheme rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rate limit testing**:
|
||||||
|
```bash
|
||||||
|
# Hit the endpoint rapidly and watch for 429
|
||||||
|
RESULTS_FILE=$(mktemp)
|
||||||
|
for i in $(seq 1 120); do
|
||||||
|
curl -s -o /dev/null -w "%{http_code}\n" \
|
||||||
|
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
"https://api.example.com/api/data" >> "$RESULTS_FILE" &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Count status codes
|
||||||
|
echo "=== Rate Limit Results ==="
|
||||||
|
sort "$RESULTS_FILE" | uniq -c | sort -rn
|
||||||
|
# Expected: ~100 x 200, ~20 x 429
|
||||||
|
|
||||||
|
# Check rate limit headers on a single request
|
||||||
|
curl -s -D- -o /dev/null \
|
||||||
|
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
"https://api.example.com/api/data" | grep -i "x-ratelimit"
|
||||||
|
# Expected headers:
|
||||||
|
# X-RateLimit-Limit: 100
|
||||||
|
# X-RateLimit-Remaining: 99
|
||||||
|
# X-RateLimit-Reset: 1700000060
|
||||||
|
|
||||||
|
rm "$RESULTS_FILE"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Backoff strategy**: On 429, respect `Retry-After` header. Use exponential backoff (1s, 2s, 4s...) as fallback. Verify the API returns `X-RateLimit-Reset` for client scheduling.
|
||||||
|
|
||||||
|
### Example 3: Testing a Webhook Endpoint
|
||||||
|
|
||||||
|
Scenario: Your API accepts webhook callbacks at `POST /webhooks/payment` with HMAC-SHA256 signature verification.
|
||||||
|
|
||||||
|
**Payload and signature generation**:
|
||||||
|
```bash
|
||||||
|
WEBHOOK_SECRET="whsec_test_secret_key_12345"
|
||||||
|
PAYLOAD='{"event":"payment.completed","data":{"id":"pay_123","amount":4999,"currency":"usd"}}'
|
||||||
|
TIMESTAMP=$(date +%s)
|
||||||
|
SIGNATURE=$(printf "%s.%s" "$TIMESTAMP" "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')
|
||||||
|
|
||||||
|
# Valid webhook delivery
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-Webhook-Signature: t=$TIMESTAMP,v1=$SIGNATURE" \
|
||||||
|
-H "X-Webhook-Id: wh_evt_001" \
|
||||||
|
-d "$PAYLOAD" \
|
||||||
|
"https://api.example.com/webhooks/payment")
|
||||||
|
[ "$STATUS" = "200" ] || [ "$STATUS" = "204" ] && echo "PASS: Valid webhook accepted" || echo "FAIL: Got $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Signature verification tests**:
|
||||||
|
```bash
|
||||||
|
# Wrong signature — expect 401 or 403
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-Webhook-Signature: t=$TIMESTAMP,v1=badsignaturevalue" \
|
||||||
|
-d "$PAYLOAD" \
|
||||||
|
"https://api.example.com/webhooks/payment")
|
||||||
|
[ "$STATUS" = "401" ] || [ "$STATUS" = "403" ] && echo "PASS: Bad signature rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Missing signature header — expect 401
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$PAYLOAD" \
|
||||||
|
"https://api.example.com/webhooks/payment")
|
||||||
|
[ "$STATUS" = "401" ] && echo "PASS: Missing signature rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Stale timestamp (replay attack) — expect 403
|
||||||
|
OLD_TIMESTAMP=$((TIMESTAMP - 600))
|
||||||
|
OLD_SIGNATURE=$(printf "%s.%s" "$OLD_TIMESTAMP" "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "X-Webhook-Signature: t=$OLD_TIMESTAMP,v1=$OLD_SIGNATURE" \
|
||||||
|
-d "$PAYLOAD" \
|
||||||
|
"https://api.example.com/webhooks/payment")
|
||||||
|
[ "$STATUS" = "403" ] && echo "PASS: Stale timestamp rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Also test**: idempotency (same `X-Webhook-Id` sent twice — should be processed once), invalid/empty payloads (expect 400).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Authentication Testing Patterns
|
||||||
|
|
||||||
|
### OAuth 2.0 Flow Testing
|
||||||
|
|
||||||
|
**Authorization Code flow**:
|
||||||
|
```bash
|
||||||
|
# Step 1: Initiate authorization — verify redirect
|
||||||
|
AUTHORIZE_URL="https://api.example.com/oauth/authorize?response_type=code&client_id=myapp&redirect_uri=https://myapp.example.com/callback&scope=read+write&state=random_state_123"
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "$AUTHORIZE_URL")
|
||||||
|
[ "$STATUS" = "302" ] || [ "$STATUS" = "200" ] && echo "PASS: Auth endpoint reachable" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Step 2: Exchange authorization code for token
|
||||||
|
TOKEN_RESPONSE=$(curl -s -X POST \
|
||||||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
|
-d "grant_type=authorization_code&code=AUTH_CODE_HERE&redirect_uri=https://myapp.example.com/callback&client_id=myapp&client_secret=secret" \
|
||||||
|
"https://api.example.com/oauth/token")
|
||||||
|
echo "$TOKEN_RESPONSE" | python3 -m json.tool
|
||||||
|
# Verify: access_token, refresh_token, expires_in, token_type present
|
||||||
|
|
||||||
|
# Step 3: Use invalid authorization code — expect 400
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
|
-d "grant_type=authorization_code&code=INVALID_CODE&redirect_uri=https://myapp.example.com/callback&client_id=myapp&client_secret=secret" \
|
||||||
|
"https://api.example.com/oauth/token")
|
||||||
|
[ "$STATUS" = "400" ] && echo "PASS: Invalid code rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Step 4: Reuse authorization code — must fail (codes are single-use)
|
||||||
|
# Use the same AUTH_CODE_HERE again
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
|
-d "grant_type=authorization_code&code=AUTH_CODE_HERE&redirect_uri=https://myapp.example.com/callback&client_id=myapp&client_secret=secret" \
|
||||||
|
"https://api.example.com/oauth/token")
|
||||||
|
[ "$STATUS" = "400" ] && echo "PASS: Code reuse rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Client Credentials flow**: Same pattern as above with `grant_type=client_credentials`. Test: valid credentials (expect `access_token`), invalid secret (expect 401), invalid `grant_type` (expect 400).
|
||||||
|
|
||||||
|
**Refresh Token flow**: Exchange `grant_type=refresh_token` with `refresh_token=$REFRESH_TOKEN`. Verify: new `access_token` returned, old refresh token invalidated if rotation is enabled (reuse should return 400/401).
|
||||||
|
|
||||||
|
### JWT Validation Testing
|
||||||
|
|
||||||
|
Test each type of JWT failure independently:
|
||||||
|
|
||||||
|
| Test Case | Token Modification | Expected Status | Expected Error |
|
||||||
|
|-----------|-------------------|-----------------|----------------|
|
||||||
|
| Expired token | Set `exp` to past timestamp | 401 | `token_expired` |
|
||||||
|
| Not-yet-valid | Set `nbf` to future timestamp | 401 | `token_not_yet_valid` |
|
||||||
|
| Wrong signature | Sign with different key | 401 | `invalid_signature` |
|
||||||
|
| Malformed token | Remove a segment | 401 | `malformed_token` |
|
||||||
|
| Missing `sub` claim | Remove `sub` from payload | 401 | `missing_claims` |
|
||||||
|
| Wrong audience | Set `aud` to different app | 401 | `invalid_audience` |
|
||||||
|
| Wrong issuer | Set `iss` to unknown issuer | 401 | `invalid_issuer` |
|
||||||
|
| Algorithm none attack | Set `alg: none`, remove signature | 401 | `invalid_algorithm` |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate a test JWT with wrong signature (using python3 as a helper)
|
||||||
|
HEADER=$(echo -n '{"alg":"HS256","typ":"JWT"}' | base64 | tr -d '=' | tr '+/' '-_')
|
||||||
|
PAYLOAD=$(echo -n '{"sub":"user123","exp":9999999999}' | base64 | tr -d '=' | tr '+/' '-_')
|
||||||
|
BAD_SIG=$(echo -n "fakesignature" | base64 | tr -d '=' | tr '+/' '-_')
|
||||||
|
BAD_JWT="${HEADER}.${PAYLOAD}.${BAD_SIG}"
|
||||||
|
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "Authorization: Bearer $BAD_JWT" \
|
||||||
|
"https://api.example.com/api/protected")
|
||||||
|
[ "$STATUS" = "401" ] && echo "PASS: Bad JWT signature rejected" || echo "FAIL: Got $STATUS"
|
||||||
|
|
||||||
|
# Algorithm "none" attack
|
||||||
|
NONE_HEADER=$(echo -n '{"alg":"none","typ":"JWT"}' | base64 | tr -d '=' | tr '+/' '-_')
|
||||||
|
NONE_JWT="${NONE_HEADER}.${PAYLOAD}."
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "Authorization: Bearer $NONE_JWT" \
|
||||||
|
"https://api.example.com/api/protected")
|
||||||
|
[ "$STATUS" = "401" ] && echo "PASS: alg:none attack blocked" || echo "FAIL: Got $STATUS — SECURITY RISK"
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Key Testing Patterns
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Valid API key in header
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
|
||||||
|
-H "X-API-Key: valid_key_abc123" \
|
||||||
|
"https://api.example.com/api/data")
|
||||||
|
[ "$STATUS" = "200" ] && echo "PASS: Valid API key" || echo "FAIL: Got $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Also test**: key in query param (if supported), revoked key (expect 401/403), empty key (expect 401), read-only key attempting write (expect 403).
|
||||||
|
|
||||||
|
### Session-Based Auth Testing
|
||||||
|
|
||||||
|
Test pattern: login (capture `Set-Cookie`), use cookie for authenticated request (expect 200), logout, reuse cookie (expect 401). Also verify session fixation prevention — session ID should rotate on login.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Contract Testing
|
||||||
|
|
||||||
|
### Schema Validation Techniques
|
||||||
|
|
||||||
|
Validate API responses against a JSON Schema using `python3 -c "from jsonschema import validate; ..."`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Fetch response and validate against schema file
|
||||||
|
curl -s -H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/users/user_001" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
from jsonschema import validate, ValidationError
|
||||||
|
schema = json.load(open('/tmp/user_schema.json'))
|
||||||
|
try:
|
||||||
|
validate(instance=json.load(sys.stdin), schema=schema)
|
||||||
|
print('PASS: Schema valid')
|
||||||
|
except ValidationError as e:
|
||||||
|
print(f'FAIL: {e.message}')
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
Schema should define `required` fields, property `type`/`format`/`enum` constraints, and `additionalProperties: false` for strict mode.
|
||||||
|
|
||||||
|
### Breaking Change Detection
|
||||||
|
|
||||||
|
Compare current response structure against a recorded baseline:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Helper: extract JSON shape as "path: type" lines
|
||||||
|
extract_shape() {
|
||||||
|
curl -s -H "Authorization: Bearer $TOKEN" "$1" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
def shape(obj, prefix=''):
|
||||||
|
s = {}
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
for k, v in obj.items():
|
||||||
|
p = f'{prefix}.{k}' if prefix else k
|
||||||
|
s[p] = type(v).__name__; s.update(shape(v, p))
|
||||||
|
elif isinstance(obj, list) and obj:
|
||||||
|
s[f'{prefix}[]'] = type(obj[0]).__name__; s.update(shape(obj[0], f'{prefix}[]'))
|
||||||
|
return s
|
||||||
|
for p, t in sorted(shape(json.load(sys.stdin)).items()): print(f'{p}: {t}')
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Record baseline once, then diff against current
|
||||||
|
extract_shape "https://api.example.com/api/users/user_001" > /tmp/api_baseline.txt
|
||||||
|
# ... later ...
|
||||||
|
extract_shape "https://api.example.com/api/users/user_001" > /tmp/api_current.txt
|
||||||
|
diff /tmp/api_baseline.txt /tmp/api_current.txt && echo "PASS: No schema changes" || echo "WARN: Schema changed"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backward Compatibility Checklist
|
||||||
|
|
||||||
|
When a new API version is deployed, verify that existing consumers are not broken:
|
||||||
|
|
||||||
|
| Check | How to Test | Severity |
|
||||||
|
|-------|------------|----------|
|
||||||
|
| Removed fields | Diff response shape against baseline | **HIGH** — breaks consumers |
|
||||||
|
| Renamed fields | Diff response keys | **HIGH** — breaks consumers |
|
||||||
|
| Changed field type | Compare type of each field | **HIGH** — breaks deserialization |
|
||||||
|
| New required request field | Send old-format request | **HIGH** — breaks callers |
|
||||||
|
| Changed enum values | Check if old values still accepted | **MEDIUM** — breaks validation |
|
||||||
|
| Changed error format | Compare error response structure | **MEDIUM** — breaks error handlers |
|
||||||
|
| Changed status codes | Compare response codes for same input | **MEDIUM** — breaks status checks |
|
||||||
|
| New optional fields | Verify response still parses | **LOW** — usually safe |
|
||||||
|
| Pagination format change | Test with existing page params | **MEDIUM** — breaks pagination loops |
|
||||||
|
|
||||||
|
### Consumer-Driven Contract Testing
|
||||||
|
|
||||||
|
Concept: Each API consumer defines the minimum contract they need (required fields, forbidden fields, expected status codes). The provider runs all consumer contracts in CI.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"consumer": "mobile-app-v2",
|
||||||
|
"provider": "user-service",
|
||||||
|
"interactions": [
|
||||||
|
{
|
||||||
|
"description": "get user profile",
|
||||||
|
"request": {"method": "GET", "path": "/api/users/me", "headers": {"Authorization": "Bearer valid_token"}},
|
||||||
|
"response": {"status": 200, "body_contains": ["id", "name", "email"], "body_must_not_contain": ["password", "internal_id"]}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Runner approach: iterate interactions, execute each request with curl, verify status code matches and required/forbidden fields are present/absent in the response body.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Performance Testing Deep Dive
|
||||||
|
|
||||||
|
### Load Test Types
|
||||||
|
|
||||||
|
| Type | Purpose | Pattern |
|
||||||
|
|------|---------|---------|
|
||||||
|
| **Soak** | Detect memory leaks, connection pool exhaustion | Steady traffic (e.g., 5 req/s) for hours; compare first-quarter vs last-quarter response times |
|
||||||
|
| **Spike** | Verify graceful handling of sudden bursts | Baseline → 10x-20x burst → recovery; check error rate and recovery time |
|
||||||
|
| **Stress** | Find the breaking point | Incrementally increase concurrency until errors begin |
|
||||||
|
|
||||||
|
### Stress Testing (Representative Example)
|
||||||
|
|
||||||
|
Incrementally increase load until errors begin — adapt the same pattern for soak (fixed concurrency, long duration) or spike (sudden burst) testing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo "concurrency,success_rate,avg_time,p95_time" > /tmp/stress_results.csv
|
||||||
|
for CONCURRENCY in 10 25 50 100 200 500; do
|
||||||
|
RESULTS=$(mktemp)
|
||||||
|
for i in $(seq 1 $CONCURRENCY); do
|
||||||
|
curl -s -o /dev/null -w "%{http_code} %{time_total}\n" \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/data" >> "$RESULTS" &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
TOTAL=$(wc -l < "$RESULTS")
|
||||||
|
SUCCESS=$(grep -c "^200" "$RESULTS")
|
||||||
|
AVG_TIME=$(awk '{sum+=$2; n++} END {printf "%.3f", sum/n}' "$RESULTS")
|
||||||
|
P95_TIME=$(awk '{print $2}' "$RESULTS" | sort -n | awk -v p=0.95 'NR==1{n=0} {a[n++]=$1} END {print a[int(n*p)]}')
|
||||||
|
|
||||||
|
echo "$CONCURRENCY,$((SUCCESS*100/TOTAL))%,$AVG_TIME,$P95_TIME" >> /tmp/stress_results.csv
|
||||||
|
echo "Concurrency $CONCURRENCY: ${SUCCESS}/${TOTAL} success, avg=${AVG_TIME}s, p95=${P95_TIME}s"
|
||||||
|
|
||||||
|
rm "$RESULTS"
|
||||||
|
sleep 3 # Let the server recover between steps
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "=== Stress Test Summary ==="
|
||||||
|
column -t -s',' /tmp/stress_results.csv
|
||||||
|
```
|
||||||
|
|
||||||
|
### Latency Percentile Analysis
|
||||||
|
|
||||||
|
Collect many response times (e.g., 1000 with concurrency capped at 20), then compute p50/p75/p90/p95/p99 percentiles. Compare first-quarter vs last-quarter averages to detect degradation over time.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Collect response times
|
||||||
|
TIMES_FILE=$(mktemp)
|
||||||
|
for i in $(seq 1 1000); do
|
||||||
|
curl -s -o /dev/null -w "%{time_total}\n" \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/data" >> "$TIMES_FILE" &
|
||||||
|
[ $((i % 20)) -eq 0 ] && wait
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
# Sort and compute percentiles with: sort -n "$TIMES_FILE" | python3 ...
|
||||||
|
rm "$TIMES_FILE"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connection Pool Testing
|
||||||
|
|
||||||
|
- **Keep-alive reuse**: Send multiple URLs in one curl call with `Connection: keep-alive`; second/third requests should show near-zero `time_connect`.
|
||||||
|
- **Connection exhaustion**: Open 500 concurrent keep-alive connections; watch for 503 or connection refused errors.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common API Bugs & How to Find Them
|
||||||
|
|
||||||
|
### N+1 Query Detection
|
||||||
|
|
||||||
|
Response time should not scale linearly with data size. If fetching 10 items takes 100ms but 100 items takes 1000ms, the API likely has an N+1 query problem.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Compare response times for different page sizes
|
||||||
|
for SIZE in 1 10 50 100; do
|
||||||
|
TIME=$(curl -s -o /dev/null -w "%{time_total}" \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/orders?per_page=$SIZE")
|
||||||
|
echo "page_size=$SIZE time=${TIME}s"
|
||||||
|
done
|
||||||
|
# Expected (healthy): Times should NOT scale linearly
|
||||||
|
# page_size=1 time=0.045s
|
||||||
|
# page_size=10 time=0.052s
|
||||||
|
# page_size=50 time=0.078s
|
||||||
|
# page_size=100 time=0.110s
|
||||||
|
# Red flag (N+1): Times scale roughly linearly
|
||||||
|
# page_size=1 time=0.045s
|
||||||
|
# page_size=10 time=0.350s
|
||||||
|
# page_size=50 time=1.600s
|
||||||
|
# page_size=100 time=3.200s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Race Condition Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Concurrent counter increment — final value should equal attempt count
|
||||||
|
curl -s -X PUT -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
|
||||||
|
-d '{"value": 0}' "https://api.example.com/api/counters/counter_001"
|
||||||
|
|
||||||
|
for i in $(seq 1 50); do
|
||||||
|
curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
|
||||||
|
-d '{"increment": 1}' "https://api.example.com/api/counters/counter_001/increment" &
|
||||||
|
done
|
||||||
|
wait
|
||||||
|
|
||||||
|
FINAL=$(curl -s -H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/counters/counter_001" | python3 -c "import sys,json; print(json.load(sys.stdin)['value'])")
|
||||||
|
[ "$FINAL" = "50" ] && echo "PASS: No race condition" || echo "FAIL: Lost $((50 - FINAL)) increments"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Optimistic locking test**: Two concurrent PUTs with same `If-Match` ETag — one should get 200, the other 409 Conflict.
|
||||||
|
|
||||||
|
### Pagination Edge Cases
|
||||||
|
|
||||||
|
| Input | Expected Behavior |
|
||||||
|
|-------|------------------|
|
||||||
|
| `page=0` | 400, or treat as page 1 |
|
||||||
|
| `page=-1` | 400 |
|
||||||
|
| `page=99999` (beyond data) | 200 with empty array, not error |
|
||||||
|
| `per_page=0` | 400 or use default |
|
||||||
|
| `per_page=100000` | Capped to server max (e.g., 100) |
|
||||||
|
| Delete item mid-pagination | No items skipped or duplicated on next page |
|
||||||
|
|
||||||
|
### Timezone Handling Bugs
|
||||||
|
|
||||||
|
Test that equivalent timestamps in different offset formats are stored identically:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# All four represent the same moment — stored values should be equivalent
|
||||||
|
for TZ in "2025-06-15T10:00:00Z" "2025-06-15T10:00:00+00:00" "2025-06-15T18:00:00+08:00" "2025-06-15T05:00:00-05:00"; do
|
||||||
|
STORED=$(curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
|
||||||
|
-d "{\"title\": \"tz_test\", \"scheduled_at\": \"$TZ\"}" \
|
||||||
|
"https://api.example.com/api/events" | python3 -c "import sys,json; print(json.load(sys.stdin).get('scheduled_at','ERROR'))")
|
||||||
|
echo "Input: $TZ -> Stored: $STORED"
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
**Also test**: date range filters across timezone boundaries, midnight boundary inclusion/exclusion behavior.
|
||||||
|
|
||||||
|
### Character Encoding Issues
|
||||||
|
|
||||||
|
Test that the API correctly round-trips various Unicode inputs. Key test values:
|
||||||
|
|
||||||
|
| Category | Example | What Breaks |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| Emoji | `Hello 🌍🚀` | UTF-8 4-byte sequences, database column width |
|
||||||
|
| CJK | `你好世界` | Multi-byte encoding, string length vs byte length |
|
||||||
|
| Diacritics | `café` (composed vs decomposed) | Unicode normalization (NFC vs NFD) |
|
||||||
|
| Zero-width | `test\u200Bword` | Invisible characters in search/comparison |
|
||||||
|
| Null byte | `test\u0000value` | String termination in C-based systems |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Round-trip test pattern: POST a value, verify GET returns the same
|
||||||
|
for VALUE in "Hello 🌍🚀" "你好世界" "café"; do
|
||||||
|
RESPONSE=$(curl -s -X POST -H "Content-Type: application/json; charset=utf-8" \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
-d "{\"name\": \"$VALUE\"}" \
|
||||||
|
"https://api.example.com/api/items")
|
||||||
|
RETURNED=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('name','ERROR'))")
|
||||||
|
[ "$VALUE" = "$RETURNED" ] && echo "PASS: $VALUE" || echo "FAIL: sent='$VALUE' got='$RETURNED'"
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Advanced curl Patterns
|
||||||
|
|
||||||
|
### File Upload Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Single file upload
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
-F "file=@/path/to/document.pdf" \
|
||||||
|
-F "description=Test upload" \
|
||||||
|
"https://api.example.com/api/uploads")
|
||||||
|
echo "Single file upload: $STATUS"
|
||||||
|
|
||||||
|
# Multiple file upload
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
-F "files[]=@/path/to/file1.png" \
|
||||||
|
-F "files[]=@/path/to/file2.png" \
|
||||||
|
-F "category=images" \
|
||||||
|
"https://api.example.com/api/uploads/batch")
|
||||||
|
echo "Multi-file upload: $STATUS"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Edge cases to also test**: oversized files (expect 413), wrong content type (e.g., `script.sh` declared as `image/png`), zero-byte files (expect 400).
|
||||||
|
|
||||||
|
### Multipart Form Data
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Mixed multipart: file + JSON metadata
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
-F "metadata={\"title\":\"Report Q4\",\"tags\":[\"finance\",\"quarterly\"]};type=application/json" \
|
||||||
|
-F "file=@/path/to/report.pdf" \
|
||||||
|
"https://api.example.com/api/documents"
|
||||||
|
|
||||||
|
# Form-encoded data (not JSON)
|
||||||
|
curl -s -X POST \
|
||||||
|
-H "Content-Type: application/x-www-form-urlencoded" \
|
||||||
|
-d "username=testuser&password=testpass&remember=true" \
|
||||||
|
"https://api.example.com/auth/login"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Cookie-Based Session Testing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Full session lifecycle with cookie jar
|
||||||
|
COOKIE_JAR=$(mktemp)
|
||||||
|
|
||||||
|
# Login — store cookies
|
||||||
|
curl -s -c "$COOKIE_JAR" -X POST \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{"username": "testuser", "password": "testpass"}' \
|
||||||
|
"https://api.example.com/auth/login"
|
||||||
|
|
||||||
|
# Authenticated request — send cookies
|
||||||
|
curl -s -b "$COOKIE_JAR" -c "$COOKIE_JAR" \
|
||||||
|
"https://api.example.com/api/profile"
|
||||||
|
|
||||||
|
# Logout and verify session invalidated
|
||||||
|
curl -s -b "$COOKIE_JAR" -c "$COOKIE_JAR" -X POST \
|
||||||
|
"https://api.example.com/auth/logout"
|
||||||
|
STATUS=$(curl -s -b "$COOKIE_JAR" -o /dev/null -w "%{http_code}" \
|
||||||
|
"https://api.example.com/api/profile")
|
||||||
|
[ "$STATUS" = "401" ] && echo "PASS: Session invalidated" || echo "FAIL: Got $STATUS"
|
||||||
|
rm "$COOKIE_JAR"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Also verify**: HttpOnly/Secure/SameSite cookie attributes, session ID rotation on login (session fixation prevention).
|
||||||
|
|
||||||
|
### Following Redirects
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Follow redirects automatically
|
||||||
|
curl -s -L -o /dev/null -w "final_url:%{url_effective} status:%{http_code} redirects:%{num_redirects}\n" \
|
||||||
|
"https://api.example.com/old-endpoint"
|
||||||
|
|
||||||
|
# Don't follow — inspect redirect target
|
||||||
|
curl -s -D- -o /dev/null \
|
||||||
|
"https://api.example.com/old-endpoint" | grep -i "location:"
|
||||||
|
|
||||||
|
# Open redirect vulnerability test
|
||||||
|
LOCATION=$(curl -s -D- -o /dev/null \
|
||||||
|
"https://api.example.com/redirect?url=https://evil.example.com" | grep -i "location:" | tr -d '\r')
|
||||||
|
echo "$LOCATION" | grep -q "evil.example.com" && echo "FAIL: Open redirect vulnerability" || echo "PASS: Redirect restricted"
|
||||||
|
|
||||||
|
# HTTP to HTTPS redirect check
|
||||||
|
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "http://api.example.com/api/data")
|
||||||
|
[ "$STATUS" = "301" ] || [ "$STATUS" = "308" ] && echo "PASS: HTTP redirects to HTTPS" || echo "WARN: No HTTPS redirect (got $STATUS)"
|
||||||
|
```
|
||||||
|
|
||||||
|
### HEAD, OPTIONS, and CORS
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# HEAD request — verify no body returned
|
||||||
|
curl -s -I -w "status:%{http_code} size:%{size_download}\n" \
|
||||||
|
-H "Authorization: Bearer $TOKEN" \
|
||||||
|
"https://api.example.com/api/data"
|
||||||
|
|
||||||
|
# OPTIONS request — check CORS and allowed methods
|
||||||
|
curl -s -X OPTIONS -D- -o /dev/null \
|
||||||
|
-H "Origin: https://myapp.example.com" \
|
||||||
|
-H "Access-Control-Request-Method: POST" \
|
||||||
|
"https://api.example.com/api/data" | grep -iE "(allow|access-control)"
|
||||||
|
```
|
||||||
@@ -296,6 +296,169 @@ token_consumption = "low"
|
|||||||
default_active = true
|
default_active = true
|
||||||
activation_warning = "Browser hand runs continuously but mainly consumes tokens when actively performing web tasks."
|
activation_warning = "Browser hand runs continuously but mainly consumes tokens when actively performing web tasks."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "浏览器 Hand"
|
name = "浏览器 Hand"
|
||||||
description = "自主网页浏览器——导航网站、填写表单、点击按钮,经用户批准后完成多步骤网页任务"
|
description = "自主网页浏览器——导航网站、填写表单、点击按钮,经用户批准后完成多步骤网页任务"
|
||||||
|
category = "生产力"
|
||||||
|
|
||||||
|
[i18n.zh.settings.headless]
|
||||||
|
label = "无头模式"
|
||||||
|
description = "在不显示浏览器窗口的情况下运行(推荐用于服务器环境)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "购买审批"
|
||||||
|
description = "在完成任何购买或支付操作前,需要用户明确确认"
|
||||||
|
|
||||||
|
[i18n.zh.settings.max_pages_per_task]
|
||||||
|
label = "每任务最大页面数"
|
||||||
|
description = "每个任务允许的最大页面导航次数,防止无限浏览"
|
||||||
|
|
||||||
|
[i18n.zh.settings.default_wait]
|
||||||
|
label = "操作后默认等待"
|
||||||
|
description = "点击或导航后等待页面稳定的时长"
|
||||||
|
|
||||||
|
[i18n.zh.settings.screenshot_on_action]
|
||||||
|
label = "操作后截图"
|
||||||
|
description = "每次点击/导航后自动截图,用于视觉验证"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "ブラウザ Hand"
|
||||||
|
description = "自律型ウェブブラウザ——サイトのナビゲーション、フォーム入力、ボタンクリック、ユーザー承認付きの複数ステップWebタスクの実行"
|
||||||
|
category = "生産性"
|
||||||
|
|
||||||
|
[i18n.ja.settings.headless]
|
||||||
|
label = "ヘッドレスモード"
|
||||||
|
description = "ブラウザウィンドウを表示せずに実行する(サーバー環境に推奨)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "購入承認"
|
||||||
|
description = "購入や支払いを完了する前にユーザーの明示的な確認を求める"
|
||||||
|
|
||||||
|
[i18n.ja.settings.max_pages_per_task]
|
||||||
|
label = "タスクあたりの最大ページ数"
|
||||||
|
description = "暴走的なブラウジングを防ぐため、タスクごとに許可されるページ遷移の最大数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.default_wait]
|
||||||
|
label = "操作後のデフォルト待機時間"
|
||||||
|
description = "クリックやナビゲーション後、ページが安定するまでの待機時間"
|
||||||
|
|
||||||
|
[i18n.ja.settings.screenshot_on_action]
|
||||||
|
label = "操作後のスクリーンショット"
|
||||||
|
description = "クリック/ナビゲーションのたびに自動的にスクリーンショットを撮影し、視覚的に確認する"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Navegador"
|
||||||
|
description = "Navegador web autónomo — navega sitios, completa formularios, hace clic en botones y realiza tareas web de múltiples pasos con aprobación del usuario para compras"
|
||||||
|
category = "Productividad"
|
||||||
|
|
||||||
|
[i18n.es.settings.headless]
|
||||||
|
label = "Modo sin interfaz"
|
||||||
|
description = "Ejecutar el navegador sin ventana visible (recomendado para servidores)"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Aprobación de compras"
|
||||||
|
description = "Requerir confirmación explícita del usuario antes de completar cualquier compra o pago"
|
||||||
|
|
||||||
|
[i18n.es.settings.max_pages_per_task]
|
||||||
|
label = "Máximo de páginas por tarea"
|
||||||
|
description = "Número máximo de navegaciones de página permitidas por tarea para evitar navegación descontrolada"
|
||||||
|
|
||||||
|
[i18n.es.settings.default_wait]
|
||||||
|
label = "Espera predeterminada tras acción"
|
||||||
|
description = "Cuánto tiempo esperar después de hacer clic o navegar para que la página se estabilice"
|
||||||
|
|
||||||
|
[i18n.es.settings.screenshot_on_action]
|
||||||
|
label = "Captura de pantalla tras acciones"
|
||||||
|
description = "Tomar automáticamente una captura de pantalla después de cada clic/navegación para verificación visual"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Navigateur"
|
||||||
|
description = "Navigateur web autonome — navigue sur les sites, remplit les formulaires, clique sur les boutons et exécute des tâches web multi-étapes avec approbation utilisateur pour les achats"
|
||||||
|
category = "Productivité"
|
||||||
|
|
||||||
|
[i18n.fr.settings.headless]
|
||||||
|
label = "Mode sans interface"
|
||||||
|
description = "Exécuter le navigateur sans fenêtre visible (recommandé pour les serveurs)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Approbation des achats"
|
||||||
|
description = "Exiger la confirmation explicite de l'utilisateur avant de finaliser tout achat ou paiement"
|
||||||
|
|
||||||
|
[i18n.fr.settings.max_pages_per_task]
|
||||||
|
label = "Pages maximum par tâche"
|
||||||
|
description = "Nombre maximum de navigations de page autorisées par tâche pour éviter une navigation incontrôlée"
|
||||||
|
|
||||||
|
[i18n.fr.settings.default_wait]
|
||||||
|
label = "Attente par défaut après action"
|
||||||
|
description = "Durée d'attente après un clic ou une navigation pour que la page se stabilise"
|
||||||
|
|
||||||
|
[i18n.fr.settings.screenshot_on_action]
|
||||||
|
label = "Capture d'écran après action"
|
||||||
|
description = "Prendre automatiquement une capture d'écran après chaque clic/navigation pour vérification visuelle"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Browser-Hand"
|
||||||
|
description = "Autonomer Webbrowser — navigiert Websites, füllt Formulare aus, klickt Schaltflächen und führt mehrstufige Webaufgaben mit Benutzerfreigabe für Käufe aus"
|
||||||
|
category = "Produktivität"
|
||||||
|
|
||||||
|
[i18n.de.settings.headless]
|
||||||
|
label = "Headless-Modus"
|
||||||
|
description = "Browser ohne sichtbares Fenster ausführen (empfohlen für Server)"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Kaufgenehmigung"
|
||||||
|
description = "Ausdrückliche Benutzerbestätigung vor dem Abschluss eines Kaufs oder einer Zahlung erforderlich"
|
||||||
|
|
||||||
|
[i18n.de.settings.max_pages_per_task]
|
||||||
|
label = "Maximale Seiten pro Aufgabe"
|
||||||
|
description = "Maximale Anzahl erlaubter Seitennavigationen pro Aufgabe, um unkontrolliertes Surfen zu verhindern"
|
||||||
|
|
||||||
|
[i18n.de.settings.default_wait]
|
||||||
|
label = "Standard-Wartezeit nach Aktion"
|
||||||
|
description = "Wartezeit nach einem Klick oder einer Navigation, bis sich die Seite stabilisiert hat"
|
||||||
|
|
||||||
|
[i18n.de.settings.screenshot_on_action]
|
||||||
|
label = "Screenshot nach Aktion"
|
||||||
|
description = "Nach jedem Klick/jeder Navigation automatisch einen Screenshot für visuelle Überprüfung erstellen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "브라우저 Hand"
|
||||||
|
description = "자율 웹 브라우저 — 사이트 탐색, 양식 작성, 버튼 클릭, 구매 시 사용자 승인을 받아 다단계 웹 작업 수행"
|
||||||
|
category = "생산성"
|
||||||
|
|
||||||
|
[i18n.ko.settings.headless]
|
||||||
|
label = "헤드리스 모드"
|
||||||
|
description = "브라우저 창을 표시하지 않고 실행 (서버 환경에 권장)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "구매 승인"
|
||||||
|
description = "구매 또는 결제 완료 전 사용자의 명시적 확인 필요"
|
||||||
|
|
||||||
|
[i18n.ko.settings.max_pages_per_task]
|
||||||
|
label = "작업당 최대 페이지 수"
|
||||||
|
description = "작업당 허용되는 최대 페이지 탐색 횟수 (무한 브라우징 방지)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.default_wait]
|
||||||
|
label = "동작 후 기본 대기"
|
||||||
|
description = "클릭 또는 탐색 후 페이지가 안정될 때까지 대기하는 시간"
|
||||||
|
|
||||||
|
[i18n.ko.settings.screenshot_on_action]
|
||||||
|
label = "동작 후 스크린샷"
|
||||||
|
description = "클릭/탐색 후 자동으로 스크린샷을 캡처하여 시각적으로 검증"
|
||||||
@@ -645,6 +645,289 @@ frequency = "on-demand"
|
|||||||
token_consumption = "medium"
|
token_consumption = "medium"
|
||||||
default_active = false
|
default_active = false
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "视频剪辑 Hand"
|
name = "视频剪辑 Hand"
|
||||||
description = "将长视频自动剪辑为病毒式短视频,配有字幕和缩略图"
|
description = "将长视频自动剪辑为病毒式短视频,配有字幕和缩略图"
|
||||||
|
category = "内容"
|
||||||
|
|
||||||
|
[i18n.zh.settings.stt_provider]
|
||||||
|
label = "语音转文字服务"
|
||||||
|
description = "用于生成字幕和片段选择的音频转录方式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.tts_provider]
|
||||||
|
label = "文字转语音服务"
|
||||||
|
description = "可选的配音或旁白生成服务"
|
||||||
|
|
||||||
|
[i18n.zh.settings.elevenlabs_api_key]
|
||||||
|
label = "ElevenLabs API 密钥"
|
||||||
|
description = "来自 elevenlabs.io 的高质量文字转语音 API 密钥。选择 ElevenLabs TTS 时必填。"
|
||||||
|
|
||||||
|
[i18n.zh.settings.publish_target]
|
||||||
|
label = "发布目标"
|
||||||
|
description = "处理完成后将短视频发送到哪里。选择"仅本地"则跳过发布。"
|
||||||
|
|
||||||
|
[i18n.zh.settings.telegram_bot_token]
|
||||||
|
label = "Telegram 机器人令牌"
|
||||||
|
description = "从 Telegram 的 @BotFather 获取(例如 123456:ABC-DEF...)。机器人需为目标频道管理员。"
|
||||||
|
|
||||||
|
[i18n.zh.settings.telegram_chat_id]
|
||||||
|
label = "Telegram 聊天 ID"
|
||||||
|
description = "频道:-100XXXXXXXXXX 或 @频道名。群组:数字 ID。可通过 @userinfobot 获取。"
|
||||||
|
|
||||||
|
[i18n.zh.settings.whatsapp_token]
|
||||||
|
label = "WhatsApp 访问令牌"
|
||||||
|
description = "从 Meta 商务管理平台 > 系统用户获取的永久令牌。临时令牌 24 小时后过期。"
|
||||||
|
|
||||||
|
[i18n.zh.settings.whatsapp_phone_id]
|
||||||
|
label = "WhatsApp 电话号码 ID"
|
||||||
|
description = "从 Meta 开发者门户 > WhatsApp > API 设置获取(例如 1234567890)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.whatsapp_recipient]
|
||||||
|
label = "WhatsApp 接收方"
|
||||||
|
description = "国际格式的电话号码,不含 + 号或空格(例如 14155551234)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "审批模式"
|
||||||
|
description = "发布到频道前将短视频加入队列供审核"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "動画クリップ Hand"
|
||||||
|
description = "長尺動画をキャプション付きサムネイル付きのバイラルショートクリップに変換"
|
||||||
|
category = "コンテンツ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.stt_provider]
|
||||||
|
label = "音声テキスト変換プロバイダー"
|
||||||
|
description = "字幕生成とクリップ選択に使用する音声の文字起こし方法"
|
||||||
|
|
||||||
|
[i18n.ja.settings.tts_provider]
|
||||||
|
label = "テキスト音声変換プロバイダー"
|
||||||
|
description = "クリップへのオプションのボイスオーバーまたはナレーション生成"
|
||||||
|
|
||||||
|
[i18n.ja.settings.elevenlabs_api_key]
|
||||||
|
label = "ElevenLabs APIキー"
|
||||||
|
description = "elevenlabs.ioの高品質テキスト音声変換用APIキー。ElevenLabs TTSを選択した場合に必須。"
|
||||||
|
|
||||||
|
[i18n.ja.settings.publish_target]
|
||||||
|
label = "公開先"
|
||||||
|
description = "処理完了後にクリップを送信する先。「ローカルのみ」を選択すると公開をスキップします。"
|
||||||
|
|
||||||
|
[i18n.ja.settings.telegram_bot_token]
|
||||||
|
label = "Telegramボットトークン"
|
||||||
|
description = "Telegramの@BotFatherから取得(例: 123456:ABC-DEF...)。ボットは対象チャンネルの管理者である必要があります。"
|
||||||
|
|
||||||
|
[i18n.ja.settings.telegram_chat_id]
|
||||||
|
label = "TelegramチャットID"
|
||||||
|
description = "チャンネル: -100XXXXXXXXXX または @チャンネル名。グループ: 数値ID。@userinfobot で取得可能。"
|
||||||
|
|
||||||
|
[i18n.ja.settings.whatsapp_token]
|
||||||
|
label = "WhatsAppアクセストークン"
|
||||||
|
description = "Metaビジネス設定 > システムユーザーから取得した永続トークン。一時トークンは24時間で期限切れになります。"
|
||||||
|
|
||||||
|
[i18n.ja.settings.whatsapp_phone_id]
|
||||||
|
label = "WhatsApp電話番号ID"
|
||||||
|
description = "Meta開発者ポータル > WhatsApp > APIセットアップから取得(例: 1234567890)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.whatsapp_recipient]
|
||||||
|
label = "WhatsApp送信先"
|
||||||
|
description = "国際形式の電話番号(+やスペースなし、例: 14155551234)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "承認モード"
|
||||||
|
description = "チャンネルに公開する前にクリップをレビュー用キューに追加する"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Clips de Video"
|
||||||
|
description = "Convierte videos largos en clips cortos virales con subtítulos y miniaturas"
|
||||||
|
category = "Contenido"
|
||||||
|
|
||||||
|
[i18n.es.settings.stt_provider]
|
||||||
|
label = "Proveedor de voz a texto"
|
||||||
|
description = "Cómo se transcribe el audio a texto para subtítulos y selección de clips"
|
||||||
|
|
||||||
|
[i18n.es.settings.tts_provider]
|
||||||
|
label = "Proveedor de texto a voz"
|
||||||
|
description = "Generación opcional de locución o narración para los clips"
|
||||||
|
|
||||||
|
[i18n.es.settings.elevenlabs_api_key]
|
||||||
|
label = "Clave API de ElevenLabs"
|
||||||
|
description = "Clave API de elevenlabs.io para texto a voz de alta calidad. Requerida cuando se selecciona ElevenLabs TTS."
|
||||||
|
|
||||||
|
[i18n.es.settings.publish_target]
|
||||||
|
label = "Destino de publicación"
|
||||||
|
description = "Dónde enviar los clips terminados después del procesamiento. Seleccionar 'Solo local' para omitir la publicación."
|
||||||
|
|
||||||
|
[i18n.es.settings.telegram_bot_token]
|
||||||
|
label = "Token del bot de Telegram"
|
||||||
|
description = "De @BotFather en Telegram (ej. 123456:ABC-DEF...). El bot debe ser administrador del canal de destino."
|
||||||
|
|
||||||
|
[i18n.es.settings.telegram_chat_id]
|
||||||
|
label = "ID de chat de Telegram"
|
||||||
|
description = "Canal: -100XXXXXXXXXX o @nombrechannel. Grupo: ID numérico. Obtener mediante @userinfobot."
|
||||||
|
|
||||||
|
[i18n.es.settings.whatsapp_token]
|
||||||
|
label = "Token de acceso de WhatsApp"
|
||||||
|
description = "Token permanente de Meta Business Settings > Usuarios del sistema. Los tokens temporales expiran en 24h."
|
||||||
|
|
||||||
|
[i18n.es.settings.whatsapp_phone_id]
|
||||||
|
label = "ID de número de teléfono de WhatsApp"
|
||||||
|
description = "Desde el Portal de Desarrolladores de Meta > WhatsApp > Configuración de API (ej. 1234567890)"
|
||||||
|
|
||||||
|
[i18n.es.settings.whatsapp_recipient]
|
||||||
|
label = "Destinatario de WhatsApp"
|
||||||
|
description = "Número de teléfono en formato internacional, sin + ni espacios (ej. 14155551234)"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Modo de aprobación"
|
||||||
|
description = "Poner clips en cola para revisión antes de publicarlos en los canales"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Clips Vidéo"
|
||||||
|
description = "Transforme les longues vidéos en clips courts viraux avec sous-titres et miniatures"
|
||||||
|
category = "Contenu"
|
||||||
|
|
||||||
|
[i18n.fr.settings.stt_provider]
|
||||||
|
label = "Fournisseur de reconnaissance vocale"
|
||||||
|
description = "Méthode de transcription audio pour les sous-titres et la sélection de clips"
|
||||||
|
|
||||||
|
[i18n.fr.settings.tts_provider]
|
||||||
|
label = "Fournisseur de synthèse vocale"
|
||||||
|
description = "Génération optionnelle de voix off ou de narration pour les clips"
|
||||||
|
|
||||||
|
[i18n.fr.settings.elevenlabs_api_key]
|
||||||
|
label = "Clé API ElevenLabs"
|
||||||
|
description = "Clé API de elevenlabs.io pour la synthèse vocale haute qualité. Requise lorsque ElevenLabs TTS est sélectionné."
|
||||||
|
|
||||||
|
[i18n.fr.settings.publish_target]
|
||||||
|
label = "Destination de publication"
|
||||||
|
description = "Où envoyer les clips terminés après traitement. Sélectionner 'Local uniquement' pour ignorer la publication."
|
||||||
|
|
||||||
|
[i18n.fr.settings.telegram_bot_token]
|
||||||
|
label = "Jeton du bot Telegram"
|
||||||
|
description = "De @BotFather sur Telegram (ex. 123456:ABC-DEF...). Le bot doit être administrateur du canal cible."
|
||||||
|
|
||||||
|
[i18n.fr.settings.telegram_chat_id]
|
||||||
|
label = "ID de chat Telegram"
|
||||||
|
description = "Canal : -100XXXXXXXXXX ou @nomducanal. Groupe : ID numérique. Obtenir via @userinfobot."
|
||||||
|
|
||||||
|
[i18n.fr.settings.whatsapp_token]
|
||||||
|
label = "Jeton d'accès WhatsApp"
|
||||||
|
description = "Jeton permanent depuis Meta Business Settings > Utilisateurs système. Les jetons temporaires expirent en 24h."
|
||||||
|
|
||||||
|
[i18n.fr.settings.whatsapp_phone_id]
|
||||||
|
label = "ID de numéro de téléphone WhatsApp"
|
||||||
|
description = "Depuis le Portail Développeurs Meta > WhatsApp > Configuration API (ex. 1234567890)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.whatsapp_recipient]
|
||||||
|
label = "Destinataire WhatsApp"
|
||||||
|
description = "Numéro de téléphone au format international, sans + ni espaces (ex. 14155551234)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Mode d'approbation"
|
||||||
|
description = "Mettre les clips en file d'attente pour révision avant publication sur les canaux"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Videoclip-Hand"
|
||||||
|
description = "Verwandelt lange Videos in virale Kurzclips mit Untertiteln und Vorschaubildern"
|
||||||
|
category = "Inhalt"
|
||||||
|
|
||||||
|
[i18n.de.settings.stt_provider]
|
||||||
|
label = "Sprache-zu-Text-Anbieter"
|
||||||
|
description = "Methode der Audiotranskription für Untertitel und Clipauswahl"
|
||||||
|
|
||||||
|
[i18n.de.settings.tts_provider]
|
||||||
|
label = "Text-zu-Sprache-Anbieter"
|
||||||
|
description = "Optionale Voiceover- oder Erzählungsgenerierung für Clips"
|
||||||
|
|
||||||
|
[i18n.de.settings.elevenlabs_api_key]
|
||||||
|
label = "ElevenLabs API-Schlüssel"
|
||||||
|
description = "API-Schlüssel von elevenlabs.io für hochwertige Text-zu-Sprache. Erforderlich bei Auswahl von ElevenLabs TTS."
|
||||||
|
|
||||||
|
[i18n.de.settings.publish_target]
|
||||||
|
label = "Veröffentlichungsziel"
|
||||||
|
description = "Wohin fertige Clips nach der Verarbeitung gesendet werden. 'Nur lokal' wählen, um die Veröffentlichung zu überspringen."
|
||||||
|
|
||||||
|
[i18n.de.settings.telegram_bot_token]
|
||||||
|
label = "Telegram-Bot-Token"
|
||||||
|
description = "Von @BotFather auf Telegram (z.B. 123456:ABC-DEF...). Der Bot muss Administrator des Zielkanals sein."
|
||||||
|
|
||||||
|
[i18n.de.settings.telegram_chat_id]
|
||||||
|
label = "Telegram-Chat-ID"
|
||||||
|
description = "Kanal: -100XXXXXXXXXX oder @Kanalname. Gruppe: Numerische ID. Über @userinfobot abrufbar."
|
||||||
|
|
||||||
|
[i18n.de.settings.whatsapp_token]
|
||||||
|
label = "WhatsApp-Zugriffstoken"
|
||||||
|
description = "Permanentes Token aus Meta Business Settings > Systembenutzer. Temporäre Token laufen nach 24h ab."
|
||||||
|
|
||||||
|
[i18n.de.settings.whatsapp_phone_id]
|
||||||
|
label = "WhatsApp-Telefonnummer-ID"
|
||||||
|
description = "Aus dem Meta-Entwicklerportal > WhatsApp > API-Einrichtung (z.B. 1234567890)"
|
||||||
|
|
||||||
|
[i18n.de.settings.whatsapp_recipient]
|
||||||
|
label = "WhatsApp-Empfänger"
|
||||||
|
description = "Telefonnummer im internationalen Format, ohne + oder Leerzeichen (z.B. 14155551234)"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Genehmigungsmodus"
|
||||||
|
description = "Clips zur Überprüfung in die Warteschlange stellen, bevor sie auf Kanälen veröffentlicht werden"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "비디오 클립 Hand"
|
||||||
|
description = "장편 영상을 자막과 썸네일이 포함된 바이럴 숏폼 클립으로 변환"
|
||||||
|
category = "콘텐츠"
|
||||||
|
|
||||||
|
[i18n.ko.settings.stt_provider]
|
||||||
|
label = "음성-텍스트 변환 서비스"
|
||||||
|
description = "자막 생성 및 클립 선택을 위한 오디오 전사 방식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.tts_provider]
|
||||||
|
label = "텍스트-음성 변환 서비스"
|
||||||
|
description = "선택적 더빙 또는 나레이션 생성 서비스"
|
||||||
|
|
||||||
|
[i18n.ko.settings.elevenlabs_api_key]
|
||||||
|
label = "ElevenLabs API 키"
|
||||||
|
description = "elevenlabs.io의 고품질 텍스트-음성 변환 API 키. ElevenLabs TTS 선택 시 필수."
|
||||||
|
|
||||||
|
[i18n.ko.settings.publish_target]
|
||||||
|
label = "게시 대상"
|
||||||
|
description = "처리 완료 후 숏폼 클립을 전송할 위치. '로컬 전용'을 선택하면 게시를 건너뜁니다."
|
||||||
|
|
||||||
|
[i18n.ko.settings.telegram_bot_token]
|
||||||
|
label = "Telegram 봇 토큰"
|
||||||
|
description = "Telegram의 @BotFather에서 발급 (예: 123456:ABC-DEF...). 봇이 대상 채널의 관리자여야 합니다."
|
||||||
|
|
||||||
|
[i18n.ko.settings.telegram_chat_id]
|
||||||
|
label = "Telegram 채팅 ID"
|
||||||
|
description = "채널: -100XXXXXXXXXX 또는 @채널명. 그룹: 숫자 ID. @userinfobot으로 확인 가능."
|
||||||
|
|
||||||
|
[i18n.ko.settings.whatsapp_token]
|
||||||
|
label = "WhatsApp 액세스 토큰"
|
||||||
|
description = "Meta 비즈니스 설정 > 시스템 사용자에서 발급한 영구 토큰. 임시 토큰은 24시간 후 만료."
|
||||||
|
|
||||||
|
[i18n.ko.settings.whatsapp_phone_id]
|
||||||
|
label = "WhatsApp 전화번호 ID"
|
||||||
|
description = "Meta 개발자 포털 > WhatsApp > API 설정에서 확인 (예: 1234567890)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.whatsapp_recipient]
|
||||||
|
label = "WhatsApp 수신자"
|
||||||
|
description = "+ 기호나 공백 없이 국제 형식의 전화번호 (예: 14155551234)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "승인 모드"
|
||||||
|
description = "채널에 게시하기 전 클립을 대기열에 추가하여 검토"
|
||||||
@@ -391,6 +391,241 @@ token_consumption = "high"
|
|||||||
default_active = false
|
default_active = false
|
||||||
activation_warning = "Collector hand runs continuously and monitors targets, consuming tokens."
|
activation_warning = "Collector hand runs continuously and monitors targets, consuming tokens."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "情报采集 Hand"
|
name = "情报采集 Hand"
|
||||||
description = "自主情报采集智能体——持续监控目标,支持变更检测和知识图谱"
|
description = "自主情报采集智能体——持续监控目标,支持变更检测和知识图谱"
|
||||||
|
category = "数据"
|
||||||
|
|
||||||
|
[i18n.zh.settings.target_subject]
|
||||||
|
label = "监控目标"
|
||||||
|
description = "要监控的对象(公司名称、人物、技术、市场、话题)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.collection_depth]
|
||||||
|
label = "采集深度"
|
||||||
|
description = "每个采集周期的挖掘深度"
|
||||||
|
|
||||||
|
[i18n.zh.settings.update_frequency]
|
||||||
|
label = "更新频率"
|
||||||
|
description = "执行采集扫描的频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.focus_area]
|
||||||
|
label = "关注领域"
|
||||||
|
description = "分析采集情报时的侧重角度"
|
||||||
|
|
||||||
|
[i18n.zh.settings.alert_on_changes]
|
||||||
|
label = "变更告警"
|
||||||
|
description = "检测到重大变更时发布事件通知"
|
||||||
|
|
||||||
|
[i18n.zh.settings.report_format]
|
||||||
|
label = "报告格式"
|
||||||
|
description = "情报报告的输出格式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.max_sources_per_cycle]
|
||||||
|
label = "每周期最大来源数"
|
||||||
|
description = "每次采集扫描处理的最大来源数量"
|
||||||
|
|
||||||
|
[i18n.zh.settings.track_sentiment]
|
||||||
|
label = "情感追踪"
|
||||||
|
description = "分析并追踪随时间变化的情感趋势"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "インテリジェンス収集 Hand"
|
||||||
|
description = "自律型インテリジェンス収集エージェント——変更検出とナレッジグラフによる対象の継続的監視"
|
||||||
|
category = "データ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.target_subject]
|
||||||
|
label = "監視対象"
|
||||||
|
description = "監視する対象(企業名、人物、技術、市場、トピック)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.collection_depth]
|
||||||
|
label = "収集深度"
|
||||||
|
description = "各収集サイクルでの調査の深さ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.update_frequency]
|
||||||
|
label = "更新頻度"
|
||||||
|
description = "収集スキャンの実行頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.focus_area]
|
||||||
|
label = "フォーカスエリア"
|
||||||
|
description = "収集したインテリジェンスを分析する際の視点"
|
||||||
|
|
||||||
|
[i18n.ja.settings.alert_on_changes]
|
||||||
|
label = "変更アラート"
|
||||||
|
description = "重大な変更が検出された場合にイベント通知を発行する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.report_format]
|
||||||
|
label = "レポート形式"
|
||||||
|
description = "インテリジェンスレポートの出力形式"
|
||||||
|
|
||||||
|
[i18n.ja.settings.max_sources_per_cycle]
|
||||||
|
label = "サイクルあたりの最大ソース数"
|
||||||
|
description = "各収集スキャンで処理するソースの最大数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.track_sentiment]
|
||||||
|
label = "センチメント追跡"
|
||||||
|
description = "時間の経過に伴うセンチメントの傾向を分析・追跡する"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Recopilación de Inteligencia"
|
||||||
|
description = "Recopilador autónomo de inteligencia — monitorea cualquier objetivo de forma continua con detección de cambios y grafos de conocimiento"
|
||||||
|
category = "Datos"
|
||||||
|
|
||||||
|
[i18n.es.settings.target_subject]
|
||||||
|
label = "Objetivo de monitoreo"
|
||||||
|
description = "Qué monitorear (nombre de empresa, persona, tecnología, mercado, tema)"
|
||||||
|
|
||||||
|
[i18n.es.settings.collection_depth]
|
||||||
|
label = "Profundidad de recopilación"
|
||||||
|
description = "Qué tan profundo investigar en cada ciclo"
|
||||||
|
|
||||||
|
[i18n.es.settings.update_frequency]
|
||||||
|
label = "Frecuencia de actualización"
|
||||||
|
description = "Con qué frecuencia ejecutar los barridos de recopilación"
|
||||||
|
|
||||||
|
[i18n.es.settings.focus_area]
|
||||||
|
label = "Área de enfoque"
|
||||||
|
description = "Perspectiva desde la cual analizar la inteligencia recopilada"
|
||||||
|
|
||||||
|
[i18n.es.settings.alert_on_changes]
|
||||||
|
label = "Alertar ante cambios"
|
||||||
|
description = "Publicar un evento cuando se detecten cambios significativos"
|
||||||
|
|
||||||
|
[i18n.es.settings.report_format]
|
||||||
|
label = "Formato de informe"
|
||||||
|
description = "Formato de salida para los informes de inteligencia"
|
||||||
|
|
||||||
|
[i18n.es.settings.max_sources_per_cycle]
|
||||||
|
label = "Máximo de fuentes por ciclo"
|
||||||
|
description = "Número máximo de fuentes a procesar por barrido de recopilación"
|
||||||
|
|
||||||
|
[i18n.es.settings.track_sentiment]
|
||||||
|
label = "Seguimiento de sentimiento"
|
||||||
|
description = "Analizar y rastrear las tendencias de sentimiento a lo largo del tiempo"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Collecteur de Renseignements"
|
||||||
|
description = "Collecteur autonome de renseignements — surveille toute cible en continu avec détection de changements et graphes de connaissances"
|
||||||
|
category = "Données"
|
||||||
|
|
||||||
|
[i18n.fr.settings.target_subject]
|
||||||
|
label = "Sujet cible"
|
||||||
|
description = "Objet de la surveillance (nom d'entreprise, personne, technologie, marché, sujet)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.collection_depth]
|
||||||
|
label = "Profondeur de collecte"
|
||||||
|
description = "Niveau d'approfondissement à chaque cycle de collecte"
|
||||||
|
|
||||||
|
[i18n.fr.settings.update_frequency]
|
||||||
|
label = "Fréquence de mise à jour"
|
||||||
|
description = "Fréquence d'exécution des cycles de collecte"
|
||||||
|
|
||||||
|
[i18n.fr.settings.focus_area]
|
||||||
|
label = "Domaine d'intérêt"
|
||||||
|
description = "Angle d'analyse des renseignements collectés"
|
||||||
|
|
||||||
|
[i18n.fr.settings.alert_on_changes]
|
||||||
|
label = "Alerte sur changements"
|
||||||
|
description = "Publier un événement lorsque des changements significatifs sont détectés"
|
||||||
|
|
||||||
|
[i18n.fr.settings.report_format]
|
||||||
|
label = "Format de rapport"
|
||||||
|
description = "Format de sortie pour les rapports de renseignements"
|
||||||
|
|
||||||
|
[i18n.fr.settings.max_sources_per_cycle]
|
||||||
|
label = "Sources maximum par cycle"
|
||||||
|
description = "Nombre maximum de sources à traiter par cycle de collecte"
|
||||||
|
|
||||||
|
[i18n.fr.settings.track_sentiment]
|
||||||
|
label = "Suivi du sentiment"
|
||||||
|
description = "Analyser et suivre les tendances de sentiment au fil du temps"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Informationssammlungs-Hand"
|
||||||
|
description = "Autonomer Informationssammler — überwacht jedes Ziel kontinuierlich mit Änderungserkennung und Wissensgraphen"
|
||||||
|
category = "Daten"
|
||||||
|
|
||||||
|
[i18n.de.settings.target_subject]
|
||||||
|
label = "Zielobjekt"
|
||||||
|
description = "Was überwacht werden soll (Firmenname, Person, Technologie, Markt, Thema)"
|
||||||
|
|
||||||
|
[i18n.de.settings.collection_depth]
|
||||||
|
label = "Sammlungstiefe"
|
||||||
|
description = "Wie tief in jedem Sammlungszyklus recherchiert wird"
|
||||||
|
|
||||||
|
[i18n.de.settings.update_frequency]
|
||||||
|
label = "Aktualisierungshäufigkeit"
|
||||||
|
description = "Wie oft Sammlungszyklen ausgeführt werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.focus_area]
|
||||||
|
label = "Fokusbereich"
|
||||||
|
description = "Perspektive für die Analyse der gesammelten Informationen"
|
||||||
|
|
||||||
|
[i18n.de.settings.alert_on_changes]
|
||||||
|
label = "Warnung bei Änderungen"
|
||||||
|
description = "Ein Ereignis veröffentlichen, wenn bedeutende Änderungen erkannt werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.report_format]
|
||||||
|
label = "Berichtsformat"
|
||||||
|
description = "Ausgabeformat für Informationsberichte"
|
||||||
|
|
||||||
|
[i18n.de.settings.max_sources_per_cycle]
|
||||||
|
label = "Maximale Quellen pro Zyklus"
|
||||||
|
description = "Maximale Anzahl der pro Sammlungszyklus zu verarbeitenden Quellen"
|
||||||
|
|
||||||
|
[i18n.de.settings.track_sentiment]
|
||||||
|
label = "Stimmungsverfolgung"
|
||||||
|
description = "Stimmungstrends im Zeitverlauf analysieren und verfolgen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "정보 수집 Hand"
|
||||||
|
description = "자율 정보 수집 에이전트 — 대상을 지속적으로 모니터링하며 변경 감지 및 지식 그래프 지원"
|
||||||
|
category = "데이터"
|
||||||
|
|
||||||
|
[i18n.ko.settings.target_subject]
|
||||||
|
label = "모니터링 대상"
|
||||||
|
description = "모니터링할 대상 (회사명, 인물, 기술, 시장, 주제)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.collection_depth]
|
||||||
|
label = "수집 깊이"
|
||||||
|
description = "각 수집 주기의 조사 깊이"
|
||||||
|
|
||||||
|
[i18n.ko.settings.update_frequency]
|
||||||
|
label = "업데이트 빈도"
|
||||||
|
description = "수집 스캔 실행 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.focus_area]
|
||||||
|
label = "관심 분야"
|
||||||
|
description = "수집된 정보를 분석하는 관점"
|
||||||
|
|
||||||
|
[i18n.ko.settings.alert_on_changes]
|
||||||
|
label = "변경 알림"
|
||||||
|
description = "중요한 변경 사항 감지 시 이벤트 알림 발행"
|
||||||
|
|
||||||
|
[i18n.ko.settings.report_format]
|
||||||
|
label = "보고서 형식"
|
||||||
|
description = "정보 보고서의 출력 형식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.max_sources_per_cycle]
|
||||||
|
label = "주기당 최대 소스 수"
|
||||||
|
description = "수집 스캔당 처리할 최대 소스 수"
|
||||||
|
|
||||||
|
[i18n.ko.settings.track_sentiment]
|
||||||
|
label = "감성 추적"
|
||||||
|
description = "시간에 따른 감성 추세 분석 및 추적"
|
||||||
@@ -269,3 +269,744 @@ Before including data in the knowledge graph, evaluate:
|
|||||||
6. **Track record**: Has this source been reliable in the past?
|
6. **Track record**: Has this source been reliable in the past?
|
||||||
|
|
||||||
If a claim fails 3+ checks, downgrade its confidence to "low".
|
If a claim fails 3+ checks, downgrade its confidence to "low".
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Competitor Monitoring Campaign
|
||||||
|
|
||||||
|
**Scenario**: A B2B SaaS company wants continuous intelligence on three direct competitors: AlphaCloud, BetaStack, and GammaSuite.
|
||||||
|
|
||||||
|
**Step 1 — Define targets and collection requirements**
|
||||||
|
|
||||||
|
Configure the hand with:
|
||||||
|
```
|
||||||
|
target_subject: "AlphaCloud, BetaStack, GammaSuite"
|
||||||
|
focus_area: competitor
|
||||||
|
collection_depth: deep
|
||||||
|
update_frequency: daily
|
||||||
|
alert_on_changes: true
|
||||||
|
track_sentiment: true
|
||||||
|
max_sources_per_cycle: 50
|
||||||
|
```
|
||||||
|
|
||||||
|
Build the initial query set:
|
||||||
|
```
|
||||||
|
"AlphaCloud" pricing OR plans OR tiers
|
||||||
|
"AlphaCloud" product launch OR release OR update
|
||||||
|
"AlphaCloud" review site:g2.com OR site:capterra.com
|
||||||
|
"AlphaCloud" customer case study
|
||||||
|
"AlphaCloud" hiring site:linkedin.com OR site:greenhouse.io
|
||||||
|
"switch from AlphaCloud to"
|
||||||
|
(repeat for BetaStack and GammaSuite)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Run first collection cycle**
|
||||||
|
|
||||||
|
Execute queries, fetch top results, extract entities:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{"type": "product", "name": "AlphaCloud v4.2", "company": "AlphaCloud", "launch_date": "2025-11-15", "source": "alphacloud.com/blog"},
|
||||||
|
{"type": "person", "name": "Sarah Chen", "role": "New VP Engineering", "company": "BetaStack", "source": "linkedin.com/in/sarachen"},
|
||||||
|
{"type": "event", "name": "GammaSuite Series C", "amount": "$85M", "date": "2025-11-10", "source": "techcrunch.com/2025/11/10/gammasuite-series-c"}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Build knowledge graph entries**
|
||||||
|
|
||||||
|
```
|
||||||
|
knowledge_add_entity type=company name="AlphaCloud" industry="SaaS" funding_stage="Series B"
|
||||||
|
knowledge_add_entity type=product name="AlphaCloud v4.2" category="cloud platform"
|
||||||
|
knowledge_add_entity type=person name="Sarah Chen" role="VP Engineering" company="BetaStack"
|
||||||
|
knowledge_add_relation source="AlphaCloud" relation="launched" target="AlphaCloud v4.2"
|
||||||
|
knowledge_add_relation source="Sarah Chen" relation="works_at" target="BetaStack"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 4 — Process findings into change detection**
|
||||||
|
|
||||||
|
| Change | Type | Significance | Action |
|
||||||
|
|--------|------|-------------|--------|
|
||||||
|
| AlphaCloud released v4.2 with AI features | Product launch | IMPORTANT | Include in report, compare against own roadmap |
|
||||||
|
| BetaStack hired VP Engineering from FAANG | Leadership change | IMPORTANT | Track subsequent hiring patterns |
|
||||||
|
| GammaSuite raised $85M Series C | Major funding | CRITICAL | Immediate alert, expect aggressive expansion |
|
||||||
|
|
||||||
|
**Step 5 — Generate intelligence brief**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Competitor Intelligence Brief
|
||||||
|
**Date**: 2025-11-16 | **Cycle**: 1 | **Sources**: 47
|
||||||
|
|
||||||
|
## Priority Changes
|
||||||
|
1. [CRITICAL] GammaSuite closed $85M Series C led by Sequoia (TechCrunch, confirmed via Crunchbase)
|
||||||
|
2. [IMPORTANT] AlphaCloud shipped v4.2 with AI-assisted workflow builder
|
||||||
|
3. [IMPORTANT] BetaStack hired Sarah Chen (ex-Google) as VP Engineering
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
GammaSuite's large funding round signals intent to accelerate growth — expect increased
|
||||||
|
marketing spend and possible M&A activity in the next 6 months. AlphaCloud's v4.2
|
||||||
|
introduces direct feature overlap with our AI pipeline. BetaStack's engineering
|
||||||
|
leadership hire suggests a product quality push.
|
||||||
|
|
||||||
|
## Recommended Actions
|
||||||
|
- Review AlphaCloud v4.2 feature parity against our roadmap
|
||||||
|
- Monitor GammaSuite job postings for expansion signals
|
||||||
|
- Track BetaStack engineering team growth over next 3 cycles
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 2: Technology Landscape Mapping
|
||||||
|
|
||||||
|
**Scenario**: Map the emerging real-time AI inference landscape — track frameworks, adoption signals, key players, and performance benchmarks.
|
||||||
|
|
||||||
|
**Step 1 — Define scope and seed entities**
|
||||||
|
|
||||||
|
```
|
||||||
|
target_subject: "real-time AI inference (vLLM, TensorRT-LLM, Triton, Ollama, llama.cpp)"
|
||||||
|
focus_area: technology
|
||||||
|
collection_depth: exhaustive
|
||||||
|
update_frequency: weekly
|
||||||
|
```
|
||||||
|
|
||||||
|
Initial seed queries:
|
||||||
|
```
|
||||||
|
"real-time AI inference" benchmark 2025
|
||||||
|
"vLLM" vs "TensorRT-LLM" performance
|
||||||
|
"llama.cpp" release changelog
|
||||||
|
"AI inference" startup funding 2025
|
||||||
|
"edge AI inference" adoption enterprise
|
||||||
|
"AI inference" tokens per second benchmark
|
||||||
|
site:github.com "vLLM" stars OR contributors
|
||||||
|
site:arxiv.org "inference optimization" 2025
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Build entity graph from first sweep**
|
||||||
|
|
||||||
|
Entities collected:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{"type": "technology", "name": "vLLM", "version": "0.6.3", "vendor": "UC Berkeley / community", "category": "inference engine"},
|
||||||
|
{"type": "technology", "name": "TensorRT-LLM", "version": "0.15", "vendor": "NVIDIA", "category": "inference engine"},
|
||||||
|
{"type": "company", "name": "Groq", "industry": "AI hardware", "product": "LPU Inference Engine"},
|
||||||
|
{"type": "number", "metric": "tokens_per_second", "value": 523, "context": "Groq Llama 3 70B", "date": "2025-10"},
|
||||||
|
{"type": "number", "metric": "github_stars", "value": 32400, "context": "vLLM", "date": "2025-11"}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Relationships:
|
||||||
|
```
|
||||||
|
vLLM --competes_with--> TensorRT-LLM
|
||||||
|
vLLM --competes_with--> Ollama
|
||||||
|
Groq --launched--> "LPU Inference Engine"
|
||||||
|
NVIDIA --launched--> TensorRT-LLM
|
||||||
|
llama.cpp --uses--> GGUF format
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Track adoption signals across cycles**
|
||||||
|
|
||||||
|
| Signal Type | What to Watch | Detection Method |
|
||||||
|
|-------------|--------------|-----------------|
|
||||||
|
| GitHub velocity | Stars, forks, contributor count week-over-week | Snapshot comparison |
|
||||||
|
| Enterprise adoption | Case studies, "we migrated to X" blog posts | Keyword search |
|
||||||
|
| Benchmark results | Tokens/sec, latency, cost-per-token comparisons | Structured extraction |
|
||||||
|
| Job postings | "Experience with vLLM" in job descriptions | Job board queries |
|
||||||
|
| Conference talks | Accepted papers, keynote mentions | Conference program search |
|
||||||
|
|
||||||
|
**Step 4 — Detect trends over 4 weekly cycles**
|
||||||
|
|
||||||
|
```
|
||||||
|
Cycle 1: vLLM 31,800 stars | TensorRT-LLM 9,200 stars | Ollama 98,000 stars
|
||||||
|
Cycle 2: vLLM 32,400 stars | TensorRT-LLM 9,500 stars | Ollama 101,000 stars
|
||||||
|
Cycle 3: vLLM 33,500 stars | TensorRT-LLM 9,600 stars | Ollama 103,500 stars
|
||||||
|
Cycle 4: vLLM 35,200 stars | TensorRT-LLM 9,700 stars | Ollama 105,000 stars
|
||||||
|
|
||||||
|
Trend: vLLM accelerating (+1,700/wk avg → +1,700 last week)
|
||||||
|
Ollama decelerating (+3,000/wk → +1,500/wk)
|
||||||
|
TensorRT-LLM flat (~200/wk)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 5 — Produce technology landscape report**
|
||||||
|
|
||||||
|
Include a positioning summary:
|
||||||
|
|
||||||
|
| Framework | Strengths | Weaknesses | Momentum | Best For |
|
||||||
|
|-----------|-----------|------------|----------|----------|
|
||||||
|
| vLLM | High throughput, PagedAttention | GPU-only, complex setup | Accelerating | Production serving at scale |
|
||||||
|
| TensorRT-LLM | NVIDIA optimization, low latency | Vendor lock-in, NVIDIA GPUs only | Flat | NVIDIA-stack deployments |
|
||||||
|
| Ollama | Simple UX, local-first | Lower throughput, less tunable | Decelerating | Developer experimentation |
|
||||||
|
| llama.cpp | CPU support, portable | Manual optimization needed | Steady | Edge/embedded inference |
|
||||||
|
| Groq LPU | Extreme speed, low latency | Limited model support, cloud-only | Growing | Latency-critical applications |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 3: M&A Signal Detection
|
||||||
|
|
||||||
|
**Scenario**: Detect early acquisition indicators for companies in the enterprise observability space (Datadog, Grafana Labs, Chronosphere, Honeycomb).
|
||||||
|
|
||||||
|
**Step 1 — Define M&A signal categories**
|
||||||
|
|
||||||
|
| Signal Category | Indicators | Weight |
|
||||||
|
|----------------|-----------|--------|
|
||||||
|
| Executive changes | CEO/CFO departure, new "Chief Strategy Officer", board additions | High |
|
||||||
|
| Hiring patterns | Sudden corporate development/M&A roles, legal team expansion | High |
|
||||||
|
| Financial signals | Unusual funding, secondary sales, down round, runway concerns | High |
|
||||||
|
| Strategic moves | Exclusive partnerships, technology licensing, IP transfers | Medium |
|
||||||
|
| Market behavior | Quiet period (no product updates), website changes, domain changes | Medium |
|
||||||
|
| Social signals | Founder tone shifts, "exciting news soon" posts, unusual silence | Low |
|
||||||
|
|
||||||
|
**Step 2 — Build targeted queries**
|
||||||
|
|
||||||
|
```
|
||||||
|
"Chronosphere" AND ("acquisition" OR "acquire" OR "acqui-hire" OR "merger")
|
||||||
|
"Honeycomb" AND ("strategic alternatives" OR "exploring options" OR "advisors")
|
||||||
|
"Grafana Labs" AND ("corporate development" OR "M&A" OR "strategic partnership")
|
||||||
|
site:linkedin.com "Chronosphere" "corporate development" OR "M&A"
|
||||||
|
site:sec.gov "Honeycomb" OR "Hound Technology"
|
||||||
|
"[company]" "quiet period" OR "exciting announcement"
|
||||||
|
"[company]" hiring "corporate development" OR "business development director"
|
||||||
|
"[company]" board of directors new appointment
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Entity and event extraction**
|
||||||
|
|
||||||
|
From collected sources, extract and classify:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "event",
|
||||||
|
"name": "Chronosphere CFO departure",
|
||||||
|
"date": "2025-10-28",
|
||||||
|
"entities": ["Chronosphere", "Lisa Park"],
|
||||||
|
"signal_category": "executive_change",
|
||||||
|
"m_and_a_weight": "high",
|
||||||
|
"source": "linkedin.com/posts/lisapark-farewell"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "event",
|
||||||
|
"name": "Honeycomb hires Goldman Sachs advisor",
|
||||||
|
"date": "2025-11-02",
|
||||||
|
"entities": ["Honeycomb", "Goldman Sachs"],
|
||||||
|
"signal_category": "financial",
|
||||||
|
"m_and_a_weight": "high",
|
||||||
|
"source": "theinformation.com/articles/honeycomb-advisors"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "event",
|
||||||
|
"name": "Datadog acquires incident.io",
|
||||||
|
"date": "2025-11-08",
|
||||||
|
"entities": ["Datadog", "incident.io"],
|
||||||
|
"signal_category": "strategic",
|
||||||
|
"m_and_a_weight": "confirmed_event",
|
||||||
|
"source": "datadog.com/blog/incident-io-acquisition"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 4 — Score composite M&A probability**
|
||||||
|
|
||||||
|
Aggregate signals per company over a rolling 90-day window:
|
||||||
|
|
||||||
|
```
|
||||||
|
Chronosphere:
|
||||||
|
- CFO departed (high) +3
|
||||||
|
- 2 corp dev job postings +2
|
||||||
|
- No product release in 90d +1
|
||||||
|
- Composite score: 6/10 → ELEVATED
|
||||||
|
|
||||||
|
Honeycomb:
|
||||||
|
- Hired investment bank +4
|
||||||
|
- Board added PE partner +2
|
||||||
|
- Founder "grateful" post +1
|
||||||
|
- Composite score: 7/10 → HIGH
|
||||||
|
|
||||||
|
Grafana Labs:
|
||||||
|
- New enterprise partnerships +1
|
||||||
|
- Active hiring across all -1 (normal growth, reduces M&A signal)
|
||||||
|
- Composite score: 0/10 → LOW
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 5 — Generate M&A signal alert**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# M&A Signal Alert: Enterprise Observability Sector
|
||||||
|
**Date**: 2025-11-10 | **Window**: 90 days
|
||||||
|
|
||||||
|
## HIGH probability
|
||||||
|
- **Honeycomb**: Investment bank engagement + board changes suggest active process.
|
||||||
|
Key evidence: Goldman Sachs advisory (The Information), new PE board member.
|
||||||
|
Likely acquirers: Datadog, Cisco, ServiceNow.
|
||||||
|
|
||||||
|
## ELEVATED probability
|
||||||
|
- **Chronosphere**: Leadership turnover + hiring freeze + corp dev roles.
|
||||||
|
Key evidence: CFO departure, no product releases, corp dev postings on LinkedIn.
|
||||||
|
Could indicate: acquisition target OR internal restructuring.
|
||||||
|
|
||||||
|
## LOW probability
|
||||||
|
- **Grafana Labs**: Normal operating patterns, active hiring, regular releases.
|
||||||
|
- **Datadog**: Active acquirer (incident.io deal closed), not a target.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Advanced Entity Extraction
|
||||||
|
|
||||||
|
### Relationship Mapping from Unstructured Text
|
||||||
|
|
||||||
|
Extract relationships by identifying sentence-level patterns that connect two named entities.
|
||||||
|
|
||||||
|
**Pattern templates**:
|
||||||
|
```
|
||||||
|
[Person] joined [Company] as [Role]
|
||||||
|
→ relation: works_at, attributes: {role: Role, event: "joined"}
|
||||||
|
|
||||||
|
[Company] acquired [Company] for [Amount]
|
||||||
|
→ relation: acquired, attributes: {amount: Amount}
|
||||||
|
|
||||||
|
[Person] and [Person] co-founded [Company]
|
||||||
|
→ relations: founded (x2), co_founded_with (between persons)
|
||||||
|
|
||||||
|
[Company] partnered with [Company] to [Purpose]
|
||||||
|
→ relation: partnered_with, attributes: {purpose: Purpose}
|
||||||
|
|
||||||
|
[Person] left [Company] to join [Company]
|
||||||
|
→ relation: left (old), works_at (new), attributes: {event: "departure"}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Multi-hop relationships**: When A relates to B and B relates to C, infer indirect connections:
|
||||||
|
```
|
||||||
|
Sarah Chen works_at BetaStack
|
||||||
|
BetaStack competes_with AlphaCloud
|
||||||
|
→ Indirect: Sarah Chen is key_person_at competitor of AlphaCloud
|
||||||
|
```
|
||||||
|
|
||||||
|
**Negation detection**: Watch for negated relationships that should NOT be added:
|
||||||
|
```
|
||||||
|
"Company X denied it was in acquisition talks with Company Y"
|
||||||
|
→ Do NOT add acquired relation. Add entity note: "denied acquisition rumor, [date]"
|
||||||
|
|
||||||
|
"Former CEO of Company X" → Person left. Mark works_at as ended.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Temporal Event Extraction (Timeline Construction)
|
||||||
|
|
||||||
|
Extract dates and temporal markers to build event timelines.
|
||||||
|
|
||||||
|
**Explicit dates**:
|
||||||
|
```
|
||||||
|
"On March 15, 2025, Acme launched ProductX"
|
||||||
|
→ event: product_launch, date: 2025-03-15, entities: [Acme, ProductX]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Relative dates** (resolve against article publication date):
|
||||||
|
```
|
||||||
|
"last week" → pub_date - 7 days
|
||||||
|
"earlier today" → pub_date
|
||||||
|
"next quarter" → pub_date + next fiscal quarter boundary
|
||||||
|
"in Q3" → July-September of article's year
|
||||||
|
"recently" → pub_date - 30 days (approximate, confidence: medium)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Temporal ordering heuristics**:
|
||||||
|
```
|
||||||
|
"before the acquisition" → event precedes known acquisition date
|
||||||
|
"following the launch" → event follows known launch date
|
||||||
|
"amid layoffs" → event concurrent with layoff period
|
||||||
|
```
|
||||||
|
|
||||||
|
**Timeline output format**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"entity": "Acme Corp",
|
||||||
|
"timeline": [
|
||||||
|
{"date": "2025-01-15", "event": "Series B ($40M)", "type": "funding", "confidence": "high"},
|
||||||
|
{"date": "2025-03-20", "event": "Hired new CTO (Jane Lee)", "type": "leadership", "confidence": "high"},
|
||||||
|
{"date": "2025-06-01", "event": "Launched v3.0", "type": "product", "confidence": "high"},
|
||||||
|
{"date": "2025-08-10", "event": "Partnership with CloudCo", "type": "partnership", "confidence": "medium"},
|
||||||
|
{"date": "2025-11-05", "event": "Acquired by BigCorp", "type": "acquisition", "confidence": "high"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Quantitative Data Extraction
|
||||||
|
|
||||||
|
Extract numerical data points with units, context, and time reference.
|
||||||
|
|
||||||
|
**Financial figures**:
|
||||||
|
```
|
||||||
|
Pattern: "[Company] raised $[amount][M/B] in [round]"
|
||||||
|
Example: "Acme raised $40M in Series B"
|
||||||
|
→ {metric: "funding", value: 40000000, currency: "USD", context: "Series B", entity: "Acme"}
|
||||||
|
|
||||||
|
Pattern: "[Company] revenue of $[amount][M/B]"
|
||||||
|
Example: "reported annual revenue of $120M"
|
||||||
|
→ {metric: "revenue", value: 120000000, currency: "USD", period: "annual", entity: subject}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Growth rates**:
|
||||||
|
```
|
||||||
|
Pattern: "[metric] grew [X]% [period]"
|
||||||
|
Example: "ARR grew 45% year-over-year"
|
||||||
|
→ {metric: "ARR_growth", value: 0.45, period: "YoY", entity: subject}
|
||||||
|
|
||||||
|
Pattern: "from [X] to [Y]"
|
||||||
|
Example: "headcount grew from 200 to 350"
|
||||||
|
→ {metric: "headcount", previous: 200, current: 350, growth: 0.75, entity: subject}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Headcounts and scale metrics**:
|
||||||
|
```
|
||||||
|
"[Company] now has [N] employees"
|
||||||
|
"[Company] serves [N] customers"
|
||||||
|
"[Product] has [N] monthly active users"
|
||||||
|
"[Company] operates in [N] countries"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Extraction validation rules**:
|
||||||
|
- Currency amounts without a clear entity reference: discard or mark confidence "low"
|
||||||
|
- Growth percentages without a base period: mark confidence "medium"
|
||||||
|
- Round numbers (e.g., "about 1,000 employees"): flag as approximate
|
||||||
|
- Conflicting numbers from different sources: record both, note discrepancy
|
||||||
|
|
||||||
|
### Multi-Source Entity Resolution
|
||||||
|
|
||||||
|
When the same entity appears across different sources with variations, deduplicate.
|
||||||
|
|
||||||
|
**Company name normalization**:
|
||||||
|
```
|
||||||
|
"Acme Corp" = "Acme Corporation" = "Acme, Inc." = "ACME" (when context matches)
|
||||||
|
"Google" = "Alphabet" (parent) — but keep as separate entities with parent_of relation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Resolution rules**:
|
||||||
|
| Signal | Match Confidence | Action |
|
||||||
|
|--------|-----------------|--------|
|
||||||
|
| Exact name match | High | Merge immediately |
|
||||||
|
| Name + same industry + same location | High | Merge |
|
||||||
|
| Abbreviated name + same context | Medium | Merge with note |
|
||||||
|
| Similar name, different industry | Low | Keep separate, flag for review |
|
||||||
|
| Person same name, different company | Low | Keep separate unless linked by career event |
|
||||||
|
|
||||||
|
**Deduplication process**:
|
||||||
|
1. Normalize: lowercase, strip legal suffixes, expand abbreviations
|
||||||
|
2. Match: compare against existing entity list using normalized form
|
||||||
|
3. Verify: check at least one corroborating attribute (industry, location, person association)
|
||||||
|
4. Merge: combine attributes, keep all source references, use highest confidence level
|
||||||
|
5. Log: record the merge decision for audit
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"canonical": "entity_acme_corp",
|
||||||
|
"aliases": ["Acme Corp", "Acme Corporation", "Acme, Inc.", "ACME"],
|
||||||
|
"merged_from": ["source_techcrunch_entity_12", "source_linkedin_entity_89"],
|
||||||
|
"merge_confidence": "high",
|
||||||
|
"merge_reason": "exact name + same industry (SaaS) + same HQ (San Francisco)"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Collection Automation Patterns
|
||||||
|
|
||||||
|
### Scheduled Collection Workflows
|
||||||
|
|
||||||
|
Define collection cadences matched to intelligence needs.
|
||||||
|
|
||||||
|
**Daily cycle** (for active competitive monitoring):
|
||||||
|
```
|
||||||
|
06:00 UTC — Run news queries for all targets (surface scan)
|
||||||
|
06:15 UTC — Check social media and forums for overnight mentions
|
||||||
|
06:30 UTC — Compare against yesterday's snapshot, flag changes
|
||||||
|
06:45 UTC — Generate daily brief, send alerts for CRITICAL items
|
||||||
|
```
|
||||||
|
|
||||||
|
**Weekly cycle** (for technology landscape and market mapping):
|
||||||
|
```
|
||||||
|
Monday — Full source sweep: news, blogs, official sites
|
||||||
|
Tuesday — Job board scan: new postings, closed postings, pattern analysis
|
||||||
|
Wednesday — Financial data: funding rounds, SEC filings, earnings
|
||||||
|
Thursday — Community signals: GitHub activity, forum discussions, reviews
|
||||||
|
Friday — Synthesis: generate weekly report, update entity graph, adjust queries
|
||||||
|
```
|
||||||
|
|
||||||
|
**Event-triggered cycle** (supplement scheduled runs):
|
||||||
|
```
|
||||||
|
Trigger: CRITICAL change detected in any cycle
|
||||||
|
→ Immediately run deep collection on the affected entity
|
||||||
|
→ Expand query set to cover related entities
|
||||||
|
→ Generate ad-hoc alert report
|
||||||
|
→ Shorten next scheduled cycle interval (e.g., weekly → daily for 7 days)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Source Prioritization Based on Hit Rate
|
||||||
|
|
||||||
|
Track which sources consistently produce actionable intelligence and allocate collection effort accordingly.
|
||||||
|
|
||||||
|
**Hit rate calculation**:
|
||||||
|
```
|
||||||
|
hit_rate = (data_points_extracted / fetches_from_source) over last 10 cycles
|
||||||
|
```
|
||||||
|
|
||||||
|
**Priority tiers**:
|
||||||
|
| Hit Rate | Priority | Collection Behavior |
|
||||||
|
|----------|----------|-------------------|
|
||||||
|
| > 60% | Tier 1 | Always fetch, process first |
|
||||||
|
| 30-60% | Tier 2 | Fetch on every cycle |
|
||||||
|
| 10-30% | Tier 3 | Fetch every other cycle |
|
||||||
|
| < 10% | Tier 4 | Fetch weekly regardless of cycle frequency |
|
||||||
|
| 0% for 5+ cycles | Drop | Remove from active source list, log reason |
|
||||||
|
|
||||||
|
**Source performance tracking**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"source": "techcrunch.com",
|
||||||
|
"total_fetches": 48,
|
||||||
|
"data_points_extracted": 31,
|
||||||
|
"hit_rate": 0.65,
|
||||||
|
"tier": 1,
|
||||||
|
"avg_confidence": "medium-high",
|
||||||
|
"last_hit": "2025-11-15",
|
||||||
|
"best_queries": ["[company] funding", "[company] acquisition"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Incremental Collection (Only New/Changed Content)
|
||||||
|
|
||||||
|
Avoid re-processing unchanged content across cycles.
|
||||||
|
|
||||||
|
**Techniques**:
|
||||||
|
1. **URL deduplication**: Maintain a set of already-processed URLs. Skip on subsequent cycles.
|
||||||
|
2. **Content hashing**: Hash the extracted text body. If hash matches previous cycle, skip processing.
|
||||||
|
3. **Date filtering**: Append date ranges to queries to limit results to new content.
|
||||||
|
4. **Pagination cursors**: For APIs and structured sources, store the last-seen ID or timestamp.
|
||||||
|
|
||||||
|
**Query date narrowing**:
|
||||||
|
```
|
||||||
|
Cycle runs daily at 06:00 UTC:
|
||||||
|
"AlphaCloud" after:2025-11-15 before:2025-11-16
|
||||||
|
"AlphaCloud" news past 24 hours
|
||||||
|
|
||||||
|
Cycle runs weekly:
|
||||||
|
"AlphaCloud" after:2025-11-08 before:2025-11-15
|
||||||
|
```
|
||||||
|
|
||||||
|
**State tracking for incremental collection**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"processed_urls": ["https://example.com/article-1", "..."],
|
||||||
|
"content_hashes": {"url1": "sha256:abc123", "url2": "sha256:def456"},
|
||||||
|
"last_collection_time": "2025-11-15T06:00:00Z",
|
||||||
|
"query_cursors": {
|
||||||
|
"techcrunch_rss": "2025-11-15T05:30:00Z",
|
||||||
|
"github_api_events": "event_id_98765"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alert Trigger Conditions and Escalation Rules
|
||||||
|
|
||||||
|
Define when and how to escalate detected changes.
|
||||||
|
|
||||||
|
**Trigger conditions**:
|
||||||
|
```
|
||||||
|
IMMEDIATE ALERT (publish event_publish within the cycle):
|
||||||
|
- Leadership change at target company (CEO, CTO, CFO)
|
||||||
|
- Acquisition or merger announcement
|
||||||
|
- Funding round > $10M
|
||||||
|
- Product discontinuation or major pivot
|
||||||
|
- Regulatory action or legal filing
|
||||||
|
- Data breach or security incident
|
||||||
|
|
||||||
|
DAILY DIGEST (batch into next daily report):
|
||||||
|
- New product feature or version release
|
||||||
|
- New partnership announcement
|
||||||
|
- Hiring surge (> 5 new roles in a category)
|
||||||
|
- Pricing or packaging change
|
||||||
|
- Significant sentiment shift (score delta > 2 in one cycle)
|
||||||
|
|
||||||
|
WEEKLY SUMMARY (include in weekly report only):
|
||||||
|
- Blog posts and thought leadership
|
||||||
|
- Conference appearances
|
||||||
|
- Minor version updates or patches
|
||||||
|
- Individual job postings
|
||||||
|
- Social media activity within normal range
|
||||||
|
```
|
||||||
|
|
||||||
|
**Escalation rules**:
|
||||||
|
```
|
||||||
|
Level 1 — Auto-include in next scheduled report (default for all changes)
|
||||||
|
Level 2 — event_publish immediately (for CRITICAL significance changes)
|
||||||
|
Level 3 — event_publish + re-run deep collection on affected entity (for M&A, major crises)
|
||||||
|
```
|
||||||
|
|
||||||
|
**False positive suppression**:
|
||||||
|
- Require 2+ independent sources before triggering Level 2 alerts
|
||||||
|
- Ignore "rumor" or "speculation" tagged content for immediate alerts
|
||||||
|
- If the same alert fired in the previous cycle with no new corroboration, suppress repeat
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Analysis Techniques
|
||||||
|
|
||||||
|
### Link Analysis (Connection Mapping)
|
||||||
|
|
||||||
|
Map the network of relationships between entities to reveal hidden connections, influence patterns, and structural vulnerabilities.
|
||||||
|
|
||||||
|
**Building the adjacency map**:
|
||||||
|
```
|
||||||
|
From the knowledge graph, extract all relations and build:
|
||||||
|
|
||||||
|
Nodes: [Acme, BetaCo, GammaSuite, Jane Lee, CloudCo, InvestorX]
|
||||||
|
Edges:
|
||||||
|
Acme --competes_with--> BetaCo
|
||||||
|
Acme --partnered_with--> CloudCo
|
||||||
|
Jane Lee --works_at--> Acme
|
||||||
|
Jane Lee --formerly--> BetaCo
|
||||||
|
InvestorX --invested_in--> Acme
|
||||||
|
InvestorX --invested_in--> GammaSuite
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key metrics to compute**:
|
||||||
|
| Metric | Meaning | Use |
|
||||||
|
|--------|---------|-----|
|
||||||
|
| Degree centrality | Number of direct connections | Identifies most-connected entities |
|
||||||
|
| Shared connections | Entities with overlapping relationships | Reveals indirect competition or collaboration |
|
||||||
|
| Bridge nodes | Entities connecting otherwise separate clusters | Identifies key influencers or gatekeepers |
|
||||||
|
| Cluster density | Ratio of actual to possible connections in a group | Measures how tightly coupled a set of entities is |
|
||||||
|
|
||||||
|
**Practical analysis patterns**:
|
||||||
|
```
|
||||||
|
Investor overlap:
|
||||||
|
InvestorX invested_in Acme AND GammaSuite
|
||||||
|
→ Potential: board-level information sharing, future merger pressure
|
||||||
|
|
||||||
|
Talent flow:
|
||||||
|
Jane Lee: BetaCo (2020-2024) → Acme (2024-present)
|
||||||
|
3 other engineers: BetaCo → Acme in same period
|
||||||
|
→ Pattern: talent drain from BetaCo to Acme, possible IP risk
|
||||||
|
|
||||||
|
Supply chain dependency:
|
||||||
|
Acme uses CloudCo infrastructure
|
||||||
|
BetaCo uses CloudCo infrastructure
|
||||||
|
→ Shared dependency: CloudCo outage affects both competitors
|
||||||
|
```
|
||||||
|
|
||||||
|
### Timeline Analysis (Event Sequencing and Pattern Detection)
|
||||||
|
|
||||||
|
Arrange extracted events chronologically to detect causal chains, recurring patterns, and anomalous timing.
|
||||||
|
|
||||||
|
**Constructing the timeline**:
|
||||||
|
```
|
||||||
|
2025-01 Acme raises Series B ($40M)
|
||||||
|
2025-02 Acme posts 15 engineering roles
|
||||||
|
2025-03 Acme hires CTO from Google
|
||||||
|
2025-05 Acme acquires small startup (data pipeline tool)
|
||||||
|
2025-06 Acme launches v3.0 with data pipeline features
|
||||||
|
2025-08 Acme announces enterprise pricing tier
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pattern detection rules**:
|
||||||
|
|
||||||
|
| Pattern | Sequence | Interpretation |
|
||||||
|
|---------|----------|---------------|
|
||||||
|
| Build-up to launch | Funding → Hiring surge → Leadership hire → Product release | Normal growth execution |
|
||||||
|
| Acquisition integration | Acquire company → Quiet period (2-4 months) → Feature launch using acquired tech | Successful integration |
|
||||||
|
| Pre-acquisition signals | Advisor hire → Leadership departures → Quiet period → Announcement | Target company being acquired |
|
||||||
|
| Distress pattern | Layoffs → Pricing cuts → Leadership change → Pivot or shutdown | Company in trouble |
|
||||||
|
| Expansion play | Funding → New market entry → Localized hiring → Regional partnerships | Geographic or vertical expansion |
|
||||||
|
|
||||||
|
**Anomaly detection**:
|
||||||
|
```
|
||||||
|
Expected: Funding round → hiring surge within 60 days
|
||||||
|
Observed: Funding round → no hiring after 90 days
|
||||||
|
→ Flag: "Post-funding hiring anomaly — possible pivot, internal issues, or stealth project"
|
||||||
|
|
||||||
|
Expected: Product launch → marketing push within 30 days
|
||||||
|
Observed: Product launch → silence
|
||||||
|
→ Flag: "Launch without marketing — possible soft launch, or product issues"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Trend Detection (Acceleration, Deceleration, Inflection Points)
|
||||||
|
|
||||||
|
Track metrics across collection cycles to identify directional shifts.
|
||||||
|
|
||||||
|
**Metric tracking format**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"entity": "Acme Corp",
|
||||||
|
"metric": "job_postings",
|
||||||
|
"series": [
|
||||||
|
{"cycle": 1, "date": "2025-09-01", "value": 12},
|
||||||
|
{"cycle": 2, "date": "2025-09-08", "value": 18},
|
||||||
|
{"cycle": 3, "date": "2025-09-15", "value": 31},
|
||||||
|
{"cycle": 4, "date": "2025-09-22", "value": 45},
|
||||||
|
{"cycle": 5, "date": "2025-09-29", "value": 42}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Trend classification**:
|
||||||
|
| Pattern | Detection Rule | Meaning |
|
||||||
|
|---------|---------------|---------|
|
||||||
|
| Accelerating | Growth rate increasing cycle-over-cycle | Expanding investment in area |
|
||||||
|
| Decelerating | Growth rate decreasing but still positive | Approaching saturation or shift in priorities |
|
||||||
|
| Inflection point | Direction change (growth → decline or vice versa) | Strategic shift, market event, or external shock |
|
||||||
|
| Plateau | Value stable within 10% for 3+ cycles | Steady state, maintenance mode |
|
||||||
|
| Spike | Single-cycle jump > 2x previous value | One-time event (launch, announcement, crisis) |
|
||||||
|
| Cliff | Single-cycle drop > 50% | Sudden change (layoff, shutdown, policy change) |
|
||||||
|
|
||||||
|
**Multi-metric correlation**:
|
||||||
|
```
|
||||||
|
When two metrics move together, the correlation strengthens the signal:
|
||||||
|
|
||||||
|
Acme job_postings: accelerating
|
||||||
|
Acme github_commits: accelerating
|
||||||
|
→ Corroborated signal: major development push underway
|
||||||
|
|
||||||
|
BetaCo job_postings: cliff (-60%)
|
||||||
|
BetaCo glassdoor_rating: declining
|
||||||
|
→ Corroborated signal: organizational distress
|
||||||
|
```
|
||||||
|
|
||||||
|
### Competitive Positioning Maps
|
||||||
|
|
||||||
|
Synthesize collected intelligence into comparative frameworks.
|
||||||
|
|
||||||
|
**Feature parity matrix**:
|
||||||
|
| Capability | Acme | BetaCo | GammaSuite | Your Product |
|
||||||
|
|-----------|------|--------|------------|-------------|
|
||||||
|
| Real-time dashboards | Yes (v2.0+) | Yes | Limited | Yes |
|
||||||
|
| AI-powered alerts | Yes (new in v4.2) | No | Beta | Planned Q1 |
|
||||||
|
| On-prem deployment | No | Yes | Yes | Yes |
|
||||||
|
| SOC2 compliance | Yes | Yes | In progress | Yes |
|
||||||
|
| Free tier | No | Yes (limited) | Yes | Yes |
|
||||||
|
|
||||||
|
**Market position quadrant** (based on collected metrics):
|
||||||
|
```
|
||||||
|
High Market Share
|
||||||
|
|
|
||||||
|
Leaders | Challengers
|
||||||
|
(Acme) | (GammaSuite)
|
||||||
|
|
|
||||||
|
Low Growth ────────────┼──────────── High Growth
|
||||||
|
|
|
||||||
|
Declining | Emerging
|
||||||
|
(Legacy Co) | (BetaCo)
|
||||||
|
|
|
||||||
|
Low Market Share
|
||||||
|
```
|
||||||
|
|
||||||
|
Inputs for positioning:
|
||||||
|
- **Market share proxy**: mention frequency, customer count, job posting volume
|
||||||
|
- **Growth proxy**: funding recency, hiring rate, product release velocity, GitHub star velocity
|
||||||
|
|
||||||
|
**Pricing intelligence table**:
|
||||||
|
| Tier | Acme | BetaCo | GammaSuite | Notes |
|
||||||
|
|------|------|--------|------------|-------|
|
||||||
|
| Free | -- | 5 users | 10 users | BetaCo most restrictive |
|
||||||
|
| Team | $15/user/mo | $12/user/mo | $20/user/mo | BetaCo cheapest |
|
||||||
|
| Enterprise | Custom | $35/user/mo | Custom | BetaCo only one with public enterprise pricing |
|
||||||
|
| Notable changes | Raised Team tier 20% in Q3 | Unchanged 12 months | New tier added Q4 | Acme pricing pressure |
|
||||||
|
|
||||||
|
Track pricing changes across cycles — pricing increases signal confidence, decreases signal competitive pressure or churn concerns.
|
||||||
@@ -490,6 +490,265 @@ token_consumption = "high"
|
|||||||
default_active = false
|
default_active = false
|
||||||
activation_warning = "DevOps hand runs continuously and monitors infrastructure, consuming tokens."
|
activation_warning = "DevOps hand runs continuously and monitors infrastructure, consuming tokens."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "DevOps Hand"
|
name = "DevOps Hand"
|
||||||
description = "自主 DevOps 工程师——CI/CD 管理、基础设施监控、部署自动化和事件响应"
|
description = "自主 DevOps 工程师——CI/CD 管理、基础设施监控、部署自动化和事件响应"
|
||||||
|
category = "开发"
|
||||||
|
|
||||||
|
[i18n.zh.settings.infrastructure]
|
||||||
|
label = "基础设施类型"
|
||||||
|
description = "主要基础设施平台"
|
||||||
|
|
||||||
|
[i18n.zh.settings.ci_platform]
|
||||||
|
label = "CI/CD 平台"
|
||||||
|
description = "主要 CI/CD 平台"
|
||||||
|
|
||||||
|
[i18n.zh.settings.monitoring_focus]
|
||||||
|
label = "监控重点"
|
||||||
|
description = "主要监控和告警的关注方向"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_monitor]
|
||||||
|
label = "自动监控"
|
||||||
|
description = "自动监控基础设施并在出现问题时告警"
|
||||||
|
|
||||||
|
[i18n.zh.settings.check_interval]
|
||||||
|
label = "健康检查间隔"
|
||||||
|
description = "自动健康检查的执行频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.service_urls]
|
||||||
|
label = "服务 URL"
|
||||||
|
description = "要监控的 URL 列表,以逗号分隔(例如 https://api.example.com/health,https://app.example.com)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.alert_on_failure]
|
||||||
|
label = "故障告警"
|
||||||
|
description = "健康检查失败时发布事件通知"
|
||||||
|
|
||||||
|
[i18n.zh.settings.rollback_strategy]
|
||||||
|
label = "回滚策略"
|
||||||
|
description = "部署失败时的默认回滚方式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "审批模式"
|
||||||
|
description = "将部署和基础设施操作加入队列供审核,而非直接执行"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "DevOps Hand"
|
||||||
|
description = "自律型DevOpsエンジニア——CI/CD管理、インフラ監視、デプロイ自動化、インシデント対応"
|
||||||
|
category = "開発"
|
||||||
|
|
||||||
|
[i18n.ja.settings.infrastructure]
|
||||||
|
label = "インフラタイプ"
|
||||||
|
description = "主要なインフラプラットフォーム"
|
||||||
|
|
||||||
|
[i18n.ja.settings.ci_platform]
|
||||||
|
label = "CI/CDプラットフォーム"
|
||||||
|
description = "主要なCI/CDプラットフォーム"
|
||||||
|
|
||||||
|
[i18n.ja.settings.monitoring_focus]
|
||||||
|
label = "監視の重点"
|
||||||
|
description = "監視とアラートの主な対象分野"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_monitor]
|
||||||
|
label = "自動監視"
|
||||||
|
description = "インフラを自動監視し、問題発生時にアラートを出す"
|
||||||
|
|
||||||
|
[i18n.ja.settings.check_interval]
|
||||||
|
label = "ヘルスチェック間隔"
|
||||||
|
description = "自動ヘルスチェックの実行間隔"
|
||||||
|
|
||||||
|
[i18n.ja.settings.service_urls]
|
||||||
|
label = "サービスURL"
|
||||||
|
description = "監視対象のURL一覧(カンマ区切り、例: https://api.example.com/health,https://app.example.com)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.alert_on_failure]
|
||||||
|
label = "障害アラート"
|
||||||
|
description = "ヘルスチェック失敗時にイベント通知を発行する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.rollback_strategy]
|
||||||
|
label = "ロールバック戦略"
|
||||||
|
description = "デプロイ失敗時のデフォルトのロールバック方法"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "承認モード"
|
||||||
|
description = "デプロイやインフラ操作を直接実行せず、レビュー用キューに追加する"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de DevOps"
|
||||||
|
description = "Ingeniero DevOps autónomo — gestión de CI/CD, monitoreo de infraestructura, automatización de despliegues y respuesta a incidentes"
|
||||||
|
category = "Desarrollo"
|
||||||
|
|
||||||
|
[i18n.es.settings.infrastructure]
|
||||||
|
label = "Tipo de infraestructura"
|
||||||
|
description = "Plataforma de infraestructura principal"
|
||||||
|
|
||||||
|
[i18n.es.settings.ci_platform]
|
||||||
|
label = "Plataforma CI/CD"
|
||||||
|
description = "Plataforma principal de CI/CD"
|
||||||
|
|
||||||
|
[i18n.es.settings.monitoring_focus]
|
||||||
|
label = "Enfoque de monitoreo"
|
||||||
|
description = "Área principal de monitoreo y alertas"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_monitor]
|
||||||
|
label = "Monitoreo automático"
|
||||||
|
description = "Monitorear automáticamente la infraestructura y alertar ante problemas"
|
||||||
|
|
||||||
|
[i18n.es.settings.check_interval]
|
||||||
|
label = "Intervalo de comprobación de salud"
|
||||||
|
description = "Con qué frecuencia ejecutar las comprobaciones de salud automatizadas"
|
||||||
|
|
||||||
|
[i18n.es.settings.service_urls]
|
||||||
|
label = "URLs de servicios"
|
||||||
|
description = "Lista de URLs a monitorear separadas por comas (ej. https://api.example.com/health,https://app.example.com)"
|
||||||
|
|
||||||
|
[i18n.es.settings.alert_on_failure]
|
||||||
|
label = "Alertar ante fallos"
|
||||||
|
description = "Publicar eventos cuando las comprobaciones de salud fallen"
|
||||||
|
|
||||||
|
[i18n.es.settings.rollback_strategy]
|
||||||
|
label = "Estrategia de reversión"
|
||||||
|
description = "Enfoque de reversión predeterminado para despliegues fallidos"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Modo de aprobación"
|
||||||
|
description = "Poner acciones de despliegue e infraestructura en cola para revisión en lugar de ejecutarlas directamente"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand DevOps"
|
||||||
|
description = "Ingénieur DevOps autonome — gestion CI/CD, surveillance d'infrastructure, automatisation des déploiements et réponse aux incidents"
|
||||||
|
category = "Développement"
|
||||||
|
|
||||||
|
[i18n.fr.settings.infrastructure]
|
||||||
|
label = "Type d'infrastructure"
|
||||||
|
description = "Plateforme d'infrastructure principale"
|
||||||
|
|
||||||
|
[i18n.fr.settings.ci_platform]
|
||||||
|
label = "Plateforme CI/CD"
|
||||||
|
description = "Plateforme CI/CD principale"
|
||||||
|
|
||||||
|
[i18n.fr.settings.monitoring_focus]
|
||||||
|
label = "Axe de surveillance"
|
||||||
|
description = "Domaine principal de surveillance et d'alerte"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_monitor]
|
||||||
|
label = "Surveillance automatique"
|
||||||
|
description = "Surveiller automatiquement l'infrastructure et alerter en cas de problèmes"
|
||||||
|
|
||||||
|
[i18n.fr.settings.check_interval]
|
||||||
|
label = "Intervalle de vérification de santé"
|
||||||
|
description = "Fréquence d'exécution des vérifications de santé automatisées"
|
||||||
|
|
||||||
|
[i18n.fr.settings.service_urls]
|
||||||
|
label = "URLs des services"
|
||||||
|
description = "Liste d'URLs à surveiller séparées par des virgules (ex. https://api.example.com/health,https://app.example.com)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.alert_on_failure]
|
||||||
|
label = "Alerte en cas d'échec"
|
||||||
|
description = "Publier des événements lorsque les vérifications de santé échouent"
|
||||||
|
|
||||||
|
[i18n.fr.settings.rollback_strategy]
|
||||||
|
label = "Stratégie de retour en arrière"
|
||||||
|
description = "Approche de retour en arrière par défaut pour les déploiements échoués"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Mode d'approbation"
|
||||||
|
description = "Mettre les actions de déploiement et d'infrastructure en file d'attente pour révision au lieu de les exécuter directement"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "DevOps-Hand"
|
||||||
|
description = "Autonomer DevOps-Ingenieur — CI/CD-Verwaltung, Infrastrukturüberwachung, Deployment-Automatisierung und Incident-Response"
|
||||||
|
category = "Entwicklung"
|
||||||
|
|
||||||
|
[i18n.de.settings.infrastructure]
|
||||||
|
label = "Infrastrukturtyp"
|
||||||
|
description = "Primäre Infrastrukturplattform"
|
||||||
|
|
||||||
|
[i18n.de.settings.ci_platform]
|
||||||
|
label = "CI/CD-Plattform"
|
||||||
|
description = "Primäre CI/CD-Plattform"
|
||||||
|
|
||||||
|
[i18n.de.settings.monitoring_focus]
|
||||||
|
label = "Überwachungsschwerpunkt"
|
||||||
|
description = "Hauptbereich für Überwachung und Alarme"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_monitor]
|
||||||
|
label = "Automatische Überwachung"
|
||||||
|
description = "Infrastruktur automatisch überwachen und bei Problemen alarmieren"
|
||||||
|
|
||||||
|
[i18n.de.settings.check_interval]
|
||||||
|
label = "Gesundheitscheck-Intervall"
|
||||||
|
description = "Ausführungshäufigkeit der automatisierten Gesundheitschecks"
|
||||||
|
|
||||||
|
[i18n.de.settings.service_urls]
|
||||||
|
label = "Service-URLs"
|
||||||
|
description = "Kommagetrennte Liste der zu überwachenden URLs (z.B. https://api.example.com/health,https://app.example.com)"
|
||||||
|
|
||||||
|
[i18n.de.settings.alert_on_failure]
|
||||||
|
label = "Warnung bei Ausfall"
|
||||||
|
description = "Ereignisse veröffentlichen, wenn Gesundheitschecks fehlschlagen"
|
||||||
|
|
||||||
|
[i18n.de.settings.rollback_strategy]
|
||||||
|
label = "Rollback-Strategie"
|
||||||
|
description = "Standard-Rollback-Ansatz für fehlgeschlagene Deployments"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Genehmigungsmodus"
|
||||||
|
description = "Deployment- und Infrastrukturaktionen zur Überprüfung in die Warteschlange stellen, anstatt sie direkt auszuführen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "DevOps Hand"
|
||||||
|
description = "자율 DevOps 엔지니어 — CI/CD 관리, 인프라 모니터링, 배포 자동화 및 인시던트 대응"
|
||||||
|
category = "개발"
|
||||||
|
|
||||||
|
[i18n.ko.settings.infrastructure]
|
||||||
|
label = "인프라 유형"
|
||||||
|
description = "주요 인프라 플랫폼"
|
||||||
|
|
||||||
|
[i18n.ko.settings.ci_platform]
|
||||||
|
label = "CI/CD 플랫폼"
|
||||||
|
description = "주요 CI/CD 플랫폼"
|
||||||
|
|
||||||
|
[i18n.ko.settings.monitoring_focus]
|
||||||
|
label = "모니터링 중점"
|
||||||
|
description = "주요 모니터링 및 알림 방향"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_monitor]
|
||||||
|
label = "자동 모니터링"
|
||||||
|
description = "인프라를 자동으로 모니터링하고 문제 발생 시 알림"
|
||||||
|
|
||||||
|
[i18n.ko.settings.check_interval]
|
||||||
|
label = "상태 점검 간격"
|
||||||
|
description = "자동 상태 점검 실행 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.service_urls]
|
||||||
|
label = "서비스 URL"
|
||||||
|
description = "모니터링할 URL 목록 (쉼표로 구분, 예: https://api.example.com/health,https://app.example.com)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.alert_on_failure]
|
||||||
|
label = "장애 알림"
|
||||||
|
description = "상태 점검 실패 시 이벤트 알림 발행"
|
||||||
|
|
||||||
|
[i18n.ko.settings.rollback_strategy]
|
||||||
|
label = "롤백 전략"
|
||||||
|
description = "배포 실패 시 기본 롤백 방식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "승인 모드"
|
||||||
|
description = "배포 및 인프라 작업을 직접 실행하지 않고 대기열에 추가하여 검토"
|
||||||
@@ -330,3 +330,541 @@ for domain in api.example.com app.example.com; do
|
|||||||
echo "$domain: $expiry"
|
echo "$domain: $expiry"
|
||||||
done
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Zero-Downtime Deployment Pipeline
|
||||||
|
|
||||||
|
Full lifecycle from code merge to production traffic switch with rollback safety.
|
||||||
|
|
||||||
|
**Phases**: CI build and push image -> deploy to Green -> health-gate -> traffic switch -> monitor -> done (or rollback).
|
||||||
|
|
||||||
|
**Traffic switch script** (the critical step):
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
# Record current slot for rollback, then switch
|
||||||
|
CURRENT=$(kubectl get svc myapp-active -n production -o jsonpath='{.spec.selector.slot}')
|
||||||
|
echo "$CURRENT" > /tmp/rollback-slot
|
||||||
|
kubectl patch svc myapp-active -n production -p '{"spec":{"selector":{"slot":"green"}}}'
|
||||||
|
# Verify
|
||||||
|
sleep 5 && curl -sf https://api.example.com/api/health | jq '.version'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rollback**: read `/tmp/rollback-slot`, patch the service selector back, verify health.
|
||||||
|
|
||||||
|
**Decision flowchart**:
|
||||||
|
```
|
||||||
|
Code merged to main
|
||||||
|
|
|
||||||
|
v
|
||||||
|
CI build + test ----[FAIL]----> Block merge, notify author
|
||||||
|
|
|
||||||
|
[PASS]
|
||||||
|
v
|
||||||
|
Deploy to Green
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Health checks ------[FAIL]----> Alert on-call, keep Blue active
|
||||||
|
|
|
||||||
|
[PASS]
|
||||||
|
v
|
||||||
|
Switch traffic to Green
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Monitor 15 min -----[ERROR SPIKE]----> Rollback to Blue, open incident
|
||||||
|
|
|
||||||
|
[STABLE]
|
||||||
|
v
|
||||||
|
Mark Green as new Blue, done
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 2: Production Incident Response
|
||||||
|
|
||||||
|
Walkthrough of a real-world SEV1 incident: API latency spike caused by a database connection pool exhaustion.
|
||||||
|
|
||||||
|
**Timeline**
|
||||||
|
|
||||||
|
| Time (UTC) | Event | Actor |
|
||||||
|
|------------|-------|-------|
|
||||||
|
| 14:02 | PagerDuty alert: P95 latency > 2s on `/api/orders` | Monitoring |
|
||||||
|
| 14:04 | On-call acknowledges, opens incident channel `#inc-2025-0312` | On-call engineer |
|
||||||
|
| 14:06 | Check dashboard: request queue depth spiking, error rate at 12% | On-call engineer |
|
||||||
|
| 14:10 | Identify DB connection pool at 100% utilization | On-call engineer |
|
||||||
|
| 14:12 | Find long-running query from analytics job (started 13:55) | On-call engineer |
|
||||||
|
| 14:14 | Kill the runaway query, pool starts draining | On-call engineer |
|
||||||
|
| 14:18 | Latency returns to normal, error rate drops to 0.2% | Monitoring |
|
||||||
|
| 14:20 | Incident mitigated, continue monitoring | On-call engineer |
|
||||||
|
| 14:45 | Root cause confirmed: analytics cron job without query timeout | Investigation |
|
||||||
|
| 15:00 | Incident resolved, post-mortem scheduled | Incident commander |
|
||||||
|
|
||||||
|
**Detection -- Alerting rules that fired**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Prometheus alerting rule
|
||||||
|
groups:
|
||||||
|
- name: api-latency
|
||||||
|
rules:
|
||||||
|
- alert: HighAPILatency
|
||||||
|
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{job="api"}[5m])) > 2
|
||||||
|
for: 2m
|
||||||
|
labels:
|
||||||
|
severity: critical
|
||||||
|
annotations:
|
||||||
|
summary: "P95 latency above 2s for 2+ minutes"
|
||||||
|
runbook: "https://wiki.internal/runbooks/high-latency"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Triage -- Quick diagnosis commands**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Check if it's a specific endpoint or global
|
||||||
|
curl -s "http://prometheus:9090/api/v1/query?query=topk(5,rate(http_request_duration_seconds_sum[5m])/rate(http_request_duration_seconds_count[5m]))" | jq '.data.result[] | {endpoint: .metric.handler, avg_latency: .value[1]}'
|
||||||
|
|
||||||
|
# 2. Check database connection pool
|
||||||
|
psql -c "SELECT count(*) as total, state FROM pg_stat_activity GROUP BY state;"
|
||||||
|
|
||||||
|
# 3. Find the blocking query
|
||||||
|
psql -c "SELECT pid, now() - query_start AS duration, query
|
||||||
|
FROM pg_stat_activity
|
||||||
|
WHERE state = 'active' AND now() - query_start > interval '1 minute'
|
||||||
|
ORDER BY duration DESC LIMIT 5;"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Mitigation -- Kill the offending query**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Kill the long-running query by PID
|
||||||
|
psql -c "SELECT pg_terminate_backend(12345);"
|
||||||
|
|
||||||
|
# Verify pool is recovering
|
||||||
|
watch -n 2 'psql -t -c "SELECT count(*) FROM pg_stat_activity WHERE state = '\''active'\'';"'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Prevention -- Fix applied after incident**
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- Set statement timeout for analytics role
|
||||||
|
ALTER ROLE analytics_readonly SET statement_timeout = '300s';
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Add connection pool monitoring alert
|
||||||
|
- alert: DBConnectionPoolNearCapacity
|
||||||
|
expr: pg_stat_activity_count / pg_settings_max_connections > 0.8
|
||||||
|
for: 1m
|
||||||
|
labels:
|
||||||
|
severity: warning
|
||||||
|
annotations:
|
||||||
|
summary: "DB connection pool above 80% capacity"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Post-mortem action items**:
|
||||||
|
- [ ] Add `statement_timeout` to all non-interactive database roles
|
||||||
|
- [ ] Add connection pool utilization alerts (threshold: 80%)
|
||||||
|
- [ ] Move analytics queries to read replica
|
||||||
|
- [ ] Add circuit breaker to API when pool utilization exceeds 90%
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 3: Infrastructure Scaling Event
|
||||||
|
|
||||||
|
Scaling a Kubernetes deployment in response to sustained load increase.
|
||||||
|
|
||||||
|
**Phase 1 -- Alert triggers**
|
||||||
|
|
||||||
|
```
|
||||||
|
Alert: HighCPUUtilization
|
||||||
|
Condition: avg(cpu_usage) > 80% for 10 minutes
|
||||||
|
Current: 87% across 3 pods
|
||||||
|
Namespace: production
|
||||||
|
Deployment: order-service
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 2 -- Capacity analysis**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl top pods -l app=order-service -n production # Per-pod CPU/memory
|
||||||
|
kubectl describe nodes | grep -A 5 "Allocated resources" # Node headroom
|
||||||
|
kubectl get hpa order-service -n production # Current HPA state
|
||||||
|
# Result: 87% CPU across 3 pods, 842 req/s (2x baseline)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 3 -- Scaling decision matrix**
|
||||||
|
|
||||||
|
| Metric | Current | Target | Action |
|
||||||
|
|--------|---------|--------|--------|
|
||||||
|
| CPU usage | 87% | < 70% | Scale out |
|
||||||
|
| Request rate | 842/s | - | 2x normal, sustained |
|
||||||
|
| Memory | 258Mi avg | 512Mi limit | Headroom OK |
|
||||||
|
| Pod count | 3 | 6 (estimated) | Double replicas |
|
||||||
|
| Node capacity | 72% | < 85% | Sufficient for 6 pods |
|
||||||
|
|
||||||
|
**Phase 4 -- Implement scaling**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option A: Manual scale (immediate)
|
||||||
|
kubectl scale deployment order-service -n production --replicas=6
|
||||||
|
|
||||||
|
# Option B: Adjust HPA for sustained load (preferred)
|
||||||
|
kubectl patch hpa order-service -n production \
|
||||||
|
-p '{"spec":{"minReplicas":5,"maxReplicas":15}}'
|
||||||
|
|
||||||
|
# Monitor rollout
|
||||||
|
kubectl rollout status deployment/order-service -n production
|
||||||
|
|
||||||
|
# Watch pods come up
|
||||||
|
kubectl get pods -l app=order-service -n production -w
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 5 -- Verify scaling**
|
||||||
|
|
||||||
|
Confirm via `kubectl top pods` (CPU should drop to ~45% per pod), check P95 latency is back below SLO, and verify error rate < 1%.
|
||||||
|
|
||||||
|
**Post-scaling actions**:
|
||||||
|
- [ ] Investigate root cause of traffic increase (marketing event? bot traffic? organic growth?)
|
||||||
|
- [ ] Update capacity planning spreadsheet
|
||||||
|
- [ ] If sustained, adjust resource requests/limits and HPA baselines
|
||||||
|
- [ ] Set calendar reminder to review and potentially scale down in 48h
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Observability Deep Dive
|
||||||
|
|
||||||
|
### Structured Logging
|
||||||
|
|
||||||
|
Use consistent JSON log format across all services for machine-parseable aggregation.
|
||||||
|
|
||||||
|
**Log format standard**: JSON with required fields: `timestamp`, `level`, `service`, `trace_id`, `span_id`, `request_id`, `message`. Add `error` and `context` (structured key-value) as needed.
|
||||||
|
|
||||||
|
**Log levels -- when to use each**:
|
||||||
|
|
||||||
|
| Level | Purpose | Example | Persisted |
|
||||||
|
|-------|---------|---------|-----------|
|
||||||
|
| `error` | Requires human attention | Payment processing failed | 90 days |
|
||||||
|
| `warn` | Degraded but recoverable | Retry succeeded on 2nd attempt | 30 days |
|
||||||
|
| `info` | Business-significant events | Order placed, user logged in | 14 days |
|
||||||
|
| `debug` | Developer troubleshooting | Cache hit/miss, query timing | 3 days |
|
||||||
|
| `trace` | Fine-grained flow tracking | Function entry/exit, variable state | 1 day (sampled) |
|
||||||
|
|
||||||
|
**Correlation IDs**: generate `X-Request-ID` at API gateway, propagate through all downstream calls. Query across services by filtering on `request_id.keyword` in Elasticsearch/OpenSearch.
|
||||||
|
|
||||||
|
### Distributed Tracing
|
||||||
|
|
||||||
|
**Core concepts**: A Trace is the end-to-end request path. Each service call is a Span with timing. Spans nest to show the call tree (e.g., API Gateway -> Order Service -> DB Query + Payment Service -> Stripe API).
|
||||||
|
|
||||||
|
**OpenTelemetry propagation**: `traceparent: 00-<trace-id>-<span-id>-<flags>`, `tracestate: vendor=value`.
|
||||||
|
|
||||||
|
**Useful trace queries (Jaeger/Tempo)**:
|
||||||
|
```bash
|
||||||
|
curl -s "http://jaeger:16686/api/traces?service=order-service&minDuration=1s&limit=20" # Slow traces
|
||||||
|
curl -s "http://jaeger:16686/api/traces?service=order-service&tags=error%3Dtrue&limit=20" # Error traces
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alerting Best Practices
|
||||||
|
|
||||||
|
**Avoid alert fatigue -- rules of thumb**:
|
||||||
|
- Every alert must have a runbook link
|
||||||
|
- Every alert must be actionable (if no one needs to act, it is a log, not an alert)
|
||||||
|
- Group related alerts to avoid notification storms
|
||||||
|
- Use inhibition rules: if the cluster is down, suppress per-pod alerts
|
||||||
|
|
||||||
|
**SLO-based alerting (burn rate)**:
|
||||||
|
```yaml
|
||||||
|
# SLO: 99.9% availability = 43.2 min/month error budget
|
||||||
|
# Fast burn (exhausts budget in 2h): error_ratio > 14.4 * 0.001 for 2m -> critical
|
||||||
|
# Slow burn (exhausts budget in 3d): error_ratio > 3 * 0.001 for 15m -> warning
|
||||||
|
groups:
|
||||||
|
- name: slo-burn-rate
|
||||||
|
rules:
|
||||||
|
- alert: SLOBurnRateCritical
|
||||||
|
expr: sum(rate(http_requests_total{code=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > (14.4 * 0.001)
|
||||||
|
for: 2m
|
||||||
|
labels: { severity: critical }
|
||||||
|
- alert: SLOBurnRateWarning
|
||||||
|
expr: sum(rate(http_requests_total{code=~"5.."}[1h])) / sum(rate(http_requests_total[1h])) > (3 * 0.001)
|
||||||
|
for: 15m
|
||||||
|
labels: { severity: warning }
|
||||||
|
```
|
||||||
|
|
||||||
|
**Runbook template**: Each alert runbook should cover: what the alert means (one sentence), impact scope, diagnosis steps (dashboard + commands), mitigation (quick fix vs proper fix), and escalation path (who to contact after 15 min).
|
||||||
|
|
||||||
|
### Metrics Collection Patterns
|
||||||
|
|
||||||
|
**RED Method (request-scoped services)**:
|
||||||
|
|
||||||
|
| Metric | What | PromQL Example |
|
||||||
|
|--------|------|----------------|
|
||||||
|
| **R**ate | Requests per second | `sum(rate(http_requests_total[5m]))` |
|
||||||
|
| **E**rrors | Failed requests per second | `sum(rate(http_requests_total{code=~"5.."}[5m]))` |
|
||||||
|
| **D**uration | Latency distribution | `histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))` |
|
||||||
|
|
||||||
|
**USE Method (infrastructure resources)**:
|
||||||
|
|
||||||
|
| Metric | What | Example Check |
|
||||||
|
|--------|------|---------------|
|
||||||
|
| **U**tilization | % time resource is busy | `avg(rate(node_cpu_seconds_total{mode!="idle"}[5m]))` |
|
||||||
|
| **S**aturation | Queue depth / backlog | `node_load1 / count(node_cpu_seconds_total{mode="idle"})` |
|
||||||
|
| **E**rrors | Error event count | `rate(node_disk_io_time_weighted_seconds_total[5m])` |
|
||||||
|
|
||||||
|
**When to use which**:
|
||||||
|
- RED for services that handle requests (APIs, web servers, message consumers)
|
||||||
|
- USE for infrastructure (CPU, memory, disk, network interfaces, queues)
|
||||||
|
- Combine both for a complete picture
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Operations
|
||||||
|
|
||||||
|
### Secret Management
|
||||||
|
|
||||||
|
**Principles**:
|
||||||
|
- Never store secrets in source code, environment variables (in Dockerfiles), or container images
|
||||||
|
- Use a secrets manager (Vault, AWS Secrets Manager, K8s Secrets with encryption at rest)
|
||||||
|
- Rotate secrets on a schedule and immediately after any suspected compromise
|
||||||
|
- Audit all secret access
|
||||||
|
|
||||||
|
**Vault pattern -- inject secrets at runtime**:
|
||||||
|
```bash
|
||||||
|
# Store a secret
|
||||||
|
vault kv put secret/myapp/db \
|
||||||
|
username="app_user" \
|
||||||
|
password="$(openssl rand -base64 32)"
|
||||||
|
|
||||||
|
# Read a secret (application startup)
|
||||||
|
vault kv get -format=json secret/myapp/db | jq -r '.data.data.password'
|
||||||
|
|
||||||
|
# Enable audit logging
|
||||||
|
vault audit enable file file_path=/var/log/vault-audit.log
|
||||||
|
```
|
||||||
|
|
||||||
|
**Kubernetes secrets -- from Vault using sidecar injector**:
|
||||||
|
|
||||||
|
Annotate the pod template with `vault.hashicorp.com/agent-inject: "true"`, specify the role and secret path. The Vault agent sidecar renders secrets to `/vault/secrets/` and the app sources them at startup. Key annotations: `agent-inject-secret-<name>` for the path, `agent-inject-template-<name>` for the rendering template.
|
||||||
|
|
||||||
|
**Secret rotation checklist**:
|
||||||
|
- [ ] Generate new secret value
|
||||||
|
- [ ] Update secret in secrets manager
|
||||||
|
- [ ] Restart/reload affected services (rolling, not all-at-once)
|
||||||
|
- [ ] Verify services authenticate with new secret
|
||||||
|
- [ ] Revoke the old secret value
|
||||||
|
- [ ] Confirm no services are still using the old secret
|
||||||
|
|
||||||
|
### Container Security Scanning
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Scan image for vulnerabilities (Trivy) -- fail CI on critical
|
||||||
|
trivy image --exit-code 1 --severity CRITICAL registry.example.com/myapp:$CI_COMMIT_SHA
|
||||||
|
|
||||||
|
# Scan K8s cluster for misconfigurations
|
||||||
|
trivy k8s --report summary cluster
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dockerfile security essentials**: use pinned base image tags (not `:latest`), run as non-root (`USER app`), copy only needed files, never bake secrets into image layers.
|
||||||
|
|
||||||
|
### Network Security Policies
|
||||||
|
|
||||||
|
**Kubernetes NetworkPolicy -- default deny with explicit allow**:
|
||||||
|
```yaml
|
||||||
|
# Default deny all ingress, then allow specific paths
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: allow-gateway-to-orders
|
||||||
|
namespace: production
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels: { app: order-service }
|
||||||
|
ingress:
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels: { app: api-gateway }
|
||||||
|
ports:
|
||||||
|
- { protocol: TCP, port: 8080 }
|
||||||
|
```
|
||||||
|
|
||||||
|
Apply a `default-deny-ingress` policy (empty `podSelector`, `policyTypes: [Ingress]`) per namespace first, then layer allow rules on top.
|
||||||
|
|
||||||
|
### Compliance as Code
|
||||||
|
|
||||||
|
**Policy enforcement with OPA/Gatekeeper**: use `K8sRequiredResources` constraints to enforce `limits.cpu`, `limits.memory`, `requests.cpu`, `requests.memory` on all pods in production namespaces.
|
||||||
|
|
||||||
|
**Quick compliance audit commands**:
|
||||||
|
```bash
|
||||||
|
# Find pods without resource limits
|
||||||
|
kubectl get pods -A -o json | jq -r '.items[] | select(.spec.containers[].resources.limits == null) | .metadata.namespace + "/" + .metadata.name'
|
||||||
|
# Find containers running as root
|
||||||
|
kubectl get pods -A -o json | jq -r '.items[] | select(.spec.containers[].securityContext.runAsNonRoot != true) | .metadata.namespace + "/" + .metadata.name'
|
||||||
|
# Find ingress without TLS
|
||||||
|
kubectl get ingress -A -o json | jq -r '.items[] | select(.spec.tls == null) | .metadata.namespace + "/" + .metadata.name'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Automation Patterns
|
||||||
|
|
||||||
|
### Auto-Remediation
|
||||||
|
|
||||||
|
**Restart on OOM (Kubernetes)**:
|
||||||
|
```yaml
|
||||||
|
# Built-in: set resource limits and let K8s handle OOM restarts
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: myapp
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
requests:
|
||||||
|
memory: "256Mi"
|
||||||
|
# Liveness probe: restart if unhealthy
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: 8080
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
**Scale on load (HPA with custom metrics)**:
|
||||||
|
```yaml
|
||||||
|
apiVersion: autoscaling/v2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: order-service
|
||||||
|
spec:
|
||||||
|
scaleTargetRef: { apiVersion: apps/v1, kind: Deployment, name: order-service }
|
||||||
|
minReplicas: 3
|
||||||
|
maxReplicas: 20
|
||||||
|
behavior:
|
||||||
|
scaleUp: { stabilizationWindowSeconds: 60, policies: [{ type: Percent, value: 50, periodSeconds: 60 }] }
|
||||||
|
scaleDown: { stabilizationWindowSeconds: 300, policies: [{ type: Percent, value: 25, periodSeconds: 120 }] }
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource: { name: cpu, target: { type: Utilization, averageUtilization: 70 } }
|
||||||
|
- type: Pods
|
||||||
|
pods: { metric: { name: http_requests_per_second }, target: { type: AverageValue, averageValue: "1000" } }
|
||||||
|
```
|
||||||
|
|
||||||
|
**Rotate secrets on expiry (CronJob)**:
|
||||||
|
|
||||||
|
Use a K8s CronJob (e.g., monthly `"0 2 1 * *"`) with a `secret-rotator` service account that: generates new password -> updates Vault -> alters DB role password -> triggers rolling restart via `kubectl rollout restart`.
|
||||||
|
|
||||||
|
### GitOps Workflow
|
||||||
|
|
||||||
|
**Repository as source of truth**:
|
||||||
|
```
|
||||||
|
infrastructure-repo/
|
||||||
|
|-- apps/
|
||||||
|
| |-- order-service/
|
||||||
|
| | |-- deployment.yaml
|
||||||
|
| | |-- service.yaml
|
||||||
|
| | |-- hpa.yaml
|
||||||
|
| | `-- kustomization.yaml
|
||||||
|
| `-- payment-service/
|
||||||
|
| |-- deployment.yaml
|
||||||
|
| `-- kustomization.yaml
|
||||||
|
|-- base/
|
||||||
|
| |-- namespace.yaml
|
||||||
|
| |-- network-policies.yaml
|
||||||
|
| `-- resource-quotas.yaml
|
||||||
|
`-- overlays/
|
||||||
|
|-- staging/
|
||||||
|
| `-- kustomization.yaml
|
||||||
|
`-- production/
|
||||||
|
`-- kustomization.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
**Reconciliation loop (ArgoCD application)**:
|
||||||
|
```yaml
|
||||||
|
apiVersion: argoproj.io/v1alpha1
|
||||||
|
kind: Application
|
||||||
|
metadata:
|
||||||
|
name: order-service
|
||||||
|
namespace: argocd
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
source:
|
||||||
|
repoURL: https://github.com/org/infrastructure-repo.git
|
||||||
|
targetRevision: main
|
||||||
|
path: apps/order-service
|
||||||
|
destination: { server: "https://kubernetes.default.svc", namespace: production }
|
||||||
|
syncPolicy:
|
||||||
|
automated: { prune: true, selfHeal: true }
|
||||||
|
syncOptions: [CreateNamespace=true]
|
||||||
|
retry: { limit: 3, backoff: { duration: 5s, factor: 2, maxDuration: 3m } }
|
||||||
|
```
|
||||||
|
|
||||||
|
**GitOps deployment flow**:
|
||||||
|
```
|
||||||
|
Developer pushes image tag update to infrastructure-repo
|
||||||
|
|
|
||||||
|
v
|
||||||
|
ArgoCD detects drift between git state and cluster state
|
||||||
|
|
|
||||||
|
v
|
||||||
|
ArgoCD syncs: applies manifests from git to cluster
|
||||||
|
|
|
||||||
|
v
|
||||||
|
Kubernetes rolls out new pods
|
||||||
|
|
|
||||||
|
v
|
||||||
|
ArgoCD verifies health (readiness probes pass)
|
||||||
|
|
|
||||||
|
[HEALTHY] --> Done
|
||||||
|
[DEGRADED] --> ArgoCD marks sync as failed, alerts on-call
|
||||||
|
```
|
||||||
|
|
||||||
|
### Database Backup and Restore
|
||||||
|
|
||||||
|
**Automated backup (PostgreSQL)** -- run via cron `0 */6 * * *`:
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
DB_NAME="production"
|
||||||
|
BACKUP_DIR="/backups/postgres"
|
||||||
|
|
||||||
|
pg_dump -Fc -Z 9 "$DB_NAME" > "${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.dump"
|
||||||
|
aws s3 cp "${BACKUP_DIR}/${DB_NAME}_${TIMESTAMP}.dump" \
|
||||||
|
"s3://backups-bucket/postgres/" --storage-class STANDARD_IA
|
||||||
|
find "$BACKUP_DIR" -name "*.dump" -mtime +30 -delete
|
||||||
|
```
|
||||||
|
|
||||||
|
**Restore procedure**:
|
||||||
|
```bash
|
||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
BACKUP_FILE=$1 # e.g., "production_20250315_060000.dump"
|
||||||
|
RESTORE_DB="production_restore"
|
||||||
|
|
||||||
|
aws s3 cp "s3://backups-bucket/postgres/$BACKUP_FILE" /tmp/restore.dump
|
||||||
|
psql -c "DROP DATABASE IF EXISTS $RESTORE_DB;" && psql -c "CREATE DATABASE $RESTORE_DB;"
|
||||||
|
pg_restore -d "$RESTORE_DB" -j 4 --no-owner /tmp/restore.dump
|
||||||
|
# Verify: check row counts on key tables, then clean up
|
||||||
|
rm /tmp/restore.dump
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disaster Recovery Runbook Template
|
||||||
|
|
||||||
|
**Recovery Objectives**: Define RTO (e.g., 1 hour) and RPO (e.g., 6 hours) per service.
|
||||||
|
|
||||||
|
**Prerequisites**: backup storage access, Terraform state access, DNS management access, stakeholder comms channel.
|
||||||
|
|
||||||
|
| Scenario | Key Steps |
|
||||||
|
|----------|-----------|
|
||||||
|
| **Single service failure** | Check pod status -> restart deployment -> if fails, `kubectl rollout undo` -> verify health |
|
||||||
|
| **Database failure** | `pg_isready` -> promote replica (or restore from backup) -> update connection strings -> verify data integrity |
|
||||||
|
| **Full region outage** | Confirm via provider status page -> notify stakeholders -> switch DNS to DR region -> verify traffic -> failback when primary recovers |
|
||||||
|
|
||||||
|
**Communication template**: Subject `[INCIDENT] Service -- Status`. Body: what happened, impact, current status, ETA, next update time.
|
||||||
|
|
||||||
|
**Post-recovery checklist**: health checks passing, data integrity verified, monitoring restored, backups resumed, incident report filed, post-mortem scheduled within 48h.
|
||||||
@@ -380,6 +380,265 @@ token_consumption = "medium"
|
|||||||
default_active = false
|
default_active = false
|
||||||
activation_warning = "Lead hand runs continuously and generates leads on schedule, consuming tokens."
|
activation_warning = "Lead hand runs continuously and generates leads on schedule, consuming tokens."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "线索生成 Hand"
|
name = "线索生成 Hand"
|
||||||
description = "自主线索生成——按计划发现、充实并交付合格的潜在客户"
|
description = "自主线索生成——按计划发现、充实并交付合格的潜在客户"
|
||||||
|
category = "数据"
|
||||||
|
|
||||||
|
[i18n.zh.settings.target_industry]
|
||||||
|
label = "目标行业"
|
||||||
|
description = "重点关注的行业垂直领域(例如 SaaS、金融科技、医疗健康、电子商务)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.target_role]
|
||||||
|
label = "目标职位"
|
||||||
|
description = "要触达的决策者头衔(例如 CTO、工程副总裁、产品负责人)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.company_size]
|
||||||
|
label = "公司规模"
|
||||||
|
description = "按公司规模筛选线索"
|
||||||
|
|
||||||
|
[i18n.zh.settings.lead_source]
|
||||||
|
label = "线索来源"
|
||||||
|
description = "发现线索的主要方式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.output_format]
|
||||||
|
label = "输出格式"
|
||||||
|
description = "报告交付格式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.leads_per_report]
|
||||||
|
label = "每份报告线索数"
|
||||||
|
description = "每份报告中包含的线索数量"
|
||||||
|
|
||||||
|
[i18n.zh.settings.delivery_schedule]
|
||||||
|
label = "交付计划"
|
||||||
|
description = "生成和交付线索报告的时间安排"
|
||||||
|
|
||||||
|
[i18n.zh.settings.geo_focus]
|
||||||
|
label = "地域重点"
|
||||||
|
description = "优先关注的地理区域(例如美国、欧洲、亚太、全球)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.enrichment_depth]
|
||||||
|
label = "信息丰富度"
|
||||||
|
description = "对每条线索收集多少上下文信息"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "리드 생성 Hand"
|
||||||
|
description = "자율 리드 생성 — 일정에 따라 적격 리드를 탐색, 보강 및 전달"
|
||||||
|
category = "데이터"
|
||||||
|
|
||||||
|
[i18n.ko.settings.target_industry]
|
||||||
|
label = "대상 산업"
|
||||||
|
description = "집중할 산업 분야 (예: SaaS, 핀테크, 헬스케어, 이커머스)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.target_role]
|
||||||
|
label = "대상 직책"
|
||||||
|
description = "타겟할 의사결정자 직함 (예: CTO, 엔지니어링 VP, 프로덕트 총괄)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.company_size]
|
||||||
|
label = "회사 규모"
|
||||||
|
description = "회사 규모별 리드 필터링"
|
||||||
|
|
||||||
|
[i18n.ko.settings.lead_source]
|
||||||
|
label = "리드 소스"
|
||||||
|
description = "리드를 발굴하는 주요 방법"
|
||||||
|
|
||||||
|
[i18n.ko.settings.output_format]
|
||||||
|
label = "출력 형식"
|
||||||
|
description = "보고서 전달 형식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.leads_per_report]
|
||||||
|
label = "보고서당 리드 수"
|
||||||
|
description = "각 보고서에 포함할 리드 수"
|
||||||
|
|
||||||
|
[i18n.ko.settings.delivery_schedule]
|
||||||
|
label = "전달 일정"
|
||||||
|
description = "리드 보고서 생성 및 전달 시간"
|
||||||
|
|
||||||
|
[i18n.ko.settings.geo_focus]
|
||||||
|
label = "지역 중점"
|
||||||
|
description = "우선적으로 집중할 지역 (예: 미국, 유럽, 아시아 태평양, 글로벌)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.enrichment_depth]
|
||||||
|
label = "보강 깊이"
|
||||||
|
description = "리드당 수집할 컨텍스트 정보의 수준"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "リード生成 Hand"
|
||||||
|
description = "自律型リード生成エージェント——スケジュールに基づき見込み客を発見・情報付加・配信"
|
||||||
|
category = "データ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.target_industry]
|
||||||
|
label = "ターゲット業界"
|
||||||
|
description = "注力する業界バーティカル(例: SaaS、フィンテック、ヘルスケア、EC)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.target_role]
|
||||||
|
label = "ターゲット職種"
|
||||||
|
description = "アプローチする意思決定者の肩書き(例: CTO、VP Engineering、プロダクト責任者)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.company_size]
|
||||||
|
label = "企業規模"
|
||||||
|
description = "企業規模でリードをフィルタリング"
|
||||||
|
|
||||||
|
[i18n.ja.settings.lead_source]
|
||||||
|
label = "リードソース"
|
||||||
|
description = "リードを発見する主な方法"
|
||||||
|
|
||||||
|
[i18n.ja.settings.output_format]
|
||||||
|
label = "出力形式"
|
||||||
|
description = "レポートの配信形式"
|
||||||
|
|
||||||
|
[i18n.ja.settings.leads_per_report]
|
||||||
|
label = "レポートあたりのリード数"
|
||||||
|
description = "各レポートに含めるリードの数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.delivery_schedule]
|
||||||
|
label = "配信スケジュール"
|
||||||
|
description = "リードレポートの生成・配信タイミング"
|
||||||
|
|
||||||
|
[i18n.ja.settings.geo_focus]
|
||||||
|
label = "地域フォーカス"
|
||||||
|
description = "優先する地理的リージョン(例: 米国、欧州、APAC、グローバル)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.enrichment_depth]
|
||||||
|
label = "情報付加の深さ"
|
||||||
|
description = "リードごとに収集するコンテキスト情報の量"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Generación de Leads"
|
||||||
|
description = "Generación autónoma de leads — descubre, enriquece y entrega leads cualificados según un calendario"
|
||||||
|
category = "Datos"
|
||||||
|
|
||||||
|
[i18n.es.settings.target_industry]
|
||||||
|
label = "Industria objetivo"
|
||||||
|
description = "Vertical de industria en la que enfocarse (ej. SaaS, fintech, salud, e-commerce)"
|
||||||
|
|
||||||
|
[i18n.es.settings.target_role]
|
||||||
|
label = "Rol objetivo"
|
||||||
|
description = "Títulos de tomadores de decisiones a los que dirigirse (ej. CTO, VP de Ingeniería, Director de Producto)"
|
||||||
|
|
||||||
|
[i18n.es.settings.company_size]
|
||||||
|
label = "Tamaño de empresa"
|
||||||
|
description = "Filtrar leads por tamaño de empresa"
|
||||||
|
|
||||||
|
[i18n.es.settings.lead_source]
|
||||||
|
label = "Fuente de leads"
|
||||||
|
description = "Método principal para descubrir leads"
|
||||||
|
|
||||||
|
[i18n.es.settings.output_format]
|
||||||
|
label = "Formato de salida"
|
||||||
|
description = "Formato de entrega del informe"
|
||||||
|
|
||||||
|
[i18n.es.settings.leads_per_report]
|
||||||
|
label = "Leads por informe"
|
||||||
|
description = "Número de leads a incluir en cada informe"
|
||||||
|
|
||||||
|
[i18n.es.settings.delivery_schedule]
|
||||||
|
label = "Calendario de entrega"
|
||||||
|
description = "Cuándo generar y entregar los informes de leads"
|
||||||
|
|
||||||
|
[i18n.es.settings.geo_focus]
|
||||||
|
label = "Enfoque geográfico"
|
||||||
|
description = "Región geográfica a priorizar (ej. EE.UU., Europa, Asia-Pacífico, global)"
|
||||||
|
|
||||||
|
[i18n.es.settings.enrichment_depth]
|
||||||
|
label = "Profundidad de enriquecimiento"
|
||||||
|
description = "Cuánto contexto recopilar por cada lead"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Génération de Prospects"
|
||||||
|
description = "Génération autonome de prospects — découvre, enrichit et livre des prospects qualifiés selon un calendrier"
|
||||||
|
category = "Données"
|
||||||
|
|
||||||
|
[i18n.fr.settings.target_industry]
|
||||||
|
label = "Secteur cible"
|
||||||
|
description = "Secteur d'activité cible (ex. SaaS, fintech, santé, e-commerce)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.target_role]
|
||||||
|
label = "Poste cible"
|
||||||
|
description = "Titres de décideurs à cibler (ex. CTO, VP Engineering, Directeur Produit)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.company_size]
|
||||||
|
label = "Taille d'entreprise"
|
||||||
|
description = "Filtrer les prospects par taille d'entreprise"
|
||||||
|
|
||||||
|
[i18n.fr.settings.lead_source]
|
||||||
|
label = "Source de prospects"
|
||||||
|
description = "Méthode principale de découverte des prospects"
|
||||||
|
|
||||||
|
[i18n.fr.settings.output_format]
|
||||||
|
label = "Format de sortie"
|
||||||
|
description = "Format de livraison des rapports"
|
||||||
|
|
||||||
|
[i18n.fr.settings.leads_per_report]
|
||||||
|
label = "Prospects par rapport"
|
||||||
|
description = "Nombre de prospects à inclure dans chaque rapport"
|
||||||
|
|
||||||
|
[i18n.fr.settings.delivery_schedule]
|
||||||
|
label = "Calendrier de livraison"
|
||||||
|
description = "Quand générer et livrer les rapports de prospects"
|
||||||
|
|
||||||
|
[i18n.fr.settings.geo_focus]
|
||||||
|
label = "Focus géographique"
|
||||||
|
description = "Région géographique prioritaire (ex. USA, Europe, Asie-Pacifique, Mondial)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.enrichment_depth]
|
||||||
|
label = "Profondeur d'enrichissement"
|
||||||
|
description = "Niveau d'informations contextuelles à collecter par prospect"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Lead-Generierungs-Hand"
|
||||||
|
description = "Autonome Lead-Generierung — entdeckt, bereichert und liefert qualifizierte Leads nach Zeitplan"
|
||||||
|
category = "Daten"
|
||||||
|
|
||||||
|
[i18n.de.settings.target_industry]
|
||||||
|
label = "Zielbranche"
|
||||||
|
description = "Branchenvertikale für den Fokus (z.B. SaaS, Fintech, Gesundheitswesen, E-Commerce)"
|
||||||
|
|
||||||
|
[i18n.de.settings.target_role]
|
||||||
|
label = "Zielposition"
|
||||||
|
description = "Titel der Entscheidungsträger (z.B. CTO, VP Engineering, Produktleiter)"
|
||||||
|
|
||||||
|
[i18n.de.settings.company_size]
|
||||||
|
label = "Unternehmensgröße"
|
||||||
|
description = "Leads nach Unternehmensgröße filtern"
|
||||||
|
|
||||||
|
[i18n.de.settings.lead_source]
|
||||||
|
label = "Lead-Quelle"
|
||||||
|
description = "Primäre Methode zur Lead-Entdeckung"
|
||||||
|
|
||||||
|
[i18n.de.settings.output_format]
|
||||||
|
label = "Ausgabeformat"
|
||||||
|
description = "Berichtslieferformat"
|
||||||
|
|
||||||
|
[i18n.de.settings.leads_per_report]
|
||||||
|
label = "Leads pro Bericht"
|
||||||
|
description = "Anzahl der Leads pro Bericht"
|
||||||
|
|
||||||
|
[i18n.de.settings.delivery_schedule]
|
||||||
|
label = "Lieferzeitplan"
|
||||||
|
description = "Wann Lead-Berichte generiert und geliefert werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.geo_focus]
|
||||||
|
label = "Geografischer Fokus"
|
||||||
|
description = "Priorisierte geografische Region (z.B. USA, Europa, Asien-Pazifik, Global)"
|
||||||
|
|
||||||
|
[i18n.de.settings.enrichment_depth]
|
||||||
|
label = "Anreicherungstiefe"
|
||||||
|
description = "Umfang der pro Lead gesammelten Kontextinformationen"
|
||||||
@@ -62,6 +62,88 @@ site:builtwith.com "[company]"
|
|||||||
7. **News articles** — recent activity, reputation
|
7. **News articles** — recent activity, reputation
|
||||||
8. **Social media** — engagement, company culture
|
8. **Social media** — engagement, company culture
|
||||||
|
|
||||||
|
### Industry-Specific Search Patterns
|
||||||
|
|
||||||
|
#### SaaS / Technology
|
||||||
|
```
|
||||||
|
# Company directories
|
||||||
|
site:g2.com/products "[category]"
|
||||||
|
site:capterra.com "[category] software"
|
||||||
|
site:producthunt.com "[product type]" "[year]"
|
||||||
|
"[category] software" site:crunchbase.com/organization
|
||||||
|
|
||||||
|
# Tech stack signals
|
||||||
|
site:stackshare.io "[technology]" decisions
|
||||||
|
site:builtwith.com/websites/[technology]
|
||||||
|
|
||||||
|
# Growth signals
|
||||||
|
"[company] SOC 2" OR "[company] ISO 27001" — enterprise readiness
|
||||||
|
"[company] API" OR "[company] integration" — platform maturity
|
||||||
|
"[company] case study" OR "[company] customer story" — traction evidence
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Healthcare
|
||||||
|
```
|
||||||
|
# Directories & registries
|
||||||
|
site:healthcareittoday.com "[company]"
|
||||||
|
"digital health companies" site:crunchbase.com
|
||||||
|
"health tech" "[city/state]" site:angellist.co
|
||||||
|
"HIPAA compliant" "[category] software"
|
||||||
|
|
||||||
|
# Regulatory signals
|
||||||
|
"[company] FDA clearance" OR "[company] 510(k)"
|
||||||
|
"[company] HIPAA" OR "[company] HITRUST"
|
||||||
|
"[company] clinical trial" site:clinicaltrials.gov
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Financial Services
|
||||||
|
```
|
||||||
|
# Directories & databases
|
||||||
|
site:fintechmagazine.com "top" "[category]"
|
||||||
|
"fintech companies" "[region]" site:crunchbase.com
|
||||||
|
"banking technology" OR "insurtech" site:cbinsights.com
|
||||||
|
|
||||||
|
# Compliance signals
|
||||||
|
"[company] SOX compliance" OR "[company] PCI DSS"
|
||||||
|
"[company] banking license" OR "[company] money transmitter"
|
||||||
|
"[company] Series [A/B/C]" "fintech"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### E-commerce
|
||||||
|
```
|
||||||
|
# Directories & tools
|
||||||
|
site:apps.shopify.com "[category]"
|
||||||
|
site:store.bigcommerce.com "[category]"
|
||||||
|
"ecommerce brands" "[niche]" site:2pm.com OR site:modernretail.co
|
||||||
|
|
||||||
|
# Revenue signals
|
||||||
|
"[company] GMV" OR "[company] ARR"
|
||||||
|
"[company] warehouse" OR "[company] fulfillment center"
|
||||||
|
"[brand] DTC" OR "[brand] direct to consumer"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Manufacturing
|
||||||
|
```
|
||||||
|
# Directories
|
||||||
|
site:thomasnet.com "[product category]"
|
||||||
|
"manufacturing companies" "[city/state]" site:mfg.com
|
||||||
|
"industrial [category]" site:dnb.com
|
||||||
|
|
||||||
|
# Modernization signals
|
||||||
|
"[company] Industry 4.0" OR "[company] smart factory"
|
||||||
|
"[company] ERP" OR "[company] digital transformation"
|
||||||
|
"[company] ISO 9001" OR "[company] ISO 14001"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Industry Source Quick Reference
|
||||||
|
| Vertical | Primary Directories | Key Signal Keywords |
|
||||||
|
|----------|-------------------|---------------------|
|
||||||
|
| SaaS/Tech | G2, Capterra, ProductHunt, Crunchbase | "API launch", "SOC 2", "Series X" |
|
||||||
|
| Healthcare | HealthcareIT, ClinicalTrials.gov | "HIPAA", "FDA", "clinical trial" |
|
||||||
|
| Financial Services | CBInsights, Crunchbase | "PCI DSS", "banking license", "Series X" |
|
||||||
|
| E-commerce | Shopify App Store, ModernRetail | "GMV", "DTC", "fulfillment" |
|
||||||
|
| Manufacturing | ThomasNet, MFG.com | "Industry 4.0", "ISO 9001", "ERP" |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Lead Enrichment Patterns
|
## Lead Enrichment Patterns
|
||||||
@@ -145,6 +227,63 @@ Accessibility (15 points max):
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Lead Qualification Frameworks
|
||||||
|
|
||||||
|
### BANT Framework
|
||||||
|
|
||||||
|
Use BANT to quickly qualify leads during or after enrichment. Each dimension maps to data you can discover through web research.
|
||||||
|
|
||||||
|
| Dimension | Question | Research Signals |
|
||||||
|
|-----------|----------|-----------------|
|
||||||
|
| **Budget** | Can they afford the solution? | Funding rounds, revenue estimates, job postings for related roles, pricing tier of current tools |
|
||||||
|
| **Authority** | Is this person a decision-maker? | Title seniority (VP+, C-level, Director), reports to CEO/CTO, listed on "Leadership" page |
|
||||||
|
| **Need** | Do they have the problem you solve? | Job postings mentioning the pain point, tech stack gaps, competitor tool usage, complaints on forums |
|
||||||
|
| **Timeline** | Is there urgency to buy? | Contract renewals, compliance deadlines, product launches, recent leadership changes |
|
||||||
|
|
||||||
|
#### BANT Scoring Overlay
|
||||||
|
Apply these modifiers on top of the base lead score:
|
||||||
|
```
|
||||||
|
Budget confirmed (funding, revenue signal): +5
|
||||||
|
Authority confirmed (VP+ or C-level): +5
|
||||||
|
Need confirmed (pain point evidence): +5
|
||||||
|
Timeline confirmed (urgency signal): +5
|
||||||
|
Max bonus: +20
|
||||||
|
```
|
||||||
|
|
||||||
|
### MEDDIC Framework
|
||||||
|
|
||||||
|
Use MEDDIC for complex / enterprise sales qualification where longer deal cycles demand deeper research.
|
||||||
|
|
||||||
|
| Dimension | Definition | What to Look For |
|
||||||
|
|-----------|-----------|-----------------|
|
||||||
|
| **Metrics** | Quantifiable outcomes the buyer cares about | Case studies they publish, KPIs in job postings, analyst reports, earnings calls |
|
||||||
|
| **Economic Buyer** | Person with budget authority to sign | CFO, CEO, VP Finance, or "Head of Procurement" listed on team pages |
|
||||||
|
| **Decision Criteria** | Factors they use to evaluate vendors | RFP documents, vendor comparison blog posts, compliance requirements, review site feedback |
|
||||||
|
| **Decision Process** | Steps from evaluation to purchase | Procurement team presence, legal/compliance review cycles, pilot program mentions |
|
||||||
|
| **Identify Pain** | Specific problems driving the purchase | Support forums, Glassdoor reviews, social media complaints, analyst reports on industry challenges |
|
||||||
|
| **Champion** | Internal advocate for your solution | Conference speakers, blog authors, open-source contributors, people who engage with your content |
|
||||||
|
|
||||||
|
#### MEDDIC Research Checklist
|
||||||
|
```
|
||||||
|
For each enterprise lead, attempt to discover:
|
||||||
|
[ ] At least one quantifiable metric they care about
|
||||||
|
[ ] The economic buyer's name and title
|
||||||
|
[ ] 2+ decision criteria (compliance, performance, price, integration)
|
||||||
|
[ ] Whether they run formal procurement (RFP, committee)
|
||||||
|
[ ] 1+ specific pain point with evidence
|
||||||
|
[ ] A potential internal champion (engaged user, tech advocate)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Choosing Between BANT and MEDDIC
|
||||||
|
| Scenario | Recommended Framework |
|
||||||
|
|----------|----------------------|
|
||||||
|
| SMB / startup targets, short sales cycle | BANT |
|
||||||
|
| Enterprise targets, $100K+ deal size | MEDDIC |
|
||||||
|
| Mixed list with varied company sizes | BANT first pass, MEDDIC for A-grade enterprise leads |
|
||||||
|
| Time-constrained research | BANT (faster to assess) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Deduplication Strategies
|
## Deduplication Strategies
|
||||||
|
|
||||||
### Matching Algorithm
|
### Matching Algorithm
|
||||||
@@ -212,6 +351,166 @@ Name,Title,Company,Company URL,LinkedIn,Industry,Size,Score,Discovered,Notes
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Fintech SaaS Series A/B Companies (50-200 Employees)
|
||||||
|
|
||||||
|
**Objective**: Find 10 SaaS companies in the fintech space with 50-200 employees that recently raised Series A or B.
|
||||||
|
|
||||||
|
#### Step 1 — Define ICP
|
||||||
|
```
|
||||||
|
Industry: Fintech / Financial Technology
|
||||||
|
Company size: 50-200 employees (SMB)
|
||||||
|
Funding stage: Series A or Series B (raised within last 18 months)
|
||||||
|
Geography: United States (primary), UK/EU (secondary)
|
||||||
|
Decision-maker: VP Engineering, CTO, or Head of Product
|
||||||
|
Pain points: Scaling infrastructure, compliance automation, developer tooling
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 2 — Execute Search Queries
|
||||||
|
```
|
||||||
|
# Primary discovery queries
|
||||||
|
"fintech" "series A" OR "series B" site:crunchbase.com/organization
|
||||||
|
"fintech startup" "raised" "$" "2025" OR "2024" site:techcrunch.com
|
||||||
|
site:news.crunchbase.com "fintech" "series A" OR "series B"
|
||||||
|
|
||||||
|
# Employee count validation
|
||||||
|
"fintech" "50" OR "100" OR "150" "employees" site:linkedin.com/company
|
||||||
|
site:builtin.com/companies/fintech "51-200 employees"
|
||||||
|
|
||||||
|
# Growth signals
|
||||||
|
"fintech" hiring "senior engineer" OR "staff engineer" site:linkedin.com/jobs
|
||||||
|
"fintech startup" "SOC 2" OR "PCI DSS" — compliance-ready = selling to banks
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 3 — Enrich and Score Each Lead
|
||||||
|
```
|
||||||
|
For each discovered company, gather:
|
||||||
|
1. Company website → About page → leadership team, employee count
|
||||||
|
2. Crunchbase profile → funding amount, date, investors, total raised
|
||||||
|
3. LinkedIn company page → exact employee count, recent hires
|
||||||
|
4. Job boards → open roles (signals growth and tech stack)
|
||||||
|
5. Press releases → product launches, partnerships, customer wins
|
||||||
|
|
||||||
|
Scoring example for "PayFlow Inc":
|
||||||
|
ICP Match: 25/30 (fintech ✓, 130 employees ✓, US ✓, CTO found ✓, no geography bonus)
|
||||||
|
Growth Signals: 18/20 (Series B $18M ✓, hiring 8 engineers ✓, product launch ✓)
|
||||||
|
Enrichment: 15/20 (LinkedIn ✓, full company data ✓, tech stack ✓, no direct email)
|
||||||
|
Recency: 15/15 (funding announced 3 weeks ago)
|
||||||
|
Accessibility: 10/15 (company contact form, CTO LinkedIn)
|
||||||
|
TOTAL: 83/100 → Grade A
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 4 — Final Output (top 3 of 10)
|
||||||
|
| # | Name | Title | Company | Employees | Funding | Score | Key Signal |
|
||||||
|
|---|------|-------|---------|-----------|---------|-------|------------|
|
||||||
|
| 1 | Sarah Chen | CTO | PayFlow Inc | 130 | Series B, $18M | 83 | Funded 3 weeks ago, hiring 8 engineers |
|
||||||
|
| 2 | Marcus Rivera | VP Engineering | LendStack | 85 | Series A, $12M | 78 | Launched API platform Q4, SOC 2 certified |
|
||||||
|
| 3 | Priya Patel | Head of Product | ComplianceAI | 62 | Series A, $8M | 75 | Hiring product + eng, regulatory focus |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 2: Enterprise AI/ML Decision-Makers
|
||||||
|
|
||||||
|
**Objective**: Identify decision-makers at enterprise companies (500+ employees) that are actively adopting AI/ML tools.
|
||||||
|
|
||||||
|
#### Step 1 — Define ICP
|
||||||
|
```
|
||||||
|
Industry: Any (cross-industry AI adoption)
|
||||||
|
Company size: 500+ employees (Enterprise)
|
||||||
|
Signals: Active AI/ML adoption (hiring, projects, tool procurement)
|
||||||
|
Geography: North America
|
||||||
|
Decision-maker: VP/Director of Data Science, Head of AI/ML, CTO, Chief Data Officer
|
||||||
|
Pain points: ML model deployment, data pipeline scaling, AI governance
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 2 — Execute Search Queries
|
||||||
|
```
|
||||||
|
# Identify companies investing in AI
|
||||||
|
"head of AI" OR "VP data science" OR "chief data officer" hiring site:linkedin.com
|
||||||
|
"[company] machine learning" "team" OR "department" site:linkedin.com/company
|
||||||
|
"AI adoption" OR "ML platform" "enterprise" site:venturebeat.com OR site:techcrunch.com
|
||||||
|
|
||||||
|
# Conference and community signals
|
||||||
|
"speaker" "machine learning" OR "AI" site:neurips.cc OR site:icml.cc
|
||||||
|
"[company] MLOps" OR "[company] AI infrastructure" site:github.com
|
||||||
|
|
||||||
|
# Budget and procurement signals
|
||||||
|
"AI budget" OR "ML tools" RFP site:gov OR site:rfpdb.com
|
||||||
|
"[company] partnership" "AI" OR "machine learning" press release
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 3 — Multi-Source Enrichment
|
||||||
|
```
|
||||||
|
For enterprise targets, cross-reference at least 3 sources per lead:
|
||||||
|
|
||||||
|
Source 1: LinkedIn
|
||||||
|
→ Title confirmation, tenure, reporting structure
|
||||||
|
→ Company employee count, growth rate
|
||||||
|
→ Recent posts about AI/ML topics (champion signal)
|
||||||
|
|
||||||
|
Source 2: Company website + press
|
||||||
|
→ AI/ML team page, published case studies
|
||||||
|
→ Press releases about AI initiatives
|
||||||
|
→ Open positions on careers page
|
||||||
|
|
||||||
|
Source 3: Community / conferences
|
||||||
|
→ Conference talks (NeurIPS, ICML, KDD, MLOps World)
|
||||||
|
→ GitHub contributions (open-source ML projects)
|
||||||
|
→ Blog posts or whitepapers on AI strategy
|
||||||
|
|
||||||
|
MEDDIC qualification pass:
|
||||||
|
Metrics: "Reduced model deployment time by 60%" (from case study)
|
||||||
|
Economic Buyer: Chief Data Officer, reports to CEO
|
||||||
|
Decision Criteria: SOC 2 compliance, on-prem option, Python SDK
|
||||||
|
Decision Process: Procurement committee, 90-day eval period
|
||||||
|
Pain: "Manual ML pipeline taking 3 weeks per model" (job posting)
|
||||||
|
Champion: Sr. ML Engineer who spoke at MLOps World about tooling gaps
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Step 4 — Final Output (top 3)
|
||||||
|
| # | Name | Title | Company | Employees | Score | Qualification |
|
||||||
|
|---|------|-------|---------|-----------|-------|---------------|
|
||||||
|
| 1 | David Kim | Chief Data Officer | GlobalRetail Corp | 3,200 | 91 | MEDDIC 5/6: metrics, buyer, criteria, pain, champion |
|
||||||
|
| 2 | Lisa Zhang | VP Data Science | HealthFirst Systems | 1,800 | 86 | MEDDIC 4/6: buyer, criteria, pain, champion |
|
||||||
|
| 3 | James O'Brien | Director of AI | MegaBank Financial | 12,000 | 80 | MEDDIC 4/6: metrics, buyer, decision process, pain |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 3: Quick-Turn SMB List Build
|
||||||
|
|
||||||
|
**Objective**: Build a 20-lead list of SMB e-commerce brands using Shopify that might need an email marketing tool. Time budget: 30 minutes.
|
||||||
|
|
||||||
|
#### Abbreviated Flow
|
||||||
|
```
|
||||||
|
ICP (quick):
|
||||||
|
Industry: E-commerce / DTC brands
|
||||||
|
Size: 10-100 employees
|
||||||
|
Platform: Shopify
|
||||||
|
Signal: Active store, social media presence, no advanced email tool detected
|
||||||
|
|
||||||
|
Search queries (5 minutes):
|
||||||
|
site:myshopify.com "[niche]"
|
||||||
|
"[niche] brand" "shopify" site:linkedin.com/company
|
||||||
|
site:apps.shopify.com/reviews "[competitor email tool]" — negative reviews = opportunity
|
||||||
|
"DTC brands" "[niche]" "founded 2022" OR "founded 2023"
|
||||||
|
|
||||||
|
Enrichment (15 minutes, per lead):
|
||||||
|
1. Shopify store URL → active? recent products?
|
||||||
|
2. LinkedIn company page → employee count, founded year
|
||||||
|
3. BuiltWith → check for existing email/marketing tools
|
||||||
|
4. Instagram/TikTok → follower count (engagement proxy)
|
||||||
|
|
||||||
|
Scoring (5 minutes):
|
||||||
|
Use simplified scoring: ICP match (40%) + Growth signals (30%) + Reachability (30%)
|
||||||
|
Skip MEDDIC for SMB — use BANT quick-check instead
|
||||||
|
|
||||||
|
Output (5 minutes):
|
||||||
|
Deliver as CSV with columns: Brand, URL, Employees, Platform, Current Email Tool, Score, Contact
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Compliance & Ethics
|
## Compliance & Ethics
|
||||||
|
|
||||||
### DO
|
### DO
|
||||||
@@ -233,3 +532,81 @@ Name,Title,Company,Company URL,LinkedIn,Industry,Size,Score,Discovered,Notes
|
|||||||
- Keep lead data in local files only — never exfiltrate
|
- Keep lead data in local files only — never exfiltrate
|
||||||
- Mark stale leads (>90 days without activity) for review
|
- Mark stale leads (>90 days without activity) for review
|
||||||
- Provide clear data export in all supported formats
|
- Provide clear data export in all supported formats
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Pitfalls
|
||||||
|
|
||||||
|
### 1. Outdated Data
|
||||||
|
**Problem**: Company details change fast — people change jobs, startups pivot, funding info ages.
|
||||||
|
**Mitigation**:
|
||||||
|
- Verify every lead against at least 2 sources, and prefer sources updated within the last 90 days
|
||||||
|
- Flag any data point older than 6 months as "needs re-verification"
|
||||||
|
- Check LinkedIn tenure: if a contact joined their current role <3 months ago, they may not have budget authority yet
|
||||||
|
|
||||||
|
### 2. Over-Relying on a Single Source
|
||||||
|
**Problem**: Crunchbase has gaps in non-US companies. LinkedIn employee counts lag. News articles are biased toward funded companies.
|
||||||
|
**Mitigation**:
|
||||||
|
- Always cross-reference: Crunchbase funding + LinkedIn headcount + company website team page
|
||||||
|
- Use at least 2 sources for employee count (the numbers often diverge by 20-30%)
|
||||||
|
- If a company has zero press coverage, check industry-specific directories rather than discarding it
|
||||||
|
|
||||||
|
### 3. Ignoring Enrichment Quality
|
||||||
|
**Problem**: A lead list with 50 names but only 10 have titles and 5 have company size data is not actionable.
|
||||||
|
**Mitigation**:
|
||||||
|
- Set a minimum enrichment threshold before including a lead (e.g., must have: name + title + company + at least one signal)
|
||||||
|
- Track an "enrichment completeness" percentage per lead
|
||||||
|
- Return to partially-enriched leads in a second pass rather than shipping incomplete data
|
||||||
|
|
||||||
|
### 4. Vanity List Sizes
|
||||||
|
**Problem**: Delivering 100 leads when only 15 are qualified wastes the user's time and erodes trust.
|
||||||
|
**Mitigation**:
|
||||||
|
- Better to deliver 10 A-grade leads than 50 C-grade leads
|
||||||
|
- Always sort by score descending and include a clear recommendation on where to draw the cut-off line
|
||||||
|
- If the target count cannot be met at acceptable quality, say so: "Found 7 leads meeting all criteria; 13 additional leads are partial matches"
|
||||||
|
|
||||||
|
### 5. Confusing Company Name Variants
|
||||||
|
**Problem**: "Stripe, Inc.", "Stripe", and "Stripe Payments Europe Ltd" can appear as three separate leads.
|
||||||
|
**Mitigation**:
|
||||||
|
- Always normalize company names before deduplication (see Normalization Rules above)
|
||||||
|
- Match on website domain as the primary key — it is the most stable identifier
|
||||||
|
- Be especially careful with common words as company names ("Bolt", "Block", "Square")
|
||||||
|
|
||||||
|
### 6. Mistaking Hiring Activity for Purchase Intent
|
||||||
|
**Problem**: A company hiring engineers does not necessarily mean they are buying your product.
|
||||||
|
**Mitigation**:
|
||||||
|
- Hiring is a **growth signal**, not a **purchase signal** — score it accordingly (contributor, not decisive)
|
||||||
|
- Look for more direct signals: RFPs, vendor comparison blog posts, demo requests, event attendance
|
||||||
|
- Combine hiring data with tech stack analysis: hiring a "Salesforce Admin" means Salesforce budget exists
|
||||||
|
|
||||||
|
### 7. Neglecting Negative Signals
|
||||||
|
**Problem**: Focusing only on positive signals and missing red flags.
|
||||||
|
**Mitigation**:
|
||||||
|
- Check for layoffs, lawsuits, or executive departures — these reduce lead quality
|
||||||
|
- A company that just went through a 30% layoff is unlikely to approve new vendor spend
|
||||||
|
- Apply negative score modifiers:
|
||||||
|
```
|
||||||
|
Recent layoffs (>10% headcount): -10
|
||||||
|
Lawsuit / regulatory action: -5
|
||||||
|
Executive turnover (CEO/CTO left): -5
|
||||||
|
Declining web traffic (per SimilarWeb): -3
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8. Skipping the ICP Step
|
||||||
|
**Problem**: Jumping straight into search without a clear ICP produces scattered, low-quality results.
|
||||||
|
**Mitigation**:
|
||||||
|
- Always define the ICP **before** the first search query, even if it takes 5 extra minutes
|
||||||
|
- Write the ICP down explicitly (industry, size, geography, role, pain point, budget signal)
|
||||||
|
- Revisit and tighten the ICP after the first 10 leads if results are too broad
|
||||||
|
|
||||||
|
### Pitfall Severity Quick Reference
|
||||||
|
| Pitfall | Severity | Frequency | Fix Effort |
|
||||||
|
|---------|----------|-----------|------------|
|
||||||
|
| Outdated data | High | Very common | Medium (multi-source verification) |
|
||||||
|
| Single source reliance | High | Common | Low (add 1-2 extra sources) |
|
||||||
|
| Poor enrichment quality | Medium | Common | Medium (set thresholds, second pass) |
|
||||||
|
| Vanity list sizes | Medium | Common | Low (enforce scoring cut-off) |
|
||||||
|
| Company name variants | Medium | Very common | Low (normalize + domain match) |
|
||||||
|
| Hiring != purchase intent | Low | Occasional | Low (adjust scoring weight) |
|
||||||
|
| Ignoring negative signals | High | Common | Medium (add negative modifiers) |
|
||||||
|
| Skipping ICP | High | Occasional | Low (5-minute discipline) |
|
||||||
@@ -394,6 +394,241 @@ frequency = "daily"
|
|||||||
token_consumption = "medium"
|
token_consumption = "medium"
|
||||||
default_active = false
|
default_active = false
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "LinkedIn Hand"
|
name = "LinkedIn Hand"
|
||||||
description = "自主 LinkedIn 管理——个人资料优化、内容创作、人脉拓展和职业互动"
|
description = "自主 LinkedIn 管理——个人资料优化、内容创作、人脉拓展和职业互动"
|
||||||
|
category = "通信"
|
||||||
|
|
||||||
|
[i18n.zh.settings.content_style]
|
||||||
|
label = "内容风格"
|
||||||
|
description = "LinkedIn 帖子的语气和风格"
|
||||||
|
|
||||||
|
[i18n.zh.settings.post_frequency]
|
||||||
|
label = "发布频率"
|
||||||
|
description = "创建和发布内容的频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.content_topics]
|
||||||
|
label = "内容主题"
|
||||||
|
description = "要创作内容的主题(逗号分隔,例如 AI、领导力、创业)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_engage]
|
||||||
|
label = "自动互动"
|
||||||
|
description = "自动对人脉网络中的相关帖子点赞和评论"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "审批模式"
|
||||||
|
description = "将帖子加入队列等待审核,而非直接发布"
|
||||||
|
|
||||||
|
[i18n.zh.settings.hashtag_count]
|
||||||
|
label = "话题标签数量"
|
||||||
|
description = "每篇帖子包含的话题标签数量"
|
||||||
|
|
||||||
|
[i18n.zh.settings.target_audience]
|
||||||
|
label = "目标受众"
|
||||||
|
description = "内容的主要目标受众"
|
||||||
|
|
||||||
|
[i18n.zh.settings.language]
|
||||||
|
label = "语言"
|
||||||
|
description = "帖子和互动使用的语言"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "LinkedIn Hand"
|
||||||
|
description = "自律型LinkedInマネージャー——プロフィール最適化、コンテンツ作成、ネットワーキング、プロフェッショナルエンゲージメント"
|
||||||
|
category = "コミュニケーション"
|
||||||
|
|
||||||
|
[i18n.ja.settings.content_style]
|
||||||
|
label = "コンテンツスタイル"
|
||||||
|
description = "LinkedIn投稿の語調とスタイル"
|
||||||
|
|
||||||
|
[i18n.ja.settings.post_frequency]
|
||||||
|
label = "投稿頻度"
|
||||||
|
description = "コンテンツの作成・投稿の頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.content_topics]
|
||||||
|
label = "コンテンツトピック"
|
||||||
|
description = "作成するコンテンツのトピック(カンマ区切り、例: AI、リーダーシップ、スタートアップ)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_engage]
|
||||||
|
label = "自動エンゲージメント"
|
||||||
|
description = "ネットワーク内の関連投稿に自動でいいねやコメントをする"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "承認モード"
|
||||||
|
description = "投稿を直接公開せず、レビュー用キューに追加する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.hashtag_count]
|
||||||
|
label = "ハッシュタグ数"
|
||||||
|
description = "各投稿に含めるハッシュタグの数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.target_audience]
|
||||||
|
label = "ターゲットオーディエンス"
|
||||||
|
description = "コンテンツの主なターゲット層"
|
||||||
|
|
||||||
|
[i18n.ja.settings.language]
|
||||||
|
label = "言語"
|
||||||
|
description = "投稿とエンゲージメントに使用する言語"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de LinkedIn"
|
||||||
|
description = "Gestor autónomo de LinkedIn — optimización de perfil, creación de contenido, networking y engagement profesional"
|
||||||
|
category = "Comunicación"
|
||||||
|
|
||||||
|
[i18n.es.settings.content_style]
|
||||||
|
label = "Estilo de contenido"
|
||||||
|
description = "Voz y tono para las publicaciones de LinkedIn"
|
||||||
|
|
||||||
|
[i18n.es.settings.post_frequency]
|
||||||
|
label = "Frecuencia de publicación"
|
||||||
|
description = "Con qué frecuencia crear y publicar contenido"
|
||||||
|
|
||||||
|
[i18n.es.settings.content_topics]
|
||||||
|
label = "Temas de contenido"
|
||||||
|
description = "Temas sobre los que crear contenido (separados por comas, ej. IA, liderazgo, startups)"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_engage]
|
||||||
|
label = "Engagement automático"
|
||||||
|
description = "Dar like y comentar automáticamente en publicaciones relevantes de tu red"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Modo de aprobación"
|
||||||
|
description = "Poner publicaciones en cola para revisión en lugar de publicarlas directamente"
|
||||||
|
|
||||||
|
[i18n.es.settings.hashtag_count]
|
||||||
|
label = "Cantidad de hashtags"
|
||||||
|
description = "Número de hashtags a incluir por publicación"
|
||||||
|
|
||||||
|
[i18n.es.settings.target_audience]
|
||||||
|
label = "Audiencia objetivo"
|
||||||
|
description = "Audiencia principal para tu contenido"
|
||||||
|
|
||||||
|
[i18n.es.settings.language]
|
||||||
|
label = "Idioma"
|
||||||
|
description = "Idioma para publicaciones e interacciones"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand LinkedIn"
|
||||||
|
description = "Gestionnaire LinkedIn autonome — optimisation de profil, création de contenu, réseautage et engagement professionnel"
|
||||||
|
category = "Communication"
|
||||||
|
|
||||||
|
[i18n.fr.settings.content_style]
|
||||||
|
label = "Style de contenu"
|
||||||
|
description = "Ton et style pour les publications LinkedIn"
|
||||||
|
|
||||||
|
[i18n.fr.settings.post_frequency]
|
||||||
|
label = "Fréquence de publication"
|
||||||
|
description = "Fréquence de création et de publication de contenu"
|
||||||
|
|
||||||
|
[i18n.fr.settings.content_topics]
|
||||||
|
label = "Sujets de contenu"
|
||||||
|
description = "Sujets sur lesquels créer du contenu (séparés par des virgules, ex. IA, leadership, startups)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_engage]
|
||||||
|
label = "Engagement automatique"
|
||||||
|
description = "Aimer et commenter automatiquement les publications pertinentes de votre réseau"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Mode d'approbation"
|
||||||
|
description = "Mettre les publications en file d'attente pour révision au lieu de les publier directement"
|
||||||
|
|
||||||
|
[i18n.fr.settings.hashtag_count]
|
||||||
|
label = "Nombre de hashtags"
|
||||||
|
description = "Nombre de hashtags à inclure par publication"
|
||||||
|
|
||||||
|
[i18n.fr.settings.target_audience]
|
||||||
|
label = "Public cible"
|
||||||
|
description = "Public principal pour votre contenu"
|
||||||
|
|
||||||
|
[i18n.fr.settings.language]
|
||||||
|
label = "Langue"
|
||||||
|
description = "Langue pour les publications et les interactions"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "LinkedIn-Hand"
|
||||||
|
description = "Autonomer LinkedIn-Manager — Profiloptimierung, Content-Erstellung, Networking und professionelles Engagement"
|
||||||
|
category = "Kommunikation"
|
||||||
|
|
||||||
|
[i18n.de.settings.content_style]
|
||||||
|
label = "Inhaltsstil"
|
||||||
|
description = "Ton und Stil für LinkedIn-Beiträge"
|
||||||
|
|
||||||
|
[i18n.de.settings.post_frequency]
|
||||||
|
label = "Veröffentlichungshäufigkeit"
|
||||||
|
description = "Wie oft Inhalte erstellt und veröffentlicht werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.content_topics]
|
||||||
|
label = "Inhaltsthemen"
|
||||||
|
description = "Themen für die Content-Erstellung (kommagetrennt, z.B. KI, Führung, Startups)"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_engage]
|
||||||
|
label = "Automatisches Engagement"
|
||||||
|
description = "Relevante Beiträge im Netzwerk automatisch liken und kommentieren"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Genehmigungsmodus"
|
||||||
|
description = "Beiträge zur Überprüfung in die Warteschlange stellen, anstatt sie direkt zu veröffentlichen"
|
||||||
|
|
||||||
|
[i18n.de.settings.hashtag_count]
|
||||||
|
label = "Anzahl Hashtags"
|
||||||
|
description = "Anzahl der Hashtags pro Beitrag"
|
||||||
|
|
||||||
|
[i18n.de.settings.target_audience]
|
||||||
|
label = "Zielgruppe"
|
||||||
|
description = "Primäre Zielgruppe für Ihre Inhalte"
|
||||||
|
|
||||||
|
[i18n.de.settings.language]
|
||||||
|
label = "Sprache"
|
||||||
|
description = "Sprache für Beiträge und Interaktionen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "LinkedIn Hand"
|
||||||
|
description = "자율 LinkedIn 관리 — 프로필 최적화, 콘텐츠 제작, 네트워킹 및 전문적 소통"
|
||||||
|
category = "커뮤니케이션"
|
||||||
|
|
||||||
|
[i18n.ko.settings.content_style]
|
||||||
|
label = "콘텐츠 스타일"
|
||||||
|
description = "LinkedIn 게시물의 어조와 스타일"
|
||||||
|
|
||||||
|
[i18n.ko.settings.post_frequency]
|
||||||
|
label = "게시 빈도"
|
||||||
|
description = "콘텐츠를 작성하고 게시하는 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.content_topics]
|
||||||
|
label = "콘텐츠 주제"
|
||||||
|
description = "콘텐츠를 작성할 주제 (쉼표로 구분, 예: AI, 리더십, 스타트업)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_engage]
|
||||||
|
label = "자동 소통"
|
||||||
|
description = "네트워크 내 관련 게시물에 자동으로 좋아요 및 댓글"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "승인 모드"
|
||||||
|
description = "게시물을 직접 게시하지 않고 대기열에 추가하여 검토"
|
||||||
|
|
||||||
|
[i18n.ko.settings.hashtag_count]
|
||||||
|
label = "해시태그 수"
|
||||||
|
description = "게시물당 포함할 해시태그 수"
|
||||||
|
|
||||||
|
[i18n.ko.settings.target_audience]
|
||||||
|
label = "대상 독자"
|
||||||
|
description = "콘텐츠의 주요 대상 독자"
|
||||||
|
|
||||||
|
[i18n.ko.settings.language]
|
||||||
|
label = "언어"
|
||||||
|
description = "게시물 및 소통에 사용하는 언어"
|
||||||
@@ -218,3 +218,753 @@ Before posting any content, classify it:
|
|||||||
- Credit sources and tag collaborators
|
- Credit sources and tag collaborators
|
||||||
- Disclose affiliations when discussing products or services
|
- Disclose affiliations when discussing products or services
|
||||||
- Respect intellectual property and copyright
|
- Respect intellectual property and copyright
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Advanced API Patterns
|
||||||
|
|
||||||
|
### Image Post Creation (Media Upload Flow)
|
||||||
|
|
||||||
|
Posting an image requires a 3-step flow: register upload, upload binary, then create post.
|
||||||
|
|
||||||
|
**Step 1 -- Register the upload**:
|
||||||
|
```bash
|
||||||
|
curl -s -X POST "https://api.linkedin.com/rest/images?action=initializeUpload" \
|
||||||
|
-H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "LinkedIn-Version: 202405" \
|
||||||
|
-d '{
|
||||||
|
"initializeUploadRequest": {
|
||||||
|
"owner": "urn:li:person:MEMBER_ID"
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
Response contains `uploadUrl` and `image` URN (e.g., `urn:li:image:C4E...`).
|
||||||
|
|
||||||
|
**Step 2 -- Upload the binary**:
|
||||||
|
```bash
|
||||||
|
curl -s -X PUT "$UPLOAD_URL" \
|
||||||
|
-H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: image/png" \
|
||||||
|
--data-binary "@/path/to/image.png"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 -- Create post with image**:
|
||||||
|
```bash
|
||||||
|
curl -s -X POST "https://api.linkedin.com/rest/posts" \
|
||||||
|
-H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "LinkedIn-Version: 202405" \
|
||||||
|
-d '{
|
||||||
|
"author": "urn:li:person:MEMBER_ID",
|
||||||
|
"lifecycleState": "PUBLISHED",
|
||||||
|
"commentary": "Check out our Q3 results!",
|
||||||
|
"visibility": "PUBLIC",
|
||||||
|
"distribution": {"feedDistribution": "MAIN_FEED"},
|
||||||
|
"content": {
|
||||||
|
"media": {
|
||||||
|
"id": "urn:li:image:IMAGE_URN",
|
||||||
|
"title": "Q3 Performance Summary"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Document Post Creation (PDF/Carousel)
|
||||||
|
|
||||||
|
LinkedIn "document posts" (carousels) follow the same register-upload-post pattern but use the documents API.
|
||||||
|
|
||||||
|
**Register document upload**:
|
||||||
|
```bash
|
||||||
|
curl -s -X POST "https://api.linkedin.com/rest/documents?action=initializeUpload" \
|
||||||
|
-H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "LinkedIn-Version: 202405" \
|
||||||
|
-d '{
|
||||||
|
"initializeUploadRequest": {
|
||||||
|
"owner": "urn:li:person:MEMBER_ID"
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Upload the PDF and create post** (same pattern as image -- PUT binary, then POST with `content.media.id` set to the document URN).
|
||||||
|
|
||||||
|
### Article Publishing via API
|
||||||
|
|
||||||
|
**Create an article post** (link article hosted externally):
|
||||||
|
```bash
|
||||||
|
curl -s -X POST "https://api.linkedin.com/rest/posts" \
|
||||||
|
-H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "LinkedIn-Version: 202405" \
|
||||||
|
-d '{
|
||||||
|
"author": "urn:li:person:MEMBER_ID",
|
||||||
|
"lifecycleState": "PUBLISHED",
|
||||||
|
"commentary": "I wrote about why most engineering teams get incident response wrong.\n\nKey insight: the 5-minute rule changes everything.",
|
||||||
|
"visibility": "PUBLIC",
|
||||||
|
"distribution": {"feedDistribution": "MAIN_FEED"},
|
||||||
|
"content": {
|
||||||
|
"article": {
|
||||||
|
"source": "https://yourblog.com/incident-response",
|
||||||
|
"title": "The 5-Minute Rule for Incident Response",
|
||||||
|
"description": "A practical framework for engineering teams"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Note**: Article-link posts get reduced reach vs native text posts. Prefer putting links in the first comment.
|
||||||
|
|
||||||
|
### Analytics Endpoints
|
||||||
|
|
||||||
|
**Get post statistics (organic)**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "LinkedIn-Version: 202405" \
|
||||||
|
"https://api.linkedin.com/rest/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:ORG_ID&timeIntervals.timeGranularityType=DAY&timeIntervals.timeRange.start=1704067200000&timeIntervals.timeRange.end=1706745600000"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Get share statistics for a specific post**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "LinkedIn-Version: 202405" \
|
||||||
|
"https://api.linkedin.com/rest/organizationalEntityShareStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:ORG_ID&shares=urn:li:share:SHARE_ID"
|
||||||
|
```
|
||||||
|
|
||||||
|
Response fields:
|
||||||
|
| Field | Description |
|
||||||
|
|-------|-------------|
|
||||||
|
| `totalShareStatistics.impressionCount` | Total times the post appeared in feeds |
|
||||||
|
| `totalShareStatistics.uniqueImpressionsCount` | Unique viewers |
|
||||||
|
| `totalShareStatistics.clickCount` | Total clicks (content + read more) |
|
||||||
|
| `totalShareStatistics.likeCount` | Total likes/reactions |
|
||||||
|
| `totalShareStatistics.commentCount` | Total comments |
|
||||||
|
| `totalShareStatistics.shareCount` | Total reposts |
|
||||||
|
| `totalShareStatistics.engagement` | Engagement rate (decimal) |
|
||||||
|
|
||||||
|
**Get follower statistics** (organization pages):
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $LINKEDIN_ACCESS_TOKEN" \
|
||||||
|
-H "LinkedIn-Version: 202405" \
|
||||||
|
"https://api.linkedin.com/rest/organizationalEntityFollowerStatistics?q=organizationalEntity&organizationalEntity=urn:li:organization:ORG_ID"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Webhook / Notification Patterns
|
||||||
|
|
||||||
|
LinkedIn does not offer real-time webhooks for most events. Use polling instead:
|
||||||
|
|
||||||
|
```
|
||||||
|
Polling strategy:
|
||||||
|
- Post engagement: Poll every 15 minutes for first 4 hours after posting
|
||||||
|
- Mentions/comments: Poll every 5 minutes during engagement_hours
|
||||||
|
- Follower counts: Poll once per day
|
||||||
|
- Analytics: Poll once per day (data lags 24-48 hours)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling and Rate Limit Retry
|
||||||
|
|
||||||
|
```
|
||||||
|
Rate limit response headers:
|
||||||
|
X-RateLimit-Limit: 100
|
||||||
|
X-RateLimit-Remaining: 0
|
||||||
|
X-RateLimit-Reset: 1706745600
|
||||||
|
|
||||||
|
HTTP 429 response:
|
||||||
|
{"status": 429, "message": "Resource level throttle limit..."}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Retry strategy**:
|
||||||
|
```
|
||||||
|
1. On HTTP 429: Read X-RateLimit-Reset header
|
||||||
|
2. Calculate wait_seconds = reset_timestamp - current_timestamp
|
||||||
|
3. Sleep for wait_seconds + 1 (buffer)
|
||||||
|
4. Retry the request (max 3 retries)
|
||||||
|
5. On 3 consecutive 429s: back off for 15 minutes
|
||||||
|
|
||||||
|
On HTTP 5xx (server error):
|
||||||
|
1. Retry with exponential backoff: 1s, 2s, 4s
|
||||||
|
2. Max 3 retries
|
||||||
|
3. Log failure and queue for later retry
|
||||||
|
|
||||||
|
On HTTP 401 (expired token):
|
||||||
|
1. Trigger OAuth 2.0 refresh flow
|
||||||
|
2. Update stored token
|
||||||
|
3. Retry original request once
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Content Calendar Template
|
||||||
|
|
||||||
|
### Monthly Content Planning Framework
|
||||||
|
|
||||||
|
Organize content around weekly themes that rotate through your content pillars.
|
||||||
|
|
||||||
|
```
|
||||||
|
MONTH: [Month Year]
|
||||||
|
THEME ROTATION:
|
||||||
|
Week 1: [Pillar 1 -- e.g., Engineering Leadership]
|
||||||
|
Week 2: [Pillar 2 -- e.g., Industry Trends]
|
||||||
|
Week 3: [Pillar 3 -- e.g., Career Growth]
|
||||||
|
Week 4: [Pillar 1 deep dive OR seasonal/timely topic]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Weekly Content Schedule
|
||||||
|
|
||||||
|
```
|
||||||
|
WEEK OF [DATE] — Theme: [Weekly Theme]
|
||||||
|
|
||||||
|
Monday:
|
||||||
|
- 8:30 AM: [Personal story] tied to weekly theme
|
||||||
|
Format: Hook + narrative + lesson + question
|
||||||
|
Goal: High engagement to start the week
|
||||||
|
|
||||||
|
Tuesday:
|
||||||
|
- 9:00 AM: [Step-by-step guide] or [How-to]
|
||||||
|
Format: Numbered list with tactical advice
|
||||||
|
Goal: Saves and shares (authority building)
|
||||||
|
|
||||||
|
Wednesday:
|
||||||
|
- 8:30 AM: [Data/insight post] with original analysis
|
||||||
|
Format: Stat + context + your take + question
|
||||||
|
Goal: Credibility and thought leadership
|
||||||
|
|
||||||
|
Thursday:
|
||||||
|
- 9:00 AM: [Contrarian take] or [Industry opinion]
|
||||||
|
Format: Bold statement + reasoning + invitation to debate
|
||||||
|
Goal: Comments and discussion (algorithm boost)
|
||||||
|
|
||||||
|
Friday:
|
||||||
|
- 8:00 AM: [Engagement post] — poll, question, or lightweight personal content
|
||||||
|
Format: Short, conversational, easy to respond to
|
||||||
|
Goal: Community building before weekend
|
||||||
|
```
|
||||||
|
|
||||||
|
### Content Mix Ratios
|
||||||
|
|
||||||
|
| Category | % of Posts | Examples |
|
||||||
|
|----------|-----------|----------|
|
||||||
|
| Educational / Value | 40% | How-tos, frameworks, lessons learned |
|
||||||
|
| Personal / Storytelling | 25% | Career stories, failures, reflections |
|
||||||
|
| Engagement / Discussion | 20% | Questions, polls, contrarian takes |
|
||||||
|
| Promotional / Company | 10% | Product launches, hiring, milestones |
|
||||||
|
| Curated / Commentary | 5% | Industry news with your analysis |
|
||||||
|
|
||||||
|
**Rule**: Never let promotional content exceed 15%. LinkedIn penalizes overtly sales-y accounts.
|
||||||
|
|
||||||
|
### Engagement Windows and Response Strategy
|
||||||
|
|
||||||
|
```
|
||||||
|
Post published at 8:30 AM:
|
||||||
|
Minutes 0-15: Reply to EVERY comment immediately (signals activity to algorithm)
|
||||||
|
Minutes 15-60: Reply within 5 minutes of each new comment
|
||||||
|
Hours 1-4: Reply within 30 minutes
|
||||||
|
Hours 4-24: Reply within 2 hours (during business hours)
|
||||||
|
Day 2+: Reply within 24 hours
|
||||||
|
|
||||||
|
First-comment strategy:
|
||||||
|
- Post your own comment within 2 minutes of publishing
|
||||||
|
- Use it for: link to resource, additional context, question to spark discussion
|
||||||
|
- This comment acts as engagement seed
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Analytics & Optimization
|
||||||
|
|
||||||
|
### Key Metrics to Track
|
||||||
|
|
||||||
|
| Metric | Formula | Good Benchmark | Great Benchmark |
|
||||||
|
|--------|---------|----------------|-----------------|
|
||||||
|
| Engagement rate | (reactions + comments + reposts) / impressions | > 2% | > 5% |
|
||||||
|
| Comment rate | comments / impressions | > 0.3% | > 1% |
|
||||||
|
| Follower growth rate | net new followers / total followers per week | > 0.5% | > 2% |
|
||||||
|
| Profile views | weekly profile views trend | Consistent growth | 2x after viral post |
|
||||||
|
| SSI (Social Selling Index) | LinkedIn's built-in score (0-100) | > 50 | > 70 |
|
||||||
|
| Content saves | saves / impressions | > 0.5% | > 2% |
|
||||||
|
| Click-through rate | clicks / impressions | > 1% | > 3% |
|
||||||
|
|
||||||
|
### Engagement Rate Calculation
|
||||||
|
|
||||||
|
```
|
||||||
|
engagement_rate = (reactions + comments + reposts) / impressions * 100
|
||||||
|
|
||||||
|
Example:
|
||||||
|
120 reactions + 35 comments + 8 reposts = 163 engagements
|
||||||
|
163 / 5,200 impressions = 3.13% engagement rate
|
||||||
|
|
||||||
|
Per-post tracking:
|
||||||
|
| Post Date | Topic | Format | Impressions | Eng Rate | Comments |
|
||||||
|
|-----------|-------|--------|-------------|----------|----------|
|
||||||
|
| Mon 03/03 | Leadership | Story | 5,200 | 3.13% | 35 |
|
||||||
|
| Tue 03/04 | AI Tools | How-to | 3,800 | 4.21% | 22 |
|
||||||
|
| Wed 03/05 | Hiring | Data | 2,100 | 2.85% | 12 |
|
||||||
|
```
|
||||||
|
|
||||||
|
### A/B Testing Strategies
|
||||||
|
|
||||||
|
Test one variable at a time across pairs of similar posts:
|
||||||
|
|
||||||
|
| Variable | Option A | Option B | Track |
|
||||||
|
|----------|----------|----------|-------|
|
||||||
|
| Hook style | Question hook | Bold statement hook | Click-through rate |
|
||||||
|
| Post length | Short (< 800 chars) | Long (1200+ chars) | Dwell time, engagement |
|
||||||
|
| Posting time | 8:00 AM | 9:30 AM | Impressions after 4 hours |
|
||||||
|
| CTA type | Question CTA | "Agree? Repost" CTA | Comment rate vs repost rate |
|
||||||
|
| Hashtag count | 3 hashtags | 0 hashtags | Reach beyond network |
|
||||||
|
| Format | Plain text | Text + image | Engagement rate |
|
||||||
|
|
||||||
|
**How to run a test**:
|
||||||
|
1. Pick one variable to test (e.g., posting time)
|
||||||
|
2. Keep everything else constant (same pillar, similar format, similar length)
|
||||||
|
3. Run for 2 weeks (minimum 4 posts per variant)
|
||||||
|
4. Compare average metrics -- ignore outliers
|
||||||
|
5. Adopt the winner and move to next variable
|
||||||
|
|
||||||
|
### Identifying Top-Performing Content Patterns
|
||||||
|
|
||||||
|
After 30+ posts, analyze your data to find patterns:
|
||||||
|
|
||||||
|
```
|
||||||
|
Sort all posts by engagement rate (descending):
|
||||||
|
1. Look at your top 5 posts — what do they share?
|
||||||
|
- Same content pillar?
|
||||||
|
- Same format (story, how-to, contrarian)?
|
||||||
|
- Same hook style?
|
||||||
|
- Similar length range?
|
||||||
|
- Same posting day/time?
|
||||||
|
2. Look at your bottom 5 posts — what went wrong?
|
||||||
|
- External links in body?
|
||||||
|
- Promotional tone?
|
||||||
|
- Published on Friday/weekend?
|
||||||
|
- Weak hook?
|
||||||
|
3. Create your "hit formula":
|
||||||
|
Best combo: [Pillar] + [Format] + [Hook style] + [Day/Time]
|
||||||
|
Example: "Engineering Leadership + Personal Story + Confession Hook + Tuesday 8:30 AM"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Audience Growth Strategies
|
||||||
|
|
||||||
|
### Comment-First Strategy
|
||||||
|
|
||||||
|
The fastest way to grow on LinkedIn is strategic commenting on high-visibility posts.
|
||||||
|
|
||||||
|
**How it works**:
|
||||||
|
1. Identify 15-20 active creators in your niche (10K+ followers)
|
||||||
|
2. Turn on notifications for their posts
|
||||||
|
3. Be among the first 5 comments on their new posts
|
||||||
|
4. Write substantive comments (3-5 sentences) that add genuine value
|
||||||
|
|
||||||
|
**Comment templates for growth**:
|
||||||
|
```
|
||||||
|
Adding a data point:
|
||||||
|
"This resonates. At [Company/Role], we saw [specific metric] when we
|
||||||
|
implemented [related approach]. The key difference was [insight].
|
||||||
|
Curious if others have seen similar results?"
|
||||||
|
|
||||||
|
Respectful counterpoint:
|
||||||
|
"Interesting perspective. I'd push back slightly on [point] — in my
|
||||||
|
experience with [context], the opposite was true because [reason].
|
||||||
|
That said, I think [original point] absolutely holds for [use case]."
|
||||||
|
|
||||||
|
Extending the idea:
|
||||||
|
"Building on this — one thing I'd add is [new angle]. I wrote about
|
||||||
|
this recently and the biggest takeaway was [specific insight].
|
||||||
|
[Question that invites further discussion]?"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Target**: 5-10 thoughtful comments per day during peak hours (8-10 AM).
|
||||||
|
|
||||||
|
### Collaborative Content Patterns
|
||||||
|
|
||||||
|
**Tagging strategy**:
|
||||||
|
- Tag 1-3 people who would genuinely find the content relevant
|
||||||
|
- Always explain WHY you're tagging them (not drive-by tags)
|
||||||
|
- Tag people you've already engaged with (they're more likely to respond)
|
||||||
|
|
||||||
|
```
|
||||||
|
Example post with strategic tags:
|
||||||
|
"I've been thinking about how engineering teams handle on-call rotations.
|
||||||
|
|
||||||
|
After talking to 20+ eng managers, here are the 3 models that actually work:
|
||||||
|
|
||||||
|
1. Follow-the-sun (best for distributed teams)
|
||||||
|
2. Volunteer-first rotation (best for small teams)
|
||||||
|
3. Tiered escalation (best for complex systems)
|
||||||
|
|
||||||
|
@Name1 — your team's approach to #2 was eye-opening.
|
||||||
|
@Name2 — curious if your distributed team uses #1 or something else?
|
||||||
|
|
||||||
|
What model does your team use? Reply with your team size."
|
||||||
|
```
|
||||||
|
|
||||||
|
**Co-creation patterns**:
|
||||||
|
- Interview a peer and post key insights (tag them, they reshare)
|
||||||
|
- "X people I learned from this year" posts (mass tagging, high reshare rate)
|
||||||
|
- Collaborative lists: "Drop your best [resource] in the comments, I'll compile and share"
|
||||||
|
|
||||||
|
### LinkedIn Newsletter Strategy
|
||||||
|
|
||||||
|
Newsletters convert profile visitors into subscribers with direct inbox delivery.
|
||||||
|
|
||||||
|
**Newsletter setup checklist**:
|
||||||
|
```
|
||||||
|
1. Name: Clear, specific, benefit-driven
|
||||||
|
Good: "The Engineering Leader's Playbook"
|
||||||
|
Bad: "My Thoughts on Things"
|
||||||
|
|
||||||
|
2. Cadence: Weekly or biweekly (consistency > frequency)
|
||||||
|
|
||||||
|
3. Format:
|
||||||
|
- 800-1500 words (longer than posts, shorter than blog articles)
|
||||||
|
- One core idea per issue
|
||||||
|
- Actionable takeaways or frameworks
|
||||||
|
- End with a question to drive comments
|
||||||
|
|
||||||
|
4. Promotion:
|
||||||
|
- Announce each issue with a teaser post (don't just auto-share)
|
||||||
|
- Reference newsletter content in regular posts
|
||||||
|
- Cross-promote with other newsletter authors
|
||||||
|
```
|
||||||
|
|
||||||
|
**Newsletter content structure**:
|
||||||
|
```
|
||||||
|
Issue #[N]: [Compelling Title]
|
||||||
|
|
||||||
|
[Hook paragraph -- why this matters NOW]
|
||||||
|
|
||||||
|
[Section 1: The Problem / Context]
|
||||||
|
- 2-3 paragraphs with specific examples
|
||||||
|
|
||||||
|
[Section 2: The Framework / Solution]
|
||||||
|
- Numbered steps or clear model
|
||||||
|
- Real-world application examples
|
||||||
|
|
||||||
|
[Section 3: How to Apply This]
|
||||||
|
- Actionable next steps the reader can take today
|
||||||
|
|
||||||
|
[Closing: Question + CTA]
|
||||||
|
"What's your experience with [topic]? Reply in the comments."
|
||||||
|
"If you found this useful, share it with your team."
|
||||||
|
```
|
||||||
|
|
||||||
|
### LinkedIn Live and Events
|
||||||
|
|
||||||
|
**LinkedIn Live** broadcasts get 7x more reactions and 24x more comments than regular video posts.
|
||||||
|
|
||||||
|
**Live session framework**:
|
||||||
|
```
|
||||||
|
Pre-event (1 week before):
|
||||||
|
- Create LinkedIn Event and post announcement
|
||||||
|
- Send invites to relevant connections
|
||||||
|
- Post 2-3 teaser posts building anticipation
|
||||||
|
|
||||||
|
During event:
|
||||||
|
- Start 2 minutes early for tech check
|
||||||
|
- Open with clear agenda (30 seconds)
|
||||||
|
- Acknowledge live commenters by name
|
||||||
|
- Keep sessions 20-40 minutes
|
||||||
|
|
||||||
|
Post-event:
|
||||||
|
- Post key takeaways within 2 hours
|
||||||
|
- Reply to all comments on the event post
|
||||||
|
- Repurpose recording into 3-5 short clips for future posts
|
||||||
|
```
|
||||||
|
|
||||||
|
**Event types that work**:
|
||||||
|
| Type | Duration | Best For | Frequency |
|
||||||
|
|------|----------|----------|-----------|
|
||||||
|
| AMA (Ask Me Anything) | 30 min | Engagement, authority | Monthly |
|
||||||
|
| Industry deep dive | 20 min | Thought leadership | Biweekly |
|
||||||
|
| Interview / fireside chat | 40 min | Network growth | Monthly |
|
||||||
|
| Quick tip / hot take | 10 min | Visibility | Weekly |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Thought Leadership Campaign
|
||||||
|
|
||||||
|
**Scenario**: VP of Engineering building authority in "engineering culture" niche.
|
||||||
|
|
||||||
|
**Content pillars**:
|
||||||
|
```
|
||||||
|
Pillar 1: Engineering Management (40%)
|
||||||
|
Pillar 2: Scaling Teams (30%)
|
||||||
|
Pillar 3: Career Advice (20%)
|
||||||
|
Pillar 4: Personal Lessons (10%)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Week 1 posting schedule with sample posts**:
|
||||||
|
|
||||||
|
**Monday 8:30 AM -- Personal Story (Pillar 1)**:
|
||||||
|
```
|
||||||
|
I promoted my worst interviewer to Head of Recruiting.
|
||||||
|
|
||||||
|
Sounds crazy. Here's what happened.
|
||||||
|
|
||||||
|
She kept rejecting candidates everyone else loved.
|
||||||
|
Her "pass rate" was 15%. Team average was 60%.
|
||||||
|
|
||||||
|
But after 12 months, something became clear:
|
||||||
|
|
||||||
|
Her hires had:
|
||||||
|
→ 94% retention rate (team avg: 71%)
|
||||||
|
→ 2.3x faster time to first meaningful contribution
|
||||||
|
→ Zero PIPs in their first year
|
||||||
|
|
||||||
|
She wasn't a bad interviewer.
|
||||||
|
She was the only one actually doing it right.
|
||||||
|
|
||||||
|
The lesson?
|
||||||
|
Measure what matters. Pass rates reward speed.
|
||||||
|
Retention rates reward judgment.
|
||||||
|
|
||||||
|
What's one metric your team optimizes for
|
||||||
|
that might be the wrong one?
|
||||||
|
|
||||||
|
#EngineeringLeadership #Hiring #TechManagement
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tuesday 9:00 AM -- How-To Guide (Pillar 2)**:
|
||||||
|
```
|
||||||
|
How to run a team retrospective that people actually enjoy
|
||||||
|
(not the soul-crushing ones everyone dreads):
|
||||||
|
|
||||||
|
Step 1: Kill the "what went well / what didn't" format
|
||||||
|
→ Use "I wish... I wonder... I'm proud of..." instead
|
||||||
|
|
||||||
|
Step 2: Timebox ruthlessly
|
||||||
|
→ 45 minutes max. If it takes longer, your team is too big for one retro.
|
||||||
|
|
||||||
|
Step 3: One action item per person, max
|
||||||
|
→ A retro with 20 action items produces zero change.
|
||||||
|
→ One item per person = accountability.
|
||||||
|
|
||||||
|
Step 4: Start with appreciation
|
||||||
|
→ First 5 minutes: each person thanks someone else on the team.
|
||||||
|
→ This changes the entire energy of the room.
|
||||||
|
|
||||||
|
Step 5: Rotate the facilitator
|
||||||
|
→ The manager should NOT always run retros.
|
||||||
|
→ It changes what people feel safe saying.
|
||||||
|
|
||||||
|
I've used this format with teams of 5 to teams of 50.
|
||||||
|
|
||||||
|
What's your retro format? Drop it below --
|
||||||
|
I'm always looking for new approaches.
|
||||||
|
|
||||||
|
#Agile #EngineeringCulture #TeamManagement
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wednesday 8:30 AM -- Data + Insight (Pillar 2)**:
|
||||||
|
```
|
||||||
|
We tracked every engineering team meeting for 6 months.
|
||||||
|
|
||||||
|
The data was uncomfortable.
|
||||||
|
|
||||||
|
→ Average engineer: 11.2 hours/week in meetings
|
||||||
|
→ Senior engineers: 16.4 hours/week
|
||||||
|
→ Time spent in meetings that could've been async: 62%
|
||||||
|
|
||||||
|
We cut 40% of recurring meetings.
|
||||||
|
|
||||||
|
Result after 3 months:
|
||||||
|
→ Sprint velocity: +23%
|
||||||
|
→ Engineer satisfaction: +31% (internal survey)
|
||||||
|
→ "Deep work" blocks per week: 2.1 → 4.7
|
||||||
|
|
||||||
|
The surprising part?
|
||||||
|
Nobody missed the deleted meetings.
|
||||||
|
Not one person asked to bring them back.
|
||||||
|
|
||||||
|
If you haven't audited your meeting load recently,
|
||||||
|
you're probably burning 30-40% of your team's capacity.
|
||||||
|
|
||||||
|
What % of your meetings could be an async update?
|
||||||
|
|
||||||
|
#Engineering #Productivity #Leadership
|
||||||
|
```
|
||||||
|
|
||||||
|
**Thursday 9:00 AM -- Contrarian Take (Pillar 3)**:
|
||||||
|
```
|
||||||
|
Unpopular opinion: "Culture fit" interviews should be illegal.
|
||||||
|
|
||||||
|
Here's why:
|
||||||
|
|
||||||
|
Culture fit = "do I want to get a beer with this person?"
|
||||||
|
That's not hiring. That's friend-making.
|
||||||
|
|
||||||
|
What actually matters:
|
||||||
|
→ Values alignment (do they care about the same outcomes?)
|
||||||
|
→ Working style compatibility (async vs sync, docs vs meetings)
|
||||||
|
→ Growth trajectory (will they push the team forward?)
|
||||||
|
|
||||||
|
None of those require "fitting in."
|
||||||
|
|
||||||
|
The best hire I ever made was someone who challenged
|
||||||
|
every assumption we had. They didn't "fit" our culture.
|
||||||
|
|
||||||
|
They made it better.
|
||||||
|
|
||||||
|
Replace "culture fit" with "culture add."
|
||||||
|
|
||||||
|
Agree or disagree? I'd love to hear your take.
|
||||||
|
|
||||||
|
#Hiring #Diversity #EngineeringCulture #Leadership
|
||||||
|
```
|
||||||
|
|
||||||
|
**Friday 8:00 AM -- Engagement Post (Pillar 4)**:
|
||||||
|
```
|
||||||
|
Fill in the blank:
|
||||||
|
|
||||||
|
"The best career advice I ever received was ___________."
|
||||||
|
|
||||||
|
I'll go first:
|
||||||
|
|
||||||
|
"Stop optimizing for your next promotion.
|
||||||
|
Start optimizing for your next learning curve."
|
||||||
|
|
||||||
|
Changed how I made every career decision since.
|
||||||
|
|
||||||
|
Your turn.
|
||||||
|
|
||||||
|
#CareerAdvice #ProfessionalGrowth
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Company Page Management
|
||||||
|
|
||||||
|
**Scenario**: B2B SaaS company (Series B, 80 employees) managing their LinkedIn company page.
|
||||||
|
|
||||||
|
**Posting cadence**:
|
||||||
|
```
|
||||||
|
Company page: 4-5 posts per week
|
||||||
|
Employee advocacy: 2-3 employees reshare/post per week
|
||||||
|
Executive accounts: CEO + CTO post 2-3x/week each
|
||||||
|
```
|
||||||
|
|
||||||
|
**Weekly company page schedule**:
|
||||||
|
```
|
||||||
|
Monday: Industry insight or thought leadership (educational)
|
||||||
|
Tuesday: Product tip or customer use case (value-driven)
|
||||||
|
Wednesday: Team/culture spotlight (employer branding)
|
||||||
|
Thursday: Data or trend analysis (authority)
|
||||||
|
Friday: Milestone, hiring, or community post (engagement)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Sample company page posts**:
|
||||||
|
|
||||||
|
**Tuesday -- Customer Use Case**:
|
||||||
|
```
|
||||||
|
"We used to spend 3 hours every Monday pulling reports manually."
|
||||||
|
|
||||||
|
That's what @CustomerName's ops team told us last quarter.
|
||||||
|
|
||||||
|
After switching to [Product] automated workflows:
|
||||||
|
→ Report generation: 3 hours → 12 minutes
|
||||||
|
→ Data accuracy: 89% → 99.7%
|
||||||
|
→ Team freed up: 12 hours/week for strategic work
|
||||||
|
|
||||||
|
The best part? They set it up in a single afternoon.
|
||||||
|
|
||||||
|
Read the full story: [link in first comment]
|
||||||
|
|
||||||
|
#DataAutomation #Operations #CustomerSuccess
|
||||||
|
```
|
||||||
|
|
||||||
|
**Wednesday -- Team Culture Spotlight**:
|
||||||
|
```
|
||||||
|
This is Sarah. She joined us as intern #3 two years ago.
|
||||||
|
|
||||||
|
Last week she deployed our new ML pipeline to production.
|
||||||
|
By herself. On a Tuesday. No drama.
|
||||||
|
|
||||||
|
What happened in between:
|
||||||
|
→ Mentored by 4 different senior engineers
|
||||||
|
→ Shipped 47 PRs in her first year
|
||||||
|
→ Gave her first conference talk at 23
|
||||||
|
→ Now leads a team of 3
|
||||||
|
|
||||||
|
We don't hire for credentials.
|
||||||
|
We hire for curiosity and grit.
|
||||||
|
|
||||||
|
Sarah had both.
|
||||||
|
|
||||||
|
We're hiring 5 more engineers just like her.
|
||||||
|
Link in the comments.
|
||||||
|
|
||||||
|
#Hiring #Engineering #StartupCulture #WomenInTech
|
||||||
|
```
|
||||||
|
|
||||||
|
**Employee advocacy tracking**:
|
||||||
|
```
|
||||||
|
| Employee | Role | Posts/Week | Avg Reach | Topics |
|
||||||
|
|----------|------|-----------|-----------|--------|
|
||||||
|
| CEO | Executive | 3 | 8,500 | Vision, industry, leadership |
|
||||||
|
| CTO | Executive | 2 | 5,200 | Technical, architecture, hiring |
|
||||||
|
| VP Eng | Leader | 2 | 3,100 | Engineering culture, management |
|
||||||
|
| DevRel | IC | 3 | 4,800 | Tutorials, product, community |
|
||||||
|
```
|
||||||
|
|
||||||
|
**Analytics tracking cadence**:
|
||||||
|
```
|
||||||
|
Daily: Check post-level engagement (reactions, comments, shares)
|
||||||
|
Weekly: Follower growth, top-performing post, engagement rate trend
|
||||||
|
Monthly: Content audit — which pillars/formats performed best
|
||||||
|
Adjust next month's content mix based on data
|
||||||
|
Quarterly: Competitor benchmarking, SSI review, strategy refresh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3: Job Seeker Profile Optimization Campaign
|
||||||
|
|
||||||
|
**Scenario**: Senior developer transitioning to engineering management role.
|
||||||
|
|
||||||
|
**4-week content plan**:
|
||||||
|
```
|
||||||
|
Week 1: Establish expertise
|
||||||
|
- Post about a technical decision you led and its business impact
|
||||||
|
- Share a "lessons from my first year managing" story
|
||||||
|
- Comment on 10 engineering leadership posts
|
||||||
|
|
||||||
|
Week 2: Demonstrate thought leadership
|
||||||
|
- Publish a how-to post: "How I transitioned from IC to manager"
|
||||||
|
- Share data or a framework you've developed
|
||||||
|
- Start engaging with hiring managers' content in target companies
|
||||||
|
|
||||||
|
Week 3: Build social proof
|
||||||
|
- Post about a mentoring success story (tag the mentee with permission)
|
||||||
|
- Share a "things I wish I knew" post targeting new managers
|
||||||
|
- Request 3-5 recommendations from colleagues and reports
|
||||||
|
|
||||||
|
Week 4: Signal availability
|
||||||
|
- Post about what you're looking for (without desperation)
|
||||||
|
- Engage heavily in target company employees' content
|
||||||
|
- Send personalized connection requests to hiring managers
|
||||||
|
```
|
||||||
|
|
||||||
|
**Sample "open to opportunities" post**:
|
||||||
|
```
|
||||||
|
After 8 years of writing code and 2 years of leading teams,
|
||||||
|
I'm looking for my next engineering management challenge.
|
||||||
|
|
||||||
|
What I bring to the table:
|
||||||
|
→ Scaled a team from 4 to 22 engineers
|
||||||
|
→ Reduced deployment failures by 73% through better process
|
||||||
|
→ Mentored 6 engineers into senior roles
|
||||||
|
→ Built hiring pipelines that maintained 85%+ offer acceptance
|
||||||
|
|
||||||
|
What I'm looking for:
|
||||||
|
→ Series A-C company building something meaningful
|
||||||
|
→ Team of 8-20 engineers who care about craft
|
||||||
|
→ Leadership that values engineering culture, not just velocity
|
||||||
|
|
||||||
|
If your team is growing and you value
|
||||||
|
managers who still understand the code --
|
||||||
|
I'd love to chat.
|
||||||
|
|
||||||
|
DMs are open. Or drop a comment and I'll reach out.
|
||||||
|
|
||||||
|
#OpenToWork #EngineeringManager #Hiring #Leadership
|
||||||
|
```
|
||||||
@@ -425,6 +425,241 @@ token_consumption = "high"
|
|||||||
default_active = false
|
default_active = false
|
||||||
activation_warning = "Predictor hand runs continuously and generates predictions, consuming tokens."
|
activation_warning = "Predictor hand runs continuously and generates predictions, consuming tokens."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "预测 Hand"
|
name = "预测 Hand"
|
||||||
description = "自主预测智能体——收集信号、构建推理链、做出校准预测并追踪准确度"
|
description = "自主预测智能体——收集信号、构建推理链、做出校准预测并追踪准确度"
|
||||||
|
category = "数据"
|
||||||
|
|
||||||
|
[i18n.zh.settings.prediction_domain]
|
||||||
|
label = "预测领域"
|
||||||
|
description = "预测的主要关注领域"
|
||||||
|
|
||||||
|
[i18n.zh.settings.time_horizon]
|
||||||
|
label = "时间跨度"
|
||||||
|
description = "预测的前瞻时间范围"
|
||||||
|
|
||||||
|
[i18n.zh.settings.data_sources]
|
||||||
|
label = "数据来源"
|
||||||
|
description = "监控信号的来源类型"
|
||||||
|
|
||||||
|
[i18n.zh.settings.report_frequency]
|
||||||
|
label = "报告频率"
|
||||||
|
description = "生成预测报告的频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.predictions_per_report]
|
||||||
|
label = "每份报告预测数"
|
||||||
|
description = "每份报告包含的预测条目数量"
|
||||||
|
|
||||||
|
[i18n.zh.settings.track_accuracy]
|
||||||
|
label = "追踪准确度"
|
||||||
|
description = "在预测时间窗口到期后对历史预测进行评分"
|
||||||
|
|
||||||
|
[i18n.zh.settings.confidence_threshold]
|
||||||
|
label = "置信度阈值"
|
||||||
|
description = "纳入预测报告的最低置信度"
|
||||||
|
|
||||||
|
[i18n.zh.settings.contrarian_mode]
|
||||||
|
label = "逆向思维模式"
|
||||||
|
description = "主动寻找并展示与主流共识相反的预测"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "予測 Hand"
|
||||||
|
description = "自律型予測エージェント——シグナル収集、推論チェーン構築、キャリブレーション済み予測、精度追跡"
|
||||||
|
category = "データ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.prediction_domain]
|
||||||
|
label = "予測ドメイン"
|
||||||
|
description = "予測の主な対象分野"
|
||||||
|
|
||||||
|
[i18n.ja.settings.time_horizon]
|
||||||
|
label = "予測期間"
|
||||||
|
description = "どのくらい先まで予測するか"
|
||||||
|
|
||||||
|
[i18n.ja.settings.data_sources]
|
||||||
|
label = "データソース"
|
||||||
|
description = "シグナルを監視するソースの種類"
|
||||||
|
|
||||||
|
[i18n.ja.settings.report_frequency]
|
||||||
|
label = "レポート頻度"
|
||||||
|
description = "予測レポートの生成頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.predictions_per_report]
|
||||||
|
label = "レポートあたりの予測数"
|
||||||
|
description = "各レポートに含める予測項目の数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.track_accuracy]
|
||||||
|
label = "精度追跡"
|
||||||
|
description = "予測期間が終了した過去の予測にスコアを付ける"
|
||||||
|
|
||||||
|
[i18n.ja.settings.confidence_threshold]
|
||||||
|
label = "信頼度しきい値"
|
||||||
|
description = "予測をレポートに含めるための最低信頼度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.contrarian_mode]
|
||||||
|
label = "逆張りモード"
|
||||||
|
description = "コンセンサスに反する予測を積極的に探索・提示する"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Predicciones"
|
||||||
|
description = "Predictor autónomo del futuro — recopila señales, construye cadenas de razonamiento, genera predicciones calibradas y rastrea la precisión"
|
||||||
|
category = "Datos"
|
||||||
|
|
||||||
|
[i18n.es.settings.prediction_domain]
|
||||||
|
label = "Dominio de predicción"
|
||||||
|
description = "Dominio principal para las predicciones"
|
||||||
|
|
||||||
|
[i18n.es.settings.time_horizon]
|
||||||
|
label = "Horizonte temporal"
|
||||||
|
description = "Qué tan lejos en el futuro predecir"
|
||||||
|
|
||||||
|
[i18n.es.settings.data_sources]
|
||||||
|
label = "Fuentes de datos"
|
||||||
|
description = "Qué tipos de fuentes monitorear para señales"
|
||||||
|
|
||||||
|
[i18n.es.settings.report_frequency]
|
||||||
|
label = "Frecuencia de informes"
|
||||||
|
description = "Con qué frecuencia generar informes de predicción"
|
||||||
|
|
||||||
|
[i18n.es.settings.predictions_per_report]
|
||||||
|
label = "Predicciones por informe"
|
||||||
|
description = "Número de predicciones a incluir por informe"
|
||||||
|
|
||||||
|
[i18n.es.settings.track_accuracy]
|
||||||
|
label = "Rastrear precisión"
|
||||||
|
description = "Puntuar predicciones pasadas cuando su horizonte temporal expire"
|
||||||
|
|
||||||
|
[i18n.es.settings.confidence_threshold]
|
||||||
|
label = "Umbral de confianza"
|
||||||
|
description = "Confianza mínima para incluir una predicción"
|
||||||
|
|
||||||
|
[i18n.es.settings.contrarian_mode]
|
||||||
|
label = "Modo contrario"
|
||||||
|
description = "Buscar y presentar activamente predicciones contrarias al consenso"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand de Prédictions"
|
||||||
|
description = "Prédicteur autonome — collecte de signaux, construction de chaînes de raisonnement, prédictions calibrées et suivi de la précision"
|
||||||
|
category = "Données"
|
||||||
|
|
||||||
|
[i18n.fr.settings.prediction_domain]
|
||||||
|
label = "Domaine de prédiction"
|
||||||
|
description = "Domaine principal pour les prédictions"
|
||||||
|
|
||||||
|
[i18n.fr.settings.time_horizon]
|
||||||
|
label = "Horizon temporel"
|
||||||
|
description = "Jusqu'où prédire dans le futur"
|
||||||
|
|
||||||
|
[i18n.fr.settings.data_sources]
|
||||||
|
label = "Sources de données"
|
||||||
|
description = "Types de sources à surveiller pour les signaux"
|
||||||
|
|
||||||
|
[i18n.fr.settings.report_frequency]
|
||||||
|
label = "Fréquence des rapports"
|
||||||
|
description = "Fréquence de génération des rapports de prédiction"
|
||||||
|
|
||||||
|
[i18n.fr.settings.predictions_per_report]
|
||||||
|
label = "Prédictions par rapport"
|
||||||
|
description = "Nombre de prédictions à inclure par rapport"
|
||||||
|
|
||||||
|
[i18n.fr.settings.track_accuracy]
|
||||||
|
label = "Suivi de la précision"
|
||||||
|
description = "Évaluer les prédictions passées lorsque leur horizon temporel expire"
|
||||||
|
|
||||||
|
[i18n.fr.settings.confidence_threshold]
|
||||||
|
label = "Seuil de confiance"
|
||||||
|
description = "Confiance minimale pour inclure une prédiction"
|
||||||
|
|
||||||
|
[i18n.fr.settings.contrarian_mode]
|
||||||
|
label = "Mode contraire"
|
||||||
|
description = "Rechercher et présenter activement des prédictions contraires au consensus"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Vorhersage-Hand"
|
||||||
|
description = "Autonomer Vorhersage-Agent — Signalerfassung, Aufbau von Argumentationsketten, kalibrierte Vorhersagen und Genauigkeitsverfolgung"
|
||||||
|
category = "Daten"
|
||||||
|
|
||||||
|
[i18n.de.settings.prediction_domain]
|
||||||
|
label = "Vorhersagedomäne"
|
||||||
|
description = "Hauptdomäne für Vorhersagen"
|
||||||
|
|
||||||
|
[i18n.de.settings.time_horizon]
|
||||||
|
label = "Zeithorizont"
|
||||||
|
description = "Wie weit in die Zukunft vorhergesagt werden soll"
|
||||||
|
|
||||||
|
[i18n.de.settings.data_sources]
|
||||||
|
label = "Datenquellen"
|
||||||
|
description = "Welche Quellentypen auf Signale überwacht werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.report_frequency]
|
||||||
|
label = "Berichtshäufigkeit"
|
||||||
|
description = "Wie oft Vorhersageberichte generiert werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.predictions_per_report]
|
||||||
|
label = "Vorhersagen pro Bericht"
|
||||||
|
description = "Anzahl der Vorhersagen pro Bericht"
|
||||||
|
|
||||||
|
[i18n.de.settings.track_accuracy]
|
||||||
|
label = "Genauigkeitsverfolgung"
|
||||||
|
description = "Vergangene Vorhersagen bewerten, wenn ihr Zeithorizont abläuft"
|
||||||
|
|
||||||
|
[i18n.de.settings.confidence_threshold]
|
||||||
|
label = "Konfidenzschwelle"
|
||||||
|
description = "Mindestvertrauen für die Aufnahme einer Vorhersage"
|
||||||
|
|
||||||
|
[i18n.de.settings.contrarian_mode]
|
||||||
|
label = "Konträrer Modus"
|
||||||
|
description = "Aktiv nach Vorhersagen suchen und präsentieren, die dem Konsens widersprechen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "예측 Hand"
|
||||||
|
description = "자율 미래 예측 에이전트 — 신호 수집, 추론 체인 구축, 보정된 예측 수행 및 정확도 추적"
|
||||||
|
category = "데이터"
|
||||||
|
|
||||||
|
[i18n.ko.settings.prediction_domain]
|
||||||
|
label = "예측 분야"
|
||||||
|
description = "예측의 주요 관심 분야"
|
||||||
|
|
||||||
|
[i18n.ko.settings.time_horizon]
|
||||||
|
label = "시간 범위"
|
||||||
|
description = "예측의 미래 전망 기간"
|
||||||
|
|
||||||
|
[i18n.ko.settings.data_sources]
|
||||||
|
label = "데이터 소스"
|
||||||
|
description = "신호를 모니터링할 소스 유형"
|
||||||
|
|
||||||
|
[i18n.ko.settings.report_frequency]
|
||||||
|
label = "보고서 빈도"
|
||||||
|
description = "예측 보고서 생성 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.predictions_per_report]
|
||||||
|
label = "보고서당 예측 수"
|
||||||
|
description = "각 보고서에 포함할 예측 항목 수"
|
||||||
|
|
||||||
|
[i18n.ko.settings.track_accuracy]
|
||||||
|
label = "정확도 추적"
|
||||||
|
description = "예측 기간 만료 후 과거 예측에 대한 점수 평가"
|
||||||
|
|
||||||
|
[i18n.ko.settings.confidence_threshold]
|
||||||
|
label = "신뢰도 임계값"
|
||||||
|
description = "예측 보고서에 포함하기 위한 최소 신뢰도"
|
||||||
|
|
||||||
|
[i18n.ko.settings.contrarian_mode]
|
||||||
|
label = "역발상 모드"
|
||||||
|
description = "주류 컨센서스에 반하는 예측을 적극적으로 탐색하고 제시"
|
||||||
@@ -184,6 +184,591 @@ PREDICTION: [Specific, falsifiable claim]
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Corporate Acquisition
|
||||||
|
|
||||||
|
**Question**: "Will Acme Corp be acquired within 12 months?" (asked January 2025)
|
||||||
|
|
||||||
|
```
|
||||||
|
PREDICTION: Acme Corp (mid-cap SaaS, $2B market cap) will be acquired by January 2026
|
||||||
|
|
||||||
|
1. REFERENCE CLASS (Outside View)
|
||||||
|
Base rate: ~5-7% of publicly traded mid-cap SaaS companies receive
|
||||||
|
acquisition offers in any given 12-month period.
|
||||||
|
Reference examples:
|
||||||
|
- Splunk acquired by Cisco (2023) — similar scale, strategic buyer
|
||||||
|
- Figma attempted acquisition by Adobe (2022) — regulatory block
|
||||||
|
- Nuance acquired by Microsoft (2021) — vertical SaaS, strategic fit
|
||||||
|
- Mandiant acquired by Google (2022) — security vertical
|
||||||
|
- Cvent acquired by Blackstone (2021) — PE buyout at depressed valuation
|
||||||
|
|
||||||
|
Starting probability: 6%
|
||||||
|
|
||||||
|
2. SPECIFIC EVIDENCE (Inside View)
|
||||||
|
Signals FOR (+):
|
||||||
|
a. Board hired Goldman Sachs as advisor (leaked filing)
|
||||||
|
— strength: STRONG — adjustment: +20%
|
||||||
|
(Companies that retain M&A advisors complete a transaction ~40% of the time)
|
||||||
|
b. CEO sold 30% of personal holdings in Q4 (SEC filing)
|
||||||
|
— strength: MODERATE — adjustment: +5%
|
||||||
|
c. Two major competitors acquired in past 18 months (market consolidation)
|
||||||
|
— strength: MODERATE — adjustment: +8%
|
||||||
|
d. Revenue growth decelerated from 35% to 18% YoY (earnings report)
|
||||||
|
— strength: MODERATE — adjustment: +5%
|
||||||
|
(Slower-growth companies more likely to accept acquisition offers)
|
||||||
|
|
||||||
|
Signals AGAINST (-):
|
||||||
|
a. Founder still holds 25% voting control and has said "we're building for
|
||||||
|
the long term" (recent interview)
|
||||||
|
— strength: STRONG — adjustment: -12%
|
||||||
|
b. Stock price at all-time high — acquirer must pay steep premium
|
||||||
|
— strength: MODERATE — adjustment: -5%
|
||||||
|
c. Current antitrust environment — FTC blocking more deals
|
||||||
|
— strength: WEAK — adjustment: -3%
|
||||||
|
|
||||||
|
3. SYNTHESIS
|
||||||
|
Starting probability (base rate): 6%
|
||||||
|
Signals for: +20% +5% +8% +5% = +38%
|
||||||
|
Signals against: -12% -5% -3% = -20%
|
||||||
|
Net adjustment: +18%
|
||||||
|
Raw probability: 24%
|
||||||
|
|
||||||
|
Sanity check: ~1 in 4 feels right given the strong M&A advisor signal
|
||||||
|
balanced against founder control.
|
||||||
|
Final probability: 25%
|
||||||
|
|
||||||
|
4. KEY ASSUMPTIONS
|
||||||
|
- Goldman engagement is for M&A (not debt restructuring):
|
||||||
|
If wrong, probability drops to 8%
|
||||||
|
- Founder is willing to sell at the right price:
|
||||||
|
If wrong (founder vetoes any deal), probability drops to 3%
|
||||||
|
- Regulatory environment doesn't tighten further:
|
||||||
|
If wrong, probability drops to 18%
|
||||||
|
|
||||||
|
5. RESOLUTION
|
||||||
|
Date: January 31, 2026
|
||||||
|
Criteria: Definitive merger agreement announced (not just rumors)
|
||||||
|
Data source: SEC EDGAR (8-K filing), Bloomberg terminal
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Technology Adoption
|
||||||
|
|
||||||
|
**Question**: "Will WebAssembly (Wasm) reach mainstream server-side adoption by 2027?"
|
||||||
|
|
||||||
|
```
|
||||||
|
PREDICTION: >20% of new cloud-deployed services will use Wasm runtimes by
|
||||||
|
end of 2027
|
||||||
|
|
||||||
|
1. REFERENCE CLASS (Outside View)
|
||||||
|
Technology adoption lifecycle (Rogers curve):
|
||||||
|
- Innovators (2.5%) → Early Adopters (13.5%) → Early Majority (34%)
|
||||||
|
- Crossing from Early Adopters to Early Majority typically takes 3-5 years
|
||||||
|
after first production deployments
|
||||||
|
- First serious server-side Wasm deployments: ~2022 (Fermyon, Cosmonic)
|
||||||
|
- Current status (2025): Late Early Adopter stage
|
||||||
|
|
||||||
|
Historical analogues for infrastructure tech adoption:
|
||||||
|
- Containers (Docker 2013 → mainstream 2017-2018): ~4-5 years
|
||||||
|
- Kubernetes (2014 → mainstream 2018-2019): ~4-5 years
|
||||||
|
- Serverless (Lambda 2014 → mainstream 2018-2020): ~4-6 years
|
||||||
|
|
||||||
|
Base rate for "infrastructure tech reaching 20% adoption within 5 years
|
||||||
|
of first production use": ~30%
|
||||||
|
|
||||||
|
Starting probability: 30%
|
||||||
|
|
||||||
|
2. SPECIFIC EVIDENCE (Inside View)
|
||||||
|
Signals FOR (+):
|
||||||
|
a. WASI standard maturing — WASI Preview 2 shipped, component model
|
||||||
|
stabilizing (W3C working group)
|
||||||
|
— strength: STRONG — adjustment: +8%
|
||||||
|
b. Major cloud providers offering Wasm runtimes (Fastly, Cloudflare Workers,
|
||||||
|
Azure, AWS exploring)
|
||||||
|
— strength: STRONG — adjustment: +10%
|
||||||
|
c. Docker adding Wasm support natively (announced 2022, shipping)
|
||||||
|
— strength: MODERATE — adjustment: +5%
|
||||||
|
|
||||||
|
Signals AGAINST (-):
|
||||||
|
a. Ecosystem still fragmented — multiple competing runtimes, toolchain gaps
|
||||||
|
— strength: STRONG — adjustment: -10%
|
||||||
|
b. Containers already "good enough" for most workloads — weak forcing
|
||||||
|
function to switch
|
||||||
|
— strength: STRONG — adjustment: -8%
|
||||||
|
c. Wasm language support uneven — great for Rust/C++, mediocre for Python/JS
|
||||||
|
— strength: MODERATE — adjustment: -5%
|
||||||
|
|
||||||
|
Leading indicators to track:
|
||||||
|
- CNCF survey: % of respondents evaluating/using Wasm
|
||||||
|
- Job postings mentioning Wasm (Indeed/LinkedIn trend)
|
||||||
|
- GitHub stars and contributors for top Wasm runtimes (wasmtime, wasmer)
|
||||||
|
- WASI spec milestone dates vs planned dates
|
||||||
|
|
||||||
|
3. SYNTHESIS
|
||||||
|
Starting probability (base rate): 30%
|
||||||
|
Signals for: +8% +10% +5% = +23%
|
||||||
|
Signals against: -10% -8% -5% = -23%
|
||||||
|
Net adjustment: 0%
|
||||||
|
Final probability: 30%
|
||||||
|
|
||||||
|
Interpretation: The positive and negative signals roughly cancel out.
|
||||||
|
The base rate from analogous infrastructure technologies holds.
|
||||||
|
This is genuinely uncertain — the "chasm" crossing is the key risk.
|
||||||
|
|
||||||
|
4. KEY ASSUMPTIONS
|
||||||
|
- "Mainstream" defined as >20% of NEW deployments (not total installed base)
|
||||||
|
- WASI component model reaches 1.0 stable by mid-2026
|
||||||
|
If delayed beyond 2026: probability drops to 15%
|
||||||
|
- No competing paradigm emerges (e.g., eBPF expanding scope):
|
||||||
|
If strong competitor: probability drops to 20%
|
||||||
|
|
||||||
|
5. RESOLUTION
|
||||||
|
Date: December 31, 2027
|
||||||
|
Criteria: CNCF annual survey shows >20% respondents using Wasm in production
|
||||||
|
Data source: CNCF Annual Survey, Datadog Container Report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 3: Geopolitical Forecast
|
||||||
|
|
||||||
|
**Question**: "Will US-China trade tensions escalate significantly in 2025?"
|
||||||
|
(Defined as: new tariffs >25% on >$100B of goods, or export controls expanded
|
||||||
|
to 3+ new technology categories)
|
||||||
|
|
||||||
|
```
|
||||||
|
PREDICTION: Significant escalation of US-China trade tensions in 2025
|
||||||
|
|
||||||
|
1. REFERENCE CLASS (Outside View)
|
||||||
|
Historical trade conflict escalation pattern:
|
||||||
|
- US-China trade relations since 2018: escalation occurred in 4 of 7 years
|
||||||
|
- In election year +1 (new/returning administration): escalation rate ~60%
|
||||||
|
- Trade wars historically escalate in steps, with retaliation cycles
|
||||||
|
|
||||||
|
Starting probability: 55%
|
||||||
|
|
||||||
|
2. SPECIFIC EVIDENCE (Inside View)
|
||||||
|
Signals FOR (+):
|
||||||
|
a. Administration rhetoric on China hawkish across both parties
|
||||||
|
— strength: STRONG — adjustment: +10%
|
||||||
|
b. Semiconductor export controls already expanding (ASML, Tokyo Electron)
|
||||||
|
— strength: STRONG — adjustment: +8%
|
||||||
|
c. China retaliating with rare earth export restrictions
|
||||||
|
— strength: MODERATE — adjustment: +5%
|
||||||
|
|
||||||
|
Signals AGAINST (-):
|
||||||
|
a. Business lobbying against further tariffs (Chamber of Commerce, farm lobby)
|
||||||
|
— strength: MODERATE — adjustment: -5%
|
||||||
|
b. Inflation concerns create political cost for tariffs
|
||||||
|
— strength: MODERATE — adjustment: -5%
|
||||||
|
c. Diplomatic channels active (recent bilateral meetings)
|
||||||
|
— strength: WEAK — adjustment: -3%
|
||||||
|
|
||||||
|
Scenario mapping:
|
||||||
|
┌─────────────────────────┬─────────────┬────────────────────┐
|
||||||
|
│ Scenario │ Probability │ Key trigger │
|
||||||
|
├─────────────────────────┼─────────────┼────────────────────┤
|
||||||
|
│ Major escalation │ 25% │ Taiwan crisis or │
|
||||||
|
│ (new tariffs + controls │ │ tech IP theft case │
|
||||||
|
│ + retaliatory cycle) │ │ │
|
||||||
|
├─────────────────────────┼─────────────┼────────────────────┤
|
||||||
|
│ Moderate escalation │ 40% │ Incremental tariff │
|
||||||
|
│ (meets our threshold) │ │ increases + 1-2 │
|
||||||
|
│ │ │ new export controls│
|
||||||
|
├─────────────────────────┼─────────────┼────────────────────┤
|
||||||
|
│ Status quo / minor │ 30% │ Diplomatic deals, │
|
||||||
|
│ changes │ │ election distraction│
|
||||||
|
├─────────────────────────┼─────────────┼────────────────────┤
|
||||||
|
│ De-escalation │ 5% │ Grand bargain │
|
||||||
|
│ (reduced tariffs) │ │ (historically rare)│
|
||||||
|
└─────────────────────────┴─────────────┴────────────────────┘
|
||||||
|
|
||||||
|
P(meets our escalation threshold) = 25% + 40% = 65%
|
||||||
|
|
||||||
|
3. SYNTHESIS
|
||||||
|
Starting probability (base rate): 55%
|
||||||
|
Signals for: +10% +8% +5% = +23%
|
||||||
|
Signals against: -5% -5% -3% = -13%
|
||||||
|
Net adjustment: +10%
|
||||||
|
Raw probability: 65%
|
||||||
|
|
||||||
|
Cross-check with scenario mapping: 65% — consistent.
|
||||||
|
Final probability: 65%
|
||||||
|
|
||||||
|
4. KEY ASSUMPTIONS
|
||||||
|
- No major geopolitical crisis (Taiwan strait) that causes extreme
|
||||||
|
escalation or extreme restraint: If crisis occurs, split to
|
||||||
|
80% (escalation) or 20% (restraint/avoidance)
|
||||||
|
- US economy remains stable: If recession hits, probability drops
|
||||||
|
to 45% (political cost of tariffs rises)
|
||||||
|
- China does not make major trade concessions preemptively:
|
||||||
|
If it does, probability drops to 30%
|
||||||
|
|
||||||
|
5. RESOLUTION
|
||||||
|
Date: December 31, 2025
|
||||||
|
Criteria: Cumulative new tariffs >25% on >$100B goods OR export controls
|
||||||
|
expanded to 3+ new technology categories (per USTR/BIS announcements)
|
||||||
|
Data source: USTR tariff schedule, BIS Entity List updates, Congressional
|
||||||
|
Research Service reports
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fermi Estimation Techniques
|
||||||
|
|
||||||
|
Fermi estimation is the art of making reasonable order-of-magnitude guesses
|
||||||
|
by breaking unknowable questions into smaller, estimable pieces.
|
||||||
|
|
||||||
|
### Step-by-Step Process
|
||||||
|
|
||||||
|
```
|
||||||
|
1. DEFINE the quantity you want to estimate
|
||||||
|
→ Be specific about units, scope, and timeframe
|
||||||
|
|
||||||
|
2. DECOMPOSE into factors you can estimate independently
|
||||||
|
→ Prefer multiplication chains: A × B × C
|
||||||
|
→ Each factor should be something you can reason about
|
||||||
|
|
||||||
|
3. ESTIMATE each factor
|
||||||
|
→ Use round numbers (powers of 10 when possible)
|
||||||
|
→ State your confidence range for each factor
|
||||||
|
|
||||||
|
4. MULTIPLY and sanity-check
|
||||||
|
→ Does the result pass the "smell test"?
|
||||||
|
→ Cross-check with any known anchors
|
||||||
|
|
||||||
|
5. STATE your uncertainty
|
||||||
|
→ Fermi estimates are typically accurate within 1 order of magnitude
|
||||||
|
→ Give a range: [estimate / 3, estimate × 3] is a reasonable default
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Reference Anchors
|
||||||
|
|
||||||
|
Keep these memorized for quick estimation:
|
||||||
|
|
||||||
|
```
|
||||||
|
POPULATION
|
||||||
|
World: ~8 billion
|
||||||
|
US: ~340 million
|
||||||
|
EU: ~450 million
|
||||||
|
China: ~1.4 billion
|
||||||
|
India: ~1.4 billion
|
||||||
|
|
||||||
|
ECONOMICS
|
||||||
|
World GDP: ~$100 trillion
|
||||||
|
US GDP: ~$28 trillion
|
||||||
|
US median household: ~$75,000/year
|
||||||
|
US federal budget: ~$6.5 trillion
|
||||||
|
S&P 500 total cap: ~$45 trillion
|
||||||
|
|
||||||
|
TIME
|
||||||
|
Seconds in a day: ~86,400 (~10^5)
|
||||||
|
Seconds in a year: ~31.5 million (~3 × 10^7)
|
||||||
|
Working hours/year: ~2,000
|
||||||
|
|
||||||
|
TECHNOLOGY
|
||||||
|
Global internet users: ~5.5 billion
|
||||||
|
Global smartphone users: ~4.5 billion
|
||||||
|
AWS annual revenue: ~$90 billion
|
||||||
|
Global IT spending: ~$5 trillion
|
||||||
|
GitHub developers: ~100 million
|
||||||
|
|
||||||
|
INDUSTRY SIZES (annual, global)
|
||||||
|
Cloud computing: ~$600 billion
|
||||||
|
Semiconductor: ~$600 billion
|
||||||
|
Pharmaceutical: ~$1.5 trillion
|
||||||
|
Automotive: ~$3 trillion
|
||||||
|
Agriculture: ~$3 trillion
|
||||||
|
E-commerce: ~$6 trillion
|
||||||
|
```
|
||||||
|
|
||||||
|
### Worked Fermi Examples
|
||||||
|
|
||||||
|
**Example A: Estimating the TAM for an AI code review tool**
|
||||||
|
|
||||||
|
```
|
||||||
|
Question: What is the annual TAM for an AI-powered code review SaaS?
|
||||||
|
|
||||||
|
Decomposition:
|
||||||
|
TAM = (Number of professional developers)
|
||||||
|
× (% who do code reviews regularly)
|
||||||
|
× (willingness to pay for tooling)
|
||||||
|
× (average annual price)
|
||||||
|
|
||||||
|
Estimates:
|
||||||
|
Professional developers worldwide: ~30 million
|
||||||
|
(GitHub has 100M accounts, but ~30% are professional, and
|
||||||
|
not all professionals use GitHub)
|
||||||
|
|
||||||
|
% who do code reviews: ~60%
|
||||||
|
(Standard in companies > 50 engineers, less common in small shops)
|
||||||
|
|
||||||
|
Target market (teams that would buy SaaS): ~40%
|
||||||
|
(Enterprise and mid-market; small teams use free tools)
|
||||||
|
|
||||||
|
Annual price per seat: ~$300/year
|
||||||
|
(Comparable: GitHub Copilot ~$200, Snyk ~$400, middle ground)
|
||||||
|
|
||||||
|
Calculation:
|
||||||
|
30M × 0.60 × 0.40 × $300 = $2.16 billion
|
||||||
|
|
||||||
|
Sanity check:
|
||||||
|
- GitHub revenue ~$2B (broader product, ~4M paid users)
|
||||||
|
- Snyk valued at $7B (code security, related space)
|
||||||
|
- $2B TAM is plausible for a focused code review tool
|
||||||
|
|
||||||
|
Result: ~$2 billion TAM (range: $700M to $6B)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example B: Estimating daily active queries to a search engine**
|
||||||
|
|
||||||
|
```
|
||||||
|
Question: How many search queries does Google process per day?
|
||||||
|
|
||||||
|
Decomposition:
|
||||||
|
Queries/day = (Internet users who use Google)
|
||||||
|
× (searches per user per day)
|
||||||
|
|
||||||
|
Estimates:
|
||||||
|
Global internet users: ~5.5 billion
|
||||||
|
Google market share: ~90%
|
||||||
|
Google users: 5.5B × 0.90 = ~5 billion
|
||||||
|
But not all use it daily: ~50% daily active rate
|
||||||
|
Daily active Google searchers: ~2.5 billion
|
||||||
|
|
||||||
|
Searches per active user per day: ~3-4
|
||||||
|
(Some people search 10+ times, many search once or not at all)
|
||||||
|
|
||||||
|
Calculation:
|
||||||
|
2.5 billion × 3.5 = ~8.5 billion queries/day
|
||||||
|
|
||||||
|
Sanity check:
|
||||||
|
Published figure (Google): ~8.5 billion searches/day (2024)
|
||||||
|
Our estimate nailed it — sometimes Fermi estimation gets lucky.
|
||||||
|
|
||||||
|
Result: ~8.5 billion/day (range: 3B to 25B)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Order of Magnitude Sanity Checks
|
||||||
|
|
||||||
|
After any estimate, verify it makes sense:
|
||||||
|
|
||||||
|
```
|
||||||
|
CHECK 1: Per-person reasonableness
|
||||||
|
Divide by relevant population. Is the per-person number realistic?
|
||||||
|
"$50B market ÷ 340M Americans = $147/person" — plausible?
|
||||||
|
|
||||||
|
CHECK 2: Comparison to known quantities
|
||||||
|
Is your estimate bigger or smaller than things you know?
|
||||||
|
"Our estimate of X is $3B — that's 5% of AWS revenue. Reasonable?"
|
||||||
|
|
||||||
|
CHECK 3: Growth rate implied
|
||||||
|
If you're estimating a future state, what annual growth rate is implied?
|
||||||
|
>50% sustained growth for >3 years is extremely rare.
|
||||||
|
|
||||||
|
CHECK 4: Upper bound test
|
||||||
|
What is the theoretical maximum? Is your estimate within it?
|
||||||
|
"Total possible customers × maximum price = ceiling"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Prediction Market Patterns
|
||||||
|
|
||||||
|
### Interpreting Market Prices as Probabilities
|
||||||
|
|
||||||
|
Prediction market prices map to probabilities, but with important caveats:
|
||||||
|
|
||||||
|
```
|
||||||
|
Market price $0.65 for "Event X occurs"
|
||||||
|
→ Naive interpretation: 65% probability
|
||||||
|
→ Adjusted interpretation: depends on market quality
|
||||||
|
|
||||||
|
Adjustment factors:
|
||||||
|
Liquid market (Polymarket, Metaculus with many forecasters):
|
||||||
|
Price ≈ true probability (±3-5%)
|
||||||
|
|
||||||
|
Thin market (<50 traders, <$10K volume):
|
||||||
|
Price is noisy — treat as ±15% uncertainty
|
||||||
|
A $0.65 price could represent 50-80% true probability
|
||||||
|
|
||||||
|
Binary vs. multi-outcome:
|
||||||
|
Binary markets are more reliable
|
||||||
|
Multi-outcome markets often have probabilities summing to >100%
|
||||||
|
(overround) — normalize before interpreting
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Prediction Market Biases
|
||||||
|
|
||||||
|
| Bias | Description | Impact | Correction |
|
||||||
|
|------|-------------|--------|------------|
|
||||||
|
| Favorite-longshot | Favorites underpriced, longshots overpriced | Longshot events appear ~2-3x more likely than they are | If market says 5%, true probability may be 2-3% |
|
||||||
|
| Recency | Recent events dominate pricing | Probability spikes after news, then slowly reverts | Wait 24-48h after major news before trusting market prices |
|
||||||
|
| Liquidity premium | Illiquid contracts trade at a discount | Prices biased toward 50% in thin markets | Weight liquid markets more heavily |
|
||||||
|
| Expiration clustering | Prices converge to 0 or 1 near expiration | Mid-probability contracts vanish near deadline | Most useful signal is months before resolution |
|
||||||
|
| Hedging distortion | Traders hedging other positions, not expressing beliefs | Prices reflect risk management, not pure probability | Cross-reference with non-market forecasts |
|
||||||
|
|
||||||
|
### Aggregation Methods
|
||||||
|
|
||||||
|
When combining multiple probability estimates (markets, experts, models):
|
||||||
|
|
||||||
|
```
|
||||||
|
SIMPLE AVERAGE
|
||||||
|
P = (P1 + P2 + P3) / 3
|
||||||
|
Use when: Sources are roughly equally credible
|
||||||
|
Weakness: Susceptible to outliers
|
||||||
|
|
||||||
|
MEDIAN
|
||||||
|
P = middle value of sorted estimates
|
||||||
|
Use when: One source might be badly miscalibrated
|
||||||
|
Weakness: Ignores magnitude of disagreement
|
||||||
|
|
||||||
|
TRIMMED MEAN
|
||||||
|
Drop highest and lowest, average the rest
|
||||||
|
P = average(P2 ... Pn-1) after sorting
|
||||||
|
Use when: 5+ sources, want outlier robustness
|
||||||
|
|
||||||
|
EXTREMIZED AVERAGE
|
||||||
|
P_avg = simple average
|
||||||
|
P_extremized = P_avg^a / (P_avg^a + (1-P_avg)^a), where a > 1
|
||||||
|
Typical a = 1.5 to 2.5 (more extremizing with more independent sources)
|
||||||
|
Use when: Sources are genuinely independent (not reading each other)
|
||||||
|
Rationale: If 5 independent sources all say 70%, the true probability
|
||||||
|
is likely higher than 70% — shared info should push further from 50%
|
||||||
|
|
||||||
|
CONFIDENCE-WEIGHTED AVERAGE
|
||||||
|
P = Σ(wi × Pi) / Σ(wi)
|
||||||
|
where wi = track record score or source reliability
|
||||||
|
Use when: Sources have known, differing track records
|
||||||
|
```
|
||||||
|
|
||||||
|
### When Markets Beat Experts (and Vice Versa)
|
||||||
|
|
||||||
|
```
|
||||||
|
MARKETS TEND TO WIN when:
|
||||||
|
✓ Large, liquid, diverse participant pool
|
||||||
|
✓ Question is well-defined with clear resolution criteria
|
||||||
|
✓ Information is widely distributed (no single expert has edge)
|
||||||
|
✓ Time horizon is 1 month to 2 years
|
||||||
|
Examples: Election outcomes, product launch dates, economic indicators
|
||||||
|
|
||||||
|
EXPERTS TEND TO WIN when:
|
||||||
|
✓ Question requires deep domain-specific knowledge
|
||||||
|
✓ Market is thin or participants lack domain context
|
||||||
|
✓ Very long time horizons (>5 years) — markets discount distant futures
|
||||||
|
✓ Novel situations with no historical market precedent
|
||||||
|
Examples: Technical feasibility, scientific breakthroughs, niche regulation
|
||||||
|
|
||||||
|
BEST PRACTICE: Use both
|
||||||
|
Start with the market price, then adjust using expert insight.
|
||||||
|
Treat the market as the prior and expert analysis as an update.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Update Protocol
|
||||||
|
|
||||||
|
### Bayesian Updating Worked Example
|
||||||
|
|
||||||
|
```
|
||||||
|
SCENARIO: You predicted 30% chance that Company Z launches Product A in Q1.
|
||||||
|
New evidence: A leaked internal slide shows a Q1 launch timeline.
|
||||||
|
|
||||||
|
STEP 1: State the prior
|
||||||
|
P(launch in Q1) = 0.30
|
||||||
|
|
||||||
|
STEP 2: Assess the evidence
|
||||||
|
E = leaked slide showing Q1 timeline
|
||||||
|
How likely is this evidence if the launch IS happening in Q1?
|
||||||
|
P(E | launch) = 0.85
|
||||||
|
(Internal slides usually reflect real plans, but plans change)
|
||||||
|
How likely is this evidence if the launch is NOT in Q1?
|
||||||
|
P(E | no launch) = 0.15
|
||||||
|
(Could be outdated slide, aspirational, or decoy)
|
||||||
|
|
||||||
|
STEP 3: Calculate the likelihood ratio
|
||||||
|
LR = P(E | launch) / P(E | no launch) = 0.85 / 0.15 = 5.67
|
||||||
|
|
||||||
|
STEP 4: Convert prior to odds, multiply, convert back
|
||||||
|
Prior odds = 0.30 / 0.70 = 0.429
|
||||||
|
Posterior odds = 0.429 × 5.67 = 2.43
|
||||||
|
Posterior probability = 2.43 / (1 + 2.43) = 0.71
|
||||||
|
|
||||||
|
STEP 5: State the update
|
||||||
|
Prior: 30% → Posterior: 71%
|
||||||
|
Update magnitude: +41 percentage points
|
||||||
|
This is a LARGE update, appropriate because the evidence (internal
|
||||||
|
planning document) is strong and directly relevant.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Evidence Strength Classification
|
||||||
|
|
||||||
|
How much to update based on different types of evidence:
|
||||||
|
|
||||||
|
```
|
||||||
|
EVIDENCE TIER 1 — Large update (likelihood ratio 5-20x)
|
||||||
|
→ Official announcement or regulatory filing
|
||||||
|
→ Confirmed internal document (not rumor)
|
||||||
|
→ Directly observed outcome of prerequisite event
|
||||||
|
→ Multiple independent strong sources confirming same fact
|
||||||
|
Typical update: ±15-30 percentage points
|
||||||
|
|
||||||
|
EVIDENCE TIER 2 — Moderate update (likelihood ratio 2-5x)
|
||||||
|
→ Credible journalist report with named sources
|
||||||
|
→ Statistical data that changes the base rate
|
||||||
|
→ Expert with strong track record changing their view
|
||||||
|
→ Structural/policy change that alters incentives
|
||||||
|
Typical update: ±5-15 percentage points
|
||||||
|
|
||||||
|
EVIDENCE TIER 3 — Small update (likelihood ratio 1.2-2x)
|
||||||
|
→ Rumor from semi-credible source
|
||||||
|
→ Anecdotal evidence (single data point)
|
||||||
|
→ Social media sentiment shift
|
||||||
|
→ Expert opinion without new information
|
||||||
|
Typical update: ±2-5 percentage points
|
||||||
|
|
||||||
|
EVIDENCE TIER 4 — Negligible update (likelihood ratio ~1x)
|
||||||
|
→ Repetition of previously known information
|
||||||
|
→ Pundit opinion with no domain expertise
|
||||||
|
→ Vague statement open to multiple interpretations
|
||||||
|
→ Evidence equally consistent with both outcomes
|
||||||
|
Typical update: ±0-2 percentage points (or skip entirely)
|
||||||
|
```
|
||||||
|
|
||||||
|
### When to Make Large vs. Small Updates
|
||||||
|
|
||||||
|
```
|
||||||
|
MAKE A LARGE UPDATE when:
|
||||||
|
• Evidence directly addresses your key uncertainty
|
||||||
|
• The source has a strong track record on this topic
|
||||||
|
• The evidence would be very surprising if your prediction were correct
|
||||||
|
(or very unsurprising if it were wrong)
|
||||||
|
• Multiple independent signals shift in the same direction simultaneously
|
||||||
|
|
||||||
|
MAKE A SMALL UPDATE when:
|
||||||
|
• Evidence is tangentially related to your prediction
|
||||||
|
• The source's reliability is uncertain
|
||||||
|
• The evidence is consistent with multiple interpretations
|
||||||
|
• You've already incorporated similar evidence
|
||||||
|
|
||||||
|
RESIST UPDATING when:
|
||||||
|
• The "evidence" is just someone restating the consensus
|
||||||
|
• A vivid anecdote feels compelling but carries no statistical weight
|
||||||
|
• You're reacting emotionally (fear, excitement) rather than analytically
|
||||||
|
• The evidence source has an obvious incentive to mislead
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Updating Mistakes
|
||||||
|
|
||||||
|
| Mistake | Description | Fix |
|
||||||
|
|---------|-------------|-----|
|
||||||
|
| Over-updating on vivid events | A dramatic single event shifts your view by 20+ points when the base rate barely moved | Ask: "Does this event actually change the base rate, or just my emotional state?" |
|
||||||
|
| Under-updating on base rate changes | New data shows the reference class frequency shifted, but you keep your old anchor | Periodically re-derive the base rate from scratch instead of only adjusting incrementally |
|
||||||
|
| Asymmetric updating | Updating strongly on confirming evidence, weakly on disconfirming evidence | Force yourself to calculate the likelihood ratio for disconfirming evidence explicitly |
|
||||||
|
| Double-counting | Updating on a news article, then updating again on a tweet quoting the same article | Track the original source — if two signals share the same root cause, count once |
|
||||||
|
| Failure to update | Knowing the evidence should change your view but not bothering because your current number "feels right" | Set calendar reminders to review active predictions monthly with fresh evidence |
|
||||||
|
| Stampede updating | A prediction market spikes, causing you to rush your update to match | Market moves are data, not commands — assess independently, then compare |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Prediction Tracking & Scoring
|
## Prediction Tracking & Scoring
|
||||||
|
|
||||||
### Prediction Ledger Format
|
### Prediction Ledger Format
|
||||||
|
|||||||
@@ -423,6 +423,241 @@ frequency = "hourly"
|
|||||||
token_consumption = "medium"
|
token_consumption = "medium"
|
||||||
default_active = false
|
default_active = false
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "Reddit Hand"
|
name = "Reddit Hand"
|
||||||
description = "自主 Reddit 管理——监控子版块、发布内容、回复帖子并追踪 Karma 和互动"
|
description = "自主 Reddit 管理——监控子版块、发布内容、回复帖子并追踪 Karma 和互动"
|
||||||
|
category = "通信"
|
||||||
|
|
||||||
|
[i18n.zh.settings.subreddits]
|
||||||
|
label = "子版块"
|
||||||
|
description = "要监控的子版块列表(逗号分隔,例如 rust,programming,machinelearning)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.monitor_mode]
|
||||||
|
label = "监控模式"
|
||||||
|
description = "在监控的子版块中追踪哪些内容"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_reply]
|
||||||
|
label = "自动回复"
|
||||||
|
description = "自动回复相关的帖子和评论"
|
||||||
|
|
||||||
|
[i18n.zh.settings.post_frequency]
|
||||||
|
label = "发布频率"
|
||||||
|
description = "创建原创帖子的频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.content_style]
|
||||||
|
label = "内容风格"
|
||||||
|
description = "帖子和回复的语气和风格"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "审批模式"
|
||||||
|
description = "将帖子和回复加入队列等待审核,而非直接发布"
|
||||||
|
|
||||||
|
[i18n.zh.settings.min_karma_to_post]
|
||||||
|
label = "最低发帖 Karma"
|
||||||
|
description = "仅在账户拥有至少此数量 Karma 的子版块中发帖"
|
||||||
|
|
||||||
|
[i18n.zh.settings.max_reply_depth]
|
||||||
|
label = "最大回复深度"
|
||||||
|
description = "回复的最大评论嵌套深度(深层嵌套的可见度较低)"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Reddit"
|
||||||
|
description = "Gestor autónomo de Reddit — monitorea subreddits, publica contenido, responde en hilos y rastrea karma e interacciones"
|
||||||
|
category = "Comunicación"
|
||||||
|
|
||||||
|
[i18n.es.settings.subreddits]
|
||||||
|
label = "Subreddits"
|
||||||
|
description = "Lista de subreddits a monitorear separados por comas (ej. rust,programming,machinelearning)"
|
||||||
|
|
||||||
|
[i18n.es.settings.monitor_mode]
|
||||||
|
label = "Modo de monitoreo"
|
||||||
|
description = "Qué rastrear en los subreddits monitoreados"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_reply]
|
||||||
|
label = "Respuesta automática"
|
||||||
|
description = "Responder automáticamente a publicaciones y comentarios relevantes"
|
||||||
|
|
||||||
|
[i18n.es.settings.post_frequency]
|
||||||
|
label = "Frecuencia de publicación"
|
||||||
|
description = "Con qué frecuencia crear publicaciones originales"
|
||||||
|
|
||||||
|
[i18n.es.settings.content_style]
|
||||||
|
label = "Estilo de contenido"
|
||||||
|
description = "Tono y enfoque para publicaciones y respuestas"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Modo de aprobación"
|
||||||
|
description = "Poner publicaciones y respuestas en cola para revisión en lugar de publicarlas directamente"
|
||||||
|
|
||||||
|
[i18n.es.settings.min_karma_to_post]
|
||||||
|
label = "Karma mínimo para publicar"
|
||||||
|
description = "Solo publicar en subreddits donde la cuenta tenga al menos este nivel de karma"
|
||||||
|
|
||||||
|
[i18n.es.settings.max_reply_depth]
|
||||||
|
label = "Profundidad máxima de respuesta"
|
||||||
|
description = "Profundidad máxima del hilo de comentarios para responder (los hilos más profundos tienen menos visibilidad)"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "Reddit Hand"
|
||||||
|
description = "自律型Redditマネージャー——サブレディットの監視、コンテンツ投稿、スレッドへの返信、Karmaとエンゲージメントの追跡"
|
||||||
|
category = "コミュニケーション"
|
||||||
|
|
||||||
|
[i18n.ja.settings.subreddits]
|
||||||
|
label = "サブレディット"
|
||||||
|
description = "監視するサブレディットのリスト(カンマ区切り、例: rust,programming,machinelearning)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.monitor_mode]
|
||||||
|
label = "監視モード"
|
||||||
|
description = "監視対象のサブレディットで追跡する内容"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_reply]
|
||||||
|
label = "自動返信"
|
||||||
|
description = "関連する投稿やコメントに自動で返信する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.post_frequency]
|
||||||
|
label = "投稿頻度"
|
||||||
|
description = "オリジナル投稿を作成する頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.content_style]
|
||||||
|
label = "コンテンツスタイル"
|
||||||
|
description = "投稿と返信のトーンとアプローチ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "承認モード"
|
||||||
|
description = "投稿や返信を直接公開せず、レビュー用キューに追加する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.min_karma_to_post]
|
||||||
|
label = "投稿に必要な最低Karma"
|
||||||
|
description = "アカウントが最低このKarmaを持つサブレディットでのみ投稿する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.max_reply_depth]
|
||||||
|
label = "最大返信深度"
|
||||||
|
description = "返信するコメントスレッドの最大ネスト深度(深いスレッドほど可視性が低い)"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Reddit"
|
||||||
|
description = "Gestionnaire Reddit autonome — surveille les subreddits, publie du contenu, répond dans les fils et suit le karma et l'engagement"
|
||||||
|
category = "Communication"
|
||||||
|
|
||||||
|
[i18n.fr.settings.subreddits]
|
||||||
|
label = "Subreddits"
|
||||||
|
description = "Liste de subreddits à surveiller séparés par des virgules (ex. rust,programming,machinelearning)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.monitor_mode]
|
||||||
|
label = "Mode de surveillance"
|
||||||
|
description = "Ce qu'il faut suivre dans les subreddits surveillés"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_reply]
|
||||||
|
label = "Réponse automatique"
|
||||||
|
description = "Répondre automatiquement aux publications et commentaires pertinents"
|
||||||
|
|
||||||
|
[i18n.fr.settings.post_frequency]
|
||||||
|
label = "Fréquence de publication"
|
||||||
|
description = "Fréquence de création de publications originales"
|
||||||
|
|
||||||
|
[i18n.fr.settings.content_style]
|
||||||
|
label = "Style de contenu"
|
||||||
|
description = "Ton et approche pour les publications et réponses"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Mode d'approbation"
|
||||||
|
description = "Mettre les publications et réponses en file d'attente pour révision au lieu de les publier directement"
|
||||||
|
|
||||||
|
[i18n.fr.settings.min_karma_to_post]
|
||||||
|
label = "Karma minimum pour publier"
|
||||||
|
description = "Ne publier que dans les subreddits où le compte possède au moins ce niveau de karma"
|
||||||
|
|
||||||
|
[i18n.fr.settings.max_reply_depth]
|
||||||
|
label = "Profondeur maximale de réponse"
|
||||||
|
description = "Profondeur maximale d'imbrication des commentaires pour répondre (les fils plus profonds ont moins de visibilité)"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Reddit-Hand"
|
||||||
|
description = "Autonomer Reddit-Manager — überwacht Subreddits, postet Inhalte, antwortet in Threads und verfolgt Karma und Engagement"
|
||||||
|
category = "Kommunikation"
|
||||||
|
|
||||||
|
[i18n.de.settings.subreddits]
|
||||||
|
label = "Subreddits"
|
||||||
|
description = "Kommagetrennte Liste der zu überwachenden Subreddits (z.B. rust,programming,machinelearning)"
|
||||||
|
|
||||||
|
[i18n.de.settings.monitor_mode]
|
||||||
|
label = "Überwachungsmodus"
|
||||||
|
description = "Was in den überwachten Subreddits verfolgt werden soll"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_reply]
|
||||||
|
label = "Automatische Antwort"
|
||||||
|
description = "Automatisch auf relevante Beiträge und Kommentare antworten"
|
||||||
|
|
||||||
|
[i18n.de.settings.post_frequency]
|
||||||
|
label = "Veröffentlichungshäufigkeit"
|
||||||
|
description = "Wie oft originale Beiträge erstellt werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.content_style]
|
||||||
|
label = "Inhaltsstil"
|
||||||
|
description = "Ton und Ansatz für Beiträge und Antworten"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Genehmigungsmodus"
|
||||||
|
description = "Beiträge und Antworten zur Überprüfung in die Warteschlange stellen, anstatt sie direkt zu veröffentlichen"
|
||||||
|
|
||||||
|
[i18n.de.settings.min_karma_to_post]
|
||||||
|
label = "Mindest-Karma zum Posten"
|
||||||
|
description = "Nur in Subreddits posten, in denen das Konto mindestens dieses Karma-Level hat"
|
||||||
|
|
||||||
|
[i18n.de.settings.max_reply_depth]
|
||||||
|
label = "Maximale Antworttiefe"
|
||||||
|
description = "Maximale Verschachtelungstiefe für Kommentarantworten (tiefere Threads haben geringere Sichtbarkeit)"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "Reddit Hand"
|
||||||
|
description = "자율 Reddit 관리 — 서브레딧 모니터링, 콘텐츠 게시, 스레드 댓글 및 카르마와 참여도 추적"
|
||||||
|
category = "커뮤니케이션"
|
||||||
|
|
||||||
|
[i18n.ko.settings.subreddits]
|
||||||
|
label = "서브레딧"
|
||||||
|
description = "모니터링할 서브레딧 목록 (쉼표로 구분, 예: rust,programming,machinelearning)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.monitor_mode]
|
||||||
|
label = "모니터링 모드"
|
||||||
|
description = "모니터링 대상 서브레딧에서 추적할 콘텐츠"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_reply]
|
||||||
|
label = "자동 답글"
|
||||||
|
description = "관련 게시물과 댓글에 자동으로 답글 작성"
|
||||||
|
|
||||||
|
[i18n.ko.settings.post_frequency]
|
||||||
|
label = "게시 빈도"
|
||||||
|
description = "원본 게시물 작성 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.content_style]
|
||||||
|
label = "콘텐츠 스타일"
|
||||||
|
description = "게시물과 답글의 어조와 접근 방식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "승인 모드"
|
||||||
|
description = "게시물과 답글을 직접 게시하지 않고 대기열에 추가하여 검토"
|
||||||
|
|
||||||
|
[i18n.ko.settings.min_karma_to_post]
|
||||||
|
label = "최소 게시 카르마"
|
||||||
|
description = "계정이 최소 이만큼의 카르마를 보유한 서브레딧에서만 게시"
|
||||||
|
|
||||||
|
[i18n.ko.settings.max_reply_depth]
|
||||||
|
label = "최대 답글 깊이"
|
||||||
|
description = "답글 작성의 최대 댓글 중첩 깊이 (깊은 중첩일수록 노출도 감소)"
|
||||||
@@ -247,3 +247,768 @@ Monitor account standing:
|
|||||||
- Build karma organically through genuine engagement
|
- Build karma organically through genuine engagement
|
||||||
- Avoid posting too frequently (triggers spam filters)
|
- Avoid posting too frequently (triggers spam filters)
|
||||||
- Diversify activity across multiple subreddits
|
- Diversify activity across multiple subreddits
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Product Launch on Reddit
|
||||||
|
|
||||||
|
**Scenario**: You are launching a developer CLI tool and want to generate awareness on Reddit.
|
||||||
|
|
||||||
|
**Phase 1 — Subreddit Research (Week 1-2 before launch)**
|
||||||
|
|
||||||
|
Identify target subreddits and evaluate each:
|
||||||
|
```
|
||||||
|
Target subreddits (prioritized):
|
||||||
|
1. r/commandline — 350k members, accepts tool announcements, requires demo/screenshot
|
||||||
|
2. r/programming — 5M members, strict anti-marketing, only accepts substantial technical posts
|
||||||
|
3. r/opensource — 200k members, friendly to launches, requires repo link
|
||||||
|
4. r/devtools — 50k members, niche but highly targeted
|
||||||
|
5. r/sideproject — 100k members, launch-friendly, expects "what I built" framing
|
||||||
|
```
|
||||||
|
|
||||||
|
Fetch subreddit rules programmatically:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/commandline/about/rules"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 2 — Karma Building (Week 1-2 before launch)**
|
||||||
|
|
||||||
|
Before posting about your product, build credibility:
|
||||||
|
```
|
||||||
|
Day 1-3: Answer questions in r/commandline and r/programming (3-5 helpful comments/day)
|
||||||
|
Day 4-7: Share a useful tip or short guide unrelated to your product
|
||||||
|
Day 8-10: Engage in discussions, upvote good content, reply to others' posts
|
||||||
|
Day 11-14: Share a technical deep-dive related to your product's domain (not the product itself)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 3 — Launch Posts (Launch Day)**
|
||||||
|
|
||||||
|
Craft posts per subreddit culture:
|
||||||
|
|
||||||
|
For **r/sideproject** (casual, story-driven):
|
||||||
|
```
|
||||||
|
Title: "I built a CLI tool that does X — here's what I learned"
|
||||||
|
Body:
|
||||||
|
- Paragraph on the problem and motivation
|
||||||
|
- Short demo (gif/video link or code block)
|
||||||
|
- What went wrong during development
|
||||||
|
- Link to repo
|
||||||
|
- "Would love feedback on X"
|
||||||
|
```
|
||||||
|
|
||||||
|
For **r/programming** (technical, anti-fluff):
|
||||||
|
```
|
||||||
|
Title: "X: an open-source CLI for Y written in Rust [with benchmarks]"
|
||||||
|
Body:
|
||||||
|
- Link directly to repo or blog post with technical depth
|
||||||
|
- Performance comparison table
|
||||||
|
- Architecture decisions
|
||||||
|
- NO "please star my repo" language
|
||||||
|
```
|
||||||
|
|
||||||
|
For **r/commandline** (practical, demo-focused):
|
||||||
|
```
|
||||||
|
Title: "X — does Y in Z seconds from your terminal"
|
||||||
|
Body:
|
||||||
|
- Install instructions (one-liner)
|
||||||
|
- Usage example with real output
|
||||||
|
- Screenshot or asciinema link
|
||||||
|
- Comparison to existing tools
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 4 — Engagement (Launch Day + 48 hours)**
|
||||||
|
|
||||||
|
Response templates:
|
||||||
|
|
||||||
|
| Comment Type | Response Strategy |
|
||||||
|
|-------------|-------------------|
|
||||||
|
| "How does this compare to Z?" | Honest comparison table, acknowledge Z's strengths |
|
||||||
|
| "Why not just use Z?" | Explain specific use cases where yours differs, no FUD |
|
||||||
|
| "Found a bug" | Thank them, ask for details, open GitHub issue immediately |
|
||||||
|
| "This is spam" | Do NOT argue. Briefly state this is your project and you're here to discuss |
|
||||||
|
| "Great work!" | Thank them, ask what feature they'd want next |
|
||||||
|
| Feature request | Acknowledge, add to roadmap, link to issue tracker |
|
||||||
|
|
||||||
|
**Phase 5 — Follow-Up (Week after launch)**
|
||||||
|
|
||||||
|
- Reply to every comment within 12 hours
|
||||||
|
- Post an update in r/sideproject if you hit a milestone (e.g., "Hit 500 stars, here's what I changed based on Reddit feedback")
|
||||||
|
- Do NOT cross-post the same content -- write fresh posts per subreddit
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 2: Community Monitoring and Sentiment Tracking
|
||||||
|
|
||||||
|
**Scenario**: You manage a brand's Reddit presence and need to track mentions, sentiment, and emerging issues.
|
||||||
|
|
||||||
|
**Step 1 — Set Up Monitoring Queries**
|
||||||
|
|
||||||
|
Search for brand mentions across Reddit:
|
||||||
|
```bash
|
||||||
|
# Search all of Reddit for brand mentions
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/search?q=%22BrandName%22+OR+%22brandname%22&sort=new&limit=25&t=day"
|
||||||
|
```
|
||||||
|
|
||||||
|
Monitor specific subreddits where your audience lives:
|
||||||
|
```bash
|
||||||
|
# Monitor r/technology for relevant topics
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/technology/search?q=BrandName&restrict_sr=on&sort=new&limit=25&t=week"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Sentiment Classification**
|
||||||
|
|
||||||
|
Categorize each mention into:
|
||||||
|
```
|
||||||
|
POSITIVE — Praise, recommendation, success story
|
||||||
|
NEUTRAL — Factual mention, question, comparison
|
||||||
|
NEGATIVE — Complaint, bug report, frustration
|
||||||
|
CRITICAL — Security concern, viral complaint, legal risk
|
||||||
|
```
|
||||||
|
|
||||||
|
Scoring signals from Reddit data:
|
||||||
|
```
|
||||||
|
score > 100 + sentiment=NEGATIVE → High-priority alert (viral complaint)
|
||||||
|
score > 50 + sentiment=POSITIVE → Amplification opportunity
|
||||||
|
num_comments > 20 + any sentiment → Active discussion, monitor closely
|
||||||
|
upvote_ratio < 0.5 → Controversial, may escalate
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Alert Thresholds**
|
||||||
|
|
||||||
|
| Condition | Action |
|
||||||
|
|-----------|--------|
|
||||||
|
| CRITICAL mention with score > 10 | Immediate alert to team |
|
||||||
|
| 3+ NEGATIVE mentions in 24 hours | Trend alert, investigate root cause |
|
||||||
|
| NEGATIVE post in subreddit > 500k members | Monitor hourly for 48 hours |
|
||||||
|
| Competitor comparison post trending | Prepare factual response (do NOT post defensively) |
|
||||||
|
|
||||||
|
**Step 4 — Weekly Report Template**
|
||||||
|
|
||||||
|
```
|
||||||
|
## Reddit Weekly Report — [Date Range]
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
- Total mentions: X (up/down Y% from last week)
|
||||||
|
- Sentiment breakdown: X% positive, Y% neutral, Z% negative
|
||||||
|
- Top subreddits: r/sub1 (N mentions), r/sub2 (N mentions)
|
||||||
|
|
||||||
|
### Trending Topics
|
||||||
|
1. [Topic] — [Subreddit] — [Sentiment] — [Link]
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
### Action Items
|
||||||
|
- [ ] Respond to [specific thread] — negative sentiment, high visibility
|
||||||
|
- [ ] Engage with [specific thread] — positive, amplification opportunity
|
||||||
|
|
||||||
|
### Competitor Activity
|
||||||
|
- [Competitor A]: N mentions, trending topics: ...
|
||||||
|
- [Competitor B]: N mentions, trending topics: ...
|
||||||
|
|
||||||
|
### Metrics
|
||||||
|
| Metric | This Week | Last Week | Change |
|
||||||
|
|--------|-----------|-----------|--------|
|
||||||
|
| Total mentions | | | |
|
||||||
|
| Positive % | | | |
|
||||||
|
| Avg post score | | | |
|
||||||
|
| Response time (hrs) | | | |
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 3: AMA (Ask Me Anything) Management
|
||||||
|
|
||||||
|
**Scenario**: You are organizing an AMA for a tech CEO in r/technology.
|
||||||
|
|
||||||
|
**Preparation (2 Weeks Before)**
|
||||||
|
|
||||||
|
1. Contact the subreddit moderators:
|
||||||
|
- Message the mod team through modmail (not individual DMs)
|
||||||
|
- Propose date, time, and AMA subject
|
||||||
|
- Ask about specific rules for AMAs (verification, scheduling, flair)
|
||||||
|
- Confirm the post format they expect
|
||||||
|
|
||||||
|
2. Schedule for peak engagement:
|
||||||
|
```
|
||||||
|
Recommended AMA times (US-centric subreddits):
|
||||||
|
- Tuesday-Thursday, 11:00 AM - 1:00 PM EST
|
||||||
|
- Avoid: weekends, holidays, major news days
|
||||||
|
- Post the AMA thread 30-60 minutes before the host starts answering
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Prepare the AMA post:
|
||||||
|
```
|
||||||
|
Title: "I'm [Name], [Role] at [Company]. [One-line hook]. AMA!"
|
||||||
|
|
||||||
|
Body:
|
||||||
|
- Brief intro (2-3 sentences about credentials)
|
||||||
|
- Why this AMA is happening (new product, milestone, event)
|
||||||
|
- Proof/verification (link to tweet, photo with timestamp)
|
||||||
|
- "I'll start answering at [TIME] [TIMEZONE]. Ask me anything!"
|
||||||
|
- Links to relevant context (website, blog post, prior work)
|
||||||
|
```
|
||||||
|
|
||||||
|
**During the AMA (2-3 Hours)**
|
||||||
|
|
||||||
|
Real-time engagement strategy:
|
||||||
|
```
|
||||||
|
1. Sort comments by "best" and "new" alternately every 15 minutes
|
||||||
|
2. Answer top-voted questions first (these set the tone)
|
||||||
|
3. Answer at least 20-30 questions in a 2-hour session
|
||||||
|
4. Mix short answers with detailed ones — avoid walls of text for every question
|
||||||
|
5. Skip hostile/troll questions silently — do NOT acknowledge them
|
||||||
|
6. For tough questions: answer honestly or say "I can't discuss that yet"
|
||||||
|
7. Upvote good questions (even tough ones) — shows good faith
|
||||||
|
```
|
||||||
|
|
||||||
|
Response length guide:
|
||||||
|
| Question Type | Response Length |
|
||||||
|
|--------------|----------------|
|
||||||
|
| Simple factual | 1-2 sentences |
|
||||||
|
| Technical deep-dive | 2-3 paragraphs |
|
||||||
|
| Personal/funny | 1-2 sentences, match the tone |
|
||||||
|
| Critical/tough | 2-3 sentences, direct and honest |
|
||||||
|
| Off-topic | Brief redirect or polite decline |
|
||||||
|
|
||||||
|
**Follow-Up (24-48 Hours After)**
|
||||||
|
|
||||||
|
- Post an edit to the original AMA: "Thanks everyone! I answered [N] questions. Check back — I'll try to answer a few more this week."
|
||||||
|
- Answer 5-10 more highly-upvoted questions that were missed
|
||||||
|
- Share the AMA link on other platforms (Twitter, LinkedIn) to drive continued engagement
|
||||||
|
- Compile a "best of" summary with links to the strongest Q&A exchanges
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Advanced API Patterns
|
||||||
|
|
||||||
|
### Pagination Handling
|
||||||
|
|
||||||
|
Reddit uses cursor-based pagination with `after` and `before` fullnames.
|
||||||
|
|
||||||
|
**Paginate through subreddit posts**:
|
||||||
|
```bash
|
||||||
|
# Page 1
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/new?limit=100"
|
||||||
|
# Response includes: "after": "t3_abc123"
|
||||||
|
|
||||||
|
# Page 2
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/new?limit=100&after=t3_abc123"
|
||||||
|
# Response includes: "after": "t3_def456" (or null if last page)
|
||||||
|
|
||||||
|
# Page 3
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/new?limit=100&after=t3_def456"
|
||||||
|
```
|
||||||
|
|
||||||
|
Pagination rules:
|
||||||
|
- `limit` max is 100 per request
|
||||||
|
- `after` returns items chronologically older than the given fullname
|
||||||
|
- `before` returns items chronologically newer (useful for "check for new posts since last poll")
|
||||||
|
- When `after` is `null` in the response, you have reached the last page
|
||||||
|
- Reddit caps listing depth at ~1000 items regardless of pagination
|
||||||
|
|
||||||
|
**Paginate backward (newer items)**:
|
||||||
|
```bash
|
||||||
|
# Get posts newer than a known fullname
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/new?limit=25&before=t3_abc123"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Flair Management
|
||||||
|
|
||||||
|
**Get available flairs for a subreddit**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/api/link_flair_v2"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Submit a post with flair**:
|
||||||
|
```bash
|
||||||
|
curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
-d "sr=SUBREDDIT&kind=self&title=TITLE&text=BODY&flair_id=FLAIR_ID&flair_text=FLAIR_TEXT" \
|
||||||
|
"https://oauth.reddit.com/api/submit"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Set flair on an existing post** (requires mod or post author permissions):
|
||||||
|
```bash
|
||||||
|
curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
-d "link=t3_POST_ID&flair_template_id=FLAIR_ID" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/api/selectflair"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Moderation Endpoints
|
||||||
|
|
||||||
|
These require moderator permissions on the target subreddit.
|
||||||
|
|
||||||
|
**Get moderation queue**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/about/modqueue?limit=25"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Approve a post/comment**:
|
||||||
|
```bash
|
||||||
|
curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
-d "id=FULLNAME" \
|
||||||
|
"https://oauth.reddit.com/api/approve"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Remove a post/comment**:
|
||||||
|
```bash
|
||||||
|
curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
-d "id=FULLNAME&spam=false" \
|
||||||
|
"https://oauth.reddit.com/api/remove"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Get moderation log**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/about/log?limit=25&type=removelink"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Distinguish a comment as moderator**:
|
||||||
|
```bash
|
||||||
|
curl -s -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
-d "id=FULLNAME&how=yes" \
|
||||||
|
"https://oauth.reddit.com/api/distinguish"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multi-Subreddit Monitoring
|
||||||
|
|
||||||
|
**Monitor multiple subreddits in a single request**:
|
||||||
|
```bash
|
||||||
|
# Combine subreddits with "+" for a merged feed
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/python+rust+golang/new?limit=50"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Search across multiple subreddits**:
|
||||||
|
```bash
|
||||||
|
# Use the subreddit field in search to restrict
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/search?q=BrandName+subreddit%3Apython+OR+subreddit%3Arust&sort=new&limit=25"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Get subreddit metadata for comparison**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/about"
|
||||||
|
```
|
||||||
|
Key fields in response: `subscribers`, `active_user_count`, `created_utc`, `public_description`, `submit_text`, `submission_type`.
|
||||||
|
|
||||||
|
### Polling Strategies for Real-Time Awareness
|
||||||
|
|
||||||
|
Reddit has no webhook support. Use polling with these patterns:
|
||||||
|
|
||||||
|
**Efficient polling loop**:
|
||||||
|
```
|
||||||
|
1. Fetch /r/SUBREDDIT/new?limit=10 every 60 seconds
|
||||||
|
2. Store the fullname of the newest item seen
|
||||||
|
3. On next poll, use ?before=LAST_SEEN_FULLNAME to get only new items
|
||||||
|
4. If response is empty, no new posts — sleep and retry
|
||||||
|
5. If response has items, process them and update LAST_SEEN_FULLNAME
|
||||||
|
```
|
||||||
|
|
||||||
|
**Polling frequency by priority**:
|
||||||
|
| Monitoring Type | Poll Interval | Endpoint |
|
||||||
|
|----------------|---------------|----------|
|
||||||
|
| Brand crisis monitoring | 30-60 seconds | /search?q=brand&sort=new |
|
||||||
|
| Subreddit new posts | 60-120 seconds | /r/SUB/new |
|
||||||
|
| Comment replies to own posts | 120 seconds | /message/inbox |
|
||||||
|
| Competitor mentions | 300 seconds | /search?q=competitor&sort=new |
|
||||||
|
| Weekly trend analysis | Once daily | /r/SUB/top?t=day |
|
||||||
|
|
||||||
|
**Respect rate limits while polling**:
|
||||||
|
```
|
||||||
|
At 30 requests/minute (app-only auth):
|
||||||
|
- 1 subreddit at 60s interval = 1 req/min → can monitor ~25 subreddits
|
||||||
|
- 1 search query at 60s interval = 1 req/min
|
||||||
|
- Reserve 5 req/min for ad-hoc queries
|
||||||
|
- Total budget: 30 req/min, plan accordingly
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Subreddit Analysis Framework
|
||||||
|
|
||||||
|
### Evaluating a Subreddit Before Posting
|
||||||
|
|
||||||
|
Before investing effort in any subreddit, run this assessment:
|
||||||
|
|
||||||
|
**Step 1 — Pull subreddit metadata**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/about" | python3 -c "
|
||||||
|
import sys, json
|
||||||
|
d = json.load(sys.stdin)['data']
|
||||||
|
print(f'Subscribers: {d[\"subscribers\"]:,}')
|
||||||
|
print(f'Active now: {d[\"active_user_count\"]:,}')
|
||||||
|
print(f'Created: {d[\"created_utc\"]}')
|
||||||
|
print(f'Type: {d[\"submission_type\"]}')
|
||||||
|
print(f'Description: {d[\"public_description\"][:200]}')
|
||||||
|
"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Measure actual engagement** (not just subscriber count):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get top 25 hot posts and examine their scores and comment counts
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/hot?limit=25"
|
||||||
|
```
|
||||||
|
|
||||||
|
Calculate from the response:
|
||||||
|
```
|
||||||
|
Engagement Score = median(post_scores) * median(num_comments)
|
||||||
|
Activity Ratio = active_user_count / subscribers
|
||||||
|
Health Indicator = (posts_per_day > 5) AND (Activity Ratio > 0.001)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Subreddit quality scorecard**:
|
||||||
|
|
||||||
|
| Factor | Good Sign | Bad Sign |
|
||||||
|
|--------|-----------|----------|
|
||||||
|
| Active/subscriber ratio | > 0.1% | < 0.01% |
|
||||||
|
| Median hot post score | > 50 | < 10 |
|
||||||
|
| Median comment count | > 10 | < 3 |
|
||||||
|
| Posts per day | 5-50 | < 1 or > 500 (noise) |
|
||||||
|
| Mod activity | Active modqueue, clear rules | No rules, spam in feed |
|
||||||
|
| Top post age | Within last 24h | Weeks old (dead subreddit) |
|
||||||
|
| Account age requirements | Reasonable (7 days) | None (spam-prone) or extreme (1 year) |
|
||||||
|
|
||||||
|
### Peak Engagement Hours by Subreddit Type
|
||||||
|
|
||||||
|
Optimal posting times vary by audience. All times in EST:
|
||||||
|
|
||||||
|
| Subreddit Type | Peak Hours | Peak Days | Reasoning |
|
||||||
|
|---------------|------------|-----------|-----------|
|
||||||
|
| Tech/Programming | 9-11 AM EST | Tue-Thu | Developers browse during morning coffee |
|
||||||
|
| Business/Startup | 7-9 AM EST | Mon-Wed | Professionals check before work |
|
||||||
|
| Gaming | 6-10 PM EST | Fri-Sun | After work/school |
|
||||||
|
| Science/Academic | 10 AM-12 PM EST | Mon-Wed | Researchers between tasks |
|
||||||
|
| Lifestyle/Hobby | 12-2 PM EST, 7-9 PM EST | Any | Lunch breaks and evenings |
|
||||||
|
| News/Politics | 7-9 AM EST | Mon-Fri | Morning news cycle |
|
||||||
|
| Finance/Crypto | 8-10 AM EST | Mon-Fri | Pre-market and market open |
|
||||||
|
|
||||||
|
To measure a specific subreddit's peak hours:
|
||||||
|
```bash
|
||||||
|
# Pull the last 100 posts and extract their timestamps
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/r/SUBREDDIT/new?limit=100"
|
||||||
|
# Parse created_utc for each post and bucket by hour-of-day
|
||||||
|
# Cross-reference with score to find high-score hours, not just high-volume hours
|
||||||
|
```
|
||||||
|
|
||||||
|
### Competitor Presence Analysis
|
||||||
|
|
||||||
|
**Step 1 — Search for competitor mentions**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/search?q=%22CompetitorName%22&sort=new&t=month&limit=100"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2 — Build a competitor activity profile**:
|
||||||
|
```
|
||||||
|
For each competitor, track:
|
||||||
|
- Which subreddits they are mentioned in (and by whom -- users vs the company)
|
||||||
|
- Frequency of mentions (per week)
|
||||||
|
- Sentiment of mentions (positive / neutral / negative)
|
||||||
|
- Whether they have official accounts engaging in threads
|
||||||
|
- Common complaints about them (your opportunity)
|
||||||
|
- Common praise for them (your benchmark)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3 — Competitor comparison matrix**:
|
||||||
|
| Metric | Your Brand | Competitor A | Competitor B |
|
||||||
|
|--------|-----------|-------------|-------------|
|
||||||
|
| Weekly mentions | | | |
|
||||||
|
| Positive sentiment % | | | |
|
||||||
|
| Subreddits present in | | | |
|
||||||
|
| Official account activity | | | |
|
||||||
|
| Top complaint theme | | | |
|
||||||
|
| Top praise theme | | | |
|
||||||
|
|
||||||
|
### Content Format Preferences by Subreddit Type
|
||||||
|
|
||||||
|
| Subreddit Type | Preferred Format | Avoid |
|
||||||
|
|---------------|-----------------|-------|
|
||||||
|
| Technical (r/programming, r/rust) | Long-form text, code blocks, benchmarks | Short posts, images without context |
|
||||||
|
| Q&A (r/AskReddit, r/askscience) | Concise questions, detailed answers | Link-only posts |
|
||||||
|
| Showcase (r/sideproject, r/webdev) | Screenshots, demos, before/after | Text-only without visuals |
|
||||||
|
| News (r/technology, r/science) | Link to source with summary comment | Self-post opinion pieces |
|
||||||
|
| Discussion (r/startups, r/cscareerquestions) | Personal experience, specific details | Generic advice, platitudes |
|
||||||
|
| Meme-friendly (r/ProgrammerHumor) | Images, short and punchy | Long text posts |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Growth & Reputation Building
|
||||||
|
|
||||||
|
### Karma Building Strategies (Comment-First Approach)
|
||||||
|
|
||||||
|
New accounts or accounts entering a new subreddit should follow the comment-first approach:
|
||||||
|
|
||||||
|
**Week 1-2: Listen and respond**
|
||||||
|
```
|
||||||
|
1. Sort by "new" in your target subreddits
|
||||||
|
2. Find questions you can genuinely answer
|
||||||
|
3. Write substantive, helpful comments (3+ sentences with specifics)
|
||||||
|
4. Respond to 3-5 threads per day
|
||||||
|
5. Do NOT mention your product, company, or project at all
|
||||||
|
```
|
||||||
|
|
||||||
|
**Week 3-4: Establish presence**
|
||||||
|
```
|
||||||
|
1. Start sharing relevant resources (not yours) that help the community
|
||||||
|
2. Engage in discussions about trends and opinions in your domain
|
||||||
|
3. Build recognition by being consistently helpful
|
||||||
|
4. Your username should start becoming familiar to regulars
|
||||||
|
```
|
||||||
|
|
||||||
|
**Week 5+: Contribute original content**
|
||||||
|
```
|
||||||
|
1. Share a technical write-up, tutorial, or analysis (unrelated to your product)
|
||||||
|
2. If well-received, you have earned the trust to occasionally mention your work
|
||||||
|
3. Always frame self-promotional content as "I built X" (transparent) not "Check out X" (spammy)
|
||||||
|
4. Maintain the 10:1 ratio — 10 helpful contributions for every 1 self-promotional post
|
||||||
|
```
|
||||||
|
|
||||||
|
Karma accumulation benchmarks:
|
||||||
|
| Milestone | Unlocks |
|
||||||
|
|-----------|---------|
|
||||||
|
| 10 comment karma | Bypass most anti-spam filters |
|
||||||
|
| 50 comment karma | Reduced posting cooldowns |
|
||||||
|
| 100+ comment karma in a subreddit | Trusted contributor status in some subreddits |
|
||||||
|
| 1000+ total karma | Access to r/lounge and some restricted subreddits |
|
||||||
|
|
||||||
|
### Building Authority in Niche Subreddits
|
||||||
|
|
||||||
|
Authority is built through consistency and expertise, not volume:
|
||||||
|
|
||||||
|
1. **Pick 3-5 subreddits maximum** -- spreading across 20 subreddits builds no authority anywhere
|
||||||
|
2. **Develop a recognizable voice** -- consistent formatting, depth of answers, specific expertise area
|
||||||
|
3. **Answer the hard questions** -- skip the easy ones that 10 people will answer; tackle the ones that require real expertise
|
||||||
|
4. **Follow up on your own answers** -- if someone asks a follow-up, respond promptly
|
||||||
|
5. **Cite sources and show work** -- "I benchmarked this myself, here are the numbers" is worth 100x "I think X is faster"
|
||||||
|
6. **Accept corrections gracefully** -- being wrong publicly and handling it well builds more trust than never being wrong
|
||||||
|
|
||||||
|
### Cross-Posting Etiquette and Strategy
|
||||||
|
|
||||||
|
Cross-posting (sharing a post from one subreddit to another) has specific norms:
|
||||||
|
|
||||||
|
**Do:**
|
||||||
|
- Use Reddit's built-in cross-post feature (preserves attribution)
|
||||||
|
- Cross-post to subreddits where the content genuinely fits
|
||||||
|
- Add a comment explaining why it is relevant to the new subreddit
|
||||||
|
- Wait at least a few hours between cross-posts (avoid appearing spammy)
|
||||||
|
|
||||||
|
**Don't:**
|
||||||
|
- Cross-post to more than 2-3 subreddits
|
||||||
|
- Cross-post to subreddits that explicitly ban it (check rules)
|
||||||
|
- Copy-paste the same text as a new post instead of cross-posting (treated as spam)
|
||||||
|
- Cross-post your own content excessively
|
||||||
|
|
||||||
|
**Strategic cross-posting pattern**:
|
||||||
|
```
|
||||||
|
1. Post original content in the most specific/niche subreddit first
|
||||||
|
2. If it gains traction (>20 upvotes, positive comments), cross-post to a broader subreddit
|
||||||
|
3. Customize the title for the new audience
|
||||||
|
4. Engage in comments on BOTH subreddits
|
||||||
|
```
|
||||||
|
|
||||||
|
### Handling Negative Feedback and Criticism
|
||||||
|
|
||||||
|
Negative feedback on Reddit is public and permanent. Handle it strategically:
|
||||||
|
|
||||||
|
**Response framework**:
|
||||||
|
```
|
||||||
|
1. PAUSE — Do not respond within the first 15 minutes. Emotional responses backfire.
|
||||||
|
2. ASSESS — Is the criticism valid, partially valid, or trolling?
|
||||||
|
3. RESPOND (or don't):
|
||||||
|
- Valid criticism: Acknowledge, thank them, explain what you will do about it
|
||||||
|
- Partially valid: Acknowledge the valid part, clarify the rest with facts
|
||||||
|
- Trolling/bad faith: Do NOT respond. Silence is the best response.
|
||||||
|
4. FOLLOW UP — If you promised to fix something, come back and confirm when it is done
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response templates by situation**:
|
||||||
|
|
||||||
|
| Situation | Response Pattern |
|
||||||
|
|-----------|-----------------|
|
||||||
|
| Bug report | "Thanks for reporting this. Can you share [details]? I've opened [issue link] to track it." |
|
||||||
|
| Feature complaint | "That's fair feedback. Here's why we made that choice: [reason]. We're considering [alternative]." |
|
||||||
|
| Unfair comparison | "Good question. Here's a direct comparison: [facts]. [Competitor] is great at X, we focus on Y." |
|
||||||
|
| Personal attack | Do not respond. Report if it violates rules. |
|
||||||
|
| "This is trash" | "Sorry it didn't work for you. What specifically went wrong? Happy to help." |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Analytics & Reporting
|
||||||
|
|
||||||
|
### Post Performance Metrics
|
||||||
|
|
||||||
|
Key metrics to track for every post:
|
||||||
|
|
||||||
|
| Metric | Where to Find | What It Means |
|
||||||
|
|--------|--------------|---------------|
|
||||||
|
| Score | `data.score` | Net upvotes (upvotes minus downvotes) |
|
||||||
|
| Upvote ratio | `data.upvote_ratio` | 0.0-1.0, percentage of votes that are upvotes |
|
||||||
|
| Number of comments | `data.num_comments` | Total comments including replies |
|
||||||
|
| Awards | `data.all_awardings` | List of awards received |
|
||||||
|
| Cross-posts | `data.num_crossposts` | How many times others cross-posted it |
|
||||||
|
|
||||||
|
**Fetch post performance**:
|
||||||
|
```bash
|
||||||
|
curl -s -H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||||
|
-A "LibreFang Reddit Hand/1.0" \
|
||||||
|
"https://oauth.reddit.com/by_id/t3_POST_ID"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Quality indicators**:
|
||||||
|
```
|
||||||
|
High engagement: upvote_ratio > 0.85 AND num_comments > 20
|
||||||
|
Controversial: upvote_ratio 0.40-0.60 (heavily split votes)
|
||||||
|
Viral potential: score > 100 within first 2 hours
|
||||||
|
Dead on arrival: score < 5 after 4 hours
|
||||||
|
Comment quality: avg comment length > 100 chars (real discussion vs memes)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Engagement Trend Tracking
|
||||||
|
|
||||||
|
Track performance over time by recording metrics at regular intervals:
|
||||||
|
|
||||||
|
```
|
||||||
|
For each post, capture at:
|
||||||
|
- T+1 hour: score, num_comments, upvote_ratio
|
||||||
|
- T+4 hours: score, num_comments, upvote_ratio
|
||||||
|
- T+24 hours: score, num_comments, upvote_ratio (final snapshot)
|
||||||
|
|
||||||
|
For account-level tracking:
|
||||||
|
- Weekly comment karma change
|
||||||
|
- Weekly post karma change
|
||||||
|
- Number of posts/comments per subreddit
|
||||||
|
- Average score per post by subreddit
|
||||||
|
```
|
||||||
|
|
||||||
|
**Growth trajectory assessment**:
|
||||||
|
| Period | Healthy Growth | Stagnant | Declining |
|
||||||
|
|--------|---------------|----------|-----------|
|
||||||
|
| Weekly karma change | > +50 | -10 to +10 | < -10 |
|
||||||
|
| Avg post score trend | Increasing | Flat | Decreasing |
|
||||||
|
| Comment reply rate | > 30% of comments get replies | 10-30% | < 10% |
|
||||||
|
| New subreddit penetration | 1-2 new per month | 0 | Banned from any |
|
||||||
|
|
||||||
|
### ROI Measurement for Business-Related Reddit Activity
|
||||||
|
|
||||||
|
For teams using Reddit for marketing, community building, or support:
|
||||||
|
|
||||||
|
**Trackable outcomes**:
|
||||||
|
```
|
||||||
|
Direct metrics:
|
||||||
|
- Referral traffic from Reddit (track with UTM parameters in shared links)
|
||||||
|
- Sign-ups/downloads from Reddit referral
|
||||||
|
- Support tickets deflected by Reddit answers
|
||||||
|
- GitHub stars/forks from Reddit posts (track with ?ref=reddit)
|
||||||
|
|
||||||
|
Indirect metrics:
|
||||||
|
- Brand mention volume over time
|
||||||
|
- Sentiment ratio trend (positive / total mentions)
|
||||||
|
- Share of voice vs competitors on Reddit
|
||||||
|
- Community size if you run your own subreddit
|
||||||
|
```
|
||||||
|
|
||||||
|
**Cost calculation**:
|
||||||
|
```
|
||||||
|
Time invested: Hours per week on Reddit * hourly cost
|
||||||
|
Content cost: Time creating Reddit-specific content
|
||||||
|
Tool cost: Monitoring tools, analytics
|
||||||
|
─────────────────────────────────────────────
|
||||||
|
Total cost/week: Sum of above
|
||||||
|
|
||||||
|
ROI = (Value of outcomes - Total cost) / Total cost
|
||||||
|
```
|
||||||
|
|
||||||
|
**Value assignment for outcomes**:
|
||||||
|
| Outcome | Suggested Valuation Method |
|
||||||
|
|---------|--------------------------|
|
||||||
|
| Referral sign-up | Same as other channel CAC |
|
||||||
|
| Support ticket deflected | Average support ticket cost |
|
||||||
|
| GitHub star from Reddit | Track conversion to paying user |
|
||||||
|
| Positive brand mention | Equivalent ad impression value |
|
||||||
|
| Viral post (>1000 score) | Equivalent paid reach cost |
|
||||||
|
|
||||||
|
### Weekly Reddit Activity Report Template
|
||||||
|
|
||||||
|
```
|
||||||
|
## Reddit Activity Report — Week of [Date]
|
||||||
|
|
||||||
|
### Account Health
|
||||||
|
- Current karma: [post] / [comment]
|
||||||
|
- Karma change this week: +/- [N]
|
||||||
|
- Account age: [N] days
|
||||||
|
- Active subreddits: [list]
|
||||||
|
|
||||||
|
### Content Published
|
||||||
|
| Date | Subreddit | Type | Title | Score | Comments | Upvote Ratio |
|
||||||
|
|------|-----------|------|-------|-------|----------|-------------|
|
||||||
|
| | | | | | | |
|
||||||
|
|
||||||
|
### Comments Made
|
||||||
|
- Total comments: [N]
|
||||||
|
- Avg comment score: [N]
|
||||||
|
- Top comment: [link] (score: [N])
|
||||||
|
- Subreddit breakdown: r/sub1 ([N]), r/sub2 ([N])
|
||||||
|
|
||||||
|
### Brand Mentions (External)
|
||||||
|
- Total mentions found: [N]
|
||||||
|
- Sentiment: [N]% positive, [N]% neutral, [N]% negative
|
||||||
|
- Notable threads:
|
||||||
|
1. [Thread title] — [subreddit] — [sentiment] — [link]
|
||||||
|
2. ...
|
||||||
|
|
||||||
|
### Engagement Metrics
|
||||||
|
| Metric | This Week | Last Week | Trend |
|
||||||
|
|--------|-----------|-----------|-------|
|
||||||
|
| Posts published | | | |
|
||||||
|
| Total post score | | | |
|
||||||
|
| Comments made | | | |
|
||||||
|
| Replies received | | | |
|
||||||
|
| Avg response time | | | |
|
||||||
|
|
||||||
|
### Referral Traffic (if tracked)
|
||||||
|
- Clicks from Reddit: [N]
|
||||||
|
- Sign-ups from Reddit: [N]
|
||||||
|
- Top referral post: [link]
|
||||||
|
|
||||||
|
### Next Week Plan
|
||||||
|
- [ ] Target subreddits: [list]
|
||||||
|
- [ ] Content planned: [description]
|
||||||
|
- [ ] Threads to follow up on: [links]
|
||||||
|
```
|
||||||
@@ -442,6 +442,241 @@ token_consumption = "high"
|
|||||||
default_active = true
|
default_active = true
|
||||||
activation_warning = "Researcher hand runs continuously and performs deep research, consuming tokens."
|
activation_warning = "Researcher hand runs continuously and performs deep research, consuming tokens."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "深度研究 Hand"
|
name = "深度研究 Hand"
|
||||||
description = "自主深度研究员——全面调研、交叉验证、事实核查和结构化报告"
|
description = "自主深度研究员——全面调研、交叉验证、事实核查和结构化报告"
|
||||||
|
category = "生产力"
|
||||||
|
|
||||||
|
[i18n.zh.settings.research_depth]
|
||||||
|
label = "研究深度"
|
||||||
|
description = "每次调研的详尽程度"
|
||||||
|
|
||||||
|
[i18n.zh.settings.output_style]
|
||||||
|
label = "输出格式"
|
||||||
|
description = "研究报告的格式风格"
|
||||||
|
|
||||||
|
[i18n.zh.settings.source_verification]
|
||||||
|
label = "来源验证"
|
||||||
|
description = "在引用前通过多个来源交叉验证论述"
|
||||||
|
|
||||||
|
[i18n.zh.settings.max_sources]
|
||||||
|
label = "最大来源数"
|
||||||
|
description = "每次调研参考的最大来源数量"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_follow_up]
|
||||||
|
label = "自动追问"
|
||||||
|
description = "自动研究调查过程中发现的延伸问题"
|
||||||
|
|
||||||
|
[i18n.zh.settings.save_research_log]
|
||||||
|
label = "保存研究日志"
|
||||||
|
description = "保存详细的搜索查询和来源评估记录"
|
||||||
|
|
||||||
|
[i18n.zh.settings.citation_style]
|
||||||
|
label = "引用格式"
|
||||||
|
description = "报告中引用来源的格式"
|
||||||
|
|
||||||
|
[i18n.zh.settings.language]
|
||||||
|
label = "语言"
|
||||||
|
description = "研究和输出的主要语言"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "심층 연구 Hand"
|
||||||
|
description = "자율 심층 연구원 — 철저한 조사, 교차 검증, 팩트체크 및 구조화된 보고서"
|
||||||
|
category = "생산성"
|
||||||
|
|
||||||
|
[i18n.ko.settings.research_depth]
|
||||||
|
label = "연구 깊이"
|
||||||
|
description = "각 조사의 철저함 정도"
|
||||||
|
|
||||||
|
[i18n.ko.settings.output_style]
|
||||||
|
label = "출력 스타일"
|
||||||
|
description = "연구 보고서의 형식 스타일"
|
||||||
|
|
||||||
|
[i18n.ko.settings.source_verification]
|
||||||
|
label = "출처 검증"
|
||||||
|
description = "인용 전 여러 출처를 통해 주장을 교차 검증"
|
||||||
|
|
||||||
|
[i18n.ko.settings.max_sources]
|
||||||
|
label = "최대 출처 수"
|
||||||
|
description = "조사당 참고할 최대 출처 수"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_follow_up]
|
||||||
|
label = "자동 후속 조사"
|
||||||
|
description = "조사 과정에서 발견된 후속 질문을 자동으로 연구"
|
||||||
|
|
||||||
|
[i18n.ko.settings.save_research_log]
|
||||||
|
label = "연구 로그 저장"
|
||||||
|
description = "상세한 검색 쿼리 및 출처 평가 기록 저장"
|
||||||
|
|
||||||
|
[i18n.ko.settings.citation_style]
|
||||||
|
label = "인용 형식"
|
||||||
|
description = "보고서에서 출처를 인용하는 형식"
|
||||||
|
|
||||||
|
[i18n.ko.settings.language]
|
||||||
|
label = "언어"
|
||||||
|
description = "연구 및 출력의 주요 언어"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "ディープリサーチ Hand"
|
||||||
|
description = "自律型深層調査エージェント——徹底的な調査、クロスリファレンス、ファクトチェック、構造化レポート"
|
||||||
|
category = "生産性"
|
||||||
|
|
||||||
|
[i18n.ja.settings.research_depth]
|
||||||
|
label = "調査の深さ"
|
||||||
|
description = "各調査の徹底度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.output_style]
|
||||||
|
label = "出力スタイル"
|
||||||
|
description = "調査レポートのフォーマットスタイル"
|
||||||
|
|
||||||
|
[i18n.ja.settings.source_verification]
|
||||||
|
label = "ソース検証"
|
||||||
|
description = "引用前に複数のソースでクレームをクロスチェックする"
|
||||||
|
|
||||||
|
[i18n.ja.settings.max_sources]
|
||||||
|
label = "最大ソース数"
|
||||||
|
description = "調査ごとに参照するソースの最大数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_follow_up]
|
||||||
|
label = "自動フォローアップ"
|
||||||
|
description = "調査中に発見されたフォローアップ質問を自動的に調査する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.save_research_log]
|
||||||
|
label = "調査ログの保存"
|
||||||
|
description = "詳細な検索クエリとソース評価の記録を保存する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.citation_style]
|
||||||
|
label = "引用スタイル"
|
||||||
|
description = "レポートでのソース引用の形式"
|
||||||
|
|
||||||
|
[i18n.ja.settings.language]
|
||||||
|
label = "言語"
|
||||||
|
description = "調査と出力の主要言語"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Investigación"
|
||||||
|
description = "Investigador autónomo en profundidad — investigación exhaustiva, referencias cruzadas, verificación de hechos e informes estructurados"
|
||||||
|
category = "Productividad"
|
||||||
|
|
||||||
|
[i18n.es.settings.research_depth]
|
||||||
|
label = "Profundidad de investigación"
|
||||||
|
description = "Qué tan exhaustiva debe ser cada investigación"
|
||||||
|
|
||||||
|
[i18n.es.settings.output_style]
|
||||||
|
label = "Estilo de salida"
|
||||||
|
description = "Cómo formatear los informes de investigación"
|
||||||
|
|
||||||
|
[i18n.es.settings.source_verification]
|
||||||
|
label = "Verificación de fuentes"
|
||||||
|
description = "Verificar afirmaciones cruzando múltiples fuentes antes de incluirlas"
|
||||||
|
|
||||||
|
[i18n.es.settings.max_sources]
|
||||||
|
label = "Máximo de fuentes"
|
||||||
|
description = "Número máximo de fuentes a consultar por investigación"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_follow_up]
|
||||||
|
label = "Seguimiento automático"
|
||||||
|
description = "Investigar automáticamente preguntas de seguimiento descubiertas durante la investigación"
|
||||||
|
|
||||||
|
[i18n.es.settings.save_research_log]
|
||||||
|
label = "Guardar registro de investigación"
|
||||||
|
description = "Guardar consultas de búsqueda detalladas y notas de evaluación de fuentes"
|
||||||
|
|
||||||
|
[i18n.es.settings.citation_style]
|
||||||
|
label = "Estilo de citación"
|
||||||
|
description = "Cómo citar fuentes en los informes"
|
||||||
|
|
||||||
|
[i18n.es.settings.language]
|
||||||
|
label = "Idioma"
|
||||||
|
description = "Idioma principal para la investigación y los resultados"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand de Recherche Approfondie"
|
||||||
|
description = "Chercheur autonome en profondeur — recherche exhaustive, références croisées, vérification des faits et rapports structurés"
|
||||||
|
category = "Productivité"
|
||||||
|
|
||||||
|
[i18n.fr.settings.research_depth]
|
||||||
|
label = "Profondeur de recherche"
|
||||||
|
description = "Niveau de minutie de chaque investigation"
|
||||||
|
|
||||||
|
[i18n.fr.settings.output_style]
|
||||||
|
label = "Style de sortie"
|
||||||
|
description = "Style de formatage du rapport de recherche"
|
||||||
|
|
||||||
|
[i18n.fr.settings.source_verification]
|
||||||
|
label = "Vérification des sources"
|
||||||
|
description = "Vérifier les affirmations auprès de plusieurs sources avant de citer"
|
||||||
|
|
||||||
|
[i18n.fr.settings.max_sources]
|
||||||
|
label = "Nombre maximum de sources"
|
||||||
|
description = "Nombre maximum de sources à consulter par recherche"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_follow_up]
|
||||||
|
label = "Suivi automatique"
|
||||||
|
description = "Rechercher automatiquement les questions de suivi découvertes pendant l'investigation"
|
||||||
|
|
||||||
|
[i18n.fr.settings.save_research_log]
|
||||||
|
label = "Sauvegarder le journal de recherche"
|
||||||
|
description = "Conserver les journaux détaillés des requêtes de recherche et des évaluations de sources"
|
||||||
|
|
||||||
|
[i18n.fr.settings.citation_style]
|
||||||
|
label = "Style de citation"
|
||||||
|
description = "Format de citation des sources dans les rapports"
|
||||||
|
|
||||||
|
[i18n.fr.settings.language]
|
||||||
|
label = "Langue"
|
||||||
|
description = "Langue principale pour la recherche et les résultats"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Tiefenforschungs-Hand"
|
||||||
|
description = "Autonomer Tiefenforscher — gründliche Untersuchung, Querverweise, Faktencheck und strukturierte Berichte"
|
||||||
|
category = "Produktivität"
|
||||||
|
|
||||||
|
[i18n.de.settings.research_depth]
|
||||||
|
label = "Forschungstiefe"
|
||||||
|
description = "Gründlichkeit jeder Untersuchung"
|
||||||
|
|
||||||
|
[i18n.de.settings.output_style]
|
||||||
|
label = "Ausgabestil"
|
||||||
|
description = "Formatierungsstil des Forschungsberichts"
|
||||||
|
|
||||||
|
[i18n.de.settings.source_verification]
|
||||||
|
label = "Quellenverifikation"
|
||||||
|
description = "Behauptungen vor dem Zitieren mit mehreren Quellen gegenkontrollieren"
|
||||||
|
|
||||||
|
[i18n.de.settings.max_sources]
|
||||||
|
label = "Maximale Quellen"
|
||||||
|
description = "Maximale Anzahl der pro Untersuchung zu konsultierenden Quellen"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_follow_up]
|
||||||
|
label = "Automatisches Nachfassen"
|
||||||
|
description = "Während der Untersuchung entdeckte Folgefragen automatisch recherchieren"
|
||||||
|
|
||||||
|
[i18n.de.settings.save_research_log]
|
||||||
|
label = "Forschungsprotokoll speichern"
|
||||||
|
description = "Detaillierte Protokolle der Suchabfragen und Quellenbewertungen speichern"
|
||||||
|
|
||||||
|
[i18n.de.settings.citation_style]
|
||||||
|
label = "Zitierstil"
|
||||||
|
description = "Format für Quellenangaben in Berichten"
|
||||||
|
|
||||||
|
[i18n.de.settings.language]
|
||||||
|
label = "Sprache"
|
||||||
|
description = "Hauptsprache für Forschung und Ergebnisse"
|
||||||
@@ -183,6 +183,179 @@ After synthesis, explicitly note:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Technology Adoption Decision
|
||||||
|
|
||||||
|
**Question**: "Should our company adopt Rust for backend services?"
|
||||||
|
|
||||||
|
**Phase 1 — Define**
|
||||||
|
|
||||||
|
Decompose into sub-questions:
|
||||||
|
```
|
||||||
|
Main: "Should our company adopt Rust for backend services?"
|
||||||
|
Sub-questions:
|
||||||
|
1. What are Rust's strengths for backend work? (factual)
|
||||||
|
2. What are the real-world costs of adoption? (factual + case studies)
|
||||||
|
3. How does Rust compare to our current stack (Go) on key metrics? (comparative)
|
||||||
|
4. What do teams of our size (15-30 engineers) report? (case studies)
|
||||||
|
5. What is the hiring/training landscape? (survey)
|
||||||
|
6. What are the migration paths and risks? (how-to + risk analysis)
|
||||||
|
```
|
||||||
|
|
||||||
|
Scope constraints: Backend HTTP services, team of 20 engineers currently using Go, latency-sensitive workloads, 18-month planning horizon.
|
||||||
|
|
||||||
|
**Phase 2 — Search (multi-strategy)**
|
||||||
|
```
|
||||||
|
Strategy 1 (Direct): "Rust backend production experience"
|
||||||
|
Strategy 2 (Authoritative): site:arxiv.org "Rust" "memory safety" performance
|
||||||
|
Strategy 3 (Practical): "migrating from Go to Rust" blog OR postmortem
|
||||||
|
Strategy 4 (Contrarian): "Rust backend" problems OR regret OR "not worth"
|
||||||
|
Strategy 5 (Data): "Rust" "developer survey" adoption 2024 2025
|
||||||
|
Strategy 6 (Case studies): site:engineering.*.com Rust adoption
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 3 — Evaluate (CRAAP scoring)**
|
||||||
|
```
|
||||||
|
Source 1: Rust annual survey (rust-lang.org) → A (primary, current)
|
||||||
|
Source 2: Discord engineering blog on Rust migration → A (primary, practitioner)
|
||||||
|
Source 3: Figma "Rust in production" post → A (primary, detailed metrics)
|
||||||
|
Source 4: Random Medium post "Rust is the future" → D (no credentials, no data)
|
||||||
|
Source 5: AWS SDK for Rust announcement → B (authoritative, but marketing)
|
||||||
|
Source 6: "Why we moved back to Go" blog post → B (primary experience, single case)
|
||||||
|
Source 7: Stack Overflow developer survey → A (large sample, methodology documented)
|
||||||
|
```
|
||||||
|
|
||||||
|
Drop Source 4 entirely. Use Source 6 as a counterpoint despite being a single case.
|
||||||
|
|
||||||
|
**Phase 4 — Synthesize**
|
||||||
|
```
|
||||||
|
FINDING 1: Rust delivers measurable performance and reliability gains
|
||||||
|
Evidence for: Discord reported 50% memory reduction after migration [2].
|
||||||
|
Figma measured p99 latency improvements of 3-5x for compute-heavy paths [3].
|
||||||
|
Evidence against: Gains may be marginal for I/O-bound CRUD services [6].
|
||||||
|
Confidence: High for compute-intensive workloads, medium for I/O-bound.
|
||||||
|
|
||||||
|
FINDING 2: Adoption cost is front-loaded and significant
|
||||||
|
Evidence for: Average ramp-up time for experienced Go/C++ engineers is
|
||||||
|
3-6 months to productive Rust [2][7]. Compile times 2-5x longer than Go [3].
|
||||||
|
Evidence against: Teams report that after the learning curve, maintenance
|
||||||
|
costs drop due to fewer production incidents [2][3].
|
||||||
|
Confidence: High
|
||||||
|
|
||||||
|
FINDING 3: Hiring pipeline is narrow but growing
|
||||||
|
Evidence for: Rust ranks as "most admired" language for 8 consecutive years
|
||||||
|
in SO survey, but only ~13% of developers use it professionally [7].
|
||||||
|
Evidence against: Rust job demand is growing ~40% YoY [7].
|
||||||
|
Confidence: Medium — hiring data is self-reported.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 5 — Verify and deliver**
|
||||||
|
|
||||||
|
Cross-check: Discord and Figma metrics are confirmed by independent engineering talks. SO survey methodology is published and peer-reviewed.
|
||||||
|
|
||||||
|
Final recommendation structure:
|
||||||
|
```
|
||||||
|
Adopt for: Latency-sensitive, compute-heavy services (strong evidence)
|
||||||
|
Avoid for: Simple CRUD APIs where Go is already performant (low ROI)
|
||||||
|
Mitigate hiring risk: Invest in internal training, start with one team
|
||||||
|
Timeline: 6-month pilot on a non-critical service before broader adoption
|
||||||
|
Confidence: Medium-high — strong technical evidence, moderate organizational evidence
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example 2: Incident Analysis
|
||||||
|
|
||||||
|
**Question**: "What caused the 2024 CrowdStrike outage and what are the implications?"
|
||||||
|
|
||||||
|
**Phase 1 — Define**
|
||||||
|
|
||||||
|
This is a causal question with survey elements. Decompose:
|
||||||
|
```
|
||||||
|
Main: "What caused the 2024 CrowdStrike outage?"
|
||||||
|
Sub-questions:
|
||||||
|
1. What happened? (timeline — factual)
|
||||||
|
2. What was the technical root cause? (causal)
|
||||||
|
3. What was the scope of impact? (factual, data)
|
||||||
|
4. How did CrowdStrike respond? (factual)
|
||||||
|
5. What systemic issues does this reveal? (analytical)
|
||||||
|
6. What changed in the industry as a result? (survey + predictive)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 2 — Search**
|
||||||
|
```
|
||||||
|
Strategy 1 (Primary): site:crowdstrike.com "July 2024" postmortem OR incident
|
||||||
|
Strategy 2 (Technical): "CrowdStrike" "channel file" root cause analysis
|
||||||
|
Strategy 3 (Impact data): "CrowdStrike outage" damages OR cost OR impact 2024
|
||||||
|
Strategy 4 (Regulatory): site:gov "CrowdStrike" review OR hearing OR testimony
|
||||||
|
Strategy 5 (Contrarian): "CrowdStrike" "kernel driver" criticism before:2024-07-01
|
||||||
|
Strategy 6 (Expert): "CrowdStrike outage" analysis site:*.edu OR site:arxiv.org
|
||||||
|
```
|
||||||
|
|
||||||
|
Note Strategy 5: searching for pre-incident criticism establishes whether warnings existed.
|
||||||
|
|
||||||
|
**Phase 3 — Evaluate and build timeline**
|
||||||
|
```
|
||||||
|
Timeline (verified — Level 3):
|
||||||
|
2024-07-19 04:09 UTC CrowdStrike deploys Channel File 291 update
|
||||||
|
2024-07-19 04:09-05:27 Falcon sensor crashes → Windows BSOD on boot
|
||||||
|
2024-07-19 05:27 UTC CrowdStrike reverts the channel file
|
||||||
|
2024-07-19 ~06:00 Scope becomes apparent: 8.5M Windows devices affected
|
||||||
|
2024-07-19-21 Manual remediation required (boot to Safe Mode, delete file)
|
||||||
|
2024-07-20-25 Airlines, hospitals, banks in multi-day recovery
|
||||||
|
|
||||||
|
Sources: CrowdStrike PIR [A], Microsoft blog [A], Reuters reporting [B],
|
||||||
|
Congressional testimony transcript [A]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 4 — Synthesize root cause**
|
||||||
|
```
|
||||||
|
FINDING 1: Technical root cause was an out-of-bounds memory read
|
||||||
|
A channel file update (type 291) contained malformed data.
|
||||||
|
The Falcon sensor's Content Interpreter triggered an OOB read,
|
||||||
|
causing a kernel-level crash (BSOD). The sensor ran as a kernel
|
||||||
|
driver, so its crash took down the entire OS.
|
||||||
|
Sources: CrowdStrike PIR [A], independent reverse engineering [B]
|
||||||
|
Confidence: High (confirmed by vendor + independent analysis)
|
||||||
|
|
||||||
|
FINDING 2: The update bypassed adequate testing
|
||||||
|
Channel files ("rapid response content") used a different validation
|
||||||
|
pipeline than sensor code. The Template Type tested had 20 input
|
||||||
|
fields; the deployed content provided 21. The validator did not
|
||||||
|
catch the mismatch.
|
||||||
|
Sources: CrowdStrike PIR [A], Congressional testimony [A]
|
||||||
|
Confidence: High
|
||||||
|
|
||||||
|
FINDING 3: Impact — $5-10B+ in estimated damages
|
||||||
|
8.5M devices affected (Microsoft estimate). Delta Air Lines alone
|
||||||
|
reported $500M in losses. Parametrix estimated $5.4B in direct
|
||||||
|
losses for Fortune 500 companies.
|
||||||
|
Sources: Microsoft [A], Parametrix [B], Delta SEC filing [A]
|
||||||
|
Confidence: Medium-high (total figure is estimated, individual claims are documented)
|
||||||
|
|
||||||
|
FINDING 4: Systemic issue — monoculture risk in security infrastructure
|
||||||
|
A single vendor's kernel-level agent was present on ~24% of
|
||||||
|
enterprise Windows endpoints. Pre-incident criticism of kernel-mode
|
||||||
|
security agents existed but was not widely acted upon.
|
||||||
|
Sources: Congressional hearing [A], pre-incident security research [B]
|
||||||
|
Confidence: High
|
||||||
|
```
|
||||||
|
|
||||||
|
**Phase 5 — Verify and present implications**
|
||||||
|
```
|
||||||
|
Verified implications (cross-referenced across 3+ independent sources):
|
||||||
|
1. Regulatory pressure on kernel-mode security agents accelerated
|
||||||
|
2. Microsoft announced Windows Resiliency Initiative (user-mode alternatives)
|
||||||
|
3. Enterprise customers began requiring staged/canary rollout for security updates
|
||||||
|
4. Cyber insurance models updated to account for single-vendor concentration
|
||||||
|
|
||||||
|
Remaining uncertainties:
|
||||||
|
- Full financial impact is still in litigation (Delta v. CrowdStrike)
|
||||||
|
- Long-term market share impact on CrowdStrike is unclear
|
||||||
|
- Whether kernel-mode restrictions will actually be enforced
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Citation Formats
|
## Citation Formats
|
||||||
|
|
||||||
### Inline URL
|
### Inline URL
|
||||||
@@ -325,3 +498,99 @@ Be aware of these biases during research:
|
|||||||
- Check if findings have been replicated
|
- Check if findings have been replicated
|
||||||
- Preprints have not been peer-reviewed — note this caveat
|
- Preprints have not been peer-reviewed — note this caveat
|
||||||
- p-values and effect sizes both matter — not just "statistically significant"
|
- p-values and effect sizes both matter — not just "statistically significant"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Research Shortcuts
|
||||||
|
|
||||||
|
### When to Stop Researching
|
||||||
|
|
||||||
|
Research has diminishing returns. Recognize these signals:
|
||||||
|
|
||||||
|
**Stop signals — you have enough**:
|
||||||
|
- Three independent sources converge on the same answer
|
||||||
|
- New searches return sources you have already seen
|
||||||
|
- The last 3 searches added no new information or perspectives
|
||||||
|
- You have found primary source data that directly answers the question
|
||||||
|
- Remaining disagreements are about edge cases, not the core finding
|
||||||
|
|
||||||
|
**Keep going signals — you do not have enough**:
|
||||||
|
- Only one source supports a critical claim
|
||||||
|
- Two credible sources directly contradict each other with no resolution
|
||||||
|
- The requester's specific context (industry, scale, constraints) is not addressed
|
||||||
|
- You have secondary reporting but no primary source for a key fact
|
||||||
|
- Your confidence assessment would be "low" on a central finding
|
||||||
|
|
||||||
|
**Time-boxing rule**: For a standard research question, allocate effort roughly as:
|
||||||
|
```
|
||||||
|
Quick facts: 2-4 searches, 1-2 minutes
|
||||||
|
Standard question: 6-12 searches, 5-10 minutes
|
||||||
|
Deep dive: 15-30 searches, 20-40 minutes
|
||||||
|
```
|
||||||
|
If you exceed 2x the expected searches without convergence, stop and report what you have with explicit gaps noted.
|
||||||
|
|
||||||
|
### Quick Assessment vs Deep Dive
|
||||||
|
|
||||||
|
Not every question deserves a full 5-phase research process. Use this decision matrix:
|
||||||
|
|
||||||
|
```
|
||||||
|
Quick assessment (skip to synthesis fast):
|
||||||
|
✓ Question has a single factual answer
|
||||||
|
✓ Authoritative primary source exists and is accessible
|
||||||
|
✓ Low stakes — wrong answer has minimal consequences
|
||||||
|
✓ Requester wants speed over thoroughness
|
||||||
|
Example: "What version of Python dropped GIL?"
|
||||||
|
→ Check python.org docs/PEPs, answer in one search.
|
||||||
|
|
||||||
|
Standard research (full 5-phase process):
|
||||||
|
✓ Comparative or analytical question
|
||||||
|
✓ Multiple valid perspectives exist
|
||||||
|
✓ Answer will inform a decision
|
||||||
|
✓ Moderate stakes
|
||||||
|
Example: "React vs Svelte for our new dashboard?"
|
||||||
|
→ Full decomposition, multi-source, synthesis needed.
|
||||||
|
|
||||||
|
Deep dive (extended research with formal deliverable):
|
||||||
|
✓ High-stakes decision (architecture, vendor, strategy)
|
||||||
|
✓ Conflicting information is likely
|
||||||
|
✓ Historical context and trend analysis needed
|
||||||
|
✓ Requester expects a report they can share with others
|
||||||
|
Example: "Should we move from AWS to multi-cloud?"
|
||||||
|
→ Multiple sub-questions, 10+ sources, formal report.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Source Reuse Patterns
|
||||||
|
|
||||||
|
Not every question starts from zero. Build efficiency by recognizing reusable sources.
|
||||||
|
|
||||||
|
**Tier 1 — Canonical references (always check first for their domain)**:
|
||||||
|
```
|
||||||
|
Programming languages: Official docs, language spec, release notes
|
||||||
|
Cloud services: AWS/GCP/Azure docs, status pages, pricing pages
|
||||||
|
Security: CVE databases, vendor advisories, NIST NVD
|
||||||
|
Statistics: Official census/survey data, World Bank, OECD
|
||||||
|
Companies: SEC filings (EDGAR), official IR pages
|
||||||
|
Open source: GitHub repo, CHANGELOG, issue tracker
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tier 2 — High-signal aggregators (good starting points)**:
|
||||||
|
```
|
||||||
|
Technology trends: ThoughtWorks Radar, Stack Overflow survey, TIOBE
|
||||||
|
Security incidents: CISA advisories, Krebs on Security
|
||||||
|
Academic papers: Google Scholar, Semantic Scholar, arXiv
|
||||||
|
Industry analysis: Gartner (with bias caveat), a16z, Sequoia
|
||||||
|
Developer experience: JetBrains survey, GitHub Octoverse
|
||||||
|
```
|
||||||
|
|
||||||
|
**Tier 3 — Practitioner sources (for real-world validation)**:
|
||||||
|
```
|
||||||
|
Engineering blogs: Company engineering blogs (Netflix, Uber, Stripe, Discord)
|
||||||
|
Conference talks: Recorded talks from Strange Loop, QCon, KubeCon
|
||||||
|
Community discussion: Hacker News (comments often more valuable than articles),
|
||||||
|
Reddit (r/programming, r/devops, domain-specific subs)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Anti-patterns to avoid**:
|
||||||
|
- Do not reuse a source across topics just because it scored well once — re-evaluate CRAAP for the new topic
|
||||||
|
- Do not treat aggregator rankings (Gartner Magic Quadrant, G2 reviews) as primary evidence — they are influenced by vendor spending
|
||||||
|
- Do not assume a source's authority transfers across domains — a security vendor's blog is authoritative on threats but not on database performance
|
||||||
@@ -378,6 +378,241 @@ token_consumption = "medium"
|
|||||||
default_active = true
|
default_active = true
|
||||||
activation_warning = "Strategist hand runs continuously and performs strategic analysis, consuming tokens."
|
activation_warning = "Strategist hand runs continuously and performs strategic analysis, consuming tokens."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "策略分析 Hand"
|
name = "策略分析 Hand"
|
||||||
description = "自主策略分析师——市场研究、竞争分析、商业规划和战略建议"
|
description = "自主策略分析师——市场研究、竞争分析、商业规划和战略建议"
|
||||||
|
category = "生产力"
|
||||||
|
|
||||||
|
[i18n.zh.settings.focus_area]
|
||||||
|
label = "聚焦方向"
|
||||||
|
description = "战略分析的主要方向"
|
||||||
|
|
||||||
|
[i18n.zh.settings.analysis_depth]
|
||||||
|
label = "分析深度"
|
||||||
|
description = "每次战略分析的详尽程度"
|
||||||
|
|
||||||
|
[i18n.zh.settings.industry]
|
||||||
|
label = "行业"
|
||||||
|
description = "重点分析的行业(例如 SaaS、金融科技、医疗健康)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.competitors]
|
||||||
|
label = "主要竞争对手"
|
||||||
|
description = "需要追踪的竞争对手列表(逗号分隔)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_monitor]
|
||||||
|
label = "自动监控"
|
||||||
|
description = "自动追踪竞争对手动态和市场变化"
|
||||||
|
|
||||||
|
[i18n.zh.settings.report_format]
|
||||||
|
label = "报告格式"
|
||||||
|
description = "战略报告的格式风格"
|
||||||
|
|
||||||
|
[i18n.zh.settings.confidence_threshold]
|
||||||
|
label = "置信度阈值"
|
||||||
|
description = "报告中纳入分析结论的最低置信度"
|
||||||
|
|
||||||
|
[i18n.zh.settings.frameworks]
|
||||||
|
label = "首选分析框架"
|
||||||
|
description = "优先使用的战略分析框架(逗号分隔,例如 SWOT,Porter,PESTEL)"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Estrategia"
|
||||||
|
description = "Analista estratégico autónomo — investigación de mercado, análisis competitivo, planificación empresarial y recomendaciones estratégicas"
|
||||||
|
category = "Productividad"
|
||||||
|
|
||||||
|
[i18n.es.settings.focus_area]
|
||||||
|
label = "Área de enfoque"
|
||||||
|
description = "Área principal del análisis estratégico"
|
||||||
|
|
||||||
|
[i18n.es.settings.analysis_depth]
|
||||||
|
label = "Profundidad del análisis"
|
||||||
|
description = "Nivel de detalle de cada análisis estratégico"
|
||||||
|
|
||||||
|
[i18n.es.settings.industry]
|
||||||
|
label = "Industria"
|
||||||
|
description = "Industria principal en la que enfocar el análisis (ej. SaaS, fintech, salud)"
|
||||||
|
|
||||||
|
[i18n.es.settings.competitors]
|
||||||
|
label = "Competidores clave"
|
||||||
|
description = "Lista de competidores a rastrear separados por comas"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_monitor]
|
||||||
|
label = "Monitoreo automático"
|
||||||
|
description = "Rastrear automáticamente movimientos de competidores y cambios del mercado"
|
||||||
|
|
||||||
|
[i18n.es.settings.report_format]
|
||||||
|
label = "Formato de informe"
|
||||||
|
description = "Formato de los informes estratégicos"
|
||||||
|
|
||||||
|
[i18n.es.settings.confidence_threshold]
|
||||||
|
label = "Umbral de confianza"
|
||||||
|
description = "Nivel mínimo de confianza para incluir hallazgos en los informes"
|
||||||
|
|
||||||
|
[i18n.es.settings.frameworks]
|
||||||
|
label = "Marcos de análisis preferidos"
|
||||||
|
description = "Marcos estratégicos a priorizar (separados por comas, ej. SWOT, Porter, PESTEL)"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "戦略分析 Hand"
|
||||||
|
description = "自律型戦略アナリスト——市場調査、競合分析、事業計画、戦略的提言"
|
||||||
|
category = "生産性"
|
||||||
|
|
||||||
|
[i18n.ja.settings.focus_area]
|
||||||
|
label = "フォーカスエリア"
|
||||||
|
description = "戦略分析の主な対象分野"
|
||||||
|
|
||||||
|
[i18n.ja.settings.analysis_depth]
|
||||||
|
label = "分析の深さ"
|
||||||
|
description = "各戦略分析の詳細度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.industry]
|
||||||
|
label = "業界"
|
||||||
|
description = "分析の対象となる主要業界(例: SaaS、フィンテック、ヘルスケア)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.competitors]
|
||||||
|
label = "主要な競合"
|
||||||
|
description = "追跡する競合のリスト(カンマ区切り)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_monitor]
|
||||||
|
label = "自動監視"
|
||||||
|
description = "競合の動向と市場の変化を自動的に追跡する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.report_format]
|
||||||
|
label = "レポート形式"
|
||||||
|
description = "戦略レポートのフォーマット"
|
||||||
|
|
||||||
|
[i18n.ja.settings.confidence_threshold]
|
||||||
|
label = "信頼度しきい値"
|
||||||
|
description = "レポートに分析結果を含めるための最低信頼度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.frameworks]
|
||||||
|
label = "優先フレームワーク"
|
||||||
|
description = "優先的に使用する戦略分析フレームワーク(カンマ区切り、例: SWOT,Porter,PESTEL)"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Stratégique"
|
||||||
|
description = "Analyste stratégique autonome — étude de marché, analyse concurrentielle, planification d'entreprise et recommandations stratégiques"
|
||||||
|
category = "Productivité"
|
||||||
|
|
||||||
|
[i18n.fr.settings.focus_area]
|
||||||
|
label = "Domaine d'intérêt"
|
||||||
|
description = "Domaine principal de l'analyse stratégique"
|
||||||
|
|
||||||
|
[i18n.fr.settings.analysis_depth]
|
||||||
|
label = "Profondeur d'analyse"
|
||||||
|
description = "Niveau de détail de chaque analyse stratégique"
|
||||||
|
|
||||||
|
[i18n.fr.settings.industry]
|
||||||
|
label = "Secteur"
|
||||||
|
description = "Secteur principal d'analyse (ex. SaaS, fintech, santé)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.competitors]
|
||||||
|
label = "Concurrents clés"
|
||||||
|
description = "Liste de concurrents à suivre séparée par des virgules"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_monitor]
|
||||||
|
label = "Surveillance automatique"
|
||||||
|
description = "Suivre automatiquement les mouvements des concurrents et les évolutions du marché"
|
||||||
|
|
||||||
|
[i18n.fr.settings.report_format]
|
||||||
|
label = "Format de rapport"
|
||||||
|
description = "Format des rapports stratégiques"
|
||||||
|
|
||||||
|
[i18n.fr.settings.confidence_threshold]
|
||||||
|
label = "Seuil de confiance"
|
||||||
|
description = "Niveau de confiance minimum pour inclure les résultats dans les rapports"
|
||||||
|
|
||||||
|
[i18n.fr.settings.frameworks]
|
||||||
|
label = "Cadres d'analyse préférés"
|
||||||
|
description = "Cadres d'analyse stratégique à privilégier (séparés par des virgules, ex. SWOT, Porter, PESTEL)"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Strategie-Hand"
|
||||||
|
description = "Autonomer Strategieanalyst — Marktforschung, Wettbewerbsanalyse, Geschäftsplanung und strategische Empfehlungen"
|
||||||
|
category = "Produktivität"
|
||||||
|
|
||||||
|
[i18n.de.settings.focus_area]
|
||||||
|
label = "Fokusbereich"
|
||||||
|
description = "Hauptbereich der strategischen Analyse"
|
||||||
|
|
||||||
|
[i18n.de.settings.analysis_depth]
|
||||||
|
label = "Analysetiefe"
|
||||||
|
description = "Detailgrad jeder strategischen Analyse"
|
||||||
|
|
||||||
|
[i18n.de.settings.industry]
|
||||||
|
label = "Branche"
|
||||||
|
description = "Hauptbranche für die Analyse (z.B. SaaS, Fintech, Gesundheitswesen)"
|
||||||
|
|
||||||
|
[i18n.de.settings.competitors]
|
||||||
|
label = "Wichtige Wettbewerber"
|
||||||
|
description = "Kommagetrennte Liste der zu verfolgenden Wettbewerber"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_monitor]
|
||||||
|
label = "Automatische Überwachung"
|
||||||
|
description = "Wettbewerberbewegungen und Marktveränderungen automatisch verfolgen"
|
||||||
|
|
||||||
|
[i18n.de.settings.report_format]
|
||||||
|
label = "Berichtsformat"
|
||||||
|
description = "Format der Strategieberichte"
|
||||||
|
|
||||||
|
[i18n.de.settings.confidence_threshold]
|
||||||
|
label = "Konfidenzschwelle"
|
||||||
|
description = "Mindest-Konfidenzniveau für die Aufnahme von Ergebnissen in Berichte"
|
||||||
|
|
||||||
|
[i18n.de.settings.frameworks]
|
||||||
|
label = "Bevorzugte Analyse-Frameworks"
|
||||||
|
description = "Bevorzugte strategische Analyse-Frameworks (kommagetrennt, z.B. SWOT, Porter, PESTEL)"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "전략 분석 Hand"
|
||||||
|
description = "자율 전략 분석가 — 시장 조사, 경쟁 분석, 사업 계획 및 전략적 권고"
|
||||||
|
category = "생산성"
|
||||||
|
|
||||||
|
[i18n.ko.settings.focus_area]
|
||||||
|
label = "집중 분야"
|
||||||
|
description = "전략 분석의 주요 방향"
|
||||||
|
|
||||||
|
[i18n.ko.settings.analysis_depth]
|
||||||
|
label = "분석 깊이"
|
||||||
|
description = "각 전략 분석의 철저함 정도"
|
||||||
|
|
||||||
|
[i18n.ko.settings.industry]
|
||||||
|
label = "산업"
|
||||||
|
description = "분석의 중점 산업 (예: SaaS, 핀테크, 헬스케어)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.competitors]
|
||||||
|
label = "주요 경쟁사"
|
||||||
|
description = "추적할 경쟁사 목록 (쉼표로 구분)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_monitor]
|
||||||
|
label = "자동 모니터링"
|
||||||
|
description = "경쟁사 동향 및 시장 변화를 자동으로 추적"
|
||||||
|
|
||||||
|
[i18n.ko.settings.report_format]
|
||||||
|
label = "보고서 형식"
|
||||||
|
description = "전략 보고서의 형식 스타일"
|
||||||
|
|
||||||
|
[i18n.ko.settings.confidence_threshold]
|
||||||
|
label = "신뢰도 임계값"
|
||||||
|
description = "보고서에 분석 결과를 포함하기 위한 최소 신뢰도"
|
||||||
|
|
||||||
|
[i18n.ko.settings.frameworks]
|
||||||
|
label = "선호 분석 프레임워크"
|
||||||
|
description = "우선적으로 사용할 전략 분석 프레임워크 (쉼표로 구분, 예: SWOT,Porter,PESTEL)"
|
||||||
@@ -236,3 +236,725 @@ Employee Count: [Growth indicator]
|
|||||||
## Implementation
|
## Implementation
|
||||||
[How to execute the recommendation]
|
[How to execute the recommendation]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: B2B SaaS Market Entry into Japan
|
||||||
|
|
||||||
|
**Context**: A US-based B2B SaaS company (project management tool, $15M ARR, 200 employees) evaluating entry into the Japanese market.
|
||||||
|
|
||||||
|
**PESTEL Analysis — Japan B2B SaaS (2025):**
|
||||||
|
|
||||||
|
| Factor | Assessment | Impact | Score (1-5) |
|
||||||
|
|--------|-----------|--------|-------------|
|
||||||
|
| **Political** | Stable democracy; strong US-Japan trade relations; Digital Agency pushing government digitization | Positive | 4 |
|
||||||
|
| **Economic** | GDP $4.2T; weak yen (150 JPY/USD) makes USD-priced SaaS expensive; enterprise IT spend growing 4% YoY | Mixed | 3 |
|
||||||
|
| **Social** | Aging workforce accelerates automation need; consensus-driven decision making lengthens sales cycles (avg 6-9 months); strong preference for local-language support | Critical constraint | 2 |
|
||||||
|
| **Technological** | High internet penetration (93%); cloud adoption lagging US by 3-5 years but accelerating; 5G rollout complete in urban areas | Opportunity | 4 |
|
||||||
|
| **Environmental** | ESG reporting mandated for listed companies from 2023; sustainability-linked procurement gaining traction | Moderate opportunity | 3 |
|
||||||
|
| **Legal** | APPI (Act on Protection of Personal Information) requires data residency consideration; strict labor laws affect HR SaaS | Compliance cost | 2 |
|
||||||
|
|
||||||
|
**PESTEL Score**: 18/30 — Moderately favorable. Key risk: social/cultural factors demand significant localization investment.
|
||||||
|
|
||||||
|
**Porter's Five Forces — Japan Project Management SaaS:**
|
||||||
|
|
||||||
|
| Force | Rating | Evidence |
|
||||||
|
|-------|--------|---------|
|
||||||
|
| New Entrants | 2/5 | High localization cost ($500K-$1M); relationship-driven market favors incumbents |
|
||||||
|
| Supplier Power | 1/5 | Cloud infrastructure (AWS Tokyo, Azure Japan) is commodity; no supplier concentration |
|
||||||
|
| Buyer Power | 4/5 | Enterprise buyers demand customization; long procurement cycles give buyers leverage; RFP-driven purchasing |
|
||||||
|
| Substitutes | 3/5 | Excel/spreadsheet culture deeply entrenched; domestic tools (Backlog, Jooto) have cultural fit advantage |
|
||||||
|
| Rivalry | 4/5 | Asana, Monday.com, Notion already present; domestic players Backlog (Nulab) and Redmine have loyal bases |
|
||||||
|
|
||||||
|
**Go-to-Market Recommendation:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Strategy: Partner-Led Entry (not direct sales)
|
||||||
|
Timeline: 18 months to first enterprise deal
|
||||||
|
|
||||||
|
Phase 1 (Months 1-6): Foundation
|
||||||
|
- Hire Country Manager (must be bilingual Japanese national)
|
||||||
|
- Full UI/UX localization (not just translation — date formats, name order, honorifics)
|
||||||
|
- Achieve ISMAP certification (required for government/enterprise procurement)
|
||||||
|
- Data residency: Deploy on AWS Tokyo region
|
||||||
|
- Budget: $800K
|
||||||
|
|
||||||
|
Phase 2 (Months 4-12): Channel Development
|
||||||
|
- Sign 2-3 SIer (System Integrator) partners: target NTT Data, Fujitsu, NEC
|
||||||
|
- Japanese SIers control 60% of enterprise software purchasing decisions
|
||||||
|
- Co-develop integration with domestic tools (kintone, Sansan, freee)
|
||||||
|
- Budget: $600K (partner enablement + integration development)
|
||||||
|
|
||||||
|
Phase 3 (Months 8-18): Market Penetration
|
||||||
|
- Target mid-market first (500-2000 employees) — faster decision cycles than enterprise
|
||||||
|
- Launch at Japan IT Week (Spring/Autumn) and SaaS Industry Conference
|
||||||
|
- Content marketing: Japanese-language case studies, webinars with local customers
|
||||||
|
- Target: 20 paying customers, $500K ARR by month 18
|
||||||
|
- Budget: $400K
|
||||||
|
|
||||||
|
Total Investment: $1.8M over 18 months
|
||||||
|
Break-even: Month 30 (projected)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Decision**: Proceed with caution. The $4.2T economy and cloud adoption tailwind justify the investment, but only with proper localization and channel strategy. Direct sales without SIer partnerships has a historically high failure rate (>70% for foreign SaaS in Japan).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 2: Competitive Response — Major Player Enters Your Niche
|
||||||
|
|
||||||
|
**Context**: You run a $5M ARR vertical SaaS for veterinary clinics (500 customers, 15% market share). Salesforce just announced "Salesforce for Veterinary" — a vertical solution built on their platform.
|
||||||
|
|
||||||
|
**Threat Assessment:**
|
||||||
|
|
||||||
|
| Dimension | Your Position | Salesforce | Gap |
|
||||||
|
|-----------|--------------|------------|-----|
|
||||||
|
| Brand recognition | Niche leader | Global enterprise brand | Large — but irrelevant in vet niche |
|
||||||
|
| Product depth | Purpose-built (8 years domain expertise) | Horizontal platform with vertical skin | Strong advantage |
|
||||||
|
| Price point | $200/mo per clinic | $500/mo estimated (Salesforce pricing) | 2.5x cheaper |
|
||||||
|
| Implementation time | 2 weeks | 3-6 months (typical SF implementation) | Strong advantage |
|
||||||
|
| Integration depth | Deep PMS/PIMS integration | API-based, requires middleware | Strong advantage |
|
||||||
|
| Sales motion | Direct + word-of-mouth | Enterprise sales team + SI partners | Different segments |
|
||||||
|
| Switching cost for your customers | Moderate (data migration + retraining) | High (Salesforce ecosystem lock-in) | Neutral |
|
||||||
|
|
||||||
|
**Strategic Response Framework:**
|
||||||
|
|
||||||
|
```
|
||||||
|
IMMEDIATE (Week 1-4): Defend the Base
|
||||||
|
1. Customer communication campaign
|
||||||
|
- CEO letter to all 500 customers: "Our commitment to veterinary"
|
||||||
|
- Emphasize: purpose-built > horizontal platform
|
||||||
|
- Announce product roadmap acceleration
|
||||||
|
|
||||||
|
2. Lock in at-risk accounts
|
||||||
|
- Identify top 50 accounts by revenue
|
||||||
|
- Offer annual contract discounts (15-20% for 2-year commitment)
|
||||||
|
- Schedule QBRs with all enterprise accounts within 30 days
|
||||||
|
|
||||||
|
3. Competitive battle card
|
||||||
|
- Create internal sales doc: feature-by-feature comparison
|
||||||
|
- "Why vets choose us over Salesforce" — 5 key differentiators
|
||||||
|
- Objection handling for "shouldn't we go with the safe choice?"
|
||||||
|
|
||||||
|
SHORT-TERM (Month 2-6): Deepen the Moat
|
||||||
|
4. Accelerate domain-specific features
|
||||||
|
- AI-powered treatment plan suggestions (Salesforce can't match this)
|
||||||
|
- Telemedicine integration (vertical-specific)
|
||||||
|
- Inventory management tied to treatment protocols
|
||||||
|
|
||||||
|
5. Build switching costs
|
||||||
|
- Launch data analytics dashboard (clinics depend on historical trends)
|
||||||
|
- Introduce multi-location management (target growing chains)
|
||||||
|
- API marketplace for vet-specific integrations (lab equipment, imaging)
|
||||||
|
|
||||||
|
6. Community defense
|
||||||
|
- Launch "Vet Tech Community" — user forum + knowledge base
|
||||||
|
- Annual user conference (even virtual — creates tribal loyalty)
|
||||||
|
- Customer advisory board (top 10 clinics = co-development partners)
|
||||||
|
|
||||||
|
MEDIUM-TERM (Month 6-18): Counterattack
|
||||||
|
7. Move upmarket selectively
|
||||||
|
- Enterprise tier for 10+ location chains ($500/mo — match SF pricing)
|
||||||
|
- Offer white-glove migration from legacy systems
|
||||||
|
- This is the segment Salesforce will target — contest it
|
||||||
|
|
||||||
|
8. Geographic expansion
|
||||||
|
- Salesforce announcement creates awareness of the category
|
||||||
|
- Ride the wave: "Already purpose-built, already proven"
|
||||||
|
- Target UK, Australia, Canada (English-speaking, similar vet market structure)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pricing Response Decision Matrix:**
|
||||||
|
|
||||||
|
| Option | Revenue Impact | Competitive Effect | Risk |
|
||||||
|
|--------|---------------|-------------------|------|
|
||||||
|
| No change | Neutral | Salesforce still 2.5x more expensive | Low — price isn't the battleground |
|
||||||
|
| Cut prices 20% | -$1M ARR | Signals weakness; Salesforce won't match | High |
|
||||||
|
| Add premium tier | +$500K potential | Compete at enterprise level; justify R&D | Medium |
|
||||||
|
| Usage-based addon | +$300K potential | Expand ARPU without base price war | Low |
|
||||||
|
|
||||||
|
**Recommendation**: Add premium tier + usage-based addons. Do NOT cut base prices. Salesforce's entry validates your market — use it to raise your valuation narrative ("Salesforce sees a $2B market opportunity in vet SaaS — we already own 15%").
|
||||||
|
|
||||||
|
**Confidence**: Medium-High (75%) — Historical pattern: when Salesforce enters verticals, purpose-built incumbents retain 80%+ of existing customers. Risk is in new customer acquisition where brand matters more.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Example 3: Platform Sunset Decision — Migrate or Maintain Legacy Product
|
||||||
|
|
||||||
|
**Context**: A mid-stage startup ($20M ARR) runs two products: a legacy desktop app (60% of revenue, declining 10% YoY) and a modern cloud product (40% of revenue, growing 50% YoY). Should they sunset the desktop app?
|
||||||
|
|
||||||
|
**Decision Matrix:**
|
||||||
|
|
||||||
|
| Criterion (Weight) | Option A: Maintain Both | Option B: Sunset in 12mo | Option C: Sunset in 24mo |
|
||||||
|
|--------------------|------------------------|--------------------------|--------------------------|
|
||||||
|
| Revenue protection (30%) | 5 — No disruption | 2 — Lose 40% of legacy revenue | 4 — Gradual migration |
|
||||||
|
| Engineering efficiency (25%) | 1 — Two codebases drain resources | 5 — Full focus on cloud | 3 — Phased transition |
|
||||||
|
| Customer satisfaction (20%) | 3 — Legacy stagnates | 2 — Forced migration angers users | 4 — Supported migration path |
|
||||||
|
| Market positioning (15%) | 2 — Confused narrative | 5 — Clear cloud-first story | 4 — Transitional narrative |
|
||||||
|
| Financial risk (10%) | 3 — Slow bleed sustainable | 2 — Revenue cliff risk | 4 — Manageable decline |
|
||||||
|
| **Weighted Score** | **2.95** | **3.35** | **3.75** |
|
||||||
|
|
||||||
|
**Recommendation**: Option C — 24-month sunset with structured migration program.
|
||||||
|
|
||||||
|
```
|
||||||
|
Migration Program:
|
||||||
|
Months 1-6: Feature parity audit; build top 20 missing cloud features
|
||||||
|
Months 7-12: Migration incentive (20% discount for annual cloud commitment)
|
||||||
|
Months 13-18: Desktop enters maintenance-only mode; no new features
|
||||||
|
Months 19-24: End-of-life announcement; dedicated migration support team
|
||||||
|
Month 24: Desktop product sunsets; legacy support for 6 more months
|
||||||
|
|
||||||
|
Financial Model:
|
||||||
|
Current state: $12M desktop + $8M cloud = $20M ARR
|
||||||
|
Month 12 (projected): $9M desktop + $14M cloud = $23M ARR
|
||||||
|
Month 24 (projected): $2M desktop + $22M cloud = $24M ARR
|
||||||
|
Month 30 (projected): $0 desktop + $26M cloud = $26M ARR
|
||||||
|
|
||||||
|
Net ARR risk: ~$3M from non-migrating desktop customers
|
||||||
|
Offset: Engineering savings of $1.5M/yr + faster cloud feature velocity
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Financial Analysis Frameworks
|
||||||
|
|
||||||
|
### Unit Economics
|
||||||
|
|
||||||
|
Core metrics every strategy should quantify:
|
||||||
|
|
||||||
|
```
|
||||||
|
CAC (Customer Acquisition Cost)
|
||||||
|
= Total Sales & Marketing Spend / New Customers Acquired
|
||||||
|
Example: $500K spend / 100 new customers = $5,000 CAC
|
||||||
|
|
||||||
|
LTV (Lifetime Value)
|
||||||
|
= ARPU x Gross Margin % x (1 / Churn Rate)
|
||||||
|
Example: $500/mo x 80% x (1 / 0.03) = $13,333 LTV
|
||||||
|
|
||||||
|
LTV:CAC Ratio
|
||||||
|
Target: > 3:1 for healthy SaaS
|
||||||
|
Example: $13,333 / $5,000 = 2.67:1 (below target — reduce CAC or increase retention)
|
||||||
|
|
||||||
|
CAC Payback Period
|
||||||
|
= CAC / (ARPU x Gross Margin %)
|
||||||
|
Example: $5,000 / ($500 x 0.80) = 12.5 months
|
||||||
|
Target: < 18 months for SaaS
|
||||||
|
```
|
||||||
|
|
||||||
|
**Unit Economics Health Check:**
|
||||||
|
|
||||||
|
| Metric | Danger Zone | Acceptable | Excellent |
|
||||||
|
|--------|------------|------------|-----------|
|
||||||
|
| LTV:CAC | < 1:1 | 3:1 | > 5:1 |
|
||||||
|
| CAC Payback | > 24 months | 12-18 months | < 12 months |
|
||||||
|
| Gross Margin | < 60% | 70-80% | > 80% |
|
||||||
|
| Net Revenue Retention | < 90% | 100-110% | > 120% |
|
||||||
|
| Logo Churn (monthly) | > 5% | 2-3% | < 1% |
|
||||||
|
|
||||||
|
### Revenue Modeling
|
||||||
|
|
||||||
|
**SaaS Revenue Waterfall:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Beginning ARR: $10,000,000
|
||||||
|
+ New Business: +$3,000,000 (new logos)
|
||||||
|
+ Expansion: +$1,500,000 (upsell/cross-sell)
|
||||||
|
- Contraction: -$500,000 (downgrades)
|
||||||
|
- Churn: -$1,200,000 (lost customers)
|
||||||
|
= Ending ARR: $12,800,000
|
||||||
|
|
||||||
|
Net New ARR: $2,800,000
|
||||||
|
Net Revenue Retention: 113% = ($10M + $1.5M - $0.5M - $1.2M) / $10M
|
||||||
|
Gross Revenue Retention: 88% = ($10M - $0.5M - $1.2M) / $10M
|
||||||
|
```
|
||||||
|
|
||||||
|
**MRR Growth Decomposition:**
|
||||||
|
|
||||||
|
```
|
||||||
|
MRR Growth Rate = New MRR + Expansion MRR - Churned MRR - Contraction MRR
|
||||||
|
─────────────────────────────────────────────────────────
|
||||||
|
Beginning MRR
|
||||||
|
|
||||||
|
Quick Ratio = (New MRR + Expansion MRR) / (Churned MRR + Contraction MRR)
|
||||||
|
Target: > 4 for high-growth SaaS
|
||||||
|
```
|
||||||
|
|
||||||
|
### Break-Even Analysis
|
||||||
|
|
||||||
|
```
|
||||||
|
Break-Even Revenue = Fixed Costs / Gross Margin %
|
||||||
|
|
||||||
|
Example:
|
||||||
|
Fixed Costs (monthly): $200K (salaries, rent, tools)
|
||||||
|
Gross Margin: 80%
|
||||||
|
Break-Even Revenue = $200K / 0.80 = $250K/month = $3M ARR
|
||||||
|
|
||||||
|
Break-Even Customers = Break-Even Revenue / ARPU
|
||||||
|
= $250K / $500 = 500 customers
|
||||||
|
```
|
||||||
|
|
||||||
|
**Scenario Table:**
|
||||||
|
|
||||||
|
| Scenario | Fixed Costs | Gross Margin | Break-Even ARR | Break-Even Customers |
|
||||||
|
|----------|------------|--------------|-----------------|---------------------|
|
||||||
|
| Lean | $150K/mo | 85% | $2.1M | 353 |
|
||||||
|
| Base | $200K/mo | 80% | $3.0M | 500 |
|
||||||
|
| Growth | $350K/mo | 75% | $5.6M | 933 |
|
||||||
|
|
||||||
|
### Project Evaluation — Simplified DCF
|
||||||
|
|
||||||
|
Use for evaluating strategic investments (new market entry, build vs buy, major feature investment):
|
||||||
|
|
||||||
|
```
|
||||||
|
NPV = Σ [Cash Flow_t / (1 + r)^t] - Initial Investment
|
||||||
|
|
||||||
|
Where:
|
||||||
|
r = discount rate (typically 10-15% for startups, 8-10% for established companies)
|
||||||
|
t = year (0, 1, 2, ... n)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worked Example — Should we build a mobile app?**
|
||||||
|
|
||||||
|
```
|
||||||
|
Initial Investment: $500K (development cost)
|
||||||
|
Discount Rate: 12%
|
||||||
|
|
||||||
|
Year | Incremental Revenue | Incremental Cost | Net Cash Flow | PV Factor | Present Value
|
||||||
|
------|--------------------|--------------------|---------------|-----------|-------------
|
||||||
|
0 | $0 | $500,000 | -$500,000 | 1.000 | -$500,000
|
||||||
|
1 | $200,000 | $80,000 | $120,000 | 0.893 | $107,143
|
||||||
|
2 | $400,000 | $100,000 | $300,000 | 0.797 | $239,158
|
||||||
|
3 | $600,000 | $120,000 | $480,000 | 0.712 | $341,655
|
||||||
|
4 | $700,000 | $130,000 | $570,000 | 0.636 | $362,204
|
||||||
|
|
||||||
|
NPV = $550,160 → Positive NPV → Project is financially justified
|
||||||
|
Payback Period: ~2.3 years (cumulative cash flow turns positive in Year 3)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Decision Rule:**
|
||||||
|
- NPV > 0 → Proceed (project creates value)
|
||||||
|
- NPV < 0 → Reject (project destroys value)
|
||||||
|
- Compare NPV across mutually exclusive options; pick highest
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Go-to-Market Strategy Patterns
|
||||||
|
|
||||||
|
### Growth Motion Selection
|
||||||
|
|
||||||
|
| Growth Motion | Best For | Sales Cycle | CAC | Key Metric |
|
||||||
|
|--------------|---------|-------------|-----|------------|
|
||||||
|
| **Product-Led Growth (PLG)** | Self-serve products; low price point (<$500/mo); individual users | Minutes to days | Low ($50-$500) | Activation rate, PQL conversion |
|
||||||
|
| **Sales-Led Growth** | Enterprise products; complex deployment; >$50K ACV | Weeks to months | High ($5K-$50K) | Pipeline velocity, win rate |
|
||||||
|
| **Community-Led Growth** | Developer tools; open-source; platform products | Varies | Very low ($10-$100) | Community size, contribution rate |
|
||||||
|
| **Partner-Led Growth** | Market entry; regulated industries; ecosystem products | Varies | Medium ($1K-$10K) | Partner-sourced revenue % |
|
||||||
|
|
||||||
|
**PLG Funnel:**
|
||||||
|
```
|
||||||
|
Visitor → Sign-up → Activated User → PQL → Paid Customer → Expanded Account
|
||||||
|
100% 10% 40% 25% 15% 30%
|
||||||
|
|
||||||
|
Key levers:
|
||||||
|
- Sign-up friction: Reduce form fields, add SSO
|
||||||
|
- Time-to-value: Get user to "aha moment" in < 5 minutes
|
||||||
|
- PQL definition: User hits usage threshold that correlates with purchase
|
||||||
|
- Expansion trigger: Team features, usage limits, premium capabilities
|
||||||
|
```
|
||||||
|
|
||||||
|
**Sales-Led Funnel:**
|
||||||
|
```
|
||||||
|
Lead → MQL → SQL → Opportunity → Proposal → Closed Won
|
||||||
|
100% 20% 50% 60% 70% 30%
|
||||||
|
|
||||||
|
Key levers:
|
||||||
|
- Lead quality: ICP fit scoring
|
||||||
|
- MQL→SQL handoff: Alignment between marketing and sales
|
||||||
|
- Discovery: Deep pain identification
|
||||||
|
- Champion building: Enable internal advocate
|
||||||
|
- Procurement: Legal/security review preparation
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pricing Strategy Frameworks
|
||||||
|
|
||||||
|
**Value-Based Pricing (recommended for most SaaS):**
|
||||||
|
```
|
||||||
|
1. Quantify customer value created
|
||||||
|
Example: Your tool saves 10 hours/week per user
|
||||||
|
Value = 10 hrs x $75/hr x 52 weeks = $39,000/year
|
||||||
|
|
||||||
|
2. Capture 10-20% of value created
|
||||||
|
Price = $39,000 x 15% = $5,850/year = $487/month
|
||||||
|
|
||||||
|
3. Validate with willingness-to-pay research
|
||||||
|
Van Westendorp Price Sensitivity Meter:
|
||||||
|
- "At what price is this too expensive?" → $600/mo
|
||||||
|
- "At what price is this a bargain?" → $200/mo
|
||||||
|
- "At what price does it seem expensive but you'd still consider?" → $450/mo
|
||||||
|
- "At what price does it seem too cheap to trust?" → $100/mo
|
||||||
|
→ Optimal price range: $200-$450/mo
|
||||||
|
```
|
||||||
|
|
||||||
|
**Pricing Tier Architecture:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Tier Structure (Good-Better-Best):
|
||||||
|
|
||||||
|
| | Starter | Professional | Enterprise |
|
||||||
|
|---|---------|-------------|------------|
|
||||||
|
| Target | Individual/SMB | Mid-market team | Large organization |
|
||||||
|
| Price | $29/mo | $99/mo/user | Custom (>$500/mo) |
|
||||||
|
| Anchor role | Drive adoption | Revenue driver (~60% of revenue) | Margin driver |
|
||||||
|
| Features | Core functionality | Full platform | Custom + SLA + support |
|
||||||
|
| Support | Self-serve/email | Priority email + chat | Dedicated CSM + phone |
|
||||||
|
| Billing | Monthly/Annual | Annual preferred | Annual contract |
|
||||||
|
|
||||||
|
Design principles:
|
||||||
|
- Middle tier should be the obvious best value
|
||||||
|
- Top tier exists to make middle tier look reasonable (anchoring effect)
|
||||||
|
- Feature gates should align with natural usage growth
|
||||||
|
- Price metric should scale with value received (per user, per GB, per transaction)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Competitive Pricing Analysis:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Competitor Price Map:
|
||||||
|
|
||||||
|
Competitor | Entry Price | Mid-Tier | Enterprise | Price Metric
|
||||||
|
-------------|-------------|----------|------------|-------------
|
||||||
|
Competitor A | $49/mo | $149/mo | Custom | Per user
|
||||||
|
Competitor B | $0 (free) | $99/mo | $299/mo | Flat rate
|
||||||
|
Competitor C | $29/mo | $79/mo | Custom | Per user
|
||||||
|
Your Product | ??? | ??? | ??? | ???
|
||||||
|
|
||||||
|
Positioning options:
|
||||||
|
- Price leader: 20-30% below average → requires cost advantage
|
||||||
|
- Value leader: At or above average → requires clear differentiation
|
||||||
|
- Premium: 30%+ above average → requires brand and feature superiority
|
||||||
|
```
|
||||||
|
|
||||||
|
### Channel Strategy
|
||||||
|
|
||||||
|
| Channel | Margin | Control | Scale | Best For |
|
||||||
|
|---------|--------|---------|-------|----------|
|
||||||
|
| Direct sales | High (85-95%) | Full | Slow | Enterprise, complex products |
|
||||||
|
| Inside sales | High (80-90%) | Full | Medium | Mid-market, $5K-$50K ACV |
|
||||||
|
| Self-serve | Highest (95%+) | Full | Fast | PLG, low ACV |
|
||||||
|
| Reseller/VAR | Low (60-70%) | Medium | Medium | Regional coverage, compliance |
|
||||||
|
| Marketplace (AWS/Azure) | Low (70-85%) | Low | Fast | Enterprise procurement shortcuts |
|
||||||
|
| System Integrator | Low (50-70%) | Low | Medium | Complex implementations |
|
||||||
|
| Affiliate/Referral | High (80-90%) | Low | Fast | Consumer, SMB |
|
||||||
|
|
||||||
|
### Launch Playbook Template
|
||||||
|
|
||||||
|
```
|
||||||
|
LAUNCH PLAYBOOK: [Product/Feature Name]
|
||||||
|
Launch Date: YYYY-MM-DD
|
||||||
|
Launch Type: [Major / Minor / Feature / Beta]
|
||||||
|
|
||||||
|
PRE-LAUNCH (T-8 weeks to T-0)
|
||||||
|
Week -8: Finalize positioning and messaging
|
||||||
|
Week -6: Create sales enablement materials (battle cards, one-pagers, demo script)
|
||||||
|
Week -4: Brief analyst relations (Gartner, Forrester) if applicable
|
||||||
|
Week -3: Seed beta customers (5-10 design partners); collect testimonials
|
||||||
|
Week -2: Pre-brief press/media under embargo
|
||||||
|
Week -1: Internal all-hands; sales team training; support team training
|
||||||
|
|
||||||
|
LAUNCH DAY (T-0)
|
||||||
|
- Blog post (SEO-optimized)
|
||||||
|
- Email to customer base
|
||||||
|
- Social media campaign (LinkedIn, Twitter/X)
|
||||||
|
- Press release (if major launch)
|
||||||
|
- Product Hunt submission (if applicable)
|
||||||
|
- In-app announcement for existing users
|
||||||
|
- Founder/CEO LinkedIn post (highest engagement channel)
|
||||||
|
|
||||||
|
POST-LAUNCH (T+1 to T+8 weeks)
|
||||||
|
Week +1: Monitor activation metrics; respond to all feedback
|
||||||
|
Week +2: Publish customer case study
|
||||||
|
Week +4: Webinar / live demo for pipeline
|
||||||
|
Week +6: Analyze launch metrics vs targets
|
||||||
|
Week +8: Retrospective and iteration plan
|
||||||
|
|
||||||
|
METRICS TO TRACK:
|
||||||
|
- Awareness: Blog views, social impressions, press mentions
|
||||||
|
- Activation: Sign-ups, trial starts, feature adoption rate
|
||||||
|
- Revenue: Pipeline generated, deals influenced, new ARR
|
||||||
|
- Sentiment: NPS from beta users, social sentiment, support ticket volume
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Scenario Planning
|
||||||
|
|
||||||
|
### Best / Base / Worst Case Framework
|
||||||
|
|
||||||
|
Structure every major strategic decision with three scenarios:
|
||||||
|
|
||||||
|
```
|
||||||
|
SCENARIO PLANNING: [Decision or Initiative]
|
||||||
|
|
||||||
|
| Worst Case | Base Case | Best Case
|
||||||
|
--------------------|-----------------|-----------------|------------------
|
||||||
|
Revenue impact | [quantify] | [quantify] | [quantify]
|
||||||
|
Timeline | [duration] | [duration] | [duration]
|
||||||
|
Key assumption | [what goes wrong]| [most likely] | [what goes right]
|
||||||
|
Probability | [15-25%] | [50-60%] | [15-25%]
|
||||||
|
Trigger indicators | [early signals] | [tracking metrics]| [early signals]
|
||||||
|
Response plan | [pivot/exit] | [continue/adjust]| [accelerate/expand]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Worked Example — Launching a New Product Line:**
|
||||||
|
|
||||||
|
```
|
||||||
|
SCENARIO PLANNING: Launch enterprise analytics add-on ($200/mo)
|
||||||
|
|
||||||
|
| Worst Case (20%) | Base Case (55%) | Best Case (25%)
|
||||||
|
--------------------|-------------------|-------------------|-------------------
|
||||||
|
Adoption rate | 5% of customers | 15% of customers | 30% of customers
|
||||||
|
Year 1 revenue | $120K | $360K | $720K
|
||||||
|
Development cost | $400K | $400K | $400K
|
||||||
|
Year 1 ROI | -70% | -10% | +80%
|
||||||
|
Break-even | Never (kill it) | Month 18 | Month 8
|
||||||
|
Key assumption | Customers don't | Moderate demand; | Strong demand;
|
||||||
|
| see value; churn | gradual adoption | pulls forward
|
||||||
|
| increases 2% | | enterprise deals
|
||||||
|
|
||||||
|
Trigger Indicators:
|
||||||
|
Worst: < 3% adoption after 3 months; NPS < 20 for add-on
|
||||||
|
Base: 8-12% adoption after 3 months; positive but slow pipeline
|
||||||
|
Best: > 20% adoption after 3 months; inbound enterprise interest
|
||||||
|
|
||||||
|
Response Plans:
|
||||||
|
Worst: Pivot to bundling analytics into existing plan (retention play)
|
||||||
|
Base: Continue; invest in onboarding and customer education
|
||||||
|
Best: Hire dedicated analytics PM; accelerate roadmap; raise prices 20%
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Value Calculation:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Expected Revenue = (Worst Revenue x Worst Prob) + (Base Revenue x Base Prob) + (Best Revenue x Best Prob)
|
||||||
|
= ($120K x 0.20) + ($360K x 0.55) + ($720K x 0.25)
|
||||||
|
= $24K + $198K + $180K
|
||||||
|
= $402K
|
||||||
|
|
||||||
|
Expected ROI = ($402K - $400K) / $400K = 0.5%
|
||||||
|
→ Marginal on expected value alone — proceed only if strategic upside justifies the bet
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sensitivity Analysis
|
||||||
|
|
||||||
|
Identify which variables have the highest impact on outcomes:
|
||||||
|
|
||||||
|
```
|
||||||
|
SENSITIVITY ANALYSIS: New Market Entry
|
||||||
|
|
||||||
|
Base Case NPV: $550K
|
||||||
|
|
||||||
|
Variable | -20% Change | Base | +20% Change | Sensitivity
|
||||||
|
--------------------|---------------|----------|----------------|------------
|
||||||
|
Customer price | $280K (-49%) | $550K | $820K (+49%) | HIGH
|
||||||
|
Customer volume | $310K (-44%) | $550K | $790K (+44%) | HIGH
|
||||||
|
Churn rate | $720K (+31%) | $550K | $380K (-31%) | HIGH
|
||||||
|
Development cost | $650K (+18%) | $550K | $450K (-18%) | MEDIUM
|
||||||
|
CAC | $610K (+11%) | $550K | $490K (-11%) | MEDIUM
|
||||||
|
Discount rate | $590K (+7%) | $550K | $510K (-7%) | LOW
|
||||||
|
```
|
||||||
|
|
||||||
|
**Interpretation**: Price and volume are the highest-leverage variables. Strategy should prioritize pricing power and demand generation over cost optimization.
|
||||||
|
|
||||||
|
**Tornado Chart Format (text representation):**
|
||||||
|
|
||||||
|
```
|
||||||
|
Variable Impact on NPV (base = $550K):
|
||||||
|
|
||||||
|
Customer price |████████████████████| -49% to +49%
|
||||||
|
Customer volume |███████████████████ | -44% to +44%
|
||||||
|
Churn rate |██████████████ | -31% to +31%
|
||||||
|
Development cost |█████████ | -18% to +18%
|
||||||
|
CAC |██████ | -11% to +11%
|
||||||
|
Discount rate |████ | -7% to +7%
|
||||||
|
```
|
||||||
|
|
||||||
|
### Risk-Adjusted Decision Making
|
||||||
|
|
||||||
|
**Risk Register Template:**
|
||||||
|
|
||||||
|
| Risk | Probability (1-5) | Impact (1-5) | Risk Score | Mitigation | Residual Risk |
|
||||||
|
|------|-------------------|-------------|------------|------------|---------------|
|
||||||
|
| Key hire doesn't work out | 3 | 4 | 12 | Pipeline of 2 backup candidates | 6 |
|
||||||
|
| Competitor launches first | 4 | 3 | 12 | Focus on differentiation not speed | 8 |
|
||||||
|
| Technical architecture fails to scale | 2 | 5 | 10 | Prototype load test at 10x before commit | 4 |
|
||||||
|
| Regulatory change blocks approach | 1 | 5 | 5 | Legal review + pivot plan documented | 3 |
|
||||||
|
| Customer demand lower than projected | 3 | 4 | 12 | Pre-sell to 10 design partners before building | 6 |
|
||||||
|
|
||||||
|
**Risk-Adjusted NPV:**
|
||||||
|
```
|
||||||
|
Risk-Adjusted NPV = Base NPV x (1 - Risk Discount)
|
||||||
|
|
||||||
|
Where Risk Discount = Σ (Probability x Impact x Weight) for all material risks
|
||||||
|
|
||||||
|
Example:
|
||||||
|
Base NPV: $550K
|
||||||
|
Combined risk score: 0.15 (derived from risk register)
|
||||||
|
Risk-Adjusted NPV: $550K x (1 - 0.15) = $467.5K
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Industry Analysis Templates
|
||||||
|
|
||||||
|
### Market Landscape Map
|
||||||
|
|
||||||
|
Plot all players in a market on two strategic dimensions:
|
||||||
|
|
||||||
|
```
|
||||||
|
MARKET LANDSCAPE: [Industry/Category]
|
||||||
|
|
||||||
|
Enterprise-Grade
|
||||||
|
|
|
||||||
|
Quadrant 2| Quadrant 1
|
||||||
|
Niche | Market Leaders
|
||||||
|
Enterprise|
|
||||||
|
Narrow ──────────────┼────────────── Broad
|
||||||
|
Solution | Platform
|
||||||
|
Quadrant 3| Quadrant 4
|
||||||
|
Point | Mass-Market
|
||||||
|
Solutions | Platforms
|
||||||
|
|
|
||||||
|
SMB-Focused
|
||||||
|
|
||||||
|
Example — Project Management SaaS (2025):
|
||||||
|
|
||||||
|
Quadrant 1 (Leaders): Asana, Monday.com, Smartsheet
|
||||||
|
Quadrant 2 (Niche): Targetprocess (SAFe), Planview (PPM), Kantata (services)
|
||||||
|
Quadrant 3 (Point): Todoist, Basecamp, Trello
|
||||||
|
Quadrant 4 (Platforms): Notion, ClickUp, Microsoft Planner
|
||||||
|
|
||||||
|
Your Position: [X]
|
||||||
|
Desired Position: [→ direction of strategic movement]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Building a Landscape Map:**
|
||||||
|
|
||||||
|
1. Select two dimensions that represent the most important strategic trade-offs in the market
|
||||||
|
2. Commonly used axes:
|
||||||
|
- Price / Complexity
|
||||||
|
- Breadth of platform / Depth of solution
|
||||||
|
- Enterprise / SMB focus
|
||||||
|
- Horizontal / Vertical specialization
|
||||||
|
- Self-serve / High-touch
|
||||||
|
3. Plot all known competitors (minimum 8-10 for useful map)
|
||||||
|
4. Identify white space — under-served quadrant combinations
|
||||||
|
5. Draw your strategic vector — where are you moving and why?
|
||||||
|
|
||||||
|
### Technology Adoption Lifecycle Positioning
|
||||||
|
|
||||||
|
```
|
||||||
|
THE ADOPTION CURVE:
|
||||||
|
|
||||||
|
Innovators Early Early Late Laggards
|
||||||
|
(2.5%) Adopters Majority Majority (16%)
|
||||||
|
(13.5%) (34%) (34%)
|
||||||
|
___
|
||||||
|
/ \
|
||||||
|
/ \____
|
||||||
|
/ \________
|
||||||
|
/ \_________
|
||||||
|
/ \___
|
||||||
|
|
||||||
|
↑ ↑
|
||||||
|
THE CHASM MAINSTREAM
|
||||||
|
(biggest (revenue
|
||||||
|
risk point) acceleration)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Positioning by Stage:**
|
||||||
|
|
||||||
|
| Stage | Customer Profile | Sales Approach | Pricing Strategy | Key Risk |
|
||||||
|
|-------|-----------------|----------------|------------------|----------|
|
||||||
|
| Innovators | Tech enthusiasts; will tolerate bugs | Community; direct outreach | Free/very low; usage-based | Building for wrong use case |
|
||||||
|
| Early Adopters | Visionaries; want competitive advantage | Consultative selling; pilots | Value-based; ROI-justified | Chasm — can't cross to mainstream |
|
||||||
|
| Early Majority | Pragmatists; want proven solutions | References; case studies; demos | Competitive; published pricing | Scaling sales and support |
|
||||||
|
| Late Majority | Conservatives; want complete solutions | Standard procurement; RFPs | Bundled; enterprise agreements | Margin compression |
|
||||||
|
| Laggards | Skeptics; forced by circumstance | Compliance-driven; mandates | Legacy pricing; long contracts | Market is commoditizing |
|
||||||
|
|
||||||
|
**Chasm-Crossing Checklist:**
|
||||||
|
```
|
||||||
|
□ Whole product: Does the product solve the complete use case without workarounds?
|
||||||
|
□ References: Do you have 3-5 referenceable customers in the target segment?
|
||||||
|
□ Repeatability: Can you sell and implement without founder involvement?
|
||||||
|
□ Support: Can you support customers at scale (not just white-glove)?
|
||||||
|
□ Positioning: Is the messaging pragmatist-friendly (ROI, risk reduction) not visionary?
|
||||||
|
□ Competition: Have you defined the competitive set for pragmatist comparison?
|
||||||
|
□ Pricing: Is pricing simple, transparent, and aligned with buyer expectations?
|
||||||
|
```
|
||||||
|
|
||||||
|
### Value Chain Analysis
|
||||||
|
|
||||||
|
Decompose industry activities to find competitive advantage:
|
||||||
|
|
||||||
|
```
|
||||||
|
VALUE CHAIN: [Industry]
|
||||||
|
|
||||||
|
PRIMARY ACTIVITIES:
|
||||||
|
┌─────────────┬──────────────┬──────────────┬──────────────┬──────────────┐
|
||||||
|
│ Inbound │ Operations │ Outbound │ Marketing │ Service │
|
||||||
|
│ Logistics │ │ Logistics │ & Sales │ │
|
||||||
|
├─────────────┼──────────────┼──────────────┼──────────────┼──────────────┤
|
||||||
|
│ Sourcing │ Production │ Distribution │ Branding │ Support │
|
||||||
|
│ Inventory │ Quality │ Delivery │ Pricing │ Maintenance │
|
||||||
|
│ Supplier │ Assembly │ Warehousing │ Channel mgmt │ Returns │
|
||||||
|
│ management │ Testing │ Order mgmt │ Positioning │ Training │
|
||||||
|
└─────────────┴──────────────┴──────────────┴──────────────┴──────────────┘
|
||||||
|
|
||||||
|
SUPPORT ACTIVITIES:
|
||||||
|
┌──────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Infrastructure: Finance, Legal, Management, Planning │
|
||||||
|
│ Human Resources: Recruiting, Training, Compensation, Culture │
|
||||||
|
│ Technology: R&D, IT systems, Automation, Data analytics │
|
||||||
|
│ Procurement: Vendor selection, Negotiation, Contract management │
|
||||||
|
└──────────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
**Analysis Process:**
|
||||||
|
|
||||||
|
```
|
||||||
|
For each activity:
|
||||||
|
1. Cost: What % of total cost does this activity represent?
|
||||||
|
2. Value: How much does this activity contribute to customer willingness-to-pay?
|
||||||
|
3. Capability: Rate your performance vs competitors (1-5)
|
||||||
|
4. Strategic importance: Is this a source of differentiation? (Yes/No)
|
||||||
|
|
||||||
|
Activity | Cost % | Value Contribution | Capability | Differentiator?
|
||||||
|
---------------------|--------|-------------------|------------|----------------
|
||||||
|
Inbound logistics | 15% | Low | 3/5 | No
|
||||||
|
Operations | 25% | High | 4/5 | Yes
|
||||||
|
Outbound logistics | 10% | Medium | 3/5 | No
|
||||||
|
Marketing & Sales | 30% | High | 2/5 | Needs improvement
|
||||||
|
Service | 20% | High | 5/5 | Yes
|
||||||
|
|
||||||
|
Strategic Implications:
|
||||||
|
- Invest: Operations (current strength + high value) and Service (strength to protect)
|
||||||
|
- Improve: Marketing & Sales (high cost + low capability = drag on growth)
|
||||||
|
- Optimize: Logistics (non-differentiating — minimize cost)
|
||||||
|
```
|
||||||
|
|
||||||
|
**SaaS-Specific Value Chain:**
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────┬───────────────┬──────────────┬────────────────┬─────────────┐
|
||||||
|
│ Product │ Customer │ Customer │ Customer │ Expansion │
|
||||||
|
│ Development│ Acquisition │ Onboarding │ Success │ & Retention │
|
||||||
|
├────────────┼───────────────┼──────────────┼────────────────┼─────────────┤
|
||||||
|
│ R&D │ Marketing │ Implementation│ Support │ Upsell │
|
||||||
|
│ Design │ Sales │ Training │ Account mgmt │ Cross-sell │
|
||||||
|
│ QA │ Partnerships │ Migration │ Health scoring │ Renewals │
|
||||||
|
│ Platform │ Growth/PLG │ Integration │ Community │ Advocacy │
|
||||||
|
└────────────┴───────────────┴──────────────┴────────────────┴─────────────┘
|
||||||
|
|
||||||
|
Key insight for SaaS: The majority of LTV is created AFTER the initial sale.
|
||||||
|
Disproportionate investment should go to Onboarding → Success → Expansion.
|
||||||
|
```
|
||||||
@@ -781,6 +781,337 @@ default_active = false
|
|||||||
# Warning shown when user tries to activate
|
# Warning shown when user tries to activate
|
||||||
activation_warning = "Trading hand runs continuously and consumes tokens. Deactivate when not trading."
|
activation_warning = "Trading hand runs continuously and consumes tokens. Deactivate when not trading."
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "交易 Hand"
|
name = "交易 Hand"
|
||||||
description = "自主市场情报与交易引擎——多信号分析、对抗性多空推理、校准置信度评分、严格风控和投资组合分析"
|
description = "自主市场情报与交易引擎——多信号分析、对抗性多空推理、校准置信度评分、严格风控和投资组合分析"
|
||||||
|
category = "数据"
|
||||||
|
|
||||||
|
[i18n.zh.settings.trading_mode]
|
||||||
|
label = "交易模式"
|
||||||
|
description = "交易 Hand 的运行方式——仅分析、模拟交易或实盘交易"
|
||||||
|
|
||||||
|
[i18n.zh.settings.market_focus]
|
||||||
|
label = "市场关注"
|
||||||
|
description = "监控和交易的目标市场"
|
||||||
|
|
||||||
|
[i18n.zh.settings.strategy_style]
|
||||||
|
label = "策略风格"
|
||||||
|
description = "交易时间框架和策略类型"
|
||||||
|
|
||||||
|
[i18n.zh.settings.risk_per_trade]
|
||||||
|
label = "单笔风险"
|
||||||
|
description = "单笔交易允许承受的最大仓位占比"
|
||||||
|
|
||||||
|
[i18n.zh.settings.max_daily_loss]
|
||||||
|
label = "单日最大亏损"
|
||||||
|
description = "触发熔断机制的每日最大允许亏损比例"
|
||||||
|
|
||||||
|
[i18n.zh.settings.analysis_depth]
|
||||||
|
label = "分析深度"
|
||||||
|
description = "每个标的收集和交叉验证的信号数量"
|
||||||
|
|
||||||
|
[i18n.zh.settings.scan_schedule]
|
||||||
|
label = "扫描频率"
|
||||||
|
description = "扫描市场和更新分析的频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.watchlist]
|
||||||
|
label = "关注列表"
|
||||||
|
description = "要监控的标的代码列表(逗号分隔,股票: AAPL,加密货币: BTC,ETF: SPY)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.initial_capital]
|
||||||
|
label = "初始资金"
|
||||||
|
description = "模拟交易或追踪的起始投资组合金额(美元)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.alpaca_api_key]
|
||||||
|
label = "Alpaca API 密钥"
|
||||||
|
description = "用于实盘/模拟交易的 Alpaca API 密钥(可在 alpaca.markets 免费获取)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.alpaca_secret_key]
|
||||||
|
label = "Alpaca Secret 密钥"
|
||||||
|
description = "Alpaca API 的 Secret 密钥"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "审批模式"
|
||||||
|
description = "执行实盘交易前需要用户明确审批——强烈建议开启"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Trading"
|
||||||
|
description = "Motor autónomo de inteligencia de mercado y trading — análisis multi-señal, razonamiento adversarial alcista/bajista, puntuación de confianza calibrada, gestión de riesgo estricta y analítica de cartera"
|
||||||
|
category = "Datos"
|
||||||
|
|
||||||
|
[i18n.es.settings.trading_mode]
|
||||||
|
label = "Modo de trading"
|
||||||
|
description = "Cómo opera el Hand de Trading — solo análisis, trading simulado o trading real"
|
||||||
|
|
||||||
|
[i18n.es.settings.market_focus]
|
||||||
|
label = "Enfoque de mercado"
|
||||||
|
description = "Qué mercados monitorear y operar"
|
||||||
|
|
||||||
|
[i18n.es.settings.strategy_style]
|
||||||
|
label = "Estilo de estrategia"
|
||||||
|
description = "Marco temporal y enfoque de la estrategia de trading"
|
||||||
|
|
||||||
|
[i18n.es.settings.risk_per_trade]
|
||||||
|
label = "Riesgo por operación"
|
||||||
|
description = "Porcentaje máximo de la cartera en riesgo en una sola operación"
|
||||||
|
|
||||||
|
[i18n.es.settings.max_daily_loss]
|
||||||
|
label = "Pérdida diaria máxima"
|
||||||
|
description = "Porcentaje máximo de pérdida diaria de la cartera antes de activar el disyuntor"
|
||||||
|
|
||||||
|
[i18n.es.settings.analysis_depth]
|
||||||
|
label = "Profundidad del análisis"
|
||||||
|
description = "Cuántas señales recopilar y cruzar por activo"
|
||||||
|
|
||||||
|
[i18n.es.settings.scan_schedule]
|
||||||
|
label = "Frecuencia de escaneo"
|
||||||
|
description = "Con qué frecuencia escanear los mercados y actualizar el análisis"
|
||||||
|
|
||||||
|
[i18n.es.settings.watchlist]
|
||||||
|
label = "Lista de seguimiento"
|
||||||
|
description = "Lista de tickers a monitorear separados por comas (acciones: AAPL, cripto: BTC, ETFs: SPY)"
|
||||||
|
|
||||||
|
[i18n.es.settings.initial_capital]
|
||||||
|
label = "Capital inicial"
|
||||||
|
description = "Valor inicial de la cartera para trading simulado o seguimiento (en USD)"
|
||||||
|
|
||||||
|
[i18n.es.settings.alpaca_api_key]
|
||||||
|
label = "Clave API de Alpaca"
|
||||||
|
description = "Clave API de Alpaca para trading real/simulado (obtener gratis en alpaca.markets)"
|
||||||
|
|
||||||
|
[i18n.es.settings.alpaca_secret_key]
|
||||||
|
label = "Clave secreta de Alpaca"
|
||||||
|
description = "Clave secreta de la API de Alpaca"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Modo de aprobación"
|
||||||
|
description = "Requerir aprobación explícita del usuario antes de ejecutar cualquier operación real — altamente recomendado"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "トレーディング Hand"
|
||||||
|
description = "自律型マーケットインテリジェンス&トレーディングエンジン——マルチシグナル分析、対立的ブル/ベア推論、キャリブレーション済み信頼度スコアリング、厳格なリスク管理、ポートフォリオ分析"
|
||||||
|
category = "データ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.trading_mode]
|
||||||
|
label = "トレーディングモード"
|
||||||
|
description = "トレーディングHandの動作方式——分析のみ、ペーパートレード、またはライブトレード"
|
||||||
|
|
||||||
|
[i18n.ja.settings.market_focus]
|
||||||
|
label = "マーケットフォーカス"
|
||||||
|
description = "監視・取引する対象市場"
|
||||||
|
|
||||||
|
[i18n.ja.settings.strategy_style]
|
||||||
|
label = "戦略スタイル"
|
||||||
|
description = "取引の時間軸と戦略アプローチ"
|
||||||
|
|
||||||
|
[i18n.ja.settings.risk_per_trade]
|
||||||
|
label = "1トレードあたりのリスク"
|
||||||
|
description = "1回の取引でリスクにさらすポートフォリオの最大割合"
|
||||||
|
|
||||||
|
[i18n.ja.settings.max_daily_loss]
|
||||||
|
label = "1日の最大損失"
|
||||||
|
description = "サーキットブレーカーが作動するまでの1日あたりの最大損失割合"
|
||||||
|
|
||||||
|
[i18n.ja.settings.analysis_depth]
|
||||||
|
label = "分析の深さ"
|
||||||
|
description = "銘柄ごとに収集・クロスリファレンスするシグナルの数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.scan_schedule]
|
||||||
|
label = "スキャンスケジュール"
|
||||||
|
description = "市場スキャンと分析更新の頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.watchlist]
|
||||||
|
label = "ウォッチリスト"
|
||||||
|
description = "監視するティッカーのリスト(カンマ区切り、株式: AAPL、暗号通貨: BTC、ETF: SPY)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.initial_capital]
|
||||||
|
label = "初期資金"
|
||||||
|
description = "ペーパートレードまたはトラッキングの開始ポートフォリオ額(USD)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.alpaca_api_key]
|
||||||
|
label = "Alpaca APIキー"
|
||||||
|
description = "ライブ/ペーパートレード用のAlpaca APIキー(alpaca.marketsで無料取得可能)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.alpaca_secret_key]
|
||||||
|
label = "Alpaca Secretキー"
|
||||||
|
description = "Alpaca APIのSecretキー"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "承認モード"
|
||||||
|
description = "ライブトレード実行前にユーザーの明示的な承認を必要とする——強く推奨"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand de Trading"
|
||||||
|
description = "Moteur autonome d'intelligence de marché et de trading — analyse multi-signaux, raisonnement adversarial haussier/baissier, score de confiance calibré, gestion stricte des risques et analytique de portefeuille"
|
||||||
|
category = "Données"
|
||||||
|
|
||||||
|
[i18n.fr.settings.trading_mode]
|
||||||
|
label = "Mode de trading"
|
||||||
|
description = "Mode de fonctionnement du Hand de Trading — analyse seule, trading simulé ou trading réel"
|
||||||
|
|
||||||
|
[i18n.fr.settings.market_focus]
|
||||||
|
label = "Focus marché"
|
||||||
|
description = "Quels marchés surveiller et sur lesquels opérer"
|
||||||
|
|
||||||
|
[i18n.fr.settings.strategy_style]
|
||||||
|
label = "Style de stratégie"
|
||||||
|
description = "Horizon temporel et approche de la stratégie de trading"
|
||||||
|
|
||||||
|
[i18n.fr.settings.risk_per_trade]
|
||||||
|
label = "Risque par opération"
|
||||||
|
description = "Pourcentage maximum du portefeuille en risque sur une seule opération"
|
||||||
|
|
||||||
|
[i18n.fr.settings.max_daily_loss]
|
||||||
|
label = "Perte quotidienne maximale"
|
||||||
|
description = "Pourcentage maximum de perte quotidienne du portefeuille avant déclenchement du coupe-circuit"
|
||||||
|
|
||||||
|
[i18n.fr.settings.analysis_depth]
|
||||||
|
label = "Profondeur d'analyse"
|
||||||
|
description = "Nombre de signaux à collecter et recouper par actif"
|
||||||
|
|
||||||
|
[i18n.fr.settings.scan_schedule]
|
||||||
|
label = "Fréquence de scan"
|
||||||
|
description = "Fréquence de scan des marchés et de mise à jour de l'analyse"
|
||||||
|
|
||||||
|
[i18n.fr.settings.watchlist]
|
||||||
|
label = "Liste de surveillance"
|
||||||
|
description = "Liste de tickers à surveiller séparés par des virgules (actions : AAPL, crypto : BTC, ETF : SPY)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.initial_capital]
|
||||||
|
label = "Capital initial"
|
||||||
|
description = "Valeur initiale du portefeuille pour le trading simulé ou le suivi (en USD)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.alpaca_api_key]
|
||||||
|
label = "Clé API Alpaca"
|
||||||
|
description = "Clé API Alpaca pour le trading réel/simulé (obtenir gratuitement sur alpaca.markets)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.alpaca_secret_key]
|
||||||
|
label = "Clé secrète Alpaca"
|
||||||
|
description = "Clé secrète de l'API Alpaca"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Mode d'approbation"
|
||||||
|
description = "Exiger l'approbation explicite de l'utilisateur avant d'exécuter toute opération réelle — fortement recommandé"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Trading-Hand"
|
||||||
|
description = "Autonomer Marktintelligenz- und Trading-Motor — Multi-Signal-Analyse, adversariales Bull/Bear-Reasoning, kalibriertes Konfidenz-Scoring, striktes Risikomanagement und Portfolio-Analytik"
|
||||||
|
category = "Daten"
|
||||||
|
|
||||||
|
[i18n.de.settings.trading_mode]
|
||||||
|
label = "Trading-Modus"
|
||||||
|
description = "Betriebsmodus des Trading-Hand — nur Analyse, simuliertes Trading oder Live-Trading"
|
||||||
|
|
||||||
|
[i18n.de.settings.market_focus]
|
||||||
|
label = "Marktfokus"
|
||||||
|
description = "Welche Märkte überwacht und gehandelt werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.strategy_style]
|
||||||
|
label = "Strategiestil"
|
||||||
|
description = "Zeithorizont und Ansatz der Handelsstrategie"
|
||||||
|
|
||||||
|
[i18n.de.settings.risk_per_trade]
|
||||||
|
label = "Risiko pro Trade"
|
||||||
|
description = "Maximaler Prozentsatz des Portfolios, der bei einem einzelnen Trade riskiert wird"
|
||||||
|
|
||||||
|
[i18n.de.settings.max_daily_loss]
|
||||||
|
label = "Maximaler Tagesverlust"
|
||||||
|
description = "Maximaler täglicher Portfolioverlust in Prozent, bevor der Circuit Breaker auslöst"
|
||||||
|
|
||||||
|
[i18n.de.settings.analysis_depth]
|
||||||
|
label = "Analysetiefe"
|
||||||
|
description = "Anzahl der pro Asset zu sammelnden und gegenzuprüfenden Signale"
|
||||||
|
|
||||||
|
[i18n.de.settings.scan_schedule]
|
||||||
|
label = "Scan-Zeitplan"
|
||||||
|
description = "Wie oft Märkte gescannt und Analysen aktualisiert werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.watchlist]
|
||||||
|
label = "Watchlist"
|
||||||
|
description = "Kommagetrennte Liste der zu überwachenden Ticker (Aktien: AAPL, Krypto: BTC, ETFs: SPY)"
|
||||||
|
|
||||||
|
[i18n.de.settings.initial_capital]
|
||||||
|
label = "Anfangskapital"
|
||||||
|
description = "Anfänglicher Portfoliowert für simuliertes Trading oder Tracking (in USD)"
|
||||||
|
|
||||||
|
[i18n.de.settings.alpaca_api_key]
|
||||||
|
label = "Alpaca API-Schlüssel"
|
||||||
|
description = "Alpaca API-Schlüssel für Live-/Papierhandel (kostenlos auf alpaca.markets erhältlich)"
|
||||||
|
|
||||||
|
[i18n.de.settings.alpaca_secret_key]
|
||||||
|
label = "Alpaca Secret-Schlüssel"
|
||||||
|
description = "Secret-Schlüssel der Alpaca API"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Genehmigungsmodus"
|
||||||
|
description = "Ausdrückliche Benutzergenehmigung vor der Ausführung von Live-Trades erforderlich — dringend empfohlen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "트레이딩 Hand"
|
||||||
|
description = "자율 시장 인텔리전스 및 트레이딩 엔진 — 다중 신호 분석, 대립적 매수/매도 추론, 보정된 신뢰도 평가, 엄격한 리스크 관리 및 포트폴리오 분석"
|
||||||
|
category = "데이터"
|
||||||
|
|
||||||
|
[i18n.ko.settings.trading_mode]
|
||||||
|
label = "트레이딩 모드"
|
||||||
|
description = "트레이딩 Hand의 운영 방식 — 분석 전용, 모의 거래 또는 실거래"
|
||||||
|
|
||||||
|
[i18n.ko.settings.market_focus]
|
||||||
|
label = "시장 관심"
|
||||||
|
description = "모니터링 및 거래할 대상 시장"
|
||||||
|
|
||||||
|
[i18n.ko.settings.strategy_style]
|
||||||
|
label = "전략 스타일"
|
||||||
|
description = "거래 시간 프레임 및 전략 유형"
|
||||||
|
|
||||||
|
[i18n.ko.settings.risk_per_trade]
|
||||||
|
label = "거래당 리스크"
|
||||||
|
description = "단일 거래에서 허용되는 최대 포트폴리오 비율"
|
||||||
|
|
||||||
|
[i18n.ko.settings.max_daily_loss]
|
||||||
|
label = "일일 최대 손실"
|
||||||
|
description = "서킷 브레이커 발동 전 허용되는 일일 최대 손실 비율"
|
||||||
|
|
||||||
|
[i18n.ko.settings.analysis_depth]
|
||||||
|
label = "분석 깊이"
|
||||||
|
description = "자산별 수집 및 교차 검증할 신호 수"
|
||||||
|
|
||||||
|
[i18n.ko.settings.scan_schedule]
|
||||||
|
label = "스캔 일정"
|
||||||
|
description = "시장 스캔 및 분석 업데이트 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.watchlist]
|
||||||
|
label = "관심 목록"
|
||||||
|
description = "모니터링할 종목 코드 목록 (쉼표로 구분, 주식: AAPL, 암호화폐: BTC, ETF: SPY)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.initial_capital]
|
||||||
|
label = "초기 자본"
|
||||||
|
description = "모의 거래 또는 추적을 위한 시작 포트폴리오 금액 (USD)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.alpaca_api_key]
|
||||||
|
label = "Alpaca API 키"
|
||||||
|
description = "실거래/모의 거래용 Alpaca API 키 (alpaca.markets에서 무료 발급)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.alpaca_secret_key]
|
||||||
|
label = "Alpaca 시크릿 키"
|
||||||
|
description = "Alpaca API 시크릿 키"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "승인 모드"
|
||||||
|
description = "실거래 실행 전 사용자의 명시적 승인 필요 — 강력히 권장"
|
||||||
@@ -526,6 +526,313 @@ frequency = "hourly"
|
|||||||
token_consumption = "medium"
|
token_consumption = "medium"
|
||||||
default_active = false
|
default_active = false
|
||||||
|
|
||||||
|
# ─── Internationalization (optional) ─────────────────────────────────────────
|
||||||
|
# All i18n sections are optional. Without them, the English values above are used.
|
||||||
|
# To localize, add [i18n.LANG] sections (e.g. zh, ja, ko, es, fr, de).
|
||||||
|
# Settings translations are also optional — omit to keep English labels.
|
||||||
|
|
||||||
|
# ─── Chinese (简体中文) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
[i18n.zh]
|
[i18n.zh]
|
||||||
name = "Twitter Hand"
|
name = "Twitter Hand"
|
||||||
description = "自主 Twitter/X 管理——内容创作、定时发布、互动管理和效果追踪"
|
description = "自主 Twitter/X 管理——内容创作、定时发布、互动管理和效果追踪"
|
||||||
|
category = "通信"
|
||||||
|
|
||||||
|
[i18n.zh.settings.twitter_bearer_token]
|
||||||
|
label = "Twitter Bearer Token"
|
||||||
|
description = "Twitter/X 开发者平台的 Bearer Token,所有 Twitter API 操作均需此凭证。"
|
||||||
|
|
||||||
|
[i18n.zh.settings.twitter_style]
|
||||||
|
label = "内容风格"
|
||||||
|
description = "推文的语气和风格"
|
||||||
|
|
||||||
|
[i18n.zh.settings.post_frequency]
|
||||||
|
label = "发布频率"
|
||||||
|
description = "创建和发布内容的频率"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_reply]
|
||||||
|
label = "自动回复"
|
||||||
|
description = "自动回复提及和相关对话"
|
||||||
|
|
||||||
|
[i18n.zh.settings.auto_like]
|
||||||
|
label = "自动点赞"
|
||||||
|
description = "自动为人脉网络中的推文和相关内容点赞"
|
||||||
|
|
||||||
|
[i18n.zh.settings.content_topics]
|
||||||
|
label = "内容主题"
|
||||||
|
description = "要创作内容的主题(逗号分隔,例如 AI、创业、效率提升)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.brand_voice]
|
||||||
|
label = "品牌调性"
|
||||||
|
description = "描述你的独特风格(例如"用幽默简化复杂技术的创业者")"
|
||||||
|
|
||||||
|
[i18n.zh.settings.thread_mode]
|
||||||
|
label = "推文串模式"
|
||||||
|
description = "在内容组合中加入推文串(多条推文组成的故事)"
|
||||||
|
|
||||||
|
[i18n.zh.settings.content_queue_size]
|
||||||
|
label = "内容队列大小"
|
||||||
|
description = "待发队列中保持的推文数量"
|
||||||
|
|
||||||
|
[i18n.zh.settings.engagement_hours]
|
||||||
|
label = "互动时段"
|
||||||
|
description = "检查提及和互动的时间段"
|
||||||
|
|
||||||
|
[i18n.zh.settings.approval_mode]
|
||||||
|
label = "审批模式"
|
||||||
|
description = "将推文写入队列等待审核,而非直接发布"
|
||||||
|
|
||||||
|
# ─── Spanish (Español) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.es]
|
||||||
|
name = "Hand de Twitter"
|
||||||
|
description = "Gestor autónomo de Twitter/X — creación de contenido, publicación programada, interacciones y seguimiento de rendimiento"
|
||||||
|
category = "Comunicación"
|
||||||
|
|
||||||
|
[i18n.es.settings.twitter_bearer_token]
|
||||||
|
label = "Token Bearer de Twitter"
|
||||||
|
description = "Token Bearer del Portal de Desarrolladores de Twitter/X. Requerido para todas las operaciones de la API de Twitter."
|
||||||
|
|
||||||
|
[i18n.es.settings.twitter_style]
|
||||||
|
label = "Estilo de contenido"
|
||||||
|
description = "Voz y tono para tus tweets"
|
||||||
|
|
||||||
|
[i18n.es.settings.post_frequency]
|
||||||
|
label = "Frecuencia de publicación"
|
||||||
|
description = "Con qué frecuencia crear y publicar contenido"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_reply]
|
||||||
|
label = "Respuesta automática"
|
||||||
|
description = "Responder automáticamente a menciones y conversaciones relevantes"
|
||||||
|
|
||||||
|
[i18n.es.settings.auto_like]
|
||||||
|
label = "Me gusta automático"
|
||||||
|
description = "Dar me gusta automáticamente a tweets de tu red y contenido relevante"
|
||||||
|
|
||||||
|
[i18n.es.settings.content_topics]
|
||||||
|
label = "Temas de contenido"
|
||||||
|
description = "Temas sobre los que crear contenido (separados por comas, ej. IA, startups, productividad)"
|
||||||
|
|
||||||
|
[i18n.es.settings.brand_voice]
|
||||||
|
label = "Voz de marca"
|
||||||
|
description = "Describe tu voz única (ej. 'fundador sarcástico que simplifica la tecnología compleja')"
|
||||||
|
|
||||||
|
[i18n.es.settings.thread_mode]
|
||||||
|
label = "Modo de hilos"
|
||||||
|
description = "Incluir hilos de tweets (historias de múltiples tweets) en la mezcla de contenido"
|
||||||
|
|
||||||
|
[i18n.es.settings.content_queue_size]
|
||||||
|
label = "Tamaño de la cola de contenido"
|
||||||
|
description = "Número de tweets a mantener en la cola preparada"
|
||||||
|
|
||||||
|
[i18n.es.settings.engagement_hours]
|
||||||
|
label = "Horario de interacción"
|
||||||
|
description = "Cuándo verificar menciones e interactuar"
|
||||||
|
|
||||||
|
[i18n.es.settings.approval_mode]
|
||||||
|
label = "Modo de aprobación"
|
||||||
|
description = "Escribir los tweets en un archivo de cola para revisión en lugar de publicarlos directamente"
|
||||||
|
|
||||||
|
# ─── Japanese (日本語) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ja]
|
||||||
|
name = "Twitter Hand"
|
||||||
|
description = "自律型Twitter/Xマネージャー——コンテンツ作成、スケジュール投稿、エンゲージメント管理、パフォーマンス追跡"
|
||||||
|
category = "コミュニケーション"
|
||||||
|
|
||||||
|
[i18n.ja.settings.twitter_bearer_token]
|
||||||
|
label = "Twitter Bearerトークン"
|
||||||
|
description = "Twitter/X開発者ポータルのBearerトークン。すべてのTwitter API操作に必要です。"
|
||||||
|
|
||||||
|
[i18n.ja.settings.twitter_style]
|
||||||
|
label = "コンテンツスタイル"
|
||||||
|
description = "ツイートの語調とスタイル"
|
||||||
|
|
||||||
|
[i18n.ja.settings.post_frequency]
|
||||||
|
label = "投稿頻度"
|
||||||
|
description = "コンテンツの作成・投稿の頻度"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_reply]
|
||||||
|
label = "自動返信"
|
||||||
|
description = "メンションや関連する会話に自動で返信する"
|
||||||
|
|
||||||
|
[i18n.ja.settings.auto_like]
|
||||||
|
label = "自動いいね"
|
||||||
|
description = "ネットワーク内のツイートや関連コンテンツに自動でいいねする"
|
||||||
|
|
||||||
|
[i18n.ja.settings.content_topics]
|
||||||
|
label = "コンテンツトピック"
|
||||||
|
description = "作成するコンテンツのトピック(カンマ区切り、例: AI、スタートアップ、生産性)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.brand_voice]
|
||||||
|
label = "ブランドボイス"
|
||||||
|
description = "あなた独自の語り口を記述(例:「複雑なテクノロジーをわかりやすく伝える皮肉屋の起業家」)"
|
||||||
|
|
||||||
|
[i18n.ja.settings.thread_mode]
|
||||||
|
label = "スレッドモード"
|
||||||
|
description = "コンテンツミックスにツイートスレッド(複数ツイートで構成するストーリー)を含める"
|
||||||
|
|
||||||
|
[i18n.ja.settings.content_queue_size]
|
||||||
|
label = "コンテンツキューサイズ"
|
||||||
|
description = "準備キューに保持するツイートの数"
|
||||||
|
|
||||||
|
[i18n.ja.settings.engagement_hours]
|
||||||
|
label = "エンゲージメント時間帯"
|
||||||
|
description = "メンションの確認とエンゲージメントを行う時間帯"
|
||||||
|
|
||||||
|
[i18n.ja.settings.approval_mode]
|
||||||
|
label = "承認モード"
|
||||||
|
description = "ツイートを直接投稿せず、レビュー用のキューファイルに書き出す"
|
||||||
|
|
||||||
|
# ─── French (Français) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.fr]
|
||||||
|
name = "Hand Twitter"
|
||||||
|
description = "Gestionnaire Twitter/X autonome — création de contenu, publication programmée, interactions et suivi des performances"
|
||||||
|
category = "Communication"
|
||||||
|
|
||||||
|
[i18n.fr.settings.twitter_bearer_token]
|
||||||
|
label = "Jeton Bearer Twitter"
|
||||||
|
description = "Jeton Bearer du Portail Développeurs Twitter/X. Requis pour toutes les opérations de l'API Twitter."
|
||||||
|
|
||||||
|
[i18n.fr.settings.twitter_style]
|
||||||
|
label = "Style de contenu"
|
||||||
|
description = "Ton et style pour vos tweets"
|
||||||
|
|
||||||
|
[i18n.fr.settings.post_frequency]
|
||||||
|
label = "Fréquence de publication"
|
||||||
|
description = "Fréquence de création et de publication de contenu"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_reply]
|
||||||
|
label = "Réponse automatique"
|
||||||
|
description = "Répondre automatiquement aux mentions et conversations pertinentes"
|
||||||
|
|
||||||
|
[i18n.fr.settings.auto_like]
|
||||||
|
label = "Like automatique"
|
||||||
|
description = "Aimer automatiquement les tweets de votre réseau et le contenu pertinent"
|
||||||
|
|
||||||
|
[i18n.fr.settings.content_topics]
|
||||||
|
label = "Sujets de contenu"
|
||||||
|
description = "Sujets sur lesquels créer du contenu (séparés par des virgules, ex. IA, startups, productivité)"
|
||||||
|
|
||||||
|
[i18n.fr.settings.brand_voice]
|
||||||
|
label = "Voix de marque"
|
||||||
|
description = "Décrivez votre voix unique (ex. 'fondateur sarcastique qui simplifie la technologie complexe')"
|
||||||
|
|
||||||
|
[i18n.fr.settings.thread_mode]
|
||||||
|
label = "Mode fil de discussion"
|
||||||
|
description = "Inclure des fils de tweets (histoires à plusieurs tweets) dans le mix de contenu"
|
||||||
|
|
||||||
|
[i18n.fr.settings.content_queue_size]
|
||||||
|
label = "Taille de la file de contenu"
|
||||||
|
description = "Nombre de tweets à maintenir dans la file d'attente préparée"
|
||||||
|
|
||||||
|
[i18n.fr.settings.engagement_hours]
|
||||||
|
label = "Heures d'engagement"
|
||||||
|
description = "Quand vérifier les mentions et interagir"
|
||||||
|
|
||||||
|
[i18n.fr.settings.approval_mode]
|
||||||
|
label = "Mode d'approbation"
|
||||||
|
description = "Écrire les tweets dans un fichier d'attente pour révision au lieu de les publier directement"
|
||||||
|
|
||||||
|
# ─── German (Deutsch) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.de]
|
||||||
|
name = "Twitter-Hand"
|
||||||
|
description = "Autonomer Twitter/X-Manager — Content-Erstellung, geplante Veröffentlichung, Engagement-Management und Performance-Tracking"
|
||||||
|
category = "Kommunikation"
|
||||||
|
|
||||||
|
[i18n.de.settings.twitter_bearer_token]
|
||||||
|
label = "Twitter Bearer-Token"
|
||||||
|
description = "Bearer-Token vom Twitter/X-Entwicklerportal. Erforderlich für alle Twitter-API-Operationen."
|
||||||
|
|
||||||
|
[i18n.de.settings.twitter_style]
|
||||||
|
label = "Inhaltsstil"
|
||||||
|
description = "Ton und Stil für Ihre Tweets"
|
||||||
|
|
||||||
|
[i18n.de.settings.post_frequency]
|
||||||
|
label = "Veröffentlichungshäufigkeit"
|
||||||
|
description = "Wie oft Inhalte erstellt und veröffentlicht werden"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_reply]
|
||||||
|
label = "Automatische Antwort"
|
||||||
|
description = "Automatisch auf Erwähnungen und relevante Gespräche antworten"
|
||||||
|
|
||||||
|
[i18n.de.settings.auto_like]
|
||||||
|
label = "Automatisches Like"
|
||||||
|
description = "Tweets im Netzwerk und relevante Inhalte automatisch liken"
|
||||||
|
|
||||||
|
[i18n.de.settings.content_topics]
|
||||||
|
label = "Inhaltsthemen"
|
||||||
|
description = "Themen für die Content-Erstellung (kommagetrennt, z.B. KI, Startups, Produktivität)"
|
||||||
|
|
||||||
|
[i18n.de.settings.brand_voice]
|
||||||
|
label = "Markenstimme"
|
||||||
|
description = "Beschreiben Sie Ihre einzigartige Stimme (z.B. 'sarkastischer Gründer, der komplexe Technologie vereinfacht')"
|
||||||
|
|
||||||
|
[i18n.de.settings.thread_mode]
|
||||||
|
label = "Thread-Modus"
|
||||||
|
description = "Tweet-Threads (mehrteilige Tweet-Geschichten) in den Content-Mix aufnehmen"
|
||||||
|
|
||||||
|
[i18n.de.settings.content_queue_size]
|
||||||
|
label = "Größe der Content-Warteschlange"
|
||||||
|
description = "Anzahl der Tweets in der vorbereiteten Warteschlange"
|
||||||
|
|
||||||
|
[i18n.de.settings.engagement_hours]
|
||||||
|
label = "Engagement-Zeiten"
|
||||||
|
description = "Wann Erwähnungen geprüft und interagiert werden soll"
|
||||||
|
|
||||||
|
[i18n.de.settings.approval_mode]
|
||||||
|
label = "Genehmigungsmodus"
|
||||||
|
description = "Tweets in eine Warteschlangendatei zur Überprüfung schreiben, anstatt sie direkt zu veröffentlichen"
|
||||||
|
|
||||||
|
# ─── Korean (한국어) ────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
[i18n.ko]
|
||||||
|
name = "Twitter Hand"
|
||||||
|
description = "자율 Twitter/X 관리 — 콘텐츠 제작, 예약 게시, 소통 관리 및 성과 추적"
|
||||||
|
category = "커뮤니케이션"
|
||||||
|
|
||||||
|
[i18n.ko.settings.twitter_bearer_token]
|
||||||
|
label = "Twitter Bearer 토큰"
|
||||||
|
description = "Twitter/X 개발자 포털의 Bearer 토큰. 모든 Twitter API 작업에 필수."
|
||||||
|
|
||||||
|
[i18n.ko.settings.twitter_style]
|
||||||
|
label = "콘텐츠 스타일"
|
||||||
|
description = "트윗의 어조와 스타일"
|
||||||
|
|
||||||
|
[i18n.ko.settings.post_frequency]
|
||||||
|
label = "게시 빈도"
|
||||||
|
description = "콘텐츠를 작성하고 게시하는 주기"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_reply]
|
||||||
|
label = "자동 답글"
|
||||||
|
description = "멘션 및 관련 대화에 자동으로 답글 작성"
|
||||||
|
|
||||||
|
[i18n.ko.settings.auto_like]
|
||||||
|
label = "자동 좋아요"
|
||||||
|
description = "네트워크 내 트윗 및 관련 콘텐츠에 자동으로 좋아요"
|
||||||
|
|
||||||
|
[i18n.ko.settings.content_topics]
|
||||||
|
label = "콘텐츠 주제"
|
||||||
|
description = "콘텐츠를 작성할 주제 (쉼표로 구분, 예: AI, 스타트업, 생산성)"
|
||||||
|
|
||||||
|
[i18n.ko.settings.brand_voice]
|
||||||
|
label = "브랜드 보이스"
|
||||||
|
description = "고유한 스타일을 설명 (예: '복잡한 기술을 쉽게 풀어내는 유머러스한 창업자')"
|
||||||
|
|
||||||
|
[i18n.ko.settings.thread_mode]
|
||||||
|
label = "스레드 모드"
|
||||||
|
description = "콘텐츠 구성에 트윗 스레드 (다중 트윗 스토리) 포함"
|
||||||
|
|
||||||
|
[i18n.ko.settings.content_queue_size]
|
||||||
|
label = "콘텐츠 대기열 크기"
|
||||||
|
description = "준비 대기열에 유지할 트윗 수"
|
||||||
|
|
||||||
|
[i18n.ko.settings.engagement_hours]
|
||||||
|
label = "소통 시간대"
|
||||||
|
description = "멘션 확인 및 소통 활동을 수행하는 시간대"
|
||||||
|
|
||||||
|
[i18n.ko.settings.approval_mode]
|
||||||
|
label = "승인 모드"
|
||||||
|
description = "트윗을 직접 게시하지 않고 대기열 파일에 기록하여 검토"
|
||||||
@@ -226,6 +226,72 @@ Do NOT auto-like:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Advanced Engagement Patterns
|
||||||
|
|
||||||
|
### Quote Tweet vs Reply vs Retweet
|
||||||
|
|
||||||
|
Choosing the right interaction type determines whether you gain visibility or waste it.
|
||||||
|
|
||||||
|
**Use a Quote Tweet when**:
|
||||||
|
- You have a distinct take or added context (not just "this!")
|
||||||
|
- The original tweet has high impressions and you want to draft off its reach
|
||||||
|
- You are crediting someone while adding your own insight for your audience
|
||||||
|
- The original author has a similar or larger following (exposes you to their audience)
|
||||||
|
|
||||||
|
**Use a Reply when**:
|
||||||
|
- You want to build a direct relationship with the author
|
||||||
|
- Your comment only makes sense in context of the original
|
||||||
|
- The original author has a much larger following (replies show on their thread, giving you visibility without looking self-promotional)
|
||||||
|
- You are answering a question or adding a correction
|
||||||
|
|
||||||
|
**Use a plain Retweet when**:
|
||||||
|
- The original says everything perfectly and you have nothing to add
|
||||||
|
- You want to signal-boost a community member, customer, or partner
|
||||||
|
- The content is time-sensitive (breaking news, event announcements)
|
||||||
|
|
||||||
|
**Avoid**:
|
||||||
|
- Quote tweeting with only emojis or "this" -- adds no value, looks lazy
|
||||||
|
- Quote tweeting someone with fewer followers just to dunk -- punching down
|
||||||
|
- Retweeting more than 3-4 times per day -- dilutes your original content ratio
|
||||||
|
|
||||||
|
### Thread Repurposing
|
||||||
|
|
||||||
|
A thread that performed well contains 5-7 standalone content pieces. Extract them over the following week to maximize ROI.
|
||||||
|
|
||||||
|
**Process**:
|
||||||
|
1. Day 0 (original): Post the full thread
|
||||||
|
2. Day 2: Pull the single most quotable tweet from the thread. Post it standalone with slightly different wording. No link back to the thread
|
||||||
|
3. Day 4: Turn a data point or example from the thread into a graphic or screenshot tweet
|
||||||
|
4. Day 6: Post the thread's core thesis as a hot take (one tweet, punchy)
|
||||||
|
5. Day 8+: If engagement stayed strong, post a "Part 2" thread that goes deeper on whichever tweet in the original got the most replies
|
||||||
|
|
||||||
|
**Rules**:
|
||||||
|
- Change the wording each time -- copy-pasting feels like spam to followers who saw the original
|
||||||
|
- Space extractions at least 48 hours apart
|
||||||
|
- Stop if any extraction underperforms significantly -- the topic is tapped out
|
||||||
|
- Never repurpose a thread that got low engagement; the content did not resonate
|
||||||
|
|
||||||
|
### Trending Topic Participation
|
||||||
|
|
||||||
|
**When to participate**:
|
||||||
|
- The trend directly intersects one of your content pillars
|
||||||
|
- You have a genuine, informed perspective (not a generic reaction)
|
||||||
|
- The trend is still rising (check the "Trending" tab; if it has been trending for >12 hours, you are late)
|
||||||
|
- The tone of the trend matches your brand voice
|
||||||
|
|
||||||
|
**When to avoid**:
|
||||||
|
- Tragedy, disaster, or crisis events -- opportunistic posting destroys trust
|
||||||
|
- Highly polarized political or social debates outside your expertise
|
||||||
|
- Trends driven by outrage mobs -- associating your brand is high-risk, low-reward
|
||||||
|
- You would need to force-fit your product or message into the trend
|
||||||
|
|
||||||
|
**Execution**:
|
||||||
|
- Lead with your actual insight, not the hashtag. The hashtag goes at the end or is omitted entirely if the topic keyword is in your text
|
||||||
|
- Be early or be different. If 50 people have already made the same joke, skip it
|
||||||
|
- Tie back to your pillar: "Trend X is exactly why [your pillar topic] matters more than ever"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Content Calendar Template
|
## Content Calendar Template
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -254,6 +320,169 @@ Friday:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Worked Examples
|
||||||
|
|
||||||
|
### Example 1: Product Launch Twitter Campaign (1-Week Plan)
|
||||||
|
|
||||||
|
**Context**: A dev tools startup is launching "FastDB," an open-source embedded database. The account has 2,400 followers, mostly backend engineers.
|
||||||
|
|
||||||
|
**Pre-launch (3 days before)**:
|
||||||
|
- Seed curiosity without revealing the product name
|
||||||
|
- Engage heavily in database-related threads to increase profile visits before launch
|
||||||
|
|
||||||
|
**Day 1 (Monday) -- Teaser**:
|
||||||
|
```
|
||||||
|
We've been heads-down for 8 months building something
|
||||||
|
we think embedded databases have been missing.
|
||||||
|
|
||||||
|
Shipping it open-source this Thursday.
|
||||||
|
|
||||||
|
More soon.
|
||||||
|
```
|
||||||
|
Purpose: Create anticipation. No hashtags, no links. Let curiosity drive profile visits.
|
||||||
|
|
||||||
|
**Day 2 (Tuesday) -- Problem framing**:
|
||||||
|
```
|
||||||
|
SQLite is incredible for what it does.
|
||||||
|
|
||||||
|
But if you need concurrent writes, ACID transactions,
|
||||||
|
AND sub-millisecond reads in the same embedded DB...
|
||||||
|
your options get thin fast.
|
||||||
|
|
||||||
|
We've been living in that gap. Fix incoming Thursday.
|
||||||
|
```
|
||||||
|
Purpose: Define the problem space. People who feel this pain will follow for the reveal.
|
||||||
|
|
||||||
|
**Day 3 (Wednesday) -- Social proof / build-up**:
|
||||||
|
```
|
||||||
|
Shipped our embedded DB to 12 beta testers last month.
|
||||||
|
|
||||||
|
Results so far:
|
||||||
|
- 4.2x faster concurrent writes vs SQLite WAL mode
|
||||||
|
- Zero-config replication
|
||||||
|
- Single static binary, 3.8 MB
|
||||||
|
|
||||||
|
One more day.
|
||||||
|
```
|
||||||
|
Purpose: Concrete numbers build credibility. "One more day" maintains tension.
|
||||||
|
|
||||||
|
**Day 4 (Thursday) -- Launch day thread** (6-tweet thread):
|
||||||
|
```
|
||||||
|
1/6 [HOOK]: Introducing FastDB -- embedded DB for concurrent-write-heavy
|
||||||
|
workloads. Open source. Single binary. Here's why we built it:
|
||||||
|
2/6 [PROBLEM]: SQLite = single-writer. Fine for reads, hits a wall on
|
||||||
|
write-heavy apps (event logging, IoT, realtime sync). FastDB uses
|
||||||
|
MVCC -- writers never block readers, readers never block writers.
|
||||||
|
3/6 [PROOF]: Benchmarks (M2 Mac, 8 threads): concurrent writes 51K ops/s
|
||||||
|
vs SQLite WAL 12K ops/s. Point reads on par at ~900K ops/s.
|
||||||
|
4/6 [ONBOARD]: Getting started: `cargo add fastdb` then 3 lines of code.
|
||||||
|
Full SQLite-compatible query layer coming in v0.2.
|
||||||
|
5/6 [ROADMAP]: v0.1 ships ACID transactions, built-in replication, crash
|
||||||
|
recovery, zero deps beyond libc. v0.2: SQL layer, S3 cold storage.
|
||||||
|
6/6 [CTA]: Star the repo: github.com/example/fastdb -- open issues, roast
|
||||||
|
the benchmarks, tell us what's missing.
|
||||||
|
```
|
||||||
|
Key structural choices: tweet 1 is a standalone hook, tweet 3 has hard numbers, tweet 6 ends with a specific ask (not just "check it out").
|
||||||
|
|
||||||
|
**Day 4 afternoon** -- Post a standalone tweet answering the most common reply question publicly (drives docs traffic). **Day 5 (Friday)** -- Reply to every substantive comment. Templates for common reactions:
|
||||||
|
- "How is this different from X?" -> Concrete comparison, link to docs
|
||||||
|
- "Benchmarks look suspicious" -> Link the reproduction steps, invite them to run it
|
||||||
|
- "Will you support [feature]?" -> Link the tracking issue
|
||||||
|
|
||||||
|
**Day 6-7 (Weekend)** -- Repurpose: extract the benchmark tweet as a standalone with a chart image; post a "5 things I learned launching an open-source DB" reflection thread.
|
||||||
|
|
||||||
|
### Example 2: Building Thought Leadership from Scratch (Month 1)
|
||||||
|
|
||||||
|
**Context**: An individual ML engineer with 180 followers wants to become a recognized voice in applied machine learning. No existing audience. No viral content history.
|
||||||
|
|
||||||
|
**Core principle for month 1**: Do not broadcast. Contribute. Your first 500 followers come from being consistently useful in other people's threads, not from your own tweets.
|
||||||
|
|
||||||
|
**Week 1 -- Comment-first growth**:
|
||||||
|
- Post 0 original tweets
|
||||||
|
- Find 10 accounts in your niche with 5K-50K followers who post regularly
|
||||||
|
- Reply to 5-8 of their tweets per day with substantive comments (not "great post!")
|
||||||
|
- Goal: Get 3-5 of those authors to like or reply to your comments by end of week
|
||||||
|
|
||||||
|
**What a good reply looks like**:
|
||||||
|
```
|
||||||
|
Original tweet: "Fine-tuning LLMs is overrated. Most use cases
|
||||||
|
are better served by good prompting + RAG."
|
||||||
|
|
||||||
|
Bad reply: "Agreed!"
|
||||||
|
|
||||||
|
Good reply: "Mostly agree, but there's a middle ground --
|
||||||
|
LoRA fine-tuning on 500 domain-specific examples
|
||||||
|
consistently beats RAG for structured extraction tasks.
|
||||||
|
|
||||||
|
We saw 23% higher F1 on invoice parsing after a 2-hour
|
||||||
|
fine-tune vs our best RAG setup.
|
||||||
|
|
||||||
|
RAG still wins for open-domain QA though."
|
||||||
|
```
|
||||||
|
This reply adds data, shows experience, and invites further discussion. People reading the thread see your expertise and check your profile.
|
||||||
|
|
||||||
|
**Week 2 -- First original content**:
|
||||||
|
- Continue the reply strategy (5/day minimum)
|
||||||
|
- Post 2-3 original tweets. Keep them observational, not promotional:
|
||||||
|
```
|
||||||
|
Something I've noticed after fine-tuning 30+ models
|
||||||
|
this year:
|
||||||
|
|
||||||
|
The quality of your eval set matters 10x more than
|
||||||
|
the size of your training set.
|
||||||
|
|
||||||
|
50 carefully labeled examples with clear edge cases
|
||||||
|
beats 5000 noisy scraped examples every time.
|
||||||
|
```
|
||||||
|
- Post 1 "ask the audience" tweet to start conversations:
|
||||||
|
```
|
||||||
|
ML engineers: what's the most counterintuitive lesson
|
||||||
|
you've learned about deploying models to production?
|
||||||
|
|
||||||
|
I'll start: the model is almost never the bottleneck.
|
||||||
|
Data pipelines are.
|
||||||
|
```
|
||||||
|
|
||||||
|
**Week 3 -- First thread** (5-tweet authority thread):
|
||||||
|
```
|
||||||
|
1/5 [HOOK]: I've deployed 12 ML models to production this year. The ones
|
||||||
|
that worked all had one thing in common. It wasn't the architecture.
|
||||||
|
2/5 [THESIS]: Every success had a tight feedback loop -- predictions
|
||||||
|
validated by a human within 24 hours, not "we'll evaluate next quarter."
|
||||||
|
3/5 [EVIDENCE]: Model A (invoice classifier): accountants flagged errors
|
||||||
|
same-day, retrained weekly, 84% -> 97% in 6 weeks. Model B (churn
|
||||||
|
predictor): sales ignored outputs, no feedback 3 months, drifted to
|
||||||
|
coin-flip accuracy.
|
||||||
|
4/5 [FRAMEWORK]: The pattern: (1) deploy with human-in-the-loop review,
|
||||||
|
(2) log every correction, (3) retrain on corrections every 1-2 weeks,
|
||||||
|
(4) remove human review once accuracy stabilizes.
|
||||||
|
5/5 [CTA]: If you're skipping the feedback loop, you're building on sand.
|
||||||
|
What's your experience?
|
||||||
|
```
|
||||||
|
Notice the structure: personal credibility in tweet 1, a clear thesis in tweet 2, contrasting real examples in tweet 3, an actionable takeaway in tweet 4, and a discussion prompt in tweet 5.
|
||||||
|
|
||||||
|
**Week 4 -- Establish rhythm**:
|
||||||
|
- Settle into a sustainable cadence: 1 thread/week, 1-2 standalone tweets/day, 5+ replies/day
|
||||||
|
- Review metrics from week 2-3 content to identify which topics resonated
|
||||||
|
- Double down on the topic that got the most replies (not likes -- replies indicate deeper engagement)
|
||||||
|
|
||||||
|
**Month 1 milestones**:
|
||||||
|
| Metric | Target | Why it matters |
|
||||||
|
|--------|--------|----------------|
|
||||||
|
| Followers | 350-500 | 2-3x growth signals the approach is working |
|
||||||
|
| Avg impressions per tweet | 800-2000 | Shows the algorithm is distributing your content |
|
||||||
|
| Replies received per original tweet | 3-5 | People are engaging, not just scrolling past |
|
||||||
|
| Mutual follows from target accounts | 5-10 | Your niche peers are noticing you |
|
||||||
|
| Profile visits / week | 200+ | Your replies are driving curiosity |
|
||||||
|
|
||||||
|
**What to avoid in month 1**:
|
||||||
|
- Posting 10 tweets/day hoping something sticks -- looks desperate, exhausts your ideas
|
||||||
|
- Buying followers or using engagement pods -- Twitter's algorithm detects and penalizes this
|
||||||
|
- Talking about yourself or your product -- earn attention through insight first
|
||||||
|
- Getting discouraged by low numbers -- 180 to 400 followers in a month is strong growth
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
### Key Metrics
|
### Key Metrics
|
||||||
|
|||||||
Reference in new issue
Block a user