Persona Auditor(数字人审计员)
1. Positioning & Iron Rules
Positioning: a comprehensive audit-orchestration skill whose goal is precise fixing — find the errors the user would only discover through costly trial-and-error (or never notice at all), collapse them into a handful of root causes, and let the agent fix it right the first time. It is built from four parts:
- Main line (the differentiator): user personas → project structure map → state-machine exhaustion → two-layer persona traversal → experience-layer three-way alignment → reference group → god's-eye attribution. It hunts the "contradiction between underlying logic and user experience" — built for "stuck on one point across many rounds of fixes, missing the global view".
- Orchestrated reuse (don't reinvent): for security / AI-smell / over-engineering / store review / general correctness, load and run existing skills and merge their results into one unified report.
- Self-built checks (not covered by any existing skill):
- Release hygiene: development trial-and-error, conversations, summary conclusions, real personal information, secrets, and internal decisions written into code / config / comments / docs.
- Defensive-content pollution: guardrail metadata (corrections, risk warnings, discipline, self-reminders) leaked into public deliverables and user-visible strings.
- Wheel-reinvention audit: "this whole module has a more mature open-source alternative, but you hand-rolled an outdated one".
- Adapter-convergence audit (tech-stack unification): "the same concern was solved N times, in N parallel ways, and never converged to one seam" — the subagent/borrowed-tech failure mode that leaves one concern with N adapters (or 1 live + 1 dead), a write-only capability registry, or two names/units for one fact.
- Publish gate (pre-publication self-check): "my OWN public artifact about to ship carries a specific-project fingerprint" — a project noun, a concrete field name/unit/value, a named borrowed framework, or a producer-voice "we" — applied to the artifact in your hand before it goes out (covers the skill's own README/SKILL/marketing).
- Adaptive scope: depth tiers (Lite/Standard/Deep) and loop modes (one-shot/incremental/gate) so the audit weight matches the project, never over- or under-auditing.
Paper traversal is the means, not the end: not executing, not clicking is how we cheaply exhaust every user path — faster, more global than real clicking, able to see root causes at a glance. But it is never an excuse to "not fix": the audit's closed loop is report (root cause + precise location) → user confirms → agent fixes precisely → verify via falsifiable check (symptom disappears).
Iron rules (9, not a wall — each one earns its place):
- Do not execute code, do not really click, do not modify code — mainline work happens on paper.
- Code is the single source of truth: reason from the real behavior recovered by reading code, not from design docs or memory.
- Do not fall into the "code self-consistency" trap: internally consistent code ≠ a good product.
- Exhaustiveness is the soul; sampling is negligence: steps 1.5/2/3 must fully traverse the
structure × persona × function × operation × state × timing matrix; many walker subagents each reason independently; only after traversing all paths may you do root-cause analysis. Forbidden to sample one happy path and conclude.
- Reuse first, don't reinvent: for security / AI-smell / maintainability / review, load
llm-sast-scanner / code-auditor / ponytail-audit / code-reviewer; do not rewrite their rules.
- The self-built checks (release hygiene + defensive pollution + wheel reinvention + adapter convergence + publish gate) are this skill's own — always run them, never skip.
- Read-the-code verification spans multiple steps, not just once at step 1: walker traversal (step 3), extreme testing (step 4), three-way alignment (step 10), and attribution (step 11) must each re-read the code to verify; forbidden to conclude from step-1 memory. Every
file:line must be "just read / just grepped in this round", not "from memory" — memory goes stale and hallucinates.
- No false positives, no over-auditing: before reporting anything, confirm "does this scenario apply?" — no store review for something not shipping, no mobile App Store review for a desktop app, no treating test fixtures / vendored code / build artifacts / .env templates / doc TODO placeholders as production bugs. And match the audit weight to the scenario — never run the heavy pipeline on a landing page. A wrong report hurts trust more than a missed one.
- Honest + falsifiable: if you can't find it, say what's missing — never fabricate. Every root-cause conclusion must carry a falsifiable verification method ("if I fix X, symptom Y disappears; if Y persists, X was wrong"); an unfalsifiable statement is an impression, tagged
【impression, no verification path】, never a finding.
2. Methodology (Intake Gate + Steps)
Intake Gate (mandatory, never skip, never guess)
Core principle: the agent answers first, the human only fills what AI can't know. This skill is for the agent itself — it can read code, README, and context. So most questions are answered by the agent first, inferred from code (with evidence + confidence), not dumped on the human. Only what "isn't in code, only in the founder's head" gets asked of the human.
Round 1 — agent self-answers (infer before asking). Read code + README + context; answer each item with inferred answer + evidence + confidence (high / medium / low):
- Project type — web app / CLI / library / desktop app / agent system / game / other (from README / package.json / structure). This decides what "structure unit" means in Step 1.5.
- Target users — how many types, what habits (reverse-infer from README / copy / features).
- Release scenario — ships where? personal vs commercial? software-copyright? (infer from package.json / README / deploy config; decides whether compliance / store-review checks apply).
- Type-specific follow-ups — web/desktop: which journeys are core, which step loses users, any target platform; CLI/library: target devs, integration scenarios, API constraints; agent system: interaction mode (chat/canvas/voice), automation boundary (what must never auto-run); game: target players, core fun, payment/store plan.
- Depth tier — Lite / Standard / Deep, with a one-line reason (see "Audit Depth Tiers").
- Loop mode — one-shot / incremental / gate (see "Embedding in an Existing Loop").
Round 2 — human fills the gaps (only what code can't answer). From Round 1, take the items with low confidence or that change the audit conclusion, and ask the human as multiple-choice — each question shows the agent's inferred answer as the recommended option, a few alternatives, and a "skip — use your inference" option.
Always ask the human (code never contains these):
- Design intent — for each core feature, what experience did you want the user to get? (code shows what it does, not what it means to achieve). This is also the ruler for gate vs break in Step 3a.
- Real user thoughts — the actual habits / tolerance / pain points of your target users (not in code).
- Release final say — does it actually ship / register copyright? (partly inferable, but you decide).
- Is the requirement itself right? — only when it arises (A/B reference-group choice).
Fallback rule: skipped items use the agent's inferred value, tagged 【agent-inferred, not user-stated, needs confirmation】. If a point arises that "only the user can decide" (A/B reference group, requirement validity, wheel replacement, depth tier, loop mode), stop and ask — never decide for them.
Audit Depth Tiers (adapt the weight to the project)
Not every project needs a heavy audit. The agent infers a tier from the intake answers, recommends it with a reason, and lets the user override.
How to decide: ① project size ② purpose (self-use/internal/commercial/shipping) ③ release scenario ④ risk surface (user data? concurrency? auth/payment? AI mainline?) ⑤ user intent ("quick look" vs "full acceptance").
| Tier |
For |
Runs |
Skips |
| 🟢 Lite |
landing page, one-off script, personal tool, self-use |
quick classify; 1–2 personas on the 1–3 core paths; experience alignment (core only); quick release-hygiene sweep; simplified attribution |
six-layer checks, wheel-reinvention, extreme testing, concurrency stress, orthogonal-array exhaustion, light research |
| 🟡 Standard (default) |
medium project, internal tool, acceptance |
full steps; six-layer checks trimmed by release scenario |
compliance layer if not shipping / no copyright |
| 🔴 Deep |
store shipping, copyright, commercial release, high concurrency, sensitive data, agent system, "full acceptance" |
everything: all steps + all six layers + extreme testing + concurrency stress |
nothing |
Rules: recommend, don't decide (state tier + reason, let user override); never silently escalate (a big codebase alone is not a reason for Deep); record the tier honestly in the report header.
Embedding in an Existing Loop
| Mode |
When |
Scope |
Output |
| One-shot |
standalone full audit |
everything |
full report |
| Incremental |
after each change in the loop |
git diff + paths the diff touches (inferred from the state machine) |
short: new/recurring blockers + root cause |
| Gate |
before commit / merge / release |
high-risk layers only (high-severity security + release hygiene + core paths) |
PASS / BLOCK + blocking list |
Execution principles: baseline once, then increment (first run builds personas + state machine + root causes; later runs are Incremental and reuse it — never re-run full unless asked or structure changed); incremental scope = git diff + reverse-infer affected paths; gate pass criteria stated up front; match output to the loop (full report is useless mid-loop, bare PASS/FAIL useless pre-release).
Light Research (after intake gate, before step 0; mandatory for Standard/Deep, skippable for Lite)
Personas must not be invented off the top of your head. A round of light research (capped at 3–5 searches) to get three things: ① target-user commonalities ② real pain points ③ behavior patterns. Disciplines: every conclusion carries a source URL; when research conflicts with the user-stated intake answers, user-stated wins (the founder knows their product better than external research), but list the conflict explicitly.
Step 0: Set the ruler — user-persona layering (targeted)
Based on three-way synthesis: intake gate (human-stated) + agent self-answer (code-inferred) + light research (external data), produce:
- User-persona layering table: ≥3 user types; for each: usage habits / expectations / tolerance / features they will and won't use / pain points / behavior patterns. Tag each item's source: 【user-stated】/【agent-inferred】/【light research · URL】.
- Design-intent table: for each feature, "what experience the designer wanted the user to get", source-tagged. This table doubles as the gate list for Step 3a's gate-vs-break distinction.
Step 1: Recover the truth — read code and model the state machine
- Recover the real state machine: state variables (with initial values), transition conditions, branches, boundaries, race points.
- Recover the real behavior of each feature (what the code actually does, not what the docs claim).
- Annotate: deviations between actual code behavior and design intent.
Step 1.5: Project structure map (the "brain" — see the whole before dispatching)
Before exhaustively walking paths, list what this project actually contains — so the walkers are assigned, not left to guess. Read code (not docs alone) and produce:
- Structure units — what this project is made of, in its own organizing terms (never preseed a term):
- web app → pages / routes / feature modules
- CLI → commands / subcommands
- game → play systems / mechanics
- agent system → capability scenarios (whatever the project itself calls them)
- library → modules / API surfaces
- Core journeys per unit — the typical user task in each unit (1–N journeys each).
- Journey inventory — one table of all units × their journeys. This is the sole input to Step 2.
Coverage check (explicit): the inventory must state "N units × M journeys; unit A has k journeys, unit B has j…" — a missed unit is a failure, not an option. If the tier is Lite, skip units honestly and say why, don't silently drop them.
Step 2: Exhaust paths — persona combos + combination-reuse principle
Iron rule: exhaustion = fully traversing persona combos × journey × operation × state × timing (where "journey" comes from Step 1.5's inventory), but "combos" use equivalence classes + boundary values + orthogonal arrays, not the full Cartesian product. Forbidden to sample one happy path and conclude.
The no-miss methodology (classic software-testing trio):
- Equivalence-class partitioning: personas by "behavioral similarity"; journeys grouped by "same kind of behavior" (all "create X" is one class); operations into "normal / abnormal / boundary / interruption" four classes, pick representative values per class.
- Boundary-value analysis: test both sides of numeric/length/count boundaries (0 and 1, upper and upper+1, empty and 1 char) — bugs cluster at boundaries.
- Orthogonal arrays: guarantee "every pair of dimensions' combination is covered at least once" for 3+ factors (persona × journey × operation); for 2 factors, full combination.
Coverage must be quantified and provable: the report states covered N personas × M journey groups × K operation classes = P paths; orthogonal table guarantees every two-dimension combination ≥1; boundary values cover 0/1/upper/upper+1.
Persona = persona × scenario combination (not single persona, not full Cartesian product):
- List single-scenario personas (each persona type × each scenario — use the project's own scenario names).
- List combined-scenario personas (real users often "do both A and B").
- Combination-reuse principle (avoids explosion): if "A alone" and "B alone" are each tested fine, the "A+B" persona only tests the cross-scenario delta:
① precise switching: is moving between A↔B precise, reversible, free of leftover wrong state;
② cross-scenario recall: does the memory/state layer know the relation between A and B, and recall correctly without contamination or loss;
③ is the cross-scenario mechanism working at all.
Only fully test a combination when a single scenario wasn't tested or the combo introduces new state.
Persona count is justified, not arbitrary: total = needed combos, capped ≤10. Over the cap, prioritize "single-scenario first, then high-value combos", and state what was dropped and why.
Step 3: Two-layer persona traversal — mechanical walker (objective) + intent observer (subjective)
Key distinction: deterministic traversal — code and state machines are deterministic, not a chaotic multi-agent swarm. Split into two layers with different jobs and different output status:
- Layer A — mechanical walker (objective): walks every path, records only facts. Output is falsifiable.
- Layer B — intent observer (subjective, ONE persona): watches Layer A's facts, produces reference opinions. Output tagged
【主观参考, 非可证伪发现】 — a hypothesis generator, not a finding.
3a. Layer A — mechanical walkers (record facts, never judge)
Dispatch walkers: one per persona combo from step 2. Prompt synthesized from ① light research ② intake gate ③ code reverse-inference.
Each walker verifies along the full code chain and records ONLY four facts per step:
reached: which step it reached (read code at each link: user action → entry function → state transition → tool → persistence → output → new state);
broke: did it break here — an objective, code-verifiable fact: no way to continue (no available action / state deadlocked / thrown error). Confirm by reading code, tag file:line.
gate_or_break: is this stop a gate or a break? A gate = an intended human-in-the-loop pause (from Step 0's design-intent table — e.g. confirm/approve/choose points the user deliberately designed). A break = an unintended stop (no-key early return, infinite hang with no timeout, thrown error). Gates are features, not findings; only breaks are defects. When unsure, tag gate? and let attribution decide with the user.
steps: how many steps / rounds before the stop (operation complexity, NOT wall-clock seconds — paper traversal can't measure real time).
Forbidden for walkers: do NOT judge "is this a bug / bad UX / would the user be confused" — Layer B / attribution's job. A walker that judges has overstepped; downgrade that to a Layer B hypothesis.
Make factual disagreements explicit: if two walkers record differently on the same path (state/persona differs), record both verbatim — a data point, not a dispute to smooth over.
3b. Layer B — intent observer (ONE persona; produces hypotheses, never findings)
Positioning: not "a simulated user", but a human-intent observer — like a senior UX researcher: understands human behavior and product intuition, reads Layer A's factual breakpoints, produces reference opinions.
Input: Layer A's break list (file:line + gate_or_break + step counts).
Output — every item carries three parts + a tag:
【主观参考】关注点: <which break / path segment, anchored to a Layer A fact>
理由: <why a human would most likely care here — behavior / habit intuition>
建议方向: <where attribution should read the code to verify — file:line>
Three disciplines:
- Every item MUST be tagged
【主观参考, 非可证伪发现】 — iron rule 9: an opinion is not a finding.
- It may only say "this looks suspicious, suggest reading code X" — never "this is a bug".
- Its opinion MUST anchor to a Layer A fact ("based on breakpoint #N…") — never free-floating "I think users would be confused".
What the observer adds that walkers can't: prioritization intuition — among many factual breaks, which ones a novice trips on vs an expert ignores, which everyone curses. It reads the facts and adds the human weighting Layer A deliberately does not do.
Aggregation (after both layers)
- Layer A: aggregate breaks — single-user-specific (boundary) vs hit-by-all (systemic); gates are recorded but not treated as defects.
- Layer B: attach hypotheses to the systemic breaks.
- Hand both to Step 11 (god's-eye attribution): Layer A facts = hard evidence; Layer B opinions = investigation leads. Attribution reads code to verify each lead before it becomes a finding. An opinion with no code confirmation stays
【主观参考】, never promoted.
Step 4: Extreme testing — jailbreak/injection + stress/concurrency
- Jailbreak / injection: prompt injection, role hijacking, system impersonation, jailbreak templates, invisible Unicode. Against step 1's "trusted input boundary", find penetration points and correct interception points.
- Multi-task concurrency stress: N tasks simultaneously, races, timeouts, interruption, duplicate submission, rapid switching. Traverse who overwrites whom, whether locks fail, whether queues are serialized.
Step 5: Specialized-check orchestration — reuse existing skills (don't reinvent)
| Dimension |
Reused skill |
What it checks |
| Security |
llm-sast-scanner |
34 vulnerability classes, Source→Sink taint tracking |
| AI-smell / maintainability |
code-auditor (AI-smell) + ponytail-audit |
naming emptiness / comment clichés / swallowed exceptions / TODO graveyard; over-engineering delete/stdlib/native/yagni/shrink |
| Store review |
code-auditor (copyright + store-gating) |
Conditional: only when the release scenario says ship/register (already decided in Intake Gate); otherwise skip this row. Know the platform first — an Electron desktop app does not go through App Store/Google Play mobile review |
| General correctness |
code-reviewer |
correctness / security / maintainability / performance 🔴🟡💭 — must explicitly cover: dead code / speculative abstraction (zero-consumption modules, dead switches, retired-but-kept files), duplicate definitions / same-name conflicts (one symbol defined multiple incompatible ways), god files / over-centralized modules (one file carrying too many responsibilities) |
Duplicates go to the more specialized one; dedupe then merge. Before reporting each layer, pass iron rule 8 (false-positive check).
Step 6: Release-hygiene check (self-built, mandatory)
AI-assisted-development-specific — things that should not be publicly released got written into code/config/comments/docs. Scan item by item:
- Real personal information: name / phone / email / address / school / grades / ID number, hardcoded into code, config, fixtures, comments.
- Secrets and credentials: API key / secret / token / private key / personal workspace endpoint, written outside .env.
- Development trial-and-error traces: comments like "incident observed", "user said XX", "audit found XX", "walkthrough gap N", "temporary / do this for now / to delete".
- Internal conversations and conclusions: development-time dialogue, trial-and-error conclusions, internal decisions written into prompts/comments/docs.
- Internal domain information: internal project names, private domains, internal architecture decisions, unpublished account systems.
For each hit, tag 【release hygiene】+ file:line + content category + leak level, and list separately in the report.
Step 7: Defensive-content pollution (self-built, mandatory)
The disease: AI wrote its internal guardrail metadata — corrections, risk warnings, discipline clauses, self-reminders, "as an AI" disclaimers — straight into an artifact meant to be public or a string meant for the end user. The artifact stops being universal: a marketing copy with "⚠️ needs verification" can't be published; open-source code with "// untested, don't trust this" can't be shipped; a user-facing message with "产物自己过一眼" leaks a producer-only concern.
How it differs from release hygiene: release hygiene leaks past dev traces (secrets, PII, trial-and-error); this leaks the current artifact's own defense notes. Same root cause, different symptom — a public deliverable and its internal guardrail metadata were not physically separated.
The three-question test (apply to every suspicious sentence / comment):
- Meta or content? Is this sentence about the artifact (its correctness / trust / status), or is it the artifact (the actual copy / code / doc)?
- Who is it addressed to? To the producer ("note to self", "for internal review") — or to the end user?
- Deletion test (falsifiable): delete it — is the artifact still complete and more universal? If yes, it was internal metadata and must be reported.
Signals to scan for:
- Explicit guard markers:
⚠️ / 【备注】 / 【纪律】 / risk warning / disclaimer / "AI-generated, please verify"
- Self-reminder speech: "as an AI I remind you", "please verify", "not tested", "don't ship", "for reference only", "does not constitute advice"
- Code self-notes:
TODO / FIXME / HACK / // note to self / // this broke before, don't touch
- Leaked internal correction: "this was wrong before", "temporary", "for now", "internal wording", "internal decision"
Where to scan — five surfaces (breadth: not just chat and deliverables):
Defensive pollution hides in every user-visible string. Scan all five:
- Conversation output —
appendAssistant / finalText / appendBrief / dialogue messages.
- Deliverable files — docs / code / config meant to be published or shipped (overlaps release hygiene).
- Settings / config UI text — model pickers, tier labels, capability maps, degradation-matrix wording, parameter descriptions. Internal architecture terms shown to the user. Locate:
displayName / label / title / t(...) in settings components and registry/archive files.
- Runtime result display — status text, progress, result cards, quality-gate verdicts rendered in the UI. Locate:
statusText / progress / verdict rendering.
- Run log / notifications — notification center, toast, event timeline, log panel. Internal QA/process terms shown to the user as "history". Locate:
pushNotification / toast / event feed / log lines that reach the UI.
(The concrete function names above are examples of "how to locate" each surface — the exact names differ per project; use the project's own user-visible-output entry points.)
Rule: a term is internal if it names an architecture component, a process step, or a producer-only concern. The same term is not pollution when the audience is an operator configuring the system (power-user settings may legitimately name engines). Apply iron rule 8: "end-user-facing text" vs "operator-facing text" are different audiences — only the former is pollution.
Severity: High = makes the artifact unpublishable; Medium = local contamination; Low = deliberate compliance disclaimer (flag, don't assume it's a bug).
Root cause (god's-eye): guardrail metadata was not physically separated from the deliverable. Triggers: ① guardrail tools set to on_fail="fix" rewriting in place; ② prompts telling the model to "self-correct" without distinguishing internal vs external; ③ internal discussion leaking into context and copied into output.
Fix direction (for the report, not the audit): two-layer output (draft vs public_release), a product_mode parameter, defense metadata routed to a side channel (logs / review queue) — never injected into the payload. The audit detects the leak and points at its root cause; it does not redesign the pipeline.
Step 8: Wheel-reinvention audit (self-built, mandatory)
Find "this whole module has a more mature open-source alternative, but you hand-rolled an outdated one."
- Enumerate the project's feature modules / self-built dependencies (especially "looks hand-written": auth, state management, message queue, ORM, template engine, utility collections, protocol implementations…).
- For each suspected module, search first (web_search / npm view / GitHub search) for mature alternatives, comparing maturity, maintenance, completeness, license.
- Code comparison: self-built vs mature alternative — where does it fall short?
- When something is "clearly worse", stop and ask the user whether to replace — don't decide unilaterally.
Step 9: Adapter-convergence audit — tech-stack unification (self-built, mandatory)
The disease this catches is NOT "a module is bad" — it's "the same concern was solved N times, in N parallel ways, and never converged to one seam."
This is the failure mode of subagent / borrowed-tech-driven development: each subagent or borrow adds its own adapter (LLM client, storage layer, renderer, tool dispatcher) for a concern that already had one. Left unmanaged, you get "one concern → N adapters", where N adapter instances each carry lifecycle/params duplicated, or one adapter is dead while a parallel copy is alive. The debt lives in the interface/architecture layer (how many ways reach the same capability), not in whether any single module is well-written.
How it differs from Step 8 (wheel reinvention):
- Wheel reinvention asks "did you hand-roll a worse version of something with a mature OSS alternative?" — the fix is replace/borrow.
- Adapter convergence asks "do you have more than one adapter for the same concern?" — even if each is well-built, having N is the debt. The fix is converge to one seam (delete redundant adapters, or wire the one that's dead, or make N share a single interface).
Detection method — a strict, falsifiable, four-pass scan (per concern):
For each cross-cutting concern (LLM / model, storage / persistence, rendering, tool dispatch, voice I/O, logging, config), run:
Enumerate ALL implementations of that concern — find every file that claims the concern's job (grep the concern's verbs: "send"/"openai"/"chat", "write"/"store"/"save", "render"/"draw", "call tool"/"dispatch", "transcribe"/"speak"). Do NOT stop at the one the design doc names; grepping is what surfaces the parallel ones.
Find every call-site that reaches the concern — not just the definitions. A definition is separable from whether it's reachable: grep the adapter's exported symbol + import path. A symbol with quotes in a test/script but zero production callers is DEAD (unwired), not "reserved". Record: definition (file:line) + call-sites (count, file:line) + is there a production caller?.
Count the distinct adapters (the headline finding): for the same concern, is it 1 adapter used everywhere (converged — good), or N adapters where N≥2, or 1 live + 1 dead, or N that each hold partial capability? The cardinality of "ways to reach a concern" IS the finding.
Verify "single source of truth" for the concern's metadata: do the adapters read the SAME capability spec (window size, modalities, dialect, limits), or is the same fact stored in N registries with N field names / N units (e.g. one registry calls it context in tokens, another context in thousands; one uses a boolean supportsImages, another a modalities list containing image)? N registries = drift risk; a value changed in one and stale in the other is the proof. This is the "same fact, two copies" check.
The six signals that flag a convergence failure (each falsifiable, pick matching ones):
| Signal |
What it means |
Prove by |
| 🎯 Dead adapter (unwired) |
a whole adapter module exists, has exported symbols, but zero production callers; only a manual test script imports it |
grep the symbol + import path → only hits are the module itself + a non-CI script |
| 🧩 Parallel adapters |
the same concern solved by N separate implementations (N renderer instances / N storage stores / N tool-dispatch paths) at once |
grep count of new XRenderer / distinct store/types / distinct dispatch entrypoints |
| 📇 Write-only capability schema |
a config/registry declares fields (context, limits, dialect, vision, tools) that NO code reads |
grep each declared field → zero readers |
| 👻 Ghost enum value |
a union/type declares a value that no producer sets and no dispatcher handles |
grep the value → only the type + a comment |
| 🔄 Split meaning of one thing |
the same fact stored in N registries with N field names/units (drift) |
compare field names + units across registries, show a real stale example |
| 🧹 Partial-use borrow |
a heavy library imported, but only a tiny non-core surface used (a full editor for a single screen + two utility calls) |
list import lines vs the actual call-sites |
Governance method (for the report — how to keep it converged going forward):
- One concern = one seam. For each of the enumerated concerns, name the one adapter that is canonical; every caller must go through it.
- Dead means deleted. An unwired adapter (dead-code signal) is either wired now or removed — never left as "reserved / pilot / test-only". A non-CI script referencing it is not a reason to keep it.
- One metadata registry per concern. Capability facts (context, modalities, dialect, limits) live in exactly one place; the other registries either read it or are merged/deleted. Never two names / two units for one fact.
- Converge, don't keep both. When a concern has 2 live adapters, decide "which is canonical" and migrate — do NOT keep N "because both work". N working adapters is still N× the maintenance.
- Brace against future borrows: the report's conclusion must state "the next time a tech is borrowed, it either enters the canonical seam or is deliberately scoped + removed; nothing stays 'borrowed but unwired'."
Output: list per concern → concern | adapter cardinality (1 / N / 1-live-1-dead) | signal(s) marked | evidence file:line | canonical seam to converge to | action (delete / wire / merge).
Every conclusion obeys iron rule 9: a convergence finding must be falsifiable — "delete the dead adapter → does behavior change? no → it was dead"; "route all callers through the canonical seam → do the N ways collapse to 1? yes → convergence confirmed".
Step 10: Experience-layer three-way alignment + reference group
- Three-way alignment: for each feature, lay out ① design intent ② actual code behavior ③ real user expectation; find the gaps, focusing on "self-consistent but experience-wrong".
- Reference-group experiment: for features where "is the requirement itself right" is doubtful, design A/B comparisons, and on paper traverse what each design gives the user.
Step 11: God's-eye global attribution (the last step — after all errors have arrived)
This is the final attribution of the whole audit — wait until all errors from every prior step (walker traversal + six-layer checks + three-way alignment + stress testing) are collected.
Attribution methodology (distinguish "correlation" from "causation"):
- Collect the full error set: aggregate all errors into one table (each with file:line + trigger condition + symptom).
- Cluster candidate root causes: by "shared code location / trigger condition / mechanism". Each cluster is a candidate (not yet verified).
- Counterfactual verification (separates root cause from symptom): for each candidate — "if I fix this one spot, do the errors in this cluster disappear together?" Disappear together → true root cause; only one disappears → it was a symptom. Write it out:
candidate X → assume fixed → traverse: do A/B/C disappear?
- Draw the causal chain (not a flat list):
root cause → intermediate cause → symptom. Mark necessary/sufficient conditions.
- Layer root causes + rank by impact: prioritize by "how many symptoms one root cause eliminates", not by individual symptom severity.
- Every root cause carries a falsifiable verification method (mandatory): "how to verify it's true" —
assume X is true → fix X → expect A/B/C to disappear together; if they persist, X is wrong. No verification path = tag 【impression, no verification path】, never a conclusion.
Step 12: Produce the report — classified layers + converged directions
Output the layered results + step 11's attribution. The body is the layer classification, but the conclusion is "the few root causes + impact-ranked convergence directions", not a symptom list.
Step 13: Publish gate — self-check BEFORE releasing any public artifact (self-built, mandatory)
The disease: you're about to publish something public — a README, a marketing copy, an open-source skill, a public doc, a released string — but it carries a specific-project fingerprint (your own product's name, an internal borrowed-library name, a concrete field name/unit/value you measured, a "we / our product" voice). It works for you because it's your own context; it leaks because the audience is a stranger.
This is Step 7 (defensive pollution) applied to YOUR OWN artifact you're about to ship, rather than to a codebase you're auditing. Step 7 scans someone else's deliverable; Step 13 scans the one in your hand, right before it goes out.
Trigger: whenever you are about to publish / commit / push / release / submit anything that a stranger will read — a repo file, a README, a skill, a landing page, a public doc, an issue, a PR description. Apply it to the artifact itself, not just to code.
The four-question test (run against every public artifact before releasing):
- Project-specific noun? Does it name your own product/feature/domain (a brand, an internal module, a scenario name)? → Replace with a generic term (e.g. "a card", "a scene", "an agent workspace").
- Fingerprint detail? Does it carry a concrete field name, unit, or measured value that only your code produces (a registry field, a
XX:1000 number, a hardcoded enum value)? → Abstract to a placeholder (<field>, <value>), or phrase it as "one registry calls it X, another Y" without the real names.
- Borrowed/inspiration name? Does it name a specific third-party project you borrowed from, as if the reader knows it (a framework's name as a contrast)? → Say the kind instead ("a chaotic multi-agent swarm"), not the brand.
- Producer-voice leakage? Does it address the producer ("note to self", "we/there's only one dev", "my product") instead of the reader? → Rewrite for the reader; the artifact must stand alone without knowing you.
The deletion test (falsifiable, iron rule 9): delete every project-specific noun / fingerprint / borrowed name / producer-voice phrase — is the artifact still complete and MORE universal? If yes, those were leaks and must go. If removing it breaks the meaning, it was load-bearing; keep it but phrase it generically.
Breadth — apply it everywhere, not just the main file: README, marketing/promotion copy, the skill's own SKILL.md, public docs, example code, config templates, commit messages, PR descriptions, issue bodies, release notes. The leak hides in the small file as often as the big one.
Severity: High = leaks an internal design/product detail that (a) does not apply to strangers, or (b) reveals you measured an internal metric — makes the artifact non-universal; Medium = a named borrowed framework subtly narrowing the audience; Low = a producer-voice "we" that reads oddly but doesn't confuse.
Iron rule 8 (false-positive check): a generic word (rendering, storage, agent, card, scene, model) is NOT a leak — it's the reader-facing vocabulary. Only flag terms that (a) are proper nouns of your own project, (b) are concrete fingerprints, or (c) assume the reader shares your internal context. Don't over-sanitize a good universal sentence.
3. Output Format
# Persona Auditor Report
## 0. Audit tier + scope (which tier ran, what was skipped and why — honest)
## 1. User-persona layering table + design-intent table (source-tagged)
## 2. State-machine recovery + deviations from design intent
## 3. Project structure map (units × journeys inventory; coverage check)
## 4. Exhaustion matrix (persona × journey × operation × state × timing, coverage count)
## 5. Two-layer persona traversal results
- 5a. Mechanical walker report: factual breaks (reached / broke / gate_or_break / steps / file:line)
- 5b. Intent observer hypotheses: 【主观参考】opinions anchored to breaks
## 6. Extreme-test results — jailbreak / concurrency
## 7. Specialized-check results (security / AI-smell / compliance / general)
## 8. Release-hygiene check
## 9. Defensive-content pollution (five surfaces)
## 10. Wheel-reinvention audit
## 11. Adapter-convergence audit (tech-stack unification) — per concern: cardinality / signals / evidence / canonical seam / action
## 12. Experience-layer three-way alignment + reference group
## 13. God's-eye global attribution (counterfactually verified root causes)
- full error set → candidate clustering → counterfactual verification → causal chain → impact ranking
## 14. Convergence directions (by root-cause impact, not symptom severity)
Report header states the audit tier and what was skipped (honest, not hidden). Every defect uniformly carries: `trigger sequence → expected vs act
…(truncated)
1---2name: persona-auditor3description: Persona Auditor audits AI-generated code from the perspective of real users, surfacing the errors you would only discover through costly trial-and-error — or never notice at all — and collapsing them into a handful of root causes via god's-eye attribution, so you fix precisely instead of patching blindly. It dispatches "digital personas" that simulate real users and exhaustively traverse every user path on paper — cheaper and more global than real clicking, without executing any code. Built for AI-written code that runs fine and is internally consistent, yet keeps users stuck in the first few steps and defies root-cause diagnosis across many rounds of fixes.4---56# Persona Auditor(数字人审计员)78## 1. Positioning & Iron Rules910**Positioning**: a **comprehensive audit-orchestration skill** whose goal is **precise fixing** — find the errors the user would only discover through costly trial-and-error (or never notice at all), collapse them into a handful of root causes, and let the agent fix it right the first time. It is built from four parts:11121. **Main line (the differentiator)**: user personas → project structure map → state-machine exhaustion → two-layer persona traversal → experience-layer three-way alignment → reference group → god's-eye attribution. It hunts the "contradiction between underlying logic and user experience" — built for "stuck on one point across many rounds of fixes, missing the global view".132. **Orchestrated reuse (don't reinvent)**: for security / AI-smell / over-engineering / store review / general correctness, load and run existing skills and merge their results into one unified report.143. **Self-built checks (not covered by any existing skill)**:15 - **Release hygiene**: development trial-and-error, conversations, summary conclusions, real personal information, secrets, and internal decisions written into code / config / comments / docs.16 - **Defensive-content pollution**: guardrail metadata (corrections, risk warnings, discipline, self-reminders) leaked into public deliverables and user-visible strings.17 - **Wheel-reinvention audit**: "this whole module has a more mature open-source alternative, but you hand-rolled an outdated one".18 - **Adapter-convergence audit (tech-stack unification)**: "the same concern was solved N times, in N parallel ways, and never converged to one seam" — the subagent/borrowed-tech failure mode that leaves one concern with N adapters (or 1 live + 1 dead), a write-only capability registry, or two names/units for one fact.19 - **Publish gate (pre-publication self-check)**: "my OWN public artifact about to ship carries a specific-project fingerprint" — a project noun, a concrete field name/unit/value, a named borrowed framework, or a producer-voice "we" — applied to the artifact in your hand before it goes out (covers the skill's own README/SKILL/marketing).204. **Adaptive scope**: depth tiers (Lite/Standard/Deep) and loop modes (one-shot/incremental/gate) so the audit weight matches the project, never over- or under-auditing.2122**Paper traversal is the means, not the end**: not executing, not clicking is how we *cheaply exhaust every user path* — faster, more global than real clicking, able to see root causes at a glance. **But it is never an excuse to "not fix"**: the audit's closed loop is `report (root cause + precise location) → user confirms → agent fixes precisely → verify via falsifiable check (symptom disappears)`.2324**Iron rules** (9, not a wall — each one earns its place):251. **Do not execute code, do not really click, do not modify code** — mainline work happens on paper.262. **Code is the single source of truth**: reason from the real behavior recovered by reading code, not from design docs or memory.273. **Do not fall into the "code self-consistency" trap**: internally consistent code ≠ a good product.284. **Exhaustiveness is the soul; sampling is negligence**: steps 1.5/2/3 must fully traverse the `structure × persona × function × operation × state × timing` matrix; many walker subagents each reason independently; **only after traversing all paths may you do root-cause analysis**. Forbidden to sample one happy path and conclude.295. **Reuse first, don't reinvent**: for security / AI-smell / maintainability / review, load `llm-sast-scanner` / `code-auditor` / `ponytail-audit` / `code-reviewer`; do not rewrite their rules.306. **The self-built checks (release hygiene + defensive pollution + wheel reinvention + adapter convergence + publish gate) are this skill's own — always run them, never skip.**317. **Read-the-code verification spans multiple steps, not just once at step 1**: walker traversal (step 3), extreme testing (step 4), three-way alignment (step 10), and attribution (step 11) must each **re-read the code to verify**; forbidden to conclude from step-1 memory. Every `file:line` must be "just read / just grepped in this round", not "from memory" — memory goes stale and hallucinates.328. **No false positives, no over-auditing**: before reporting anything, confirm "does this scenario apply?" — no store review for something not shipping, no mobile App Store review for a desktop app, no treating test fixtures / vendored code / build artifacts / .env templates / doc TODO placeholders as production bugs. And match the audit weight to the scenario — never run the heavy pipeline on a landing page. **A wrong report hurts trust more than a missed one.**339. **Honest + falsifiable**: if you can't find it, say what's missing — never fabricate. Every root-cause conclusion must carry a falsifiable verification method ("if I fix X, symptom Y disappears; if Y persists, X was wrong"); an unfalsifiable statement is an impression, tagged `【impression, no verification path】`, never a finding.3435---3637## 2. Methodology (Intake Gate + Steps)3839### Intake Gate (mandatory, never skip, never guess)4041**Core principle: the agent answers first, the human only fills what AI can't know.** This skill is for the agent itself — it can read code, README, and context. So most questions are **answered by the agent first, inferred from code** (with evidence + confidence), not dumped on the human. Only what "isn't in code, only in the founder's head" gets asked of the human.4243**Round 1 — agent self-answers (infer before asking).** Read code + README + context; answer each item with `inferred answer + evidence + confidence (high / medium / low)`:44451. **Project type** — web app / CLI / library / desktop app / agent system / game / other (from README / package.json / structure). **This decides what "structure unit" means in Step 1.5.**462. **Target users** — how many types, what habits (reverse-infer from README / copy / features).473. **Release scenario** — ships where? personal vs commercial? software-copyright? (infer from package.json / README / deploy config; decides whether compliance / store-review checks apply).484. **Type-specific follow-ups** — web/desktop: which journeys are core, which step loses users, any target platform; CLI/library: target devs, integration scenarios, API constraints; agent system: interaction mode (chat/canvas/voice), automation boundary (what must never auto-run); game: target players, core fun, payment/store plan.495. **Depth tier** — Lite / Standard / Deep, with a one-line reason (see "Audit Depth Tiers").506. **Loop mode** — one-shot / incremental / gate (see "Embedding in an Existing Loop").5152**Round 2 — human fills the gaps (only what code can't answer).** From Round 1, take the items with **low confidence** or that **change the audit conclusion**, and ask the human as **multiple-choice** — each question shows the agent's inferred answer as the **recommended option**, a few alternatives, and a **"skip — use your inference"** option.5354**Always ask the human (code never contains these):**551. **Design intent** — for each core feature, what experience did you *want* the user to get? (code shows what it does, not what it means to achieve). **This is also the ruler for gate vs break in Step 3a.**562. **Real user thoughts** — the actual habits / tolerance / pain points of your target users (not in code).573. **Release final say** — does it actually ship / register copyright? (partly inferable, but you decide).584. **Is the requirement itself right?** — only when it arises (A/B reference-group choice).5960**Fallback rule**: skipped items use the agent's inferred value, tagged `【agent-inferred, not user-stated, needs confirmation】`. If a point arises that "only the user can decide" (A/B reference group, requirement validity, wheel replacement, depth tier, loop mode), **stop and ask — never decide for them**.6162### Audit Depth Tiers (adapt the weight to the project)6364**Not every project needs a heavy audit.** The agent infers a tier from the intake answers, recommends it with a reason, and lets the user override.6566How to decide: ① project size ② purpose (self-use/internal/commercial/shipping) ③ release scenario ④ risk surface (user data? concurrency? auth/payment? AI mainline?) ⑤ user intent ("quick look" vs "full acceptance").6768| Tier | For | Runs | Skips |69|---|---|---|---|70| 🟢 **Lite** | landing page, one-off script, personal tool, self-use | quick classify; 1–2 personas on the 1–3 core paths; experience alignment (core only); quick release-hygiene sweep; simplified attribution | six-layer checks, wheel-reinvention, extreme testing, concurrency stress, orthogonal-array exhaustion, light research |71| 🟡 **Standard (default)** | medium project, internal tool, acceptance | full steps; six-layer checks trimmed by release scenario | compliance layer if not shipping / no copyright |72| 🔴 **Deep** | store shipping, copyright, commercial release, high concurrency, sensitive data, agent system, "full acceptance" | everything: all steps + all six layers + extreme testing + concurrency stress | nothing |7374Rules: **recommend, don't decide** (state tier + reason, let user override); **never silently escalate** (a big codebase alone is not a reason for Deep); **record the tier honestly** in the report header.7576### Embedding in an Existing Loop7778| Mode | When | Scope | Output |79|---|---|---|---|80| **One-shot** | standalone full audit | everything | full report |81| **Incremental** | after each change in the loop | `git diff` + paths the diff touches (inferred from the state machine) | short: new/recurring blockers + root cause |82| **Gate** | before commit / merge / release | high-risk layers only (high-severity security + release hygiene + core paths) | PASS / BLOCK + blocking list |8384Execution principles: **baseline once, then increment** (first run builds personas + state machine + root causes; later runs are Incremental and reuse it — never re-run full unless asked or structure changed); **incremental scope** = `git diff` + reverse-infer affected paths; **gate pass criteria stated up front**; **match output to the loop** (full report is useless mid-loop, bare PASS/FAIL useless pre-release).8586### Light Research (after intake gate, before step 0; mandatory for Standard/Deep, skippable for Lite)8788**Personas must not be invented off the top of your head.** A round of light research (capped at 3–5 searches) to get three things: ① target-user commonalities ② real pain points ③ behavior patterns. **Disciplines**: every conclusion carries a source URL; when research conflicts with the user-stated intake answers, **user-stated wins** (the founder knows their product better than external research), but list the conflict explicitly.8990### Step 0: Set the ruler — user-persona layering (targeted)9192Based on **three-way synthesis**: intake gate (human-stated) + agent self-answer (code-inferred) + light research (external data), produce:9394- **User-persona layering table**: ≥3 user types; for each: usage habits / expectations / tolerance / features they will and won't use / pain points / behavior patterns. Tag each item's source: 【user-stated】/【agent-inferred】/【light research · URL】.95- **Design-intent table**: for each feature, "what experience the designer wanted the user to get", source-tagged. **This table doubles as the gate list for Step 3a's gate-vs-break distinction.**9697### Step 1: Recover the truth — read code and model the state machine9899- Recover the **real state machine**: state variables (with initial values), transition conditions, branches, boundaries, race points.100- Recover the **real behavior of each feature** (what the code actually does, not what the docs claim).101- Annotate: deviations between actual code behavior and design intent.102103### Step 1.5: Project structure map (the "brain" — see the whole before dispatching)104105**Before exhaustively walking paths, list what this project actually contains — so the walkers are assigned, not left to guess.** Read code (not docs alone) and produce:1061071. **Structure units** — what this project is made of, in *its own* organizing terms (never preseed a term):108 - web app → pages / routes / feature modules109 - CLI → commands / subcommands110 - game → play systems / mechanics111 - agent system → capability scenarios (whatever the project itself calls them)112 - library → modules / API surfaces1132. **Core journeys per unit** — the typical user task in each unit (1–N journeys each).1143. **Journey inventory** — one table of all units × their journeys. **This is the sole input to Step 2.**115116**Coverage check (explicit)**: the inventory must state "N units × M journeys; unit A has k journeys, unit B has j…" — a missed unit is a failure, not an option. If the tier is Lite, skip units honestly and say why, don't silently drop them.117118### Step 2: Exhaust paths — persona combos + combination-reuse principle119120**Iron rule: exhaustion = fully traversing `persona combos × journey × operation × state × timing` (where "journey" comes from Step 1.5's inventory), but "combos" use equivalence classes + boundary values + orthogonal arrays, not the full Cartesian product. Forbidden to sample one happy path and conclude.**121122**The no-miss methodology (classic software-testing trio)**:1231. **Equivalence-class partitioning**: personas by "behavioral similarity"; journeys grouped by "same kind of behavior" (all "create X" is one class); operations into "normal / abnormal / boundary / interruption" four classes, pick representative values per class.1242. **Boundary-value analysis**: test **both sides** of numeric/length/count boundaries (0 and 1, upper and upper+1, empty and 1 char) — bugs cluster at boundaries.1253. **Orthogonal arrays**: guarantee "**every pair of dimensions' combination is covered at least once**" for 3+ factors (persona × journey × operation); for 2 factors, full combination.126127**Coverage must be quantified and provable**: the report states `covered N personas × M journey groups × K operation classes = P paths; orthogonal table guarantees every two-dimension combination ≥1; boundary values cover 0/1/upper/upper+1`.128129**Persona = persona × scenario combination** (not single persona, not full Cartesian product):1301. List **single-scenario personas** (each persona type × each scenario — use the project's own scenario names).1312. List **combined-scenario personas** (real users often "do both A and B").1323. **Combination-reuse principle** (avoids explosion): if "A alone" and "B alone" are each tested fine, the "A+B" persona only tests the **cross-scenario delta**:133 ① **precise switching**: is moving between A↔B precise, reversible, free of leftover wrong state;134 ② **cross-scenario recall**: does the memory/state layer know the relation between A and B, and recall correctly without contamination or loss;135 ③ **is the cross-scenario mechanism working** at all.136 Only fully test a combination when a single scenario wasn't tested or the combo introduces new state.137138**Persona count is justified, not arbitrary**: total = needed combos, **capped ≤10**. Over the cap, prioritize "single-scenario first, then high-value combos", and state what was dropped and why.139140### Step 3: Two-layer persona traversal — mechanical walker (objective) + intent observer (subjective)141142**Key distinction**: deterministic traversal — code and state machines are deterministic, not a chaotic multi-agent swarm. Split into two layers with **different jobs and different output status**:143144- **Layer A — mechanical walker (objective)**: walks every path, records only facts. Output is **falsifiable**.145- **Layer B — intent observer (subjective, ONE persona)**: watches Layer A's facts, produces **reference opinions**. Output tagged `【主观参考, 非可证伪发现】` — a hypothesis generator, not a finding.146147#### 3a. Layer A — mechanical walkers (record facts, never judge)1481491. **Dispatch walkers**: one per persona combo from step 2. Prompt synthesized from ① light research ② intake gate ③ code reverse-inference.1501512. **Each walker verifies along the full code chain and records ONLY four facts per step**:152 - `reached`: which step it reached (read code at each link: `user action → entry function → state transition → tool → persistence → output → new state`);153 - `broke`: did it break here — an **objective, code-verifiable fact**: no way to continue (no available action / state deadlocked / thrown error). Confirm by reading code, tag `file:line`.154 - `gate_or_break`: **is this stop a gate or a break?** A *gate* = an intended human-in-the-loop pause (from Step 0's design-intent table — e.g. confirm/approve/choose points the user deliberately designed). A *break* = an unintended stop (no-key early return, infinite hang with no timeout, thrown error). **Gates are features, not findings; only breaks are defects.** When unsure, tag `gate?` and let attribution decide with the user.155 - `steps`: how many steps / rounds before the stop (operation complexity, NOT wall-clock seconds — paper traversal can't measure real time).1561573. **Forbidden for walkers**: do NOT judge "is this a bug / bad UX / would the user be confused" — Layer B / attribution's job. A walker that judges has overstepped; downgrade that to a Layer B hypothesis.1581594. **Make factual disagreements explicit**: if two walkers record differently on the same path (state/persona differs), record both verbatim — a data point, not a dispute to smooth over.160161#### 3b. Layer B — intent observer (ONE persona; produces hypotheses, never findings)162163**Positioning**: not "a simulated user", but a **human-intent observer** — like a senior UX researcher: understands human behavior and product intuition, reads Layer A's *factual* breakpoints, produces *reference opinions*.164165**Input**: Layer A's break list (`file:line` + gate_or_break + step counts).166167**Output — every item carries three parts + a tag**:168```169【主观参考】关注点: <which break / path segment, anchored to a Layer A fact>170理由: <why a human would most likely care here — behavior / habit intuition>171建议方向: <where attribution should read the code to verify — file:line>172```173174**Three disciplines**:1751. Every item MUST be tagged `【主观参考, 非可证伪发现】` — iron rule 9: an opinion is not a finding.1762. It may only say "this looks suspicious, suggest reading code X" — never "this is a bug".1773. Its opinion MUST anchor to a Layer A fact ("based on breakpoint #N…") — never free-floating "I think users would be confused".178179**What the observer adds that walkers can't**: prioritization intuition — among many factual breaks, which ones a novice trips on vs an expert ignores, which everyone curses. It reads the *facts* and adds the *human weighting* Layer A deliberately does not do.180181#### Aggregation (after both layers)182183- Layer A: aggregate breaks — single-user-specific (boundary) vs hit-by-all (systemic); **gates are recorded but not treated as defects**.184- Layer B: attach hypotheses to the systemic breaks.185- **Hand both to Step 11 (god's-eye attribution)**: Layer A facts = hard evidence; Layer B opinions = investigation leads. Attribution reads code to verify each lead before it becomes a finding. An opinion with no code confirmation stays `【主观参考】`, never promoted.186187### Step 4: Extreme testing — jailbreak/injection + stress/concurrency188189- **Jailbreak / injection**: prompt injection, role hijacking, system impersonation, jailbreak templates, invisible Unicode. Against step 1's "trusted input boundary", find penetration points and correct interception points.190- **Multi-task concurrency stress**: N tasks simultaneously, races, timeouts, interruption, duplicate submission, rapid switching. Traverse who overwrites whom, whether locks fail, whether queues are serialized.191192### Step 5: Specialized-check orchestration — reuse existing skills (don't reinvent)193194| Dimension | Reused skill | What it checks |195|---|---|---|196| Security | `llm-sast-scanner` | 34 vulnerability classes, Source→Sink taint tracking |197| AI-smell / maintainability | `code-auditor` (AI-smell) + `ponytail-audit` | naming emptiness / comment clichés / swallowed exceptions / TODO graveyard; over-engineering delete/stdlib/native/yagni/shrink |198| Store review | `code-auditor` (copyright + store-gating) | **Conditional**: only when the release scenario says ship/register (already decided in Intake Gate); otherwise skip this row. Know the platform first — an Electron desktop app does not go through App Store/Google Play mobile review |199| General correctness | `code-reviewer` | correctness / security / maintainability / performance 🔴🟡💭 — **must explicitly cover: dead code / speculative abstraction (zero-consumption modules, dead switches, retired-but-kept files), duplicate definitions / same-name conflicts (one symbol defined multiple incompatible ways), god files / over-centralized modules (one file carrying too many responsibilities)** |200201Duplicates go to the more specialized one; dedupe then merge. **Before reporting each layer, pass iron rule 8 (false-positive check).**202203### Step 6: Release-hygiene check (self-built, mandatory)204205**AI-assisted-development-specific — things that should not be publicly released got written into code/config/comments/docs.** Scan item by item:206207- **Real personal information**: name / phone / email / address / school / grades / ID number, hardcoded into code, config, fixtures, comments.208- **Secrets and credentials**: API key / secret / token / private key / personal workspace endpoint, written outside .env.209- **Development trial-and-error traces**: comments like "incident observed", "user said XX", "audit found XX", "walkthrough gap N", "temporary / do this for now / to delete".210- **Internal conversations and conclusions**: development-time dialogue, trial-and-error conclusions, internal decisions written into prompts/comments/docs.211- **Internal domain information**: internal project names, private domains, internal architecture decisions, unpublished account systems.212213For each hit, tag `【release hygiene】+ file:line + content category + leak level`, and list separately in the report.214215### Step 7: Defensive-content pollution (self-built, mandatory)216217**The disease**: AI wrote its *internal* guardrail metadata — corrections, risk warnings, discipline clauses, self-reminders, "as an AI" disclaimers — straight into an artifact meant to be public or a string meant for the end user. The artifact stops being universal: a marketing copy with "⚠️ needs verification" can't be published; open-source code with "// untested, don't trust this" can't be shipped; a user-facing message with "产物自己过一眼" leaks a producer-only concern.218219**How it differs from release hygiene**: release hygiene leaks *past* dev traces (secrets, PII, trial-and-error); this leaks the *current* artifact's own defense notes. Same root cause, different symptom — a public deliverable and its internal guardrail metadata were not physically separated.220221**The three-question test** (apply to every suspicious sentence / comment):2221. **Meta or content?** Is this sentence *about* the artifact (its correctness / trust / status), or *is* it the artifact (the actual copy / code / doc)?2232. **Who is it addressed to?** To the *producer* ("note to self", "for internal review") — or to the *end user*?2243. **Deletion test (falsifiable)**: delete it — is the artifact still complete and *more* universal? If yes, it was internal metadata and must be reported.225226**Signals to scan for**:227- Explicit guard markers: `⚠️` / `【备注】` / `【纪律】` / risk warning / disclaimer / "AI-generated, please verify"228- Self-reminder speech: "as an AI I remind you", "please verify", "not tested", "don't ship", "for reference only", "does not constitute advice"229- Code self-notes: `TODO` / `FIXME` / `HACK` / `// note to self` / `// this broke before, don't touch`230- Leaked internal correction: "this was wrong before", "temporary", "for now", "internal wording", "internal decision"231232**Where to scan — five surfaces (breadth: not just chat and deliverables)**:233234Defensive pollution hides in *every* user-visible string. Scan all five:2352361. **Conversation output** — `appendAssistant` / `finalText` / `appendBrief` / dialogue messages.2372. **Deliverable files** — docs / code / config meant to be published or shipped (overlaps release hygiene).2383. **Settings / config UI text** — model pickers, tier labels, capability maps, degradation-matrix wording, parameter descriptions. Internal architecture terms shown to the user. Locate: `displayName` / `label` / `title` / `t(...)` in settings components and registry/archive files.2394. **Runtime result display** — status text, progress, result cards, quality-gate verdicts rendered in the UI. Locate: `statusText` / progress / verdict rendering.2405. **Run log / notifications** — notification center, toast, event timeline, log panel. Internal QA/process terms shown to the user as "history". Locate: `pushNotification` / toast / event feed / log lines that reach the UI.241242*(The concrete function names above are examples of "how to locate" each surface — the exact names differ per project; use the project's own user-visible-output entry points.)*243244**Rule**: a term is internal if it names an architecture component, a process step, or a producer-only concern. The same term is *not* pollution when the audience is an operator configuring the system (power-user settings may legitimately name engines). Apply iron rule 8: "end-user-facing text" vs "operator-facing text" are different audiences — only the former is pollution.245246**Severity**: High = makes the artifact unpublishable; Medium = local contamination; Low = deliberate compliance disclaimer (flag, don't assume it's a bug).247248**Root cause (god's-eye)**: guardrail metadata was not physically separated from the deliverable. Triggers: ① guardrail tools set to `on_fail="fix"` rewriting in place; ② prompts telling the model to "self-correct" without distinguishing internal vs external; ③ internal discussion leaking into context and copied into output.249250**Fix direction (for the report, not the audit)**: two-layer output (draft vs `public_release`), a `product_mode` parameter, defense metadata routed to a side channel (logs / review queue) — never injected into the payload. The audit detects the leak and points at its root cause; it does not redesign the pipeline.251252### Step 8: Wheel-reinvention audit (self-built, mandatory)253254**Find "this whole module has a more mature open-source alternative, but you hand-rolled an outdated one."**2552561. Enumerate the project's feature modules / self-built dependencies (especially "looks hand-written": auth, state management, message queue, ORM, template engine, utility collections, protocol implementations…).2572. For each suspected module, **search first** (web_search / npm view / GitHub search) for mature alternatives, comparing maturity, maintenance, completeness, license.2583. **Code comparison**: self-built vs mature alternative — where does it fall short?2594. When something is "clearly worse", **stop and ask the user whether to replace** — don't decide unilaterally.260261### Step 9: Adapter-convergence audit — tech-stack unification (self-built, mandatory)262263**The disease this catches is NOT "a module is bad" — it's "the same concern was solved N times, in N parallel ways, and never converged to one seam."**264265This is the failure mode of **subagent / borrowed-tech-driven development**: each subagent or borrow adds its *own* adapter (LLM client, storage layer, renderer, tool dispatcher) for a concern that already had one. Left unmanaged, you get "one concern → N adapters", where N adapter instances each carry lifecycle/params duplicated, or one adapter is dead while a parallel copy is alive. The debt lives in the **interface/architecture layer** (how many ways reach the same capability), not in whether any single module is well-written.266267**How it differs from Step 8 (wheel reinvention)**:268- **Wheel reinvention** asks "did you hand-roll a *worse* version of something with a mature OSS alternative?" — the fix is *replace/borrow*.269- **Adapter convergence** asks "do you have *more than one* adapter for the same concern?" — even if each is well-built, *having N is the debt*. The fix is *converge to one seam* (delete redundant adapters, or wire the one that's dead, or make N share a single interface).270271**Detection method — a strict, falsifiable, four-pass scan (per concern):**272273For each cross-cutting concern (LLM / model, storage / persistence, rendering, tool dispatch, voice I/O, logging, config), run:2742751. **Enumerate ALL implementations of that concern** — find every file that claims the concern's job (grep the concern's verbs: "send"/"openai"/"chat", "write"/"store"/"save", "render"/"draw", "call tool"/"dispatch", "transcribe"/"speak"). Do NOT stop at the one the design doc names; grepping is what surfaces the parallel ones.2762772. **Find every call-site that reaches the concern** — not just the definitions. A definition is separable from whether it's *reachable*: `grep` the adapter's exported symbol + import path. **A symbol with quotes in a test/script but zero production callers is DEAD (unwired), not "reserved".** Record: `definition (file:line)` + `call-sites (count, file:line)` + `is there a production caller?`.2782793. **Count the distinct adapters (the headline finding)**: for the same concern, is it 1 adapter used everywhere (converged — good), or N adapters where N≥2, or 1 live + 1 dead, or N that each hold partial capability? **The cardinality of "ways to reach a concern" IS the finding.**2802814. **Verify "single source of truth" for the concern's metadata**: do the adapters read the SAME capability spec (window size, modalities, dialect, limits), or is the same fact stored in **N registries with N field names / N units** (e.g. one registry calls it `context` in tokens, another `context` in thousands; one uses a boolean `supportsImages`, another a `modalities` list containing `image`)? N registries = drift risk; a value changed in one and stale in the other is the proof. **This is the "same fact, two copies" check.**282283**The six signals that flag a convergence failure** (each falsifiable, pick matching ones):284| Signal | What it means | Prove by |285|---|---|---|286| 🎯 **Dead adapter** (unwired) | a whole adapter module exists, has exported symbols, but zero production callers; only a manual test script imports it | grep the symbol + import path → only hits are the module itself + a non-CI script |287| 🧩 **Parallel adapters** | the same concern solved by N separate implementations (N renderer instances / N storage stores / N tool-dispatch paths) at once | grep count of `new XRenderer` / distinct store/types / distinct dispatch entrypoints |288| 📇 **Write-only capability schema** | a config/registry declares fields (context, limits, dialect, vision, tools) that NO code reads | grep each declared field → zero readers |289| 👻 **Ghost enum value** | a union/type declares a value that no producer sets and no dispatcher handles | grep the value → only the type + a comment |290| 🔄 **Split meaning of one thing** | the same fact stored in N registries with N field names/units (drift) | compare field names + units across registries, show a real stale example |291| 🧹 **Partial-use borrow** | a heavy library imported, but only a tiny non-core surface used (a full editor for a single screen + two utility calls) | list import lines vs the actual call-sites |292293**Governance method (for the report — how to keep it converged going forward):**294- **One concern = one seam.** For each of the enumerated concerns, name the *one* adapter that is canonical; every caller must go through it.295- **Dead means deleted.** An unwired adapter (dead-code signal) is either wired now or removed — never left as "reserved / pilot / test-only". A non-CI script referencing it is not a reason to keep it.296- **One metadata registry per concern.** Capability facts (context, modalities, dialect, limits) live in exactly one place; the other registries either read it or are merged/deleted. Never two names / two units for one fact.297- **Converge, don't keep both.** When a concern has 2 live adapters, decide "which is canonical" and migrate — do NOT keep N "because both work". N working adapters is still N× the maintenance.298- **Brace against future borrows**: the report's conclusion must state "the next time a tech is borrowed, it either enters the canonical seam or is deliberately scoped + removed; nothing stays 'borrowed but unwired'."299300**Output**: list per concern → `concern | adapter cardinality (1 / N / 1-live-1-dead) | signal(s) marked | evidence file:line | canonical seam to converge to | action (delete / wire / merge)`.301302> Every conclusion obeys iron rule 9: a convergence finding must be falsifiable — "delete the dead adapter → does behavior change? no → it was dead"; "route all callers through the canonical seam → do the N ways collapse to 1? yes → convergence confirmed".303304### Step 10: Experience-layer three-way alignment + reference group305306- **Three-way alignment**: for each feature, lay out ① design intent ② actual code behavior ③ real user expectation; find the gaps, focusing on "self-consistent but experience-wrong".307- **Reference-group experiment**: for features where "is the requirement itself right" is doubtful, design A/B comparisons, and on paper traverse what each design gives the user.308309### Step 11: God's-eye global attribution (the last step — after all errors have arrived)310311**This is the final attribution of the whole audit — wait until all errors from every prior step (walker traversal + six-layer checks + three-way alignment + stress testing) are collected.**312313**Attribution methodology (distinguish "correlation" from "causation"):**3143151. **Collect the full error set**: aggregate all errors into one table (each with file:line + trigger condition + symptom).3162. **Cluster candidate root causes**: by "shared code location / trigger condition / mechanism". Each cluster is a *candidate* (not yet verified).3173. **Counterfactual verification (separates root cause from symptom)**: for each candidate — "**if I fix this one spot, do the errors in this cluster disappear together?**" Disappear together → true root cause; only one disappears → it was a symptom. Write it out: `candidate X → assume fixed → traverse: do A/B/C disappear?`3184. **Draw the causal chain (not a flat list)**: `root cause → intermediate cause → symptom`. Mark necessary/sufficient conditions.3195. **Layer root causes + rank by impact**: prioritize by "how many symptoms one root cause eliminates", not by individual symptom severity.3206. **Every root cause carries a falsifiable verification method (mandatory)**: "how to verify it's true" — `assume X is true → fix X → expect A/B/C to disappear together; if they persist, X is wrong`. No verification path = tag `【impression, no verification path】`, never a conclusion.321322### Step 12: Produce the report — classified layers + converged directions323324Output the layered results + step 11's attribution. The body is the layer classification, but the **conclusion is "the few root causes + impact-ranked convergence directions"**, not a symptom list.325326### Step 13: Publish gate — self-check BEFORE releasing any public artifact (self-built, mandatory)327328**The disease**: you're about to publish something public — a README, a marketing copy, an open-source skill, a public doc, a released string — but it carries a *specific-project fingerprint* (your own product's name, an internal borrowed-library name, a concrete field name/unit/value you measured, a "we / our product" voice). It works *for you* because it's your own context; it leaks because the audience is a stranger.329330**This is Step 7 (defensive pollution) applied to YOUR OWN artifact you're about to ship**, rather than to a codebase you're auditing. Step 7 scans someone else's deliverable; Step 13 scans the one in your hand, right before it goes out.331332**Trigger**: whenever you are about to publish / commit / push / release / submit anything that a stranger will read — a repo file, a README, a skill, a landing page, a public doc, an issue, a PR description. **Apply it to the artifact itself, not just to code.**333334**The four-question test** (run against every public artifact before releasing):3351. **Project-specific noun?** Does it name your own product/feature/domain (a brand, an internal module, a scenario name)? → Replace with a generic term (e.g. "a card", "a scene", "an agent workspace").3362. **Fingerprint detail?** Does it carry a *concrete* field name, unit, or measured value that only your code produces (a registry field, a `XX:1000` number, a hardcoded enum value)? → Abstract to a placeholder (`<field>`, `<value>`), or phrase it as "one registry calls it X, another Y" without the real names.3373. **Borrowed/inspiration name?** Does it name a specific third-party project you borrowed from, as if the reader knows it (a framework's name as a contrast)? → Say the *kind* instead ("a chaotic multi-agent swarm"), not the brand.3384. **Producer-voice leakage?** Does it address the producer ("note to self", "we/there's only one dev", "my product") instead of the reader? → Rewrite for the *reader*; the artifact must stand alone without knowing you.339340**The deletion test (falsifiable, iron rule 9)**: delete every project-specific noun / fingerprint / borrowed name / producer-voice phrase — is the artifact still complete and MORE universal? If yes, those were leaks and must go. If removing it breaks the meaning, it was load-bearing; keep it but phrase it generically.341342**Breadth — apply it everywhere, not just the main file**: README, marketing/promotion copy, the skill's own SKILL.md, public docs, example code, config templates, commit messages, PR descriptions, issue bodies, release notes. The leak hides in the *small* file as often as the big one.343344**Severity**: High = leaks an internal design/product detail that (a) does not apply to strangers, or (b) reveals you measured an internal metric — makes the artifact non-universal; Medium = a named borrowed framework subtly narrowing the audience; Low = a producer-voice "we" that reads oddly but doesn't confuse.345346**Iron rule 8 (false-positive check)**: a *generic* word (rendering, storage, agent, card, scene, model) is NOT a leak — it's the reader-facing vocabulary. Only flag terms that (a) are proper nouns of your own project, (b) are concrete fingerprints, or (c) assume the reader shares your internal context. Don't over-sanitize a good universal sentence.347348---349350## 3. Output Format351352```353# Persona Auditor Report354## 0. Audit tier + scope (which tier ran, what was skipped and why — honest)355## 1. User-persona layering table + design-intent table (source-tagged)356## 2. State-machine recovery + deviations from design intent357## 3. Project structure map (units × journeys inventory; coverage check)358## 4. Exhaustion matrix (persona × journey × operation × state × timing, coverage count)359## 5. Two-layer persona traversal results360 - 5a. Mechanical walker report: factual breaks (reached / broke / gate_or_break / steps / file:line)361 - 5b. Intent observer hypotheses: 【主观参考】opinions anchored to breaks362## 6. Extreme-test results — jailbreak / concurrency363## 7. Specialized-check results (security / AI-smell / compliance / general)364## 8. Release-hygiene check365## 9. Defensive-content pollution (five surfaces)366## 10. Wheel-reinvention audit367## 11. Adapter-convergence audit (tech-stack unification) — per concern: cardinality / signals / evidence / canonical seam / action368## 12. Experience-layer three-way alignment + reference group369## 13. God's-eye global attribution (counterfactually verified root causes)370 - full error set → candidate clustering → counterfactual verification → causal chain → impact ranking371## 14. Convergence directions (by root-cause impact, not symptom severity)372```373374**Report header states the audit tier** and what was skipped (honest, not hidden). Every defect uniformly carries: `trigger sequence → expected vs act375376…(truncated)