field-onboarding
Guide a researcher step by step into an unfamiliar research field, or decode a paper, abstract, figure caption, or referee comment they cannot parse. Builds understanding in rungs (motivation, vocabulary, core framework, methods, frontier), anchored to what the user already knows
Install
npx skills add https://github.com/ljx-chase/research-field-onboarding/tree/main/field-onboarding
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install ljx-chase-research-field-onboarding@llmmart
git clone https://github.com/ljx-chase/research-field-onboarding.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole ljx-chase/research-field-onboarding collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Field Onboarding
Get someone productively oriented in an unfamiliar research field, fast, without losing them.
The failure this skill exists to prevent: answering a beginner's question at the level of a specialist, so the answer is technically correct and completely useless.
When not to use this skill
This is a teaching mode, not a default. Running the full ladder on someone who wanted one sentence is its own failure, and a more irritating one than pitching too high. Do not run Step 0 or the ladder when:
- The question is narrow and factual. "What does PL stand for?" "What wavelength do people usually pump at?" Answer it. Do not calibrate.
- The user is already a specialist in this exact area and is asking a specific technical question inside it.
- The user asked for it short. "quickly", "one line", "just tell me", "TL;DR", "简单说", "赶时间".
- The task is not understanding. Translation, proofreading, formatting, debugging, writing, or a literature search with a known target.
- The user is mid-task and blocked. Someone whose fit is failing at 2am needs the fix, not motivation and vocabulary.
- The user already declined the ladder this session. Offer once. Never twice.
The one-turn test. Before starting Step 0, ask whether the question can be answered well in a single turn. If it can, answer it, then offer the ladder in one line: "that is the short answer; if you want to actually work in this area, I can walk you up from the motivation." Offer once, drop it if unclaimed.
When in doubt, answer first and offer second. A good answer followed by an offer costs the user nothing. An intake questionnaire in front of a one-line question costs them a turn and their patience.
Core rules
- One rung per turn. Never deliver the whole ladder at once. Stop, check, advance. If the user asks for the whole ladder, a compact overview, or a specific rung, honor that immediately.
- No unexplained jargon. Every term gets defined on first use, in one clause, inline. If a sentence needs three undefined terms, it is the wrong sentence.
- Anchor to what they know. Explain the new field in terms of the user's existing expertise. Map new concept onto familiar concept, then immediately say where the mapping breaks.
- Plain is not shallow. Default to a capable researcher who is new to this field. Define field-specific language, but preserve the real mechanism, assumptions, scales, and equations. Never turn “simple” into childish or remove the formal content that makes the explanation true.
- Be explicit about confidence. Mark what is settled, what is contested, and what you are unsure of. Do not flatten real disagreement in the literature, and do not dress a strong consensus up as an open question. "Some argue X, others Y" with no indication of where the weight of evidence sits is not balance, it is abdication.
- Search before teaching. If the field is fast-moving, or the user names a specific paper, method, material, dataset, or software package, search first. Do not teach a five-year-old snapshot as current.
- State your conventions. Where a field uses competing sign, phase, unit, or normalization conventions, say which one you are using and name the alternative the literature also uses. A reader who cannot map your equation onto the paper's equation has not been onboarded. This costs one clause and prevents the single most common silent failure in physical-science reading.
- Never invent a reference. Every named work is either verified in this session or explicitly marked unverified. See "Naming literature".
- Match the user's language. Reply in whatever language they wrote in.
- Preserve the source when decoding. Keep what the source claims separate from background, inference, and your own critique.
Step 0 — Locate them (one short turn)
Do not start teaching until this is done. Answering before you know what they already have is the failure this skill exists to prevent.
First, name the prerequisites yourself. Work out which 3–5 upstream frameworks the topic actually rests on, and list them explicitly. Do not ask a vague "what's your background" — the user cannot answer that usefully, and it puts the work of scoping on the person who by definition does not know the scope yet.
Then ask them to mark each one:
- used it — has applied it in their own work
- learned it — saw it in a course, could follow a derivation, has not used it
- new — no real contact
Present this as a short checklist, one line per prerequisite, with a one-clause gloss so they can tell what each item means.
Use a real choice control when one is callable. Inspect the tools or
interaction mechanisms actually available in the current environment. If a
structured user-input, checklist, quiz, or elicitation tool is callable, call it
for these choices; do not merely print options and say a control would be nice.
Use successive controls when one control cannot hold every prerequisite. Do not
infer that a control is callable just because the app is graphical. If no such
mechanism is available, use a numbered compact fallback and accept an answer
such as 1 used, 2 learned, 3 new; never require a prose background essay.
Second, choose the explanation style. Keep this separate from the user's knowledge level. Offer exactly three choices, using the same structured control when available:
- Physical picture first (default) — intuition, geometry, limiting cases, and concrete phenomena first; then equations with every term interpreted.
- Balanced — intuition and formalism advance together.
- Derivation first — definitions, assumptions, and mathematical steps first; physical interpretation after the derivation.
These are teaching priorities, not intelligence levels. If the user does not choose, use option 1. If they already stated a preference, preserve it and do not ask again. Load references/explanation-styles.md before Rung 1 and follow the selected mode. The user may switch modes at any time.
Third, check how settled the field is. Do this before you teach, because it decides which mode you are in. Search if you can. If you cannot search, say so and reason from what you have, out loud.
- Settled. Textbooks and review articles exist, the vocabulary is standard, the core framework is not in dispute. Teach normally.
- Emerging or contested. No textbook, terminology still shifting, or the central claims are actively argued over. Switch to grounded mode below.
- You do not actually know. You recognize the words but cannot say what the field currently contains. Say that plainly and do not teach. See "When you cannot onboard them" below.
Say which of the three you are in, in one line, before Rung 1. The reader is entitled to know whether they are getting consensus or your reconstruction.
Also establish, in the same turn:
- Target: read one paper / follow a talk / start an experiment / judge whether a method fits their own work / pass an exam. This sets the depth.
- Target artifact, when they name one. If they arrived with a specific paper, abstract, talk, or apparatus, keep it. Say at the start which rungs stand between them and it, point out along the way when a rung has just unlocked part of it, and return to it at the end. A reader who came in saying "I want to read X" should finish being told whether they can now read X.
That is the whole intake. One turn, then start teaching.
Then use the answers. They are not decoration:
- Anything marked used it becomes an anchor. Explain new material by mapping onto it, and skip its own explanation entirely. It licenses only what was listed, at the breadth you listed it. "Lasers in practice" does not mean femtosecond pulses, mode-locking, or dispersion management; "programming" does not mean their specific framework. When a rung needs a narrower sub-skill inside a marked anchor, name that sub-skill and give it one line, or ask. Do not silently widen an anchor to cover a neighbour.
- Anything marked learned it gets a two-line refresher at the moment it is first needed, not up front.
- Anything marked new gets built up before the rung that depends on it, or, if it is too large to build, gets a stated black box: "you can take this as given; here is the one property of it that matters downstream."
If a prerequisite marked new is genuinely load-bearing for the whole field, say so at the start and propose covering it first, rather than teaching on top of a gap.
If the user ignores the checklist and just says "go ahead", do not re-ask. Assume learned it across the board, say in one line that you are assuming it, and start. Correct downward the first time an anchor fails to land.
Paper-first exception
If the user supplies a paper, abstract, paragraph, figure caption, or referee comment and mainly wants to understand that passage, use Decode mode below instead of forcing the intake. Derive the prerequisites from the passage itself and ask about depth only if the depth they want is ambiguous.
Keep state without burdening the user
For a multi-turn ladder, when Python and temporary file access are available, load references/state-runtime.md after Step 0 and use the bundled state helper invisibly. Never ask the user to run commands, manage JSON, or choose storage. If the helper is unavailable, continue with conversation state; this capability is optional and must degrade gracefully.
When the field is not settled
If the calibration check found the field emerging, contested, or beyond what you can reliably describe, load references/unsettled-fields.md before Rung 1 and follow it for the rest of the session. In short: attribute the central claims, flag vocabulary that is not yet standard, say how old your picture is, and when you cannot form a picture at all, hand over a search instead of teaching.
The ladder
Climb these in order. One rung per turn. Announce which rung you are on and what comes next.
Length and emphasis are both set by the reader's stated target, not by the rung. Load references/pacing.md before Rung 1 for the per-target word budgets and for how each target reshapes the climb.
Rung 1 — Why this field exists
The problem it was invented to solve, and what was inadequate before it. No formalism. If the user cannot state the motivating question in their own words, nothing above this rung will stick.
End with: what the field lets you do that you could not do otherwise.
Rung 2 — Vocabulary map
The 5–10 terms that unlock the literature. For each: plain-language meaning, the symbol or notation used, and, where one exists, the equivalent concept in the user's home field.
Format as a compact table. This is the rung the user will come back to most, so make it dense and scannable. It is a reference card, not a lecture.
Include the field's abbreviations and any term that means something different here than in the user's home field. Those false friends cause the most damage.
In an emerging field, mark which terms are not yet standard and name the competing usages.
Rung 3 — The core framework
The central model, equation, or conceptual structure. Derive or motivate it from something the user already accepts. Do not assert it.
Show one worked case: the simplest non-trivial system, all the way through, with the physical meaning of each step stated. One concrete example beats three abstract ones.
State the assumptions the framework rests on and when it fails.
Rung 4 — How people actually do it
Experimental techniques, computational methods, or datasets, whichever the field runs on. What a typical measurement or calculation looks like, what the raw output is, how that output becomes a scientific claim, what the standard artifacts and failure modes are, and what practitioners argue about methodologically.
If the user's target is doing the work rather than reading it, expand this rung and compress rung 5.
Rung 5 — Frontier and entry points
What is unresolved, which groups are pushing which direction, and a short reading path: one review to orient, one or two landmark papers, one recent paper. Say what each is for and in what order to read them.
This rung names specific works, so the rules in "Naming literature" are binding here. Verify the recent paper is actually recent, and check whether a landmark result has been contested or superseded since it was published.
Naming literature
Every specific paper, review, book, or package you name is either verified in this session with a checkable identifier, or explicitly labelled from memory, unverified. There is no third option, and an identifier you did not retrieve is never attached.
Load references/citations.md before producing a reading path or attributing a claim.
Closing artifact
When the ladder finishes, or whenever the user stops, produce one compact takeaway they can keep:
- the running glossary;
- the reading path, with each item's verification label intact;
- the two or three questions the field itself has not settled;
- which prerequisites they marked new and still have not covered;
- if they arrived with a target artifact, whether they can now read it, and what is still likely to block them in it.
Keep it short enough to paste into their own notes. This is the only part of the session that survives it.
Offer it, do not force it. If they are mid-ladder and leaving, give the glossary and the open prerequisites and skip the rest.
Checkpoints
End each rung with a real diagnostic, never "make sense?", which always gets a yes. Scope it to what you just taught: you must be able to point at the sentence containing the answer, and a reader who marked exactly these prerequisites must be able to answer it. A wrong answer should reveal a hole in your explanation, not in their background.
Load references/checkpoints.md for the question types, how to branch on the answer, and what to do when the user skips it.
Decode mode
When the user supplies an abstract, paragraph, figure caption, slide, or referee comment they cannot parse, do not run the ladder. Load references/decode-mode.md and follow it: gist, term-by-term, a reconstructed passage, what you would need in order to evaluate it, and the four labels that keep source claim, background, inference, and critique apart.
References
This file is the control plane. Load a reference when the moment for it arrives, not up front.
| File | Load it when |
|---|---|
references/pacing.md |
Before Rung 1, once the target is known |
references/unsettled-fields.md |
The field is emerging, contested, or beyond you |
references/citations.md |
You are about to name a specific work |
references/search-recipes.md |
You need to verify something, or to hand over a query |
references/checkpoints.md |
Before the first checkpoint |
references/decode-mode.md |
The user supplied text instead of a field |
references/explanation-styles.md |
Before Rung 1, once the explanation style is known |
references/state-runtime.md |
A multi-turn ladder can use local Python and temporary files |
references/anti-patterns.md |
Reviewing your own output |
references/examples.md |
An example would settle how a rule applies |
references/evals.md |
You are changing this skill, not using it |
Behavioral examples
For representative first responses, negative triggers, checkpoint branching, source-fidelity handling, reading-path labelling, and multilingual behavior, consult references/examples.md when an example would help resolve how to apply these rules. Treat the examples as patterns, not scripts.
Verifying and searching
When you have a search tool, use it: to check how settled a field is, to verify every named work, and to test your own picture against what was published recently. When you do not, hand the reader the query instead of a guess.
references/search-recipes.md has the query templates for both cases. They use open APIs that need no key, so a reader can run any of them in a browser.
Running glossary
Maintain a cumulative glossary across the session. When you introduce a term, add it. When the user asks "what was X again", answer from the glossary without making them feel bad for asking. Reprint the full glossary when asked, or when the session gets long.
Anti-patterns
The full list is in references/anti-patterns.md. The three that account for most failures: running the intake on a question one turn would have answered, asking a checkpoint question the rung never taught, and producing a reading list you have not checked.
Files (research-field-onboarding)
-
agents
-
openai.yaml 139 B
interface: display_name: "Field Onboarding" short_description: "Step-by-step onboarding into unfamiliar research fields and papers"
-
-
references
-
anti-patterns.md 2.8 KB
# Anti-patterns Read when reviewing your own output, or when unsure whether a habit is helping. Each line is a way this skill has failed or could fail. ## Anti-patterns - Running the intake on a question that one turn would have answered. This is the most common way to make the skill worse than no skill. - Skipping Step 0 and guessing at their level when calibration would have changed the answer. Guessing wrong in the hard direction wastes the whole session; guessing wrong in the easy direction is patronizing. - Asking "what's your background?" instead of naming the specific prerequisites. The user cannot audit a gap they cannot see. - Printing the prerequisite checklist as plain text in an interface that has an interactive control, so the user has to type back what they could have tapped. - Asking an open-ended “what explanation style do you prefer?” when three tappable or numbered choices would remove the burden. - Treating “simple” as “remove the equations and use a childish analogy”, or treating “professional” as permission to leave field-specific notation unexplained. - Dumping all five rungs in one response because the user seems smart. - Analogies that are pleasant but wrong. If the analogy breaks, say exactly where. An analogy the user over-trusts is worse than no analogy. - Skipping rung 1 because the motivation seems obvious. It is obvious to specialists, which is the whole problem. - Hedging everything into mush, or the reverse: presenting a contested question as settled. - Producing a reading list of plausible-sounding papers you have not checked, or attaching an identifier you did not retrieve. - Asking a checkpoint question that needs a relationship the rung never stated. The user then fails a test of your writing and reads it as a test of their competence. - Widening a marked anchor to cover an adjacent skill the user never claimed. - Giving a hands-on learner the full origin story of the field at length when they asked how to build the thing. - Teaching an unsettled field in the confident register of a settled one, so the reader cannot tell consensus from your reconstruction. - Attaching a citation to every textbook sentence. Each citation slot is a chance to fabricate, so citations belong where they carry weight: the reading path, and the contested claims of an unsettled field. - Taking a target artifact at the start and never returning to it. - Writing an equation without saying which convention it is in, so the user cannot match it against the paper in front of them. - Deferring to a textbook instead of explaining. Recommend reading *after* teaching, not instead of it. - Praising the question instead of answering it. - Adding claims that are not in a supplied paper while presenting them as if they came from it. -
checkpoints.md 1.8 KB
# Checkpoints Loaded before the first checkpoint of a session. ## Checkpoints **Scope the check to what you just taught.** The question must be answerable from the rung the user has just read, plus the anchors they explicitly marked. If answering requires a quantitative relationship, a scaling law, or a sub-skill you have not stated, it is not a diagnostic, it is a trap. Teach the scaling first, or ask a different question. A wrong answer should reveal a hole in your explanation, not a hole in their background. Two tests before you ask it. Can you point to the sentence in the rung that contains the answer? Would someone who marked exactly the prerequisites this user marked, and nothing more, be able to answer? If either is no, rewrite the question. At the end of each rung, do not just ask "make sense?" That always gets a yes. Instead pick one: - Ask them to predict something: "what happens to the signal if X doubles?" - Ask them to restate the core idea in their own words. - Give a two-question multiple-choice check on the rung just covered. Render it by actually calling a structured quiz or user-input tool when one is callable; otherwise accept a single letter or number. - Ask them to spot which of two statements is the field's actual claim. Then branch: - **Solid** -> advance to the next rung. - **Shaky** -> re-explain from a different angle, not louder. Change the analogy, drop a level of abstraction, or work a concrete number. - **Bored / already knew it** -> skip ahead. Ask which rung they want. If the user skips the check and just says "continue", do not re-ask. Advance, but fold the diagnostic into the opening of the next rung and lower your assumed level by one notch. The user can always say "skip to rung N" or "just give me the whole ladder". Honor that immediately. -
citations.md 1.5 KB
# Naming literature Loaded whenever you are about to name a specific work: Rung 5, any reading path, and every attributed claim in an unsettled field. Query templates for the verification itself are in `search-recipes.md`. ## Naming literature Rung 5 and any reading path is where fabrication happens. A plausible title with a plausible author list and a plausible year is the most damaging output this skill can produce, because the user will go looking for it and lose an afternoon. Every specific paper, review, book, or software package you name falls into exactly one of two buckets, and you must mark which: - **Verified.** You looked it up in this session and confirmed it exists. Give something checkable: DOI, arXiv ID, or journal, volume, and page. - **From memory, unverified.** You believe it exists but have not checked. Say exactly that, next to the item. Never give a bare citation with no bucket. If you have no search capability, say so once, mark everything unverified, and do not compensate by sounding more confident. Prefer fewer verified items to a longer unverified list. Three papers you have checked beat seven you have not. When you cannot verify a specific recent paper, name the search instead: the venue, the group, the arXiv listing, the exact query to run. A pointer the user can execute is worth more than a citation they cannot trust. Never attach a DOI or arXiv ID you did not retrieve. A fabricated identifier is worse than no identifier, because it looks checked. -
decode-mode.md 1.2 KB
# Decode mode Loaded when the user supplies text to be understood rather than a field to be entered. ## Decode mode When the user supplies an abstract, paragraph, figure caption, slide, or referee comment they cannot parse, do not run the ladder. Do this instead: 1. **One-sentence gist.** What it is actually saying, in plain language. 2. **Term-by-term.** Every piece of jargon in the passage, one line each, in the order it appears. 3. **Reconstructed passage.** The same content rewritten so the user can read it: same claims, no jargon, no loss of precision, nothing added. 4. **What you would need to know to evaluate it.** The one or two background pieces that separate reading the claim from judging it. 5. **Next step.** Offer the ladder only if they want to work in the area: "if you want to actually work in this area, I can walk you up from the motivation." For papers or excerpts, label explicitly: - **source claim** — what the authors actually state; - **background** — established context needed to understand it; - **inference** — a reasonable implication they did not state; - **critique** — your own assessment of limitations or evidential strength. -
evals.md 10.8 KB
# Evals A regression set for the skill itself. Run it after any change to `SKILL.md` or to a reference file. It is not part of using the skill. ## How to run Start a **fresh session** with the skill installed and no other context, one prompt per session. A prompt run in a session that already discussed the skill proves nothing, because the model has been primed. Read the response against the checks. Each check is pass or fail, not a judgement call. If a check needs interpretation, it is written badly: rewrite the check. Record results as a table in your PR. Five negatives and five positives is the minimum bar for merging a change to trigger scope or to a core rule. ``` | id | pass | note | |-----|------|---------------------------------------| | N1 | ✓ | | | N2 | ✗ | opened the intake on a 3-word question | ``` A failing check is not always a bug in the model. It is at least as often a rule that reads clearly to you and ambiguously to a cold reader. Fix the rule first. --- ## Negative cases: the skill must stay out of the way These exist because v1.0.0 had broad positive triggers and no negative ones, and over-fired on every one of them. ### N1 — narrow factual question > Quick question: in this field, what does MRO stand for? - **Passes if** the answer is direct and short. - **Fails if** a prerequisite checklist, a rung, or a calibration question appears before the answer. - An offer of the ladder is allowed, once, at the end, in one line. ### N2 — specialist inside their own field > I run RA-Raman on layered antiferromagnets. For a C2h crystal, which tensor > elements survive at oblique incidence? - **Passes if** it answers the technical question. - **Fails if** it offers to teach Raman spectroscopy, or asks what the user already knows about tensors. ### N3 — explicit request for brevity > One line only: what's the difference between SHG and SFG? - **Passes if** the answer is one or two lines. - **Fails if** the ladder, the intake, or a multi-paragraph explanation appears. ### N4 — not a comprehension task > Translate this abstract into Chinese, keep the terminology as is. - **Passes if** it translates. - **Fails if** it explains the field, decodes the abstract, or offers to. ### N5 — blocked mid-task > My Lorentzian fit keeps diverging on this Raman peak and I need it working > tonight. Here's the code. - **Passes if** it goes at the problem. - **Fails if** it offers an onboarding ladder into peak fitting. ### N6 — already declined Run N1, and when the ladder is offered, reply "no thanks, just the answer". Then ask a second question in the same field. - **Passes if** the ladder is not offered again. - **Fails if** it re-offers. ### N7 — one-turn answers do not start state machinery Run N1 in an environment where the bundled state helper is available. - **Passes if** it answers directly without creating onboarding state. - **Fails if** it initializes a session merely because the helper exists. ### N8 — Decode mode does not expose or require the runtime > Decode this abstract for me: [supply a short abstract]. - **Passes if** it enters Decode mode directly. - **Fails if** it asks the user to initialize state, run a command, or manage a file before receiving the explanation. ### N9 — one-turn answers do not open a style intake Run N1 in an interface with structured choice controls. - **Passes if** it answers directly without asking for an explanation style. - **Fails if** the existence of a choice tool causes an unnecessary style or prerequisite questionnaire. --- ## Positive cases: the skill must do its job ### P1 — bare field name, no request to be taught > I keep seeing "chiral phonons" in talks. - **Passes if** it names 3-5 prerequisites and asks the user to mark each. - **Fails if** it opens with a definition paragraph, or asks "what's your background?" instead of naming the prerequisites itself. - Also fails if it teaches Rung 1 in the same turn as the intake. ### P2 — the marks are actually used Answer P1's checklist with one prerequisite marked *used it* and one marked *new*. - **Passes if** the *used it* item is treated as an anchor and never explained, and the *new* item is either built up before the rung that needs it or declared a black box with the one property that matters. - **Fails if** it explains the anchor anyway, or teaches on top of the gap without acknowledging it. ### P3 — a prerequisite control is called when available Same as P1, in an environment exposing a callable structured user-input, checklist, or elicitation tool. - **Passes if** the agent actually calls the control for the prerequisite marks, using successive controls or a compact fallback only when the tool's question limit requires it. - **Fails if** every prerequisite is printed as a static table the user has to type back despite the tool being callable. - This one failed in live testing when the rule was phrased as a conditional clause, which is why it is here. ### P4 — the checkpoint is scoped to the rung Complete one rung and reach the checkpoint. - **Passes if** the answer to the checkpoint question appears in the rung just delivered. Point at the sentence. - **Fails if** answering needs a scaling law, a formula, or a sub-skill the rung never stated. - Also fails if the question assumes a narrower skill than the user marked, for example reading "used lasers" as "familiar with femtosecond pulses". ### P5 — the target reshapes the climb Run P1 twice, once with the target "read one paper", once with "build the apparatus". - **Passes if** the two sessions differ in more than length: notation and formalism weighted in the first, Rung 4 expanded into procedure in the second, Rung 1 visibly shorter in the second. - **Fails if** the two are the same content at different word counts. ### P6 — no unverified citation goes out unlabelled Reach Rung 5, or ask directly for a reading path. - **Passes if** every named work carries either a checkable identifier or the words "from memory, unverified". - **Fails if** any title, author list, or year appears with no label, or if a DOI or arXiv ID appears that was not retrieved in the session. - With no search tool available, passes if it says so once and labels everything unverified. ### P7 — unsettled fields are declared as such > Guide me into <a field with no textbook and heavy recent churn>. - **Passes if** it states, before Rung 1, that the field is emerging or contested, and afterwards attributes central claims, flags terminology that is not yet standard, and says how old its picture is. - **Fails if** it teaches a frontier area in the same confident register as a settled one. ### P8 — it refuses when it should > Guide me into <a real but very narrow, very recent area>, and do not search. - **Passes if** it says plainly that it cannot form a reliable picture and hands over a way to find a review, rather than teaching. - **Fails if** it produces a fluent five-rung account anyway. - This is the check most likely to fail, and the most important one. ### P9 — conventions are stated Reach a rung containing an equation or a sign-dependent quantity. - **Passes if** it says which convention it is using and names the competing one where the literature disagrees. - **Fails if** the equation appears bare. ### P10 — the target artifact closes the loop Open with "I want to read this paper" and a title or abstract. - **Passes if** it says at the start which rungs stand between the reader and that paper, and at the end whether they can now read it and what is still likely to block them. - **Fails if** the paper is collected and never mentioned again. ### P11 — state support is invisible Run P1 in an environment with Python, temporary file access, and the bundled state helper, then continue for at least two concepts. - **Passes if** state is maintained without asking the user to run commands, prepare JSON, choose a file path, or understand the implementation. - **Fails if** runtime mechanics appear in the lesson or become user homework. ### P12 — state support degrades gracefully Run P1 in an environment without Python or writable files. - **Passes if** the ordinary prompt workflow continues with no loss of the calibration, pacing, or checkpoint behavior. - **Fails if** onboarding stops or the user is asked to repair the environment. ### P13 — explanation style uses a real choice control when callable Run P1 in an environment with a structured user-input or elicitation tool. - **Passes if** the agent actually calls the tool and offers exactly the three explanation styles before Rung 1. - **Fails if** it prints a free-form question or static options despite the tool being callable. ### P14 — the default is intuitive without becoming shallow Run P1, do not choose a style, and reply “go ahead” after calibration. - **Passes if** Rung 1 or the first formal rung starts from a physical picture and later retains the relevant equation, assumptions, and limitations. - **Fails if** it opens with unexplained specialist notation, or removes the formal content and substitutes a childish analogy. ### P15 — level corrections change one axis After a technical explanation, reply: “Too professional; keep the equations, but give me the physical picture and do not talk down to me.” - **Passes if** the agent preserves the claim and equation, fills only the smallest missing prerequisite, and changes the explanation order or representation. - **Fails if** it restarts the whole ladder, deletes the mathematics, or merely repeats the same explanation with simpler adjectives. --- ## Multilingual spot check ### M1 > 一步一步带我入门拓扑光子学。 - **Passes if** the whole response, including the prerequisite checklist and the three marking labels, is in Chinese. - **Fails if** it replies in English, or mixes in English section headers. ### M2 > 这个缩写在这个领域是什么意思? - Negative case in Chinese. Same bar as N1. --- ## Known-weak checks Written down so the next person does not mistake them for solid. - **P5** depends on judging whether two responses "differ in more than length", which is the softest check here. If you can make it binary, do. - **P7 and P8** need a field you personally know is unsettled. Pick one from your own area rather than trusting the model's judgement about which fields are settled, since that judgement is exactly what is under test. - Nothing here tests session length. The skill claims one rung per turn, but a ten-turn session is expensive to run and nobody has done it yet. -
examples.md 11.4 KB
# Examples Use these examples as behavioral targets, not scripts to copy verbatim. Preserve the workflow while adapting terminology, depth, and language to the user's field. ## Example 1 — When not to run the ladder **User** > Quick question: in this field, what does "MRO" stand for? **Good response** Answer it. Do not calibrate, do not open the intake, do not climb. > MRO is *mean-field reorientation* in this context (some papers write it out as > molecular reorientation). It is the term used for the population-averaged > alignment change, as opposed to the single-molecule picture. > > If you want the fuller picture of how it fits the rest of the framework, I can > walk you up from the motivation. **Why this is good** - It passes the one-turn test, so the ladder never starts. - The offer is one line at the end, made once. If the user does not take it, it is dropped. - No prerequisite checklist in front of a two-word answer. **Also do not run the ladder when** - the user is a specialist asking a specific technical question inside their own field; - the user asked for it short ("quickly", "TL;DR", "简单说"); - the task is translation, proofreading, formatting, debugging, or a search with a known target; - the user is blocked mid-experiment and needs the fix; - the user already declined the ladder earlier in the session. ## Example 2 — Field-level onboarding from an adjacent specialty **User** > I work on nonlinear optics but know almost nothing about topological photonics. Can you guide me into the field step by step? **Good first response** Start with Step 0 rather than immediately teaching topology. Name a small set of load-bearing prerequisites and exploit the user's optics background as an anchor. > Before we start, I want to locate the shortest bridge from nonlinear optics to topological photonics. Please mark each item as **used it / learned it / new**: > > | Prerequisite | Why it matters | > | --- | --- | > | Bloch modes and band structures | Topological photonics usually describes photonic modes as bands over momentum space. | > | Berry phase / Berry curvature | These encode geometric properties of bands and lead to topological invariants. | > | Coupled-mode or tight-binding models | They provide compact models for lattices of coupled resonators or waveguides. | > | Symmetry and symmetry breaking | Time-reversal, inversion, and crystalline symmetries constrain possible topological phases. | > > Choose a teaching style — reply with the number if your interface does not > show buttons: > > 1. **Physical picture first (default):** intuition and geometry, followed by > equations with each term interpreted. > 2. **Balanced:** physical picture and formalism advance together. > 3. **Derivation first:** assumptions and mathematical steps first, then the > physical interpretation. > > Also tell me your target: **read papers**, **understand experiments**, **design a system**, or **enter the field broadly**. > > I will use your nonlinear-optics intuition wherever it genuinely transfers, but I will flag where the analogy stops working. **Why this is good** - It calibrates specific prerequisites instead of asking a vague background question. - It does not reteach optics the user already knows. - It establishes the user's target before choosing depth. - It separates explanation style from prior knowledge and provides a compact fallback when no choice control is callable. - It does not dump the five-rung ladder in the first turn. ## Example 3 — Decode a dense abstract **User** > I cannot understand this abstract about moire excitons. Please explain it to me. **Good response pattern** Do not force the full Step 0 intake. Enter Decode mode. > **Gist:** The authors are studying excitons whose motion and optical properties are modified by a long-period moire potential created when two atomically thin crystals are stacked with a small twist or lattice mismatch. > > **Terms in order** > - **Exciton:** a bound electron-hole pair that behaves as a composite quasiparticle. > - **Moiré superlattice:** a long-wavelength periodic pattern produced by two slightly mismatched lattices. > - **Localization:** confinement of an exciton's center-of-mass motion to particular regions of that moire potential. > > **Reconstructed passage:** [Rewrite the supplied abstract faithfully in simpler language, preserving its claims.] > > **What you need to evaluate the claim:** (1) how excitons form in the relevant material system and (2) how a moire potential modifies their energy landscape. > > **Source fidelity:** I will label statements that are background or my inference separately from claims explicitly made in the abstract. When the actual abstract is available, preserve its terminology and scientific scope. Do not insert mechanisms, causality, or conclusions that the authors did not state. ## Example 4 — Chinese request about chiral phonons **User** > 我是做实验光学的,想入门 chiral phonons。最好一步一步讲,我主要想知道怎么做实验验证。 **Good first response** Reply in Chinese and calibrate only prerequisites that matter for an experimental target. > 可以。你的目标是**实验验证 chiral phonons**,所以我会把路线偏向“物理图像 → 可观测量 → 实验方案”,而不是先从完整的群论形式体系开始。 > > 先请把下面几项标成 **用过 / 学过 / 基本没接触**: > > | 前置概念 | 为什么重要 | > | --- | --- | > | 晶格振动与声子本征矢 | chiral phonon 的“旋转”首先体现在原子位移的相位关系上。 | > | Brillouin zone 与 K/K' valley | 很多二维材料中的声子手性与非等价谷有关。 | > | 圆偏振光与角动量 | 实验选择定则通常需要讨论光与声子的角动量交换。 | > | Raman / IR selection rules | 决定哪些声子模式能通过具体光谱手段被看到。 | > > 讲解方式请选择:**1 物理图像优先(默认) / 2 图像与推导并重 / 3 严格推导优先**。无论哪种都会保留必要公式;如果界面没有按钮,回复数字即可。 > > 你的实验目标我先按“**判断一个材料是否存在可测的 chiral phonon signature,并设计光学验证方案**”理解。如果你实际更偏向 time-resolved pump-probe 或 Raman,可以告诉我,我会调整路线。 **Why this is good** - It follows the user's language. - It uses experimental optics as an anchor. - It adapts the ladder to the stated hands-on target by preparing to expand Rung 4. - It does not assume that valley physics automatically proves phonon chirality. ## Example 9 — Correct the level without swinging to the other extreme **User** > 还是太专业了,但别把公式删掉,也别用幼儿园比喻。 **Good response pattern** Keep the scientific target and central equation. Identify the smallest missing prerequisite, add one physical picture or limiting case, and interpret the terms before continuing the derivation. Do not restart from Rung 1, discard all formalism, or praise the user's intelligence. If the user instead says “太基础了”, compress already demonstrated steps and raise the abstraction, while retaining the physical meaning of the central equation. ## Example 5 — Checkpoint and branching After teaching a rung about Berry curvature, do not end with only "Does that make sense?" **Better checkpoint** > Quick check: suppose the Berry curvature is strongly concentrated near K and has the opposite sign near K'. If both valleys are equally populated, what would you expect for a valley-summed Hall-like response? > > A. The two valley contributions tend to cancel. > B. They necessarily add. > C. Berry curvature becomes zero at each valley. **Branching behavior** - If the user chooses **A** and explains the cancellation correctly, advance. - If the user chooses **C**, explain the difference between *local nonzero Berry curvature* and *cancellation after summing contributions* using a momentum-space picture. - If the user says this is trivial, skip ahead rather than adding more elementary questions. ## Example 6 — Respect an explicit request for a compact overview **User** > I know the basics already. Give me the whole roadmap in one response so I can decide what to study. **Good behavior** Honor the request instead of enforcing one rung per turn. Give a compact five-rung roadmap, identify likely prerequisites, and let the user choose where to zoom in. Keep the overview diagnostic rather than turning every rung into a full lecture. ## Example 7 — Distinguish source claim from inference **User** > The paper says the mode has circular atomic motion at K. Does that prove it is a chiral phonon and that circularly polarized Raman must detect it? **Good response pattern** > **Source claim:** The paper reports circular atomic motion for the mode at K. > > **Background:** Circular or elliptical atomic motion can be associated with phonon angular momentum, but terminology and definitions of phonon chirality depend on the symmetry and mode context. > > **Inference:** The reported eigenvector may support a chiral-phonon interpretation, but that conclusion requires checking the mode symmetry, degeneracy, valley relation, and the definition used by the authors. > > **Not established by that statement alone:** It does not automatically imply that conventional circularly polarized Raman can detect the mode. Raman visibility depends on momentum conservation, Raman tensors or higher-order processes, resonance conditions, and the experimental geometry. The exact technical content must be adjusted to the supplied source and verified when freshness or source-specific claims matter. ## Example 8 — Labelling a reading path At Rung 5 the skill names specific works, which is where fabrication happens. Every named item is either verified in this session or explicitly marked unverified. **Good behavior, with search available** > **Reading path** > > 1. *Orientation:* [review title], [journal, year] — DOI 10.xxxx/yyyyy. Verified. > Read sections 2 and 4 only; the rest is a survey you do not need yet. > 2. *Foundation:* [landmark paper], arXiv:XXXX.XXXXX. Verified. This is where > the central construction is introduced. > 3. *Frontier:* [recent paper], [year]. Verified, published within the last > 18 months. Note that its central claim is contested by [group]; read the > comment as well. **Good behavior, without search available** > I cannot verify references in this session, so treat every item below as > **from memory, unverified** and check before citing. > > - A review by [author group] in [journal], roughly [year]. From memory, > unverified. > - For the current frontier I would rather give you a search than a citation I > cannot check: look at the arXiv listing for [category] with the query > [query], and at the recent output of [group]. **Why this is good** - No bare citations. Every item carries its bucket. - No identifier is attached that was not actually retrieved. - Where verification is impossible, an executable pointer replaces the citation rather than padding the list. - Fewer verified items beat a longer unverified list. **Bad** > Here are five key papers: [five plausible titles with plausible authors, years, > and DOIs, none of them checked]. A fabricated DOI is worse than no DOI, because it looks checked. -
explanation-styles.md 3.1 KB
# Explanation styles Load before Rung 1. The selected mode controls the order and emphasis of an explanation, not how intelligent the reader is. Names such as “Feynman/Griffiths-like” or “Landau-like” are shorthand for these priorities; do not imitate an author's voice. ## Default register Unless the user's answers show otherwise, address a **capable researcher who is new to this field**: - explain field-specific vocabulary, notation, and tacit assumptions; - keep the mechanism, relevant scales, boundary conditions, and equations; - do not reteach general algebra, calculus, or scientific reasoning unless a calibrated prerequisite requires it; - use plain language without baby talk, fake cheerleading, or toy analogies that replace the science. Plain language changes the representation, not the intellectual content. ## 1. Physical picture first — default Use this order: 1. Name the observable phenomenon or concrete system. 2. Build a spatial, dynamical, geometric, or energetic picture of what changes. 3. State a prediction or limiting case the picture gets right. 4. Introduce the equation as a compact statement of that picture. 5. Interpret every symbol and mathematical step physically. 6. State the assumptions and the point where the picture fails. Prefer causal mechanisms, diagrams in words, scale comparisons, symmetry, conservation laws, and limiting cases. Include derivations when they carry understanding; do not present formulas as decoration or omit them in the name of accessibility. ## 2. Balanced Move between picture and formalism in short loops: 1. State one physical claim. 2. Write the mathematical object that represents it. 3. Explain what the equation adds or constrains. 4. Test both on the same worked example. Do not leave a long block of analogy waiting for its equation, or a long derivation waiting for its meaning. ## 3. Derivation first Use this order: 1. Define objects, conventions, assumptions, and the target result. 2. Derive the result without skipping load-bearing steps. 3. Mark approximations at the line where they enter. 4. Interpret the result physically and test a limiting case. 5. Give one concrete worked example. “Derivation first” does not license unexplained notation or a proof dump. Keep the logical dependencies visible and say why each step is allowed. ## Correcting a mismatch Treat style and prerequisite depth as independent controls. - If the user says **too technical**, keep the scientific claim and equations, fill the smallest missing prerequisite, and change representation: add a physical picture, limiting case, or worked number. - If the user says **too basic**, raise the abstraction and compression, skip already demonstrated prerequisites, and retain one physical interpretation for each central equation. - If an analogy fails to land, replace it with a different representation; do not repeat it more loudly. - If the user requests a mode change, switch immediately and keep the same target and knowledge state. At a checkpoint, diagnose which axis failed: missing prerequisite, explanation order, notation, or pace. Change only the failed axis rather than resetting the whole lesson. -
pacing.md 1.9 KB
# Pacing and routing Loaded once per session, before Rung 1, after the target is known. ## Length Length is set by the target, not by the rung. The ceilings below are defaults for someone who wants to read a paper; shift them as the target demands. | Target | Rung 1 | Rungs 2, 5 | Rungs 3, 4 | | --- | --- | --- | --- | | Read one paper | 150-250 | 300-500 | 400-700 | | Judge whether a method fits | 200-300 | 200-400 | 500-700, weighted to 4 | | Do it hands-on | 100-200 | 200-300 | 500-700, weighted to 4 | | Follow a talk | 100-200 | 300-400 | 200-400 | Someone who wants to build the apparatus does not need the field's origin story at length. Give them the one sentence that explains why the method exists, then spend the session on Rungs 3 and 4. Compressing Rung 1 is not skipping it. Do not compress a derivation into a summary to hit a number. If a rung genuinely needs two turns, take two turns and say so at the break. ### Route on the target The target you collected in Step 0 sets the shape of every rung, not just which one gets expanded. Use it: - **Read one paper** -> weight notation and formalism. Keep Rung 2 dense and symbol-heavy; the goal is to make the page parseable. - **Judge whether a method fits their work** -> lead with phenomena and worked numbers. Treat derivations as black boxes with stated properties, expand Rung 4 into what the method can and cannot deliver, and say plainly where it is a poor fit. This target is a decision, so give them what a decision needs. - **Do it hands-on** -> Rung 4 becomes a procedure: apparatus or pipeline, typical parameters, what breaks first. Compress Rung 5 to tooling and communities. - **Follow a talk** -> compress everything. Rung 2 and Rung 5 matter most; Rung 3 can stay at the level of what the central object means. If the user gave no target, ask once, in the same turn as the prerequisites. -
search-recipes.md 3.2 KB
# Search recipes Use these when you need to verify a reference, check how settled a field is, or hand the reader a way to find ground truth you could not give them. Two rules govern everything here. If you can search, search, and label what you found as verified. If you cannot, give the reader the query itself rather than a citation you have not checked. A query they can run is worth more than a citation they cannot trust. ## Is there a review? This is the first question in an unfamiliar field, and the answer decides whether you are teaching consensus or reconstructing it. - OpenAlex, reviews only, most cited first: `https://api.openalex.org/works?filter=title_and_abstract.search:<TOPIC>,type:review&sort=cited_by_count:desc&per-page=10` - Plain search, for a human rather than an API: `<TOPIC> review` or `<TOPIC> tutorial` on Google Scholar, sorted by citations - Annual Reviews, Reviews of Modern Physics, Chemical Reviews, and Physics Reports are worth checking by name in the physical sciences; a hit there usually means the field is settled enough to have a canonical account If nothing comes back, that is itself the finding: say the field has no review yet and switch to the unsettled-field mode in `SKILL.md`. ## How current is my picture? - Recent work only: `https://api.openalex.org/works?filter=title_and_abstract.search:<TOPIC>,from_publication_date:<YYYY-MM-DD>&sort=publication_date:desc` - arXiv, newest first: `https://arxiv.org/list/<ARCHIVE>/recent`, or `https://export.arxiv.org/api/query?search_query=all:<TOPIC>&sortBy=submittedDate&sortOrder=descending&max_results=20` Compare what comes back against the account you were about to give. If the recent work uses vocabulary you did not plan to teach, your picture is stale and you should say so. ## Does this specific paper exist? Never assert a title, author list, or year you have not checked, and never attach a DOI or arXiv ID you did not retrieve. - By DOI: `https://api.crossref.org/works/<DOI>` - By title: `https://api.openalex.org/works?filter=title.search:<EXACT TITLE>` - By arXiv ID: `https://export.arxiv.org/api/query?id_list=<ID>` A miss means one of two things, and you should say which you believe: the work does not exist, or it exists outside the index. Do not quietly keep the citation either way. ## Who is working on this now? Useful when there is no review and Rung 5 has to be built from groups rather than from a canonical account. - Most cited recent work in the area: `https://api.openalex.org/works?filter=title_and_abstract.search:<TOPIC>,from_publication_date:<YYYY>-01-01&sort=cited_by_count:desc` - Then read off the recurring last authors and affiliations rather than guessing at them ## Handing the query to the reader When you cannot search, write the query out in a form they can paste, and say what to do with the result. For example: run the review query above; if it returns something from the last five years with a few hundred citations, read its introduction and section headings, and that will give you the prerequisite list this session could not. OpenAlex, Crossref, and the arXiv API are all open and need no key, so a reader can run any of these in a browser. -
state-runtime.md 2.8 KB
# Optional state runtime Use the bundled `scripts/knowledge_state.py` only as an invisible implementation detail. Never ask the user to run commands, prepare event JSON, choose storage paths, or understand the state schema. ## Capability gate Use the helper when all of these are true: - the environment can run Python 3.10+ and write a temporary file; - the request has entered the multi-turn ladder rather than Decode mode or a one-turn answer; - keeping explicit state would help across several concepts or rungs. Otherwise keep state in the conversation and continue normally. Do not mention the missing helper unless it prevents something the user explicitly requested. ## Storage boundary Create the state file in a temporary or task-local working directory, never in the installed skill directory. Treat it as session data. Do not persist it across sessions, copy it elsewhere, or commit it unless the user explicitly asks to save their learning record. ## Agent workflow After Step 0: 1. Initialize a session with the target, target artifact, language, selected explanation style, and technical register. 2. Set the field status. 3. Add the 3-5 calibrated prerequisites in dependency order. Use stable, lowercase concept IDs. Add later concepts only when they become relevant; do not attempt to build a universal ontology. 4. Ask the helper for `next`, choose one ready concept, and activate it. 5. Teach and checkpoint as required by the main skill. 6. Judge the scientific answer yourself, then record `pass`, `partial`, or `fail`. Code routes the result; it does not judge scientific correctness. 7. Ask for `next` again. At the end, read `summary` to prepare the closing artifact. Invoke the helper with the environment's Python executable: ```text python <skill-root>/scripts/knowledge_state.py <command> <state-file> ... ``` Available commands are `init`, `validate`, `add`, `set-field-status`, `set-preferences`, `next`, `activate`, `checkpoint`, and `summary`. Run `--help` for exact arguments. Use `--operation-id` with a stable value when retrying a mutating command. The same operation ID is applied at most once. ## State semantics Keep these dimensions distinct: - `preferences`: explanation style and technical register selected at intake; - `self_report`: `used`, `learned`, or `new` from calibration; - `evidence`: `untested`, `pass`, `partial`, or `fail` from checkpoints; - `progress`: `queued`, `active`, or `covered` for workflow routing. An item marked `used` starts covered for routing but remains untested. A later partial or failed checkpoint overrides that shortcut and blocks dependents. Keep the runtime invisible in the response. The user should experience only a well-paced lesson that remembers what happened. -
unsettled-fields.md 2.4 KB
# Fields that are not settled Loaded when the calibration check in `SKILL.md` finds the field is emerging, contested, or beyond what you can reliably describe. ## When the field is not settled In an emerging or contested field there is no consensus to teach from, so the usual standard, be correct, is not available. Use these instead. - **Say it up front.** One line: no textbook exists, the vocabulary is not standardized, this is what the last few years of papers look like. - **Ground the substantive claims.** In a settled field, citing a source for a textbook fact is noise. Here it is the only thing separating teaching from invention. Attribute the central claims of Rungs 3 to 5 to specific work, under the same verified / unverified labels as everywhere else, and mark anything that is your own synthesis as your synthesis. - **Flag unstable vocabulary.** Different groups routinely name the same object differently before a field settles. Say when a term has competitors, and which paper uses which. A reader who learns one group's word and then reads another group's paper will think they have found a new concept. - **Invert Rung 5.** There is no review to orient with. Give the two or three groups pushing the area, what each is claiming, and where they disagree. - **State your horizon.** Your picture of a fast-moving field ages badly. Say when it is from, and say plainly that the last year may be missing. Treat prerequisites the same way: in an emerging field your prerequisite list is inferred from adjacent settled fields, not read off a curriculum. Present it as provisional and say so. ## When you cannot onboard them Sometimes the honest answer is that you cannot do this reliably. That is the case when the field is too new or too narrow for you to have a real picture and you have no way to search. Do not fill the gap with plausible-sounding structure. Say what you can and cannot do, then hand over a way to find the ground truth themselves: - the search that would surface a review, written out so they can run it; - the two or three venues or groups the work would appear in, if you know them; - what to read the review for, which is the prerequisite list you could not give them. See [references/search-recipes.md](references/search-recipes.md) for query templates. Sending someone to a real review beats onboarding them into a field you have reconstructed.
-
-
scripts
-
knowledge_state.py 17.3 KB
#!/usr/bin/env python3 """Optional, dependency-free session state for the Field Onboarding skill. This is an agent-facing helper. End users should never need to invoke it or edit its JSON files themselves. """ from __future__ import annotations import argparse import copy import json import os import tempfile import uuid from datetime import datetime, timezone from pathlib import Path from typing import Any VERSION = "0.2.0" SELF_REPORTS = {"used", "learned", "new"} EVIDENCE = {"untested", "pass", "partial", "fail"} PROGRESS = {"queued", "active", "covered"} FIELD_STATUS = {"unknown", "settled", "emerging", "contested"} EXPLANATION_STYLES = {"physical-picture", "balanced", "derivation-first"} TECHNICAL_REGISTERS = {"foundational", "peer-new-to-field", "specialist-bridge"} class StateError(ValueError): pass def initial_state( session_id: str, field: str, goal: str, artifact: str | None = None, language: str | None = None, explanation_style: str = "physical-picture", technical_register: str = "peer-new-to-field", ) -> dict[str, Any]: state = { "version": VERSION, "session_id": required_text(session_id, "session_id"), "target": { "field": required_text(field, "field"), "goal": required_text(goal, "goal"), "artifact": artifact, }, "language": language, "preferences": { "explanation_style": explanation_style, "technical_register": technical_register, }, "field_status": "unknown", "concepts": {}, "current_concept": None, "events": [], } validate(state) return state def load(path: Path) -> dict[str, Any]: with path.open("r", encoding="utf-8") as handle: state = json.load(handle) validate(state) return state def save(state: dict[str, Any], path: Path) -> None: validate(state) path.parent.mkdir(parents=True, exist_ok=True) descriptor, temporary = tempfile.mkstemp( prefix=f".{path.name}.", suffix=".tmp", dir=path.parent ) try: with os.fdopen(descriptor, "w", encoding="utf-8") as handle: json.dump(state, handle, ensure_ascii=False, indent=2) handle.write("\n") os.replace(temporary, path) except BaseException: try: os.unlink(temporary) except FileNotFoundError: pass raise def validate(state: dict[str, Any]) -> None: if not isinstance(state, dict): raise StateError("state must be an object") if state.get("version") != VERSION: raise StateError(f"unsupported state version: {state.get('version')}") required_text(state.get("session_id"), "session_id") target = state.get("target") if not isinstance(target, dict): raise StateError("target must be an object") required_text(target.get("field"), "target.field") required_text(target.get("goal"), "target.goal") if target.get("artifact") is not None and not isinstance(target["artifact"], str): raise StateError("target.artifact must be a string or null") preferences = state.get("preferences") if not isinstance(preferences, dict): raise StateError("preferences must be an object") if preferences.get("explanation_style") not in EXPLANATION_STYLES: raise StateError( f"invalid explanation style: {preferences.get('explanation_style')}" ) if preferences.get("technical_register") not in TECHNICAL_REGISTERS: raise StateError( f"invalid technical register: {preferences.get('technical_register')}" ) if state.get("field_status") not in FIELD_STATUS: raise StateError(f"invalid field status: {state.get('field_status')}") concepts = state.get("concepts") if not isinstance(concepts, dict): raise StateError("concepts must be an object") for concept_id, concept in concepts.items(): required_text(concept_id, "concept_id") if not isinstance(concept, dict): raise StateError(f"concept {concept_id!r} must be an object") required_text(concept.get("label"), f"{concept_id}.label") if concept.get("self_report") not in SELF_REPORTS: raise StateError(f"invalid self_report for {concept_id!r}") if concept.get("evidence") not in EVIDENCE: raise StateError(f"invalid evidence for {concept_id!r}") if concept.get("progress") not in PROGRESS: raise StateError(f"invalid progress for {concept_id!r}") prerequisites = concept.get("prerequisites") if not isinstance(prerequisites, list) or not all( isinstance(item, str) and item for item in prerequisites ): raise StateError(f"invalid prerequisites for {concept_id!r}") if len(prerequisites) != len(set(prerequisites)): raise StateError(f"duplicate prerequisite for {concept_id!r}") for prerequisite in prerequisites: if prerequisite not in concepts: raise StateError( f"{concept_id!r} references missing prerequisite {prerequisite!r}" ) misconceptions = concept.get("misconceptions") if not isinstance(misconceptions, list) or not all( isinstance(item, str) and item for item in misconceptions ): raise StateError(f"invalid misconceptions for {concept_id!r}") reject_cycles(concepts) current = state.get("current_concept") if current is not None and current not in concepts: raise StateError(f"unknown current concept: {current}") active = [key for key, value in concepts.items() if value["progress"] == "active"] if len(active) > 1 or active != ([] if current is None else [current]): raise StateError("current_concept must match the only active concept") if not isinstance(state.get("events"), list): raise StateError("events must be an array") def add_concept( state: dict[str, Any], concept_id: str, label: str, self_report: str, prerequisites: list[str], ) -> None: concept_id = required_text(concept_id, "concept_id") if self_report not in SELF_REPORTS: raise StateError(f"invalid self_report: {self_report}") if concept_id in prerequisites: raise StateError("a concept cannot depend on itself") missing = [item for item in prerequisites if item not in state["concepts"]] if missing: raise StateError(f"missing prerequisites: {', '.join(missing)}") candidate = copy.deepcopy(state) existing = candidate["concepts"].get(concept_id) if existing: existing.update( label=required_text(label, "label"), self_report=self_report, prerequisites=list(dict.fromkeys(prerequisites)), ) else: candidate["concepts"][concept_id] = { "label": required_text(label, "label"), "self_report": self_report, "evidence": "untested", "progress": "covered" if self_report == "used" else "queued", "prerequisites": list(dict.fromkeys(prerequisites)), "misconceptions": [], } validate(candidate) state.clear() state.update(candidate) def set_preferences( state: dict[str, Any], explanation_style: str | None = None, technical_register: str | None = None, ) -> None: if explanation_style is None and technical_register is None: raise StateError("at least one preference must be supplied") candidate = copy.deepcopy(state) if explanation_style is not None: if explanation_style not in EXPLANATION_STYLES: raise StateError(f"invalid explanation style: {explanation_style}") candidate["preferences"]["explanation_style"] = explanation_style if technical_register is not None: if technical_register not in TECHNICAL_REGISTERS: raise StateError(f"invalid technical register: {technical_register}") candidate["preferences"]["technical_register"] = technical_register validate(candidate) state.clear() state.update(candidate) def ready_concepts(state: dict[str, Any]) -> list[str]: validate(state) return sorted( concept_id for concept_id, concept in state["concepts"].items() if concept["progress"] == "queued" and all(satisfied(state["concepts"][item]) for item in concept["prerequisites"]) ) def activate(state: dict[str, Any], concept_id: str) -> None: if concept_id not in state["concepts"]: raise StateError(f"unknown concept: {concept_id}") blocked = [ item for item in state["concepts"][concept_id]["prerequisites"] if not satisfied(state["concepts"][item]) ] if blocked: raise StateError(f"concept is blocked by: {', '.join(blocked)}") for concept in state["concepts"].values(): if concept["progress"] == "active": concept["progress"] = "queued" state["concepts"][concept_id]["progress"] = "active" state["current_concept"] = concept_id validate(state) def record_checkpoint( state: dict[str, Any], concept_id: str, result: str, misconceptions: list[str] ) -> None: if concept_id not in state["concepts"]: raise StateError(f"unknown concept: {concept_id}") if result not in {"pass", "partial", "fail"}: raise StateError(f"invalid checkpoint result: {result}") concept = state["concepts"][concept_id] concept["evidence"] = result concept["misconceptions"] = list(dict.fromkeys(misconceptions)) concept["progress"] = "covered" if result == "pass" else "active" if result == "pass": if state["current_concept"] == concept_id: state["current_concept"] = None else: for key, item in state["concepts"].items(): if key != concept_id and item["progress"] == "active": item["progress"] = "queued" state["current_concept"] = concept_id validate(state) def satisfied(concept: dict[str, Any]) -> bool: if concept["evidence"] == "pass": return True if concept["evidence"] in {"partial", "fail"}: return False return concept["self_report"] == "used" or concept["progress"] == "covered" def reject_cycles(concepts: dict[str, dict[str, Any]]) -> None: visiting: set[str] = set() visited: set[str] = set() def visit(concept_id: str) -> None: if concept_id in visiting: raise StateError(f"dependency cycle includes {concept_id!r}") if concept_id in visited: return visiting.add(concept_id) for prerequisite in concepts[concept_id]["prerequisites"]: visit(prerequisite) visiting.remove(concept_id) visited.add(concept_id) for concept_id in concepts: visit(concept_id) def record_event( state: dict[str, Any], event_type: str, payload: dict[str, Any], operation_id: str | None ) -> bool: event_id = operation_id or str(uuid.uuid4()) if any(event.get("id") == event_id for event in state["events"]): return False state["events"].append( { "id": event_id, "type": event_type, "at": datetime.now(timezone.utc).isoformat(), "payload": payload, } ) return True def required_text(value: Any, name: str) -> str: if not isinstance(value, str) or not value.strip(): raise StateError(f"{name} must be a non-empty string") return value.strip() def parser() -> argparse.ArgumentParser: root = argparse.ArgumentParser(description=__doc__) commands = root.add_subparsers(dest="command", required=True) init = commands.add_parser("init") init.add_argument("state", type=Path) init.add_argument("--session-id", required=True) init.add_argument("--field", required=True) init.add_argument("--goal", required=True) init.add_argument("--artifact") init.add_argument("--language") init.add_argument( "--style", choices=sorted(EXPLANATION_STYLES), default="physical-picture" ) init.add_argument( "--register", choices=sorted(TECHNICAL_REGISTERS), default="peer-new-to-field", ) init.add_argument("--force", action="store_true") validate_command = commands.add_parser("validate") validate_command.add_argument("state", type=Path) add = commands.add_parser("add") add.add_argument("state", type=Path) add.add_argument("--id", required=True) add.add_argument("--label", required=True) add.add_argument("--self-report", choices=sorted(SELF_REPORTS), required=True) add.add_argument("--requires", action="append", default=[]) add.add_argument("--operation-id") field_status = commands.add_parser("set-field-status") field_status.add_argument("state", type=Path) field_status.add_argument("--status", choices=sorted(FIELD_STATUS), required=True) field_status.add_argument("--operation-id") preferences = commands.add_parser("set-preferences") preferences.add_argument("state", type=Path) preferences.add_argument("--style", choices=sorted(EXPLANATION_STYLES)) preferences.add_argument("--register", choices=sorted(TECHNICAL_REGISTERS)) preferences.add_argument("--operation-id") next_command = commands.add_parser("next") next_command.add_argument("state", type=Path) activate_command = commands.add_parser("activate") activate_command.add_argument("state", type=Path) activate_command.add_argument("--id", required=True) activate_command.add_argument("--operation-id") checkpoint = commands.add_parser("checkpoint") checkpoint.add_argument("state", type=Path) checkpoint.add_argument("--id", required=True) checkpoint.add_argument("--result", choices=["pass", "partial", "fail"], required=True) checkpoint.add_argument("--misconception", action="append", default=[]) checkpoint.add_argument("--operation-id") summary = commands.add_parser("summary") summary.add_argument("state", type=Path) return root def main() -> int: args = parser().parse_args() if args.command == "init": if args.state.exists() and not args.force: raise StateError(f"state already exists: {args.state}") state = initial_state( args.session_id, args.field, args.goal, args.artifact, args.language, args.style, args.register, ) save(state, args.state) print(json.dumps({"state": str(args.state), "status": "initialized"})) return 0 state = load(args.state) if args.command == "validate": print(json.dumps({"status": "valid", "version": state["version"]})) elif args.command == "next": print(json.dumps({"ready": ready_concepts(state)}, ensure_ascii=False)) elif args.command == "summary": print( json.dumps( { "target": state["target"], "preferences": state["preferences"], "field_status": state["field_status"], "current_concept": state["current_concept"], "ready": ready_concepts(state), "concepts": state["concepts"], }, ensure_ascii=False, ) ) else: operation_id = args.operation_id if operation_id and any( event.get("id") == operation_id for event in state["events"] ): print(json.dumps({"status": "already-applied", "operation_id": operation_id})) return 0 if args.command == "add": add_concept(state, args.id, args.label, args.self_report, args.requires) event_type = "concept.upserted" payload = {"concept_id": args.id} elif args.command == "set-field-status": state["field_status"] = args.status event_type = "field_status.set" payload = {"status": args.status} elif args.command == "set-preferences": set_preferences(state, args.style, args.register) event_type = "preferences.set" payload = { key: value for key, value in { "explanation_style": args.style, "technical_register": args.register, }.items() if value is not None } elif args.command == "activate": activate(state, args.id) event_type = "concept.activated" payload = {"concept_id": args.id} elif args.command == "checkpoint": record_checkpoint(state, args.id, args.result, args.misconception) event_type = "checkpoint.recorded" payload = {"concept_id": args.id, "result": args.result} record_event(state, event_type, payload, operation_id) save(state, args.state) print(json.dumps({"status": "applied", "operation": event_type})) return 0 if __name__ == "__main__": try: raise SystemExit(main()) except StateError as error: raise SystemExit(f"state error: {error}") from error
-
-
SKILL.md 18.1 KB
--- name: field-onboarding description: Guide a researcher step by step into an unfamiliar research field, or decode a paper, abstract, figure caption, or referee comment they cannot parse. Builds understanding in rungs (motivation, vocabulary, core framework, methods, frontier), anchored to what the user already knows, with a checkpoint before each advance. Use when the user says they are new to a field, asks what a research area or method is, says an explanation was too technical, asks to be walked through something step by step, asks for a reading path, or supplies dense research text. Trigger even when the user only names an unfamiliar field or pastes an abstract without asking to be taught. Also trigger in other languages, including Chinese such as 入门, 一步一步讲, 看不懂, 这篇论文讲什么, 帮我理解这个领域. Do not use for narrow factual questions, for a specialist asking inside their own field, when the user asked for a short answer, or when the task is translation, editing, search, or debugging. --- # Field Onboarding Get someone productively oriented in an unfamiliar research field, fast, without losing them. The failure this skill exists to prevent: answering a beginner's question at the level of a specialist, so the answer is technically correct and completely useless. ## When not to use this skill This is a teaching mode, not a default. Running the full ladder on someone who wanted one sentence is its own failure, and a more irritating one than pitching too high. Do not run Step 0 or the ladder when: - **The question is narrow and factual.** "What does PL stand for?" "What wavelength do people usually pump at?" Answer it. Do not calibrate. - **The user is already a specialist in this exact area** and is asking a specific technical question inside it. - **The user asked for it short.** "quickly", "one line", "just tell me", "TL;DR", "简单说", "赶时间". - **The task is not understanding.** Translation, proofreading, formatting, debugging, writing, or a literature search with a known target. - **The user is mid-task and blocked.** Someone whose fit is failing at 2am needs the fix, not motivation and vocabulary. - **The user already declined the ladder this session.** Offer once. Never twice. **The one-turn test.** Before starting Step 0, ask whether the question can be answered well in a single turn. If it can, answer it, then offer the ladder in one line: "that is the short answer; if you want to actually work in this area, I can walk you up from the motivation." Offer once, drop it if unclaimed. When in doubt, answer first and offer second. A good answer followed by an offer costs the user nothing. An intake questionnaire in front of a one-line question costs them a turn and their patience. ## Core rules 1. **One rung per turn.** Never deliver the whole ladder at once. Stop, check, advance. If the user asks for the whole ladder, a compact overview, or a specific rung, honor that immediately. 2. **No unexplained jargon.** Every term gets defined on first use, in one clause, inline. If a sentence needs three undefined terms, it is the wrong sentence. 3. **Anchor to what they know.** Explain the new field in terms of the user's existing expertise. Map new concept onto familiar concept, then immediately say where the mapping breaks. 4. **Plain is not shallow.** Default to a capable researcher who is new to this field. Define field-specific language, but preserve the real mechanism, assumptions, scales, and equations. Never turn “simple” into childish or remove the formal content that makes the explanation true. 5. **Be explicit about confidence.** Mark what is settled, what is contested, and what you are unsure of. Do not flatten real disagreement in the literature, and do not dress a strong consensus up as an open question. "Some argue X, others Y" with no indication of where the weight of evidence sits is not balance, it is abdication. 6. **Search before teaching.** If the field is fast-moving, or the user names a specific paper, method, material, dataset, or software package, search first. Do not teach a five-year-old snapshot as current. 7. **State your conventions.** Where a field uses competing sign, phase, unit, or normalization conventions, say which one you are using and name the alternative the literature also uses. A reader who cannot map your equation onto the paper's equation has not been onboarded. This costs one clause and prevents the single most common silent failure in physical-science reading. 8. **Never invent a reference.** Every named work is either verified in this session or explicitly marked unverified. See "Naming literature". 9. **Match the user's language.** Reply in whatever language they wrote in. 10. **Preserve the source when decoding.** Keep what the source claims separate from background, inference, and your own critique. ## Step 0 — Locate them (one short turn) Do not start teaching until this is done. Answering before you know what they already have is the failure this skill exists to prevent. **First, name the prerequisites yourself.** Work out which 3–5 upstream frameworks the topic actually rests on, and list them explicitly. Do not ask a vague "what's your background" — the user cannot answer that usefully, and it puts the work of scoping on the person who by definition does not know the scope yet. Then ask them to mark each one: - **used it** — has applied it in their own work - **learned it** — saw it in a course, could follow a derivation, has not used it - **new** — no real contact Present this as a short checklist, one line per prerequisite, with a one-clause gloss so they can tell what each item means. **Use a real choice control when one is callable.** Inspect the tools or interaction mechanisms actually available in the current environment. If a structured user-input, checklist, quiz, or elicitation tool is callable, call it for these choices; do not merely print options and say a control would be nice. Use successive controls when one control cannot hold every prerequisite. Do not infer that a control is callable just because the app is graphical. If no such mechanism is available, use a numbered compact fallback and accept an answer such as `1 used, 2 learned, 3 new`; never require a prose background essay. **Second, choose the explanation style.** Keep this separate from the user's knowledge level. Offer exactly three choices, using the same structured control when available: 1. **Physical picture first (default)** — intuition, geometry, limiting cases, and concrete phenomena first; then equations with every term interpreted. 2. **Balanced** — intuition and formalism advance together. 3. **Derivation first** — definitions, assumptions, and mathematical steps first; physical interpretation after the derivation. These are teaching priorities, not intelligence levels. If the user does not choose, use option 1. If they already stated a preference, preserve it and do not ask again. Load [references/explanation-styles.md](references/explanation-styles.md) before Rung 1 and follow the selected mode. The user may switch modes at any time. **Third, check how settled the field is.** Do this before you teach, because it decides which mode you are in. Search if you can. If you cannot search, say so and reason from what you have, out loud. - **Settled.** Textbooks and review articles exist, the vocabulary is standard, the core framework is not in dispute. Teach normally. - **Emerging or contested.** No textbook, terminology still shifting, or the central claims are actively argued over. Switch to grounded mode below. - **You do not actually know.** You recognize the words but cannot say what the field currently contains. Say that plainly and do not teach. See "When you cannot onboard them" below. Say which of the three you are in, in one line, before Rung 1. The reader is entitled to know whether they are getting consensus or your reconstruction. Also establish, in the same turn: - **Target**: read one paper / follow a talk / start an experiment / judge whether a method fits their own work / pass an exam. This sets the depth. - **Target artifact**, when they name one. If they arrived with a specific paper, abstract, talk, or apparatus, keep it. Say at the start which rungs stand between them and it, point out along the way when a rung has just unlocked part of it, and return to it at the end. A reader who came in saying "I want to read X" should finish being told whether they can now read X. That is the whole intake. One turn, then start teaching. **Then use the answers.** They are not decoration: - Anything marked *used it* becomes an anchor. Explain new material by mapping onto it, and skip its own explanation entirely. It licenses **only what was listed**, at the breadth you listed it. "Lasers in practice" does not mean femtosecond pulses, mode-locking, or dispersion management; "programming" does not mean their specific framework. When a rung needs a narrower sub-skill inside a marked anchor, name that sub-skill and give it one line, or ask. Do not silently widen an anchor to cover a neighbour. - Anything marked *learned it* gets a two-line refresher at the moment it is first needed, not up front. - Anything marked *new* gets built up before the rung that depends on it, or, if it is too large to build, gets a stated black box: "you can take this as given; here is the one property of it that matters downstream." If a prerequisite marked *new* is genuinely load-bearing for the whole field, say so at the start and propose covering it first, rather than teaching on top of a gap. **If the user ignores the checklist** and just says "go ahead", do not re-ask. Assume *learned it* across the board, say in one line that you are assuming it, and start. Correct downward the first time an anchor fails to land. ### Paper-first exception If the user supplies a paper, abstract, paragraph, figure caption, or referee comment and mainly wants to understand that passage, use **Decode mode** below instead of forcing the intake. Derive the prerequisites from the passage itself and ask about depth only if the depth they want is ambiguous. ### Keep state without burdening the user For a multi-turn ladder, when Python and temporary file access are available, load [references/state-runtime.md](references/state-runtime.md) after Step 0 and use the bundled state helper invisibly. Never ask the user to run commands, manage JSON, or choose storage. If the helper is unavailable, continue with conversation state; this capability is optional and must degrade gracefully. ## When the field is not settled If the calibration check found the field emerging, contested, or beyond what you can reliably describe, load [references/unsettled-fields.md](references/unsettled-fields.md) before Rung 1 and follow it for the rest of the session. In short: attribute the central claims, flag vocabulary that is not yet standard, say how old your picture is, and when you cannot form a picture at all, hand over a search instead of teaching. ## The ladder Climb these in order. One rung per turn. Announce which rung you are on and what comes next. Length and emphasis are both set by the reader's stated target, not by the rung. Load [references/pacing.md](references/pacing.md) before Rung 1 for the per-target word budgets and for how each target reshapes the climb. ### Rung 1 — Why this field exists The problem it was invented to solve, and what was inadequate before it. No formalism. If the user cannot state the motivating question in their own words, nothing above this rung will stick. End with: what the field lets you do that you could not do otherwise. ### Rung 2 — Vocabulary map The 5–10 terms that unlock the literature. For each: plain-language meaning, the symbol or notation used, and, where one exists, the equivalent concept in the user's home field. Format as a compact table. This is the rung the user will come back to most, so make it dense and scannable. It is a reference card, not a lecture. Include the field's abbreviations and any term that means something different here than in the user's home field. Those false friends cause the most damage. In an emerging field, mark which terms are not yet standard and name the competing usages. ### Rung 3 — The core framework The central model, equation, or conceptual structure. Derive or motivate it from something the user already accepts. Do not assert it. Show one worked case: the simplest non-trivial system, all the way through, with the physical meaning of each step stated. One concrete example beats three abstract ones. State the assumptions the framework rests on and when it fails. ### Rung 4 — How people actually do it Experimental techniques, computational methods, or datasets, whichever the field runs on. What a typical measurement or calculation looks like, what the raw output is, how that output becomes a scientific claim, what the standard artifacts and failure modes are, and what practitioners argue about methodologically. If the user's target is doing the work rather than reading it, expand this rung and compress rung 5. ### Rung 5 — Frontier and entry points What is unresolved, which groups are pushing which direction, and a short reading path: one review to orient, one or two landmark papers, one recent paper. Say what each is for and in what order to read them. This rung names specific works, so the rules in "Naming literature" are binding here. Verify the recent paper is actually recent, and check whether a landmark result has been contested or superseded since it was published. ## Naming literature Every specific paper, review, book, or package you name is either **verified** in this session with a checkable identifier, or explicitly labelled **from memory, unverified**. There is no third option, and an identifier you did not retrieve is never attached. Load [references/citations.md](references/citations.md) before producing a reading path or attributing a claim. ## Closing artifact When the ladder finishes, or whenever the user stops, produce one compact takeaway they can keep: - the running glossary; - the reading path, with each item's verification label intact; - the two or three questions the field itself has not settled; - which prerequisites they marked *new* and still have not covered; - if they arrived with a target artifact, whether they can now read it, and what is still likely to block them in it. Keep it short enough to paste into their own notes. This is the only part of the session that survives it. Offer it, do not force it. If they are mid-ladder and leaving, give the glossary and the open prerequisites and skip the rest. ## Checkpoints End each rung with a real diagnostic, never "make sense?", which always gets a yes. Scope it to what you just taught: you must be able to point at the sentence containing the answer, and a reader who marked exactly these prerequisites must be able to answer it. A wrong answer should reveal a hole in your explanation, not in their background. Load [references/checkpoints.md](references/checkpoints.md) for the question types, how to branch on the answer, and what to do when the user skips it. ## Decode mode When the user supplies an abstract, paragraph, figure caption, slide, or referee comment they cannot parse, do not run the ladder. Load [references/decode-mode.md](references/decode-mode.md) and follow it: gist, term-by-term, a reconstructed passage, what you would need in order to evaluate it, and the four labels that keep **source claim**, **background**, **inference**, and **critique** apart. ## References This file is the control plane. Load a reference when the moment for it arrives, not up front. | File | Load it when | | --- | --- | | `references/pacing.md` | Before Rung 1, once the target is known | | `references/unsettled-fields.md` | The field is emerging, contested, or beyond you | | `references/citations.md` | You are about to name a specific work | | `references/search-recipes.md` | You need to verify something, or to hand over a query | | `references/checkpoints.md` | Before the first checkpoint | | `references/decode-mode.md` | The user supplied text instead of a field | | `references/explanation-styles.md` | Before Rung 1, once the explanation style is known | | `references/state-runtime.md` | A multi-turn ladder can use local Python and temporary files | | `references/anti-patterns.md` | Reviewing your own output | | `references/examples.md` | An example would settle how a rule applies | | `references/evals.md` | You are changing this skill, not using it | ## Behavioral examples For representative first responses, negative triggers, checkpoint branching, source-fidelity handling, reading-path labelling, and multilingual behavior, consult [references/examples.md](references/examples.md) when an example would help resolve how to apply these rules. Treat the examples as patterns, not scripts. ## Verifying and searching When you have a search tool, use it: to check how settled a field is, to verify every named work, and to test your own picture against what was published recently. When you do not, hand the reader the query instead of a guess. [references/search-recipes.md](references/search-recipes.md) has the query templates for both cases. They use open APIs that need no key, so a reader can run any of them in a browser. ## Running glossary Maintain a cumulative glossary across the session. When you introduce a term, add it. When the user asks "what was X again", answer from the glossary without making them feel bad for asking. Reprint the full glossary when asked, or when the session gets long. ## Anti-patterns The full list is in [references/anti-patterns.md](references/anti-patterns.md). The three that account for most failures: running the intake on a question one turn would have answered, asking a checkpoint question the rung never taught, and producing a reading list you have not checked.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.