Skip to main content

im-persona-forge

Distill how someone communicates in IM work chat into a ready-to-use persona skill — their expression style, per-recipient tone, and crucially their decision policy (what they answer, hand off, or never settle alone). Use to initialize a persona, pull IM history into a local corpus, rebuild and publish the persona skill, set the autonomy scope, check language or platform coverage, or diagnose why an inbound-message agent has gone quiet.

معلومات المصدر

المستودع
openTrinity/mycontext
آخر نشاط في المصدر
١١ أغسطس ٢٠٢٦ في ٠٢:٠٠
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥٬٠٣٠
التفرعات
١٤٩

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
31 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
im-persona-forge
description
Distill how someone communicates in IM work chat into a ready-to-use persona skill — their expression style, per-recipient tone, and crucially their decision policy (what they answer, hand off, or never settle alone). Use to initialize a persona, pull IM history into a local corpus, rebuild and publish the persona skill, set the autonomy scope, check language or platform coverage, or diagnose why an inbound-message agent has gone quiet.
# im-persona-forge A forge, not a persona. It ships with zero personal data, and it is language-agnostic and platform-agnostic by construction. On the owner's own machine, using their own credentials, it distills how *they* handle work chat into two installed skills: - **`<slug>-persona`** — decides whether a message is theirs to answer, then drafts or sends it in their voice. Discovery is the host's job: whatever dispatches messages already knows which one is new. ## The architecture in one rule **Skills are products. The corpus is the source.** ``` IM platform ──pull──▶ local corpus (SQLite, full fidelity, 700/600) │ │ source adapter ├── build ──▶ measured features (dws / jsonl) │ ↑ │ locale pack (zh-CN / en / null) └── publish ─▶ <slug>-persona ``` Delete an installed skill and `publish` reproduces it exactly. Every improvement is made here and re-published — a loading agent never tunes the persona at runtime. Hand-written corrections live in `<!-- owner:begin -->` blocks inside the published files and survive every rebuild. ## Three seams that keep it general | Concern | Lives in | Rule | |---|---|---| | Language | `forge/locales/*.json` | **No natural-language text in `forge/*.py`.** Enforced by `forge scan --scope repo`. | | Platform | `forge/sources/*.py` | Every read goes through `MessageSource`; an adapter declares what it cannot do. | | Thresholds | `signals.json → thresholds` | One named place per cutoff, versioned into `rulesVersion`. | `rulesVersion` is `signals-v3+<pack>@<version>`, so changing the locale pack invalidates derived numbers exactly like changing a threshold does. **`NULL_PACK` is the important case.** A corpus in a language nobody has written a pack for still produces a valid skill: the structural layers (length, latency, silence, reciprocity, opener distribution) are fully measured, every lexical measurement honestly reports absent, and the published `fidelity.md` says so. It never guesses, and it never lets "unmeasured" read as "they never do this". ## The published skill must be executable by a weak model A skill that is only a well-written document makes reply quality a property of *the model reading it*, not of the forge. A weaker model given five reference files will skip the live context, forget to scope a lookup to the recipient, read a measured 92% reply-rate as permission to answer anything, and never think to ask whether a fact is in the corpus at all. None of those are language failures — they are orchestration failures, and orchestration belongs in a script. So every decision that can be made mechanically is the return value of a command, not a paragraph of advice: | Decision | Command | |---|---| | What is this message answering? | `brief.respondingTo` | | Which ask kind, which risk classes? | `brief.classification` (locale-pack regexes) | | Reply, draft, hand off, or stay silent? | `brief.verdict` + `because` | | Is this fact in the corpus at all? | `facts` → `evidence` / **`none`** | | Does this draft match their habits? | `check` → `pass` / `warn` / `block` | | May this be sent? | scope + allowlist + length **+ the draft's own risk classes** | `references/rules.json` is the machine-readable twin of `decisions.md` — the same policy, one rendering for a reader (with rates, so a capable model can weigh them) and one for a script (conclusions only). A self-test invariant asserts the two agree exactly; two sources of truth for "may an agent answer this" would drift silently. The most consequential gate is in `runtime.DwsClient.send`: it now inspects the **outgoing text**, not only the recipient, and **fails closed** when the patterns are unavailable — missing *or* empty, since a pack that detects no risk classes would otherwise let every draft pass a check that never ran. It runs *before* the scope check, because a draft that states an approval is wrong in every scope — reporting "sending is disabled" first would teach the caller that widening the scope is the fix. ## Commands ```bash python3 -m forge doctor # start here when anything is wrong python3 -m forge init --display-name "<real name>" --since 2026-01-28 python3 -m forge pull --since full # first backfill; then --since auto python3 -m forge build # corpus → measured features python3 -m forge publish # install both skills python3 -m forge refresh # pull → build → publish (routine) python3 -m forge locales # installed packs; which fits this corpus python3 -m forge sources # data sources and their capabilities python3 -m forge report # coverage; --rubric for the blind test python3 -m forge autonomy --scope allowlist --allow "<name>" python3 -m forge lock # installed skills → read-only python3 -m forge export --out <file>.tar.gz # hand to an agent elsewhere python3 -m forge inspect # what is stored and what was measured python3 -m forge scan --scope repo # is this repo safe to share? python3 -m forge selftest # offline, no network, no personal data ``` Everything prints JSON. Anything touching a remote or writing accepts `--dry-run`. Non-DingTalk platforms come in through the `jsonl` source — export your history, convert it to the schema in `forge/sources/jsonl.py`, and the whole engine works unchanged: ```bash python3 -m forge init --source jsonl \ --source-option path=~/exports/slack \ --source-option 'identity={"openIds":["U0123456"],"name":"Real Name"}' ``` `identity` must be explicit. Every id in an export looks alike, and guessing the owner wrong is the worst failure available — it attributes someone else's messages to them and produces a confident, wrong persona. ## Giving the skill to another agent The point of `lock` is that "do not tune this at runtime" stops being a request and becomes a property of the filesystem: ```bash python3 -m forge lock # every installed file → 444 ``` A loading agent gets `PermissionError` if it tries to edit `SKILL.md` or any reference. Reads are unaffected, and `forge publish` still rebuilds them (it writes a temp file and renames, then re-applies the lock), so updates keep flowing from the forge only. `--unlock` reverses it. Same machine, another agent → nothing else to do; the skill is already in `~/.claude/skills/` and `~/.codex/skills/`. Another machine → `forge export`. The bundle is Markdown + scripts only: no corpus, no config, no logs, no absolute paths. `recall` / `who` / `send` report `degraded: markdown-only` there, while the decision layer, style, people and scenes work fully. ## What gets distilled | Layer | Published as | Source of truth | |---|---|---| | **Decision policy** | `decisions.md` | every incoming ask, answered *and* ignored | | Expression style | `style.md` | their own messages, measured | | Per-recipient tone | `people.md` | interaction volume + overrides | | Situations | `scenes.md` | scene-tagged messages + real turns | | Honest limits | `limits.md` | window, counts, what chat cannot show | | **Coverage** | `fidelity.md` | which layers had evidence, and which did not | The decision layer is what makes the persona usable unattended. Mining silence alongside replies is what makes it possible: a question they consistently left unanswered is evidence about what is not theirs to answer, and it exists nowhere else. `fidelity.md` is what makes it safe to hand on. It reports *coverage*, never quality — and behavioral fidelity is deliberately not self-assessed: a persona grading its own likeness produces a number that looks like evidence and is not one. `forge report --rubric` emits a blind two-agent protocol instead, whose result the owner pastes into an owner block. The rubric contains the answer key and stays in the data root, never in a published skill. ## Boundaries - **The corpus keeps everything locally** — every message, real names, real ids — because an agent cannot judge "is this mine to answer" from hashes. It lives at 600 inside a 700 data root, is never shared, and is `.gitignore`d. Credentials are the one thing scrubbed on write. - **Published skills carry no raw ids, no paths, no credentials.** `forge scan --scope skill` enforces this and runs automatically on publish, checking every known platform's id shape rather than one vendor's. - **Default autonomy is `draft_only`.** Scope only widens *who* may receive a reply, never *what* may be said. The risk gate (commitments, approvals, money, scheduling, personnel, external positions, org decisions, destructive actions) holds in every scope — and a risk class the active locale cannot even detect is treated as never-settle, not as absent. - **Never commit a corpus, config, ledger, rubric, or published persona.** ## Reading order for an operating agent 1. `README.md` — the full pipeline, the failure modes it was built against. 2. `forge/locale.py` — how a language pack is chosen, and what `NULL_PACK` guarantees when none fits. 3. `forge/sources/__init__.py` — the platform contract and the normalized message schema. 4. `forge/signals.json` — every language-independent threshold; changing one changes `rulesVersion` and therefore every derived number. 5. `forge/decide.py` — how the decision policy is mined. 6. `forge/compose.py` — how measurements become skill text, and how owner blocks are preserved.
عرض على GitHub