assistant-claw/state-schemas/customer.md
Atlas refactor bd0be97630 Refactor: drop Vega framing, promote Atlas to repo root
This repo IS Atlas (总助 Claw / 老板视角项目执行雷达). The earlier
two-profile framing (Atlas + Vega placeholder) was a misread — Vega is
the agent persona answering Multica issues, not the product. Vega has
no relationship to assistant-claw the product.

Changes:
- Move atlas/* to top-level (git mv preserves history)
- Remove empty Vega placeholders prompts/.gitkeep, tools/.gitkeep
- Delete atlas/ wrapper directory (now empty)
- Update path references in INTEGRATION-hermes.md, scripts/mirror-...sh,
  docs/decisions/0001-mirror-nuwa-skill.md
- Rewrite README.md as Atlas-only, remove dual-profile language

After this commit:
- Top-level OpenClaw 8 files (IDENTITY/SOUL/USER/AGENTS/TOOLS/MEMORY/
  BOOTSTRAP/HEARTBEAT + CLAUDE symlink + zh-CN mirrors)
- skills/{6 sub-skills + DESCRIPTION + README}
- mcp-tools/{spec + Python implementation}
- state-schemas/{project, person, customer + README}
- autopilots/{5 atlas-*.yaml}
- client-deck/, docs/decisions/, scripts/

The ~/.hermes/skills/atlas/ destination convention preserved (atlas as
a skill namespace on the operator's machine, distinct from source path).
2026-05-09 17:54:18 +08:00

189 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# State Schema: `state/customers/CUST-*.json`
Owned by: `claw-customer-radar` (write); read by `claw-report-writer`.
## Identifier convention
`CUST-<slug>` where slug is derived from the primary email domain or the boss-confirmed customer name.
Examples: `CUST-clientco`, `CUST-customer-A`, `CUST-momo-tech`
Unconfirmed candidate customers are stored as `UNCLASSIFIED-<domain>.json` and surface in W1 audit for boss to confirm/merge.
## Top-level shape
```jsonc
{
"id": "CUST-clientco", // string
"name": "客户A", // string, boss-confirmed display name
"domains": ["clientco.com", "client-co.cn"], // array<string>, all email domains for this customer
"lifecycle_stage": "At-Risk", // enum: Lead | Onboarding | Active | At-Risk | Churned
"关联项目": [ // array<object>
{
"id": "PRJ-2025-001-客户A官网改版",
"状态": "Stalled",
"金额": 120000
},
{
"id": "PRJ-2026-014-customer-A-supply",
"状态": "Active",
"金额": 80000
}
],
"健康度": { // object — Customer Health Score
"score": 62, // int 0..100
"档位": "黄(注意)", // enum: 绿(健康) | 黄(注意) | 红(危急)
"构成": { // object, weighted components
"项目健康": 0.60, // float, weight 0.4
"情绪趋势_30d": -0.5, // float, weight 0.3
"邮件频率_normalcy": 1.0, // float, weight 0.2
"金额规模_normalized": 0.7 // float, weight 0.1
},
"computed_at": "2026-05-09T07:30:00Z",
"previous_tier": "绿(健康)", // for Andon detection
"tier_change_at": "2026-05-08T07:30:00Z"
},
"情绪趋势_90d": [ // array<object>, monthly buckets
{"month": "2026-02", "score": 0.7, "代表词": "期待 / 配合", "n_quotes": 12},
{"month": "2026-03", "score": 0.5, "代表词": "等候 / 询问", "n_quotes": 9},
{"month": "2026-04", "score": 0.2, "代表词": "催 / 失望", "n_quotes": 14}
],
"RFM": { // object
"Recency": "5d", // string, time since last interaction
"Recency_iso": "2026-05-04T16:32:00Z", // ISO timestamp for sorting
"Frequency_30d": 14, // int, message count last 30d
"Frequency_90d_baseline": 38, // int, baseline for normalcy comparison
"Monetary": 200000 // number, sum of associated project amounts
},
"我方接口人": [ // array<object>, internal people who touch this customer
{"name": "张三", "角色": "项目经理", "可靠度": "中", "primary_for_projects": ["PRJ-2025-001"]},
{"name": "李四", "角色": "客户总监", "可靠度": "高", "primary_for_projects": ["PRJ-2026-014"]}
],
"客户方决策链": [ // array<object>, external people on customer side
{
"name": "客户A-王总",
"email": "wang@clientco.com",
"角色": "决策者", // enum: 决策者 | 执行接口 | 用户 | 阻拦者
"态度": "中性偏冷",
"last_intervention": "2026-04-22"
},
{
"name": "客户A-赵经理",
"email": "zhao@clientco.com",
"角色": "执行接口",
"态度": "积极",
"last_intervention": "2026-05-04"
}
],
"VoC_关键原话_30d": [ // array<object>, max 5
{
"date": "2026-04-22",
"speaker": "王总",
"speaker_email": "wang@clientco.com",
"原文": "再这样我就找别家了",
"性质": "强负向", // enum: 强正向 | 正向 | 中性 | 负向 | 强负向
"source_email_id": "msg-xyz@..."
},
{
"date": "2026-04-15",
"speaker": "赵经理",
"speaker_email": "zhao@clientco.com",
"原文": "你们做事还是认真的",
"性质": "正向",
"source_email_id": "msg-uvw@..."
}
],
"流失预警信号": [ // array<object>
{
"信号": "决策者亲自施压",
"强度": "高", // enum: 高 | 中 | 低
"时间": "2026-04-22",
"rule_ref": "R-04",
"source_email_ids": ["msg-xyz@..."]
},
{
"信号": "PRJ-001 stall 11 天",
"强度": "中",
"时间": "2026-05-09",
"rule_ref": "R-01"
}
],
"老板视角建议": "本周内安排老板亲自给王总通一次电话——执行层已经救不回来了",
"_meta": {
"created_at": "2025-06-01T09:00:00Z",
"updated_at": "2026-05-09T07:30:12Z",
"atlas_version": "v0.4",
"last_andon_alert_at": "2026-05-08T07:30:00Z",
"last_andon_acknowledged_at": null
}
}
```
## Customer Health Score (CHS) formula
```
CHS = 100 × (
0.4 × project_health
+ 0.3 × normalize(sentiment_trend_30d, [-1,1] → [0,1])
+ 0.2 × email_frequency_normalcy
+ 0.1 × monetary_scale
)
tier:
CHS >= 80 → 绿(健康)
60 <= CHS < 80 → 黄(注意)
CHS < 60 → 红(危急)
```
Score is clamped to [0, 100] and rounded to nearest integer.
## Andon Alert triggers
Fire to `state/runs/alerts.json` (and email + WeChat if configured) when:
1. **Tier downgrade**`健康度.档位` drops from 绿→黄 or 黄→红
2. **Strong-negative VoC** — new entry in `VoC_关键原话_30d` with `性质 == "强负向"`
3. **Multi-signal churn** — ≥ 2 active `流失预警信号` simultaneously
Suppression: same `(customer_id, trigger_type)` does not re-fire within 24h of `last_andon_acknowledged_at`.
## Cross-customer data isolation
When `claw-report-writer` renders a customer-specific report:
- Read ONLY this customer's JSON file
- Read ONLY projects whose `客户方` matches this customer's `id`
- Read ONLY people who appear in this customer's `我方接口人`
- Never include comparison metrics ("compared to other customers")
This isolation is enforced at the file-read layer, not just at template-render time.
## Boss override format
```
OVERRIDE CUST CUST-clientco lifecycle_stage="Active"
OVERRIDE CUST CUST-clientco merge_into="CUST-clientco-group"
OVERRIDE CUST UNCLASSIFIED-newdomain.com promote_as="CUST-newprospect"
```
## Display rules for `claw-report-writer`
- Daily Brief: only customers with tier change or new churn signal in last 24h
- Weekly Rollup: top 5 customers by CHS movement (up or down)
- Monthly Health Report: one full page per Active or At-Risk customer
- Andon Alerts: red customers with new strong-negative VoC, real-time
## Privacy
- Right-to-delete: `atlas-customer-purge --id CUST-clientco` wipes all related project state, removes person↔customer associations, writes tombstone
- Audit log preserved (anonymized) for compliance