The call ID is lov-do-they-love-me, using the Englishsingular they: refers to a person whose gender is unknown or need not be specified,
so it covers both he and she. The verb form of singular they is do, not does—does they is a grammatical error,
this is not a typo, and during later maintenance, renaming, or localization do not "correct" it to does.
The display name is fixed as "Love Index Analysis"; the ID and display name serve different roles, do not substitute one for the other.
Turn a real chat between two people into conclusions that can withstand scrutiny: first quantify the interaction rhythm, then do semantic layering, and finally deliver a vertical phone infographic. Conclusions must clearly state the scope, sample, and error,do not treat work messages as emotional heat, and do not present a custom index as a measurement of the parties' emotions.
The user gets three things: reproducible intermediate data, a card ready to send as-is, and the error range of these conclusions.
Triggers
Activate when
- "Analyze my chat history with someone", "we've been chatting for two months, what are we exactly".
- "Does he/she love me", "help me do a love index analysis", "see who is more proactive".
- "Turn our chat into a card".
- The user asks to "analyze our chat history", "make a relationship / love index card", or "is this person into me, based on the messages".
Do not activate when
- If you only need to read, search, or export WeChat records: hand off to
lov-wdb-cli。 - If conclusions already exist and you only want to lay it out as a card: hand off to
lov-mobile-infographic; this Skill only starts from data when there are no quantitative and semantic conclusions. - For group chat daily reports, official account articles, or marketing image cards: hand off to the daily report, article, and image card Skills respectively.
- If there is no real chat history and a score is wanted based only on feelings: refuse to fabricate, and explain that data is needed.
User Profile (cross-session)
Every generated Skill is connected to the shared user-profile/v1 contract in
skill.yaml. Read the shared user, brand, workspace, preferences, and this
Skill's skills.<skill_id> namespace at the start of every run. Keep the source
portable: resolved personal values belong in the shared profile, never here.
When the user directly states a durable preference or brand fact, persist it
through scripts/profile_store.py and report the saved profile path. Put
Skill-specific values under records.<field>; use brand.<field> or
user.<field> for shared values. Do not persist inferred secrets or credentials.
See references/user-profile.md for the complete contract.
Skill Group Composition
Read references/skill-composition.md before deciding whether to invoke or
extend any adjacent capability. The record distinguishes optional upstream and
downstream handoffs from embedded Kit modules. Do not silently depend on a
sibling Skill that is not shipped with this source.
Workflow (MANDATORY)
You MUST follow these steps in order.
Step 0: Resolve skill root, dependencies, and runtime context
- Use
SKILL_DIRif the environment provides it. - Otherwise infer the installed skill directory from the current skill context.
- Verify
scripts/chat_metrics.py,scripts/matrix_dataset.py,scripts/export_text.py,scripts/semantic_label.py,scripts/topic_composition.py,scripts/card_figures.py,scripts/verify_figures.py, and the four references exist before work. - If a required resource is missing, name its expected relative path and stop before producing a partial result.
When running scripts manually:
export SKILL_DIR="/path/to/lov-do-they-love-me"
Resolve context.profile on every invocation. The precedence is current request,
project context, Skill-specific profile records, shared preferences, shared
brand/user profile, then safe defaults. A direct user statement about a durable
preference or brand fact should be saved with scripts/profile_store.py record
using --confirm, followed by a concise saved-path report.
Step 1: Understand the requested outcome
- Clarify the target, time window, delivery surface (for yourself / to send to the other party / to send out) and language.
- Read
references/privacy-and-consent.md: this is a third party's private chat, process locally by default. - First define the reader and the judgment: which refutable judgment should this card answer? If you cannot write the judgment, go back to Step 3 to find evidence.
Step 1.5: Analyze nearby Skills before implementation
- Inspect related local and installed Skills by routing contract and concrete input/output, not by filename alone.
- Record upstream, core, downstream, overlap, and not-composed decisions in
references/skill-composition.md. - Keep sibling Skills optional and artifact-based. When stages require hard coupling for one outcome, create a self-contained Kit instead.
- This Skill's existing records are in
references/skill-composition.md: upstream islov-wdb-cli, downstream islov-mobile-infographic; unless the user changes the scope, do not reinvent data retrieval or layout.
Step 2: Execute the workflow
Execute the following five sections in order. Each section uses files as the handoff object; if it fails, stop at that section and explain what is missing.
2.1 Data retrieval (hand off to lov-wdb-cli)
Use the other party's nickname/remark to locate the unique contact, export the private chat within the time window as JSONL, and record the local account and the other party's account:
python3 "$WDB_SKILL/skills/wdb-query/scripts/wdb_cli.py" chats \
--contact "<昵称或备注>" --from <起> --to <止> --limit 5000 --format jsonl > messages.jsonl
First run stats to see the volume and daily distribution, then decide the window. Record truncated and meta.errors;
do not write account numbers, database paths, or table names on the card or in the report.
2.2 Quantification
python3 "$SKILL_DIR/scripts/chat_metrics.py" \
--messages messages.jsonl --me <本机账号> --other <对方账号> --out metrics.json
python3 "$SKILL_DIR/scripts/matrix_dataset.py" \
--messages messages.jsonl --me <本机账号> --other <对方账号> --out matrix.json
For detailed scope rules see references/chat-metrics.md。idx is only an activity index, state the weights clearly, and do not call it emotion.
2.3 Semantic layering (local by default)
python3 "$SKILL_DIR/scripts/export_text.py" \
--messages messages.jsonl --me <本机账号> --other <对方账号> --out label_input.jsonl
python3 "$SKILL_DIR/scripts/semantic_label.py" \
--input label_input.jsonl --out labels.jsonl --model qwen3:8b --batch 20 --context 40
- For the taxonomy, decision order, and failure modes see
references/semantic-taxonomy.md。 - Annotation isRule layer + model layerTwo levels: messages with no topic (system prompts, pure acknowledgements, pure emoji/numbers,
pure English fragments) are judged by the script according to rules
other, and the rest are passed to the model along with the preceding context. The rule layer in this project covers 10% of messages and is fully correct on the calibration set;--context 0、--no-prerulesis used only for comparison. - Must calibrate first, then annotate in full: manually annotate 40–60 items (including positive examples of both work and emotional categories, andnot overlapping with the prompt
examples) written as
gold.json, first runsemantic_label.py --input label_input.jsonl --eval-gold gold.json --report accuracy.json, and use this configuration'saccuracy.jsonas the conclusion threshold. - Threshold: if overall agreement rate < 80%, do not output proportion conclusions; when work-category recall < 75%, the work proportion must be written as a lower bound; when emotional-category predicted positives are fewer than 5, the emotional proportion is written only as "single-digit percentage". If below the threshold but delivery is still required, the card's scope line must state "below threshold, proportions for reference only".
- The built-in default prompt uses onlysynthetic examples, containing no real chat sentences. Its measured result on the project's built-in calibration set is agreement rate 77.1%, work-category recall 0.903: below the 80% threshold, so the default output proportions serve only as rough bands, and the card must state "below threshold, proportions for reference only". After switching to the user's own calibration set, rewrite the scope line according to the new results.
- Review the calibration set itself: correct the few annotations that conflict with the classification definition according to the definition, and record in the report what was changed.
- Wanting to switch to a stronger model (which would send chat content to an external provider) requires obtaining the user's explicit consent first,
use
--backend remote --api-key-env <ENV>, and keys go only through environment variables.
python3 "$SKILL_DIR/scripts/topic_composition.py" \
--labels labels.jsonl --out composition.json --accuracy accuracy.json \
--weeks-start <第1周周一> --weeks <周数>
2.4 Image generation
python3 "$SKILL_DIR/scripts/card_figures.py" \
--matrix matrix.json --composition composition.json --metrics metrics.json \
--outdir figures --partner-label "<对方昵称>"
Obtain figure-matrix.svg、figure-composition.svg、figure-weekly.svg and card-data.json.
For layout and injection positions, see references/card-blueprint.md。
2.5 Card creation (handed to lov-mobile-infographic)
Using this Skill's scaffold → author → render → audit process, inject the three SVGs into the corresponding blocks,
use "Love Index Analysis" as the title, write "Analysis subject: <nickname>" as the positioning label, and keep only one conclusion sentence on the whole card.
Step 3: Validate the deliverable
- Machine audit:
lov-mobile-infographic'saudit --strict --human-review passed。 - Geometry review:
python3 "$SKILL_DIR/scripts/verify_figures.py" --card card.html --out verify.json(SVG label overlap, overflow, going outside the canvas, being clipped by its own viewBox). Titles and axis labels on the image must be read back and confirmed one by one. - Scope review: every number has a unit, denominator, and period; semantic proportions must give both the model and the agreement rate; the statement "work does not count as emotional" must be visible on the card.
- Privacy review: the card and report contain no account, database path, table name, real name, or contact information; quotes are truncated and phone numbers/addresses/ID numbers are removed.
- Finally read back the PNG (original size + 320px thumbnail) and record specific findings before delivery.
- Validate
skill-card.yaml,cases/cases.json, andpricing-card.yamlas the standard trust bundle for this Skill.
Dependencies
- Python 3.9+ standard library (
chat_metrics、matrix_dataset、export_text、topic_composition、card_figuresno third-party packages needed). - Playwright for Python(
verify_figures, as well as downstream card rendering and auditing). - Local Ollama (default semantic annotation backend, example model
qwen3:8b); if not installed, must stop and explain, do not silently switch to an external API. - Upstream
lov-wdb-cli(data retrieval) and downstreamlov-mobile-infographic(card creation) are both optional handoffs, not hidden dependencies: when they are missing, intermediate conclusions such asmetrics.json/composition.jsoncan still be delivered.
Validation
python3 "$SKILL_DIR/scripts/chat_metrics.py" --help
python3 "$SKILL_DIR/scripts/semantic_label.py" --help
python3 "$SKILL_DIR/scripts/verify_figures.py" --card <card.html>
python3 scripts/validate_skill.py .
Runtime context (shared)
Before running, read this Skill package's skill.yaml, provided by the host skill-runtime/v1 Context. The field resolution order is: current request, project context, Skill-specific records, personal Preferences, brand/user Profile, general defaults.
- Use only the fields declared in the Manifest; the Profile stores shared user and brand data,
skills.lov-do-they-love-me.recordsstores this Skill's persistent records. - Long-term preferences or brand facts stated directly by the user are written back atomically to the Profile via
scripts/profile_store.py, and the save path is reported in the result. required: trueWhen a field is missing, ask the user one focused question according to the Manifest's question configuration.- Errors provide a copyable
context_id, field path, and source; diagnostic content avoids secrets, full private paths, and raw configuration.
General feedback loop
When the user gives modification feedback during a Skill-driven task, before continuing with the current artifact you must:
- First determine whether the feedback is
task-specific(this time only) orreusable(reusable across tasks). task-specificModify only the current task; do not change the Skill.reusableFirst determine the scope: for domain rules, update the corresponding canonical Skill first; for rules that apply to all Skills, update the shared specification first.- After completing the rule update, versioning, lint, and distribution verification, then apply the modification to the current task.
reusableThe modification invalidates prior "confirm," "continue," and "send it"; after completing the current artifact modification and reading it back, you must stop and wait for the user's next instruction, without automatically proceeding to publishing, submission, or other external writes.