[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6C1ZBR0NYM8TH9B2KAS6CSF":3,"skill-same:01M6C1ZBR0NYM8TH9B2KAS6CSF":93},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":51,"linkOnly":52,"markdownContent":53,"markdownBody":54,"frontMatter":55,"refName":63,"commitSha":64,"skillDirectory":65,"forksCount":66,"repositoryHtmlUrl":67,"repositoryHomepageUrl":68,"ownerHtmlUrl":69,"ownerBlogUrl":70,"ownerDescription":71,"updatedAt":72,"install":73,"resources":86},"01M6C1ZBR0NYM8TH9B2KAS6CSF","induct-research",null,"Induct research sources (issue, file, directory, or URI) into a research corpus — reads, annotates, and files structured induction tasks. Like address-issues but for research.","jmagly\u002Faiwg","jmagly","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1159087?v=4","01M6C10AK8N2WCSQN11FYGTJWN","Joseph Magly","01M6C10AQ8A2RMED1Y1BSVY7NF",229,"MIT","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Finduct-research\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000021","资料检索与研究","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50],"research","induct research","write","for","websearch","sonnet","sources","dry","but","files","issue","webfetch","list","MCP","read","repo","grep","coding","Bash","file","issues","run","tasks","directory","2026-11-10 10:12:30",false,"---\nnamespace: aiwg\nplatforms: [all]\nname: induct-research\ndescription: Induct research sources (issue, file, directory, or URI) into a research corpus — reads, annotates, and files structured induction tasks. Like address-issues but for research.\ncommandHint:\n  argumentHint: \"\u003Ctarget> [--repo \u003Cdest>] [--dry-run] [--priority high|medium|low] [--tag \u003Ctopic>] [--recursive]\"\n  allowedTools: Read, Write, Glob, Grep, Bash, Agent, WebFetch, WebSearch, mcp__gitea__issue_write, mcp__gitea__issue_read, mcp__gitea__list_issues, mcp__hound__authenticate\n  model: sonnet\n  category: research\n  modelRole: coding\n  modelTier: standard\n---\n\n# Induct Research\n\nBefore dispatch, apply the shared [context engineering contract](..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fdocs\u002Fcontext-engineering-contract.md) and [verification contract](..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fdocs\u002Fverification-contracts.md). Missing source, fixity, sidecar, GRADE, or lint evidence makes the result incomplete or blocked, never complete.\n\nProcess one or more research sources — an issue, a file, a directory of papers, or a URI — and file structured induction tasks into a research repository so nothing gets lost. The analogue of `address-issues` for research corpora.\n\n## Kernel Delegation\n\n> As of ADR-021, `induct-research` delegates core ingest mechanics to the semantic memory kernel.\n\n**Delegation pattern**:\n1. `induct-research` retains its public name and interactive research-induction UX\n2. Internal ingest mechanics delegate to `memory-ingest --consumer research-complete`\n3. Research-specific layers remain in this wrapper:\n   - GRADE quality assessment (via `ingestRequires: [\"grade-quality\"]`)\n   - Citation validation (via `ingestRequires: [\"provenance\"]`)\n   - Research-specific page templates\n4. Cross-references written as `@-mentions` per consumer schema\n\n**What changed**: The ingest pipeline (source reading, page creation, index update, log append) is now handled by `memory-ingest`. This skill adds the research-specific quality and citation layers on top.\n\n**Backward compatibility**: No UX changes. Existing invocations work identically.\n\n@agentic\u002Fcode\u002Faddons\u002Fsemantic-memory\u002Fskills\u002Fmemory-ingest\u002FSKILL.md\n\n## Triggers\n\n- \"induct this paper\" → single file induction\n- \"induct a research paper\" → single paper induction\n- \"add a paper to the corpus\" → corpus induction\n- \"induct the research queue\" → batch directory induction\n- \"add these references to the research repo\" → URI or file-path induction\n- \"process the research from issue-planner\" → induct `.aiwg\u002Fresearch\u002Fqueue\u002F`\n- \"induct research into gitea\" → named MCP service target\n- `\u002Finduct-research \u003Ctarget>` → direct invocation\n\n## Parameters\n\n### `\u003Ctarget>` (required)\nWhat to induct. Supported formats:\n\n| Format | Example | Behavior |\n|--------|---------|----------|\n| **Partial paper reference** | `Self-supervised representation learning (2024)` | Resolve identity before acquisition |\n| **File path** | `.aiwg\u002Fresearch\u002Fqueue\u002F` | Read all `.md` files in the directory |\n| **Single file** | `.aiwg\u002Fresearch\u002Fqueue\u002Fref-dapper.md` | Induct one source |\n| **URI** | `https:\u002F\u002Farxiv.org\u002Fabs\u002F2307.09288` | Fetch and induct the paper at that URL |\n| **Directory glob** | `papers\u002F**\u002F*.pdf` | Induct all matched files recursively |\n| **Issue reference** | `gitea:roctinam\u002Fresearch#42` | Read the issue body as a research stub |\n\n### `--repo \u003Cdest>` (optional)\nWhere to file induction tasks. Accepts the same three formats as `--induct-research` in issue-planner:\n\n| Format | Example | Behavior |\n|--------|---------|----------|\n| File path | `--repo .aiwg\u002Fresearch\u002Finducted\u002F` | Write task `.md` files locally |\n| URI | `--repo https:\u002F\u002Fgit.integrolabs.net\u002Froctinam\u002Fresearch` | File issues to that Gitea\u002FGitHub\u002FJira instance |\n| Named MCP | `--repo gitea` | Use `mcp__gitea__issue_write` directly |\n| Named MCP | `--repo codehound` | Register in Hound search index |\n\nFalls back to `AIWG_RESEARCH_REPO` env var if `--repo` is omitted.\n\n### `--dry-run` (optional)\nList what would be inducted and where, without writing or filing anything.\n\n### `--priority high|medium|low` (optional)\nOverride the suggested priority for all inducted items. Default: assessed per source.\n\n### `--tag \u003Ctopic>` (optional)\nApply a topic tag to all inducted items. Repeatable: `--tag llm --tag evaluation`.\n\n### `--recursive` (optional)\nWhen target is a directory, recurse into subdirectories. Default: top-level only.\n\n---\n\n## Execution Flow\n\n### Phase 1: Source Discovery\n\n**Paper identity gate (before acquisition or kernel delegation).** For non-ID paper\ninput — a bare title, title plus year, bibliography line, or paper URL — run\n`aiwg corpus resolve \"\u003Creference>\" --json` (add `--year YYYY` when known). Apply this\nalso to paper references extracted from issues, files and directory batches.\nContinue only on `status: resolved` (exit 0), using its canonical metadata and IDs.\nOn `ambiguous` (exit 2) or `unresolved` (exit 3), stop that source, show all candidates,\nfindings and `paths_tried`, and request a more specific reference; never guess or\nsend it to acquisition, task filing or `memory-ingest`. On `deferred` (exit 4),\nstop that source, show `paths_tried`, and retry later: incomplete lookup does not\nestablish absence. Batches pace clients and retry 429s with backoff\u002F`Retry-After`;\nbatch exit is the worst line (4 > 3 > 2 > 0); usage errors exit 1. Incomplete\nshort\u002Fgeneric titles require a verified ID; otherwise ask for year\u002Fauthor\u002FID.\nPreserve supplied titles\nand report title mismatch findings for review. Use `already_in_corpus` and\n`corpus_matches` to identify existing REFs. Once identity is resolved, retain the\n`memory-ingest --consumer research-complete` delegation described above.\n\n1. **Parse `\u003Ctarget>`** — determine input type (file, directory, URI, issue ref)\n2. **Collect sources**:\n   - **File\u002Fdirectory**: glob for `.md`, `.pdf`, `.txt`, `.yaml` files\n   - **URI**: fetch the resource; detect type (paper, doc page, repo, issue)\n   - **Issue reference**: fetch issue body and all comments via MCP or CLI\n3. **Deduplicate** — skip sources already present in the destination repo (if queryable)\n4. **Report discovery**:\n\n```\nFound 9 sources to induct:\n  3 Markdown stubs (.aiwg\u002Fresearch\u002Fqueue\u002F)\n  4 PDF papers (papers\u002F2024\u002F)\n  2 URI references\n  Skipping 1 (already inducted: REF-042)\n```\n\n---\n\n### Phase 2: Source Acquisition (acquire before analyze)\n\n**CRITICAL**: Never write analysis docs from metadata or abstracts alone. The pipeline is:\n**acquire full content → read full content → write analysis doc.**\n\nThis was learned from a session where 88 of 120 papers were inducted as shallow stubs\nwritten from arXiv abstract pages — not the actual papers. See #817.\n\nFor each source, ensure full content is available before analysis:\n\n**For PDFs \u002F full papers**:\n1. **Acquire the PDF** — call `\u002Fresearch-acquire \u003Curl> --extract-text` to download the PDF\n   to `sources\u002Fpdfs\u002Ffull\u002F` and extract full text to `sources\u002Ftext\u002F`\n2. **Verify acquisition** — confirm the PDF exists at the expected path and is non-empty\n3. **If the first path fails**, do NOT conclude the source is unavailable. Run the\n   unavailability gate below. Only after it completes may you record a deficit status,\n   and never write a full analysis doc from the abstract alone.\n\n**For URIs (web sources)**:\n1. **Fetch the full page** (WebFetch) — save to `sources\u002Fweb\u002F\u003Cslug>.html`\n2. **Classify**: paper, blog post, official docs, repo README, specification, news\n3. **If paper**: call `\u002Fresearch-acquire` to get the actual PDF — do not analyze from\n   the landing page HTML\n4. **If non-paper web source**: the fetched HTML\u002Ftext is the full content — proceed to analysis\n\n**For Markdown stubs** (from issue-planner queue files):\n- Read the stub content and relevance summary\n- If the stub references a paper URL: acquire the PDF first (same as above)\n- If the stub is a research brief with no external source: proceed as-is\n\n**For issue references**:\n- Read full issue body and comments\n- Extract referenced URLs, files, or topics\n- If URLs point to papers: acquire PDFs before analysis\n- If no external sources: treat as a research brief stub\n\n#### Unavailability gate (before recording any acquisition deficit)\n\nApplies to every source type above, not just PDFs. One failing request is not evidence of\nunavailability. Before recording\n`pending-acquisition` or `acquisition-deficit`, complete both steps and record what each\nreturned. Both are cheap; step B is cheaper than any network call.\n\n**A. Enumerate the host's access paths.** Try them in order rather than inventing one:\n\n| Host | Try, in order |\n|------|---------------|\n| Hugging Face | `resolve\u002Fmain\u002F\u003Cfile>`, `raw\u002Fmain\u002F\u003Cfile>`, `api\u002Fdatasets\u002F\u003Cid>`, `api\u002F...\u002Ftree\u002Fmain?recursive=true`, `api\u002F...\u002Fcroissant`, `datasets-server\u002Fsplits`, `hf-mirror.com` |\n| arXiv | `\u002Fabs\u002F\u003Cid>`, `\u002Fpdf\u002F\u003Cid>`, `\u002Fe-print\u002F\u003Cid>` |\n| Publisher DOI | publisher URL, Unpaywall, Europe PMC, Semantic Scholar `openAccessPdf`, arXiv full-text search, author\u002Flab pages, institutional repository |\n| Conference | ACL Anthology, PMLR, OpenReview, proceedings site |\n\nTwo traps worth naming, because both have produced false \"gated\" verdicts:\n\n- On Hugging Face, `raw\u002Fmain\u002FREADME.md` can return **401** while `resolve\u002Fmain\u002FREADME.md`\n  returns **200 with the complete card** — same repo, same revision, same anonymous client.\n  The API's `description` field is also truncated (~600 chars) where the card behind\n  `resolve\u002Fmain` is not.\n- `export.arxiv.org\u002Fapi\u002Fquery` returns **503** from some networks while `arxiv.org\u002Fabs`\n  serves fine with a browser UA. An API failure is not source unavailability.\n\n**B. Check the corpus before declaring unavailable.** Ask both, and record the answers:\n\n1. Does the corpus already hold a source that **introduces, specifies or evaluates** this\n   artifact? Benchmarks, datasets, models and tools are usually defined in a paper, and\n   that paper is often already inducted and text-extracted on local disk.\n2. Is there an **open-access companion** — preprint, technical report, or a same-group\n   paper on the same subject — covering the claim the citing document needed?\n\nBoth are `grep`\u002Findex queries against `sources\u002Ftext\u002F` and the corpus index.\n\n**Record the outcome as a named obstacle, not a bare flag.** `pending-acquisition` alone\nconflates four states that need different actions:\n\n| State | Means | Action |\n|-------|-------|--------|\n| `not-attempted` | ordinary backlog | do the work |\n| `credential-required` | one credential away (e.g. needs `HF_TOKEN`) | credential decision |\n| `structurally-unobtainable` | closed access, N services checked | subscription decision, or accept |\n| `artifact-absent` | the named artifact was never published | close as not-planned |\n\nWrite the state and the specific obstacle — `structurally-unobtainable: closed access;\nUnpaywall reports zero OA locations; Semantic Scholar reports the publisher elided the\nabstract; no arXiv preprint` — not `acquisition-failed: true`. A bare boolean cannot be\ntriaged, and the paths-tried record is what makes the verdict credible to a reader.\n\nFor tracker hand-off, mirror the state as a label (`blocked:credential-required`,\n`blocked:structurally-unobtainable`, `artifact-absent`) so the distinction survives into\ntriage instead of collapsing into one undifferentiated queue.\n\n### Phase 2.5: Per-Source Analysis (on full content)\n\nRead and follow [the analysis and verification gates](references\u002Fanalysis-verification.md)\nfor every source. This required companion preserves the full-content analysis, quality,\ncheap-verification and compiled-bibliography checks, including obstacle registration\nand citation direction verification.\n\n---\n\n### Phase 3: Induction Task Filing\n\nFor each analyzed source, file one induction task using the standard template.\n\n**Induction task body:**\n\n```markdown\n## Reference Induction\n\n**Source**: \u003CURL, file path, or issue reference>\n**Type**: \u003Cpaper | blog | docs | repo | spec | stub | issue>\n**GRADE**: \u003CA | B | C | D | unassessed>\n**Priority**: \u003Chigh | medium | low>\n**Tags**: \u003Ctopic1>, \u003Ctopic2>\n\n## Summary\n\u003C2–3 sentences: what this source covers and why it's relevant>\n\n## Key Claims \u002F Findings\n- \u003CSpecific claim or finding>\n- \u003CSpecific claim or finding>\n- \u003CSpecific claim or finding>\n\n## Relevance to Corpus\n\u003CHow this relates to existing research — cross-references to REF-XXX if applicable>\n\n## Induction Checklist\n- [ ] Read full source\n- [ ] Extract key insights as Zettelkasten notes\n- [ ] Cross-reference with existing corpus\n- [ ] Assign REF-XXX identifier\n- [ ] Tag with topic taxonomy\n- [ ] Assess with \u002Fresearch-quality\n- [ ] Archive with \u002Fresearch-archive (if paper\u002FPDF)\n- [ ] Add to citation graph with \u002Fresearch-cite\n\n### Cheap-verification gate\n- [ ] Venue confirmed against an independent record (not a LaTeX template), or demoted to `preprint`\n- [ ] Published version fetched and archived if peer-reviewed; diff vs preprint recorded\n- [ ] Every asserted code\u002Fproject\u002Fdataset URL probed\n- [ ] Retraction check run (source + date recorded, null result recorded as null)\n- [ ] Citation census run (source + date recorded)\n- [ ] Every surviving uncertainty registered as a declared check, not written as prose only\n\n### Bibliography\n- [ ] Edges taken from the compiled bibliography (`.bbl` \u002F inline \u002F PDF list), not the shipped `.bib`\n- [ ] Reference count states its counting method\n- [ ] Each edge's confirmation method recorded; `.bib`-only rejections recorded\n- [ ] Edge direction checked against publication dates\n\n## Origin\n- Surfaced by: \u003Cissue-planner | manual | other>\n- Surfaced for: \u003Cobjective or context>\n- Induction date: \u003CYYYY-MM-DD>\n```\n\n**Filing based on `--repo` target:**\n\n- **File path**: write `induct-\u003Cslug>.md` to destination directory\n- **Gitea URI\u002FMCP**: `mcp__gitea__issue_write` with label `research-induction`\n- **GitHub URI**: `gh issue create --label research-induction`\n- **Jira URI**: REST `POST \u002Frest\u002Fapi\u002F2\u002Fissue` with issue type Task\n- **Codehound MCP**: register URI in search index, create stub document\n\n---\n\n### Phase 3.5: Cross-Reference Fan-Out\n\nAfter creating each new literature note, update the broader corpus with bidirectional cross-references. This is what makes a corpus **compound** rather than just accumulate.\n\nCitation edges written here are subject to the **bibliography ground truth** rules in\nPhase 2.5: membership comes from the compiled bibliography, each edge records its\nconfirmation method, `.bib`-only rejections are recorded, and direction is checked against\npublication dates. Cross-referencing is where a fabricated edge becomes bidirectional and\ntherefore twice as expensive to unwind.\n\nFor each newly inducted source:\n\n1. **Search existing findings** for topically related REF-XXX notes:\n   - Match by shared tags\n   - Match by overlapping key claims or methodologies\n   - Match by citation overlap (both cite the same sources)\n\n2. **Add \"Related Sources\" cross-references**:\n   - In the **new note**: add a `## Related Sources` section listing existing REF-XXX notes and how they relate (confirms, contradicts, extends, prerequisite)\n   - In **existing notes**: append the new REF-XXX to their `## Related Sources` section with relationship type\n   - Before writing a citation edge in either direction, check the two publication dates.\n     A work cannot cite something published after it; if the dates say otherwise, the edge\n     is mis-directed or points at the wrong node.\n\n3. **Flag contradictions or confirmations**:\n   - If the new source contradicts an existing finding, add a `contradiction` marker to both notes\n   - If it confirms an existing finding, add a `confirms` marker\n\n4. **Update synthesis documents** in `.aiwg\u002Fresearch\u002Fsynthesis\u002F`:\n   - If a relevant synthesis document exists, append a note that new evidence is available\n\n**Example cross-reference entry:**\n\n```markdown\n## Related Sources\n\n- **REF-034** — Confirms: both identify prompt injection as the primary attack vector for LLM agents\n- **REF-042** — Extends: this source adds quantitative benchmarks missing from REF-042's qualitative analysis\n- **REF-067** — Contradicts: claims agent sandboxing overhead is \u003C5%, while REF-067 measured 15-20%\n```\n\n**Batch optimization**: When inducting multiple sources in a batch, defer cross-referencing until all new notes are created, then run a single fan-out pass across all new + existing notes. This avoids redundant searches.\n\n**Skip conditions**: Skip cross-referencing when:\n- `--dry-run` is set\n- Source is filed as a stub (not yet fully documented)\n- Fewer than 3 existing REF-XXX notes in the corpus (too early for meaningful cross-refs)\n\n---\n\n### Phase 4: Summary Report\n\n```\n## Induction Summary\n\n| # | Source | Type | Priority | Filed At |\n|---|--------|------|----------|----------|\n| 1 | RFC 9110 HTTP Semantics | spec | high | gitea#301 |\n| 2 | \"Dapper\" Google Tracing Paper | paper | high | gitea#302 |\n| 3 | opentelemetry.io\u002Fdocs | docs | medium | gitea#303 |\n| 4 | github.com\u002Fjaegertracing\u002Fjaeger | repo | medium | gitea#304 |\n| 5 | arxiv.org\u002Fabs\u002F2012.15161 | paper | low | gitea#305 |\n...\n\nInducted: 9\nSkipped: 1 (already present)\nDestination: gitea:roctinam\u002Fresearch\n\nNext steps:\n- \u002Fresearch-acquire \u003CURL> for any paper that needs PDF download\n- \u002Fresearch-document to annotate inducted sources\n- \u002Fresearch-quality to score GRADE for each inducted item\n```\n\n---\n\n## Target Resolution Logic\n\n```\nresolve_target(target):\n  if target starts with \"http:\u002F\u002F\" or \"https:\u002F\u002F\":\n    host = extract_host(target)\n    if host matches known_gitea_instances: use mcp__gitea__issue_write\n    if host == \"github.com\": use gh CLI\n    if host matches jira pattern: use Jira REST API\n    else: fetch as web resource, induct as URI reference\n\n  elif target matches \"gitea:\u003Cowner>\u002F\u003Crepo>#\u003Cn>\":\n    fetch issue via mcp__gitea__issue_read\n\n  elif target is a named MCP service (\"gitea\", \"codehound\", \"github\"):\n    use that service's write\u002Fregister tool directly\n\n  elif target is a file path:\n    if path is directory: glob for .md\u002F.pdf\u002F.txt files\n    if path is a file: induct single source\n```\n\n---\n\n## Batch Mode — Directory of Papers\n\nWhen target is a directory, process all supported files:\n\n```\n\u002Finduct-research papers\u002F2024\u002F --repo gitea --tag llm --recursive\n```\n\n```\n⏳ Scanning papers\u002F2024\u002F (recursive)...\n  Found 23 PDF files\n  Found 7 Markdown stubs\n  Found 2 YAML records\n  Deduplicating against gitea:roctinam\u002Fresearch...\n    Skipping 4 (already inducted)\n\n⏳ Analyzing 28 sources (parallel agents)...\n  ✓ Batch A (7 sources): complete\n  ✓ Batch B (7 sources): complete\n  ✓ Batch C (7 sources): complete\n  ✓ Batch D (7 sources): complete\n\n⏳ Filing 28 induction tasks to gitea:roctinam\u002Fresearch...\n✓ Inducted: 28 | Skipped: 4 | Total: 32\n```\n\n---\n\n## Integration with issue-planner\n\n`issue-planner --induct-research \u003Ctarget>` calls this skill's Phase 3 (filing) logic directly after Phase 2 research synthesis. The references are the URLs and sources discovered during the parallel research pass.\n\n`\u002Finduct-research` can also be invoked standalone to process:\n- Pre-existing queues: `\u002Finduct-research .aiwg\u002Fresearch\u002Fqueue\u002F`\n- Ad-hoc papers: `\u002Finduct-research https:\u002F\u002Farxiv.org\u002Fabs\u002F2307.09288`\n- Full directories: `\u002Finduct-research ~\u002FDownloads\u002Fpapers\u002F --repo gitea`\n\n---\n\n## Composition\n\n```\ninduct-research \u003Ctarget>\n    │\n    ├── Phase 1: Source discovery\n    │   ├── File\u002Fdirectory: glob + read\n    │   ├── URI: WebFetch + classify\n    │   └── Issue ref: mcp__gitea__issue_read or gh CLI\n    ├── Phase 2: Source acquisition (acquire before analyze)\n    │   ├── PDF\u002Fpaper → \u002Fresearch-acquire --extract-text\n    │   ├── URI → WebFetch full page → \u002Fresearch-acquire if paper\n    │   ├── Stub with URL → acquire referenced source\n    │   └── Unavailability gate before any deficit status\n    │       ├── A: enumerate the host's access paths, record each result\n    │       ├── B: corpus-first — introducing source? OA companion?\n    │       └── Record a named obstacle + state, never a bare flag\n    ├── Phase 2.5: Per-source analysis (on full content only)\n    │   ├── PDF agent → read full text, extract claims + GRADE\n    │   ├── Web agent → read full saved page, assess credibility\n    │   ├── Stub agent → parse relevance summary\n    │   ├── Quality gate: flag docs under 80 lines as potential stubs\n    │   ├── Cheap-verification gate: venue, published version, URLs, census\n    │   │   └── Residue registered as a declared check, not prose\n    │   └── Bibliography ground truth: compiled .bbl over shipped .bib\n    ├── Phase 3: Induction task filing\n    │   ├── File path → write .md task files\n    │   ├── Gitea URI\u002FMCP → mcp__gitea__issue_write\n    │   ├── GitHub URI → gh issue create\n    │   └── Codehound MCP → register in search index\n    ├── Phase 3.5: Cross-reference fan-out\n    │   ├── Search existing findings by tags + claims\n    │   ├── Add bidirectional Related Sources sections\n    │   ├── Flag contradictions \u002F confirmations\n    │   └── Update synthesis documents\n    └── Phase 4: Summary report\n```\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsdlc-complete\u002Fskills\u002Fissue-planner\u002FSKILL.md — Calls induct-research during Phase 2b\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fresearch-acquire\u002FSKILL.md — Full PDF acquisition (called for paper URIs)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fresearch-document\u002FSKILL.md — Annotate inducted sources\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fresearch-quality\u002FSKILL.md — GRADE scoring for inducted items\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsdlc-complete\u002Fskills\u002Faddress-issues\u002FSKILL.md — Analogous pattern for code issues\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fsubagent-scoping.md — Parallel batch analysis constraints\n- @$AIWG_ROOT\u002Fdocs\u002Fverification-contracts.md — Declared checks; prose uncertainty must be registered as one (#2523)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Ftemplates\u002Fcitation-sidecar.md — `Confirmed by`, `Rejected Candidates`, `bibliography` and `acquisition-obstacle` fields (#2524, #2525)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fsidecar-lint\u002FSKILL.md — Structural lint for the sidecars this skill writes\n- @$AIWG_ROOT\u002Ftools\u002Fresearch\u002Fbibliography-resolver.mjs — Applies the bibliography hierarchy mechanically (#2525)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fdocs\u002Fbibliographic-services.md — Per-service operating characteristics, the OpenAlex count trap, throttling budget (#2539)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Flint\u002Funcertainty-registered.yaml — Flags uncertainty stated without an obstacle (#2523)\n\n## Storage Routing (#934, #968)\n\nThis skill's persistence flows through `resolveStorage('research')`. On the default `fs` backend the research corpus lives at `.aiwg\u002Fresearch\u002F`. **Heavy artifacts (papers, archived sources) can move to a secondary drive** by setting `roots.research` in `.aiwg\u002Fstorage.config` (one of the headline #934 use cases).\n\n```bash\naiwg research-store path                            # resolved root\naiwg research-store list --prefix sources\u002F\naiwg research-store get sources\u002Fpaper-123.md\n```\n","# Induct Research\n\nBefore dispatch, apply the shared [context engineering contract](..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fdocs\u002Fcontext-engineering-contract.md) and [verification contract](..\u002F..\u002F..\u002F..\u002F..\u002F..\u002Fdocs\u002Fverification-contracts.md). Missing source, fixity, sidecar, GRADE, or lint evidence makes the result incomplete or blocked, never complete.\n\nProcess one or more research sources — an issue, a file, a directory of papers, or a URI — and file structured induction tasks into a research repository so nothing gets lost. The analogue of `address-issues` for research corpora.\n\n## Kernel Delegation\n\n> As of ADR-021, `induct-research` delegates core ingest mechanics to the semantic memory kernel.\n\n**Delegation pattern**:\n1. `induct-research` retains its public name and interactive research-induction UX\n2. Internal ingest mechanics delegate to `memory-ingest --consumer research-complete`\n3. Research-specific layers remain in this wrapper:\n   - GRADE quality assessment (via `ingestRequires: [\"grade-quality\"]`)\n   - Citation validation (via `ingestRequires: [\"provenance\"]`)\n   - Research-specific page templates\n4. Cross-references written as `@-mentions` per consumer schema\n\n**What changed**: The ingest pipeline (source reading, page creation, index update, log append) is now handled by `memory-ingest`. This skill adds the research-specific quality and citation layers on top.\n\n**Backward compatibility**: No UX changes. Existing invocations work identically.\n\n@agentic\u002Fcode\u002Faddons\u002Fsemantic-memory\u002Fskills\u002Fmemory-ingest\u002FSKILL.md\n\n## Triggers\n\n- \"induct this paper\" → single file induction\n- \"induct a research paper\" → single paper induction\n- \"add a paper to the corpus\" → corpus induction\n- \"induct the research queue\" → batch directory induction\n- \"add these references to the research repo\" → URI or file-path induction\n- \"process the research from issue-planner\" → induct `.aiwg\u002Fresearch\u002Fqueue\u002F`\n- \"induct research into gitea\" → named MCP service target\n- `\u002Finduct-research \u003Ctarget>` → direct invocation\n\n## Parameters\n\n### `\u003Ctarget>` (required)\nWhat to induct. Supported formats:\n\n| Format | Example | Behavior |\n|--------|---------|----------|\n| **Partial paper reference** | `Self-supervised representation learning (2024)` | Resolve identity before acquisition |\n| **File path** | `.aiwg\u002Fresearch\u002Fqueue\u002F` | Read all `.md` files in the directory |\n| **Single file** | `.aiwg\u002Fresearch\u002Fqueue\u002Fref-dapper.md` | Induct one source |\n| **URI** | `https:\u002F\u002Farxiv.org\u002Fabs\u002F2307.09288` | Fetch and induct the paper at that URL |\n| **Directory glob** | `papers\u002F**\u002F*.pdf` | Induct all matched files recursively |\n| **Issue reference** | `gitea:roctinam\u002Fresearch#42` | Read the issue body as a research stub |\n\n### `--repo \u003Cdest>` (optional)\nWhere to file induction tasks. Accepts the same three formats as `--induct-research` in issue-planner:\n\n| Format | Example | Behavior |\n|--------|---------|----------|\n| File path | `--repo .aiwg\u002Fresearch\u002Finducted\u002F` | Write task `.md` files locally |\n| URI | `--repo https:\u002F\u002Fgit.integrolabs.net\u002Froctinam\u002Fresearch` | File issues to that Gitea\u002FGitHub\u002FJira instance |\n| Named MCP | `--repo gitea` | Use `mcp__gitea__issue_write` directly |\n| Named MCP | `--repo codehound` | Register in Hound search index |\n\nFalls back to `AIWG_RESEARCH_REPO` env var if `--repo` is omitted.\n\n### `--dry-run` (optional)\nList what would be inducted and where, without writing or filing anything.\n\n### `--priority high|medium|low` (optional)\nOverride the suggested priority for all inducted items. Default: assessed per source.\n\n### `--tag \u003Ctopic>` (optional)\nApply a topic tag to all inducted items. Repeatable: `--tag llm --tag evaluation`.\n\n### `--recursive` (optional)\nWhen target is a directory, recurse into subdirectories. Default: top-level only.\n\n---\n\n## Execution Flow\n\n### Phase 1: Source Discovery\n\n**Paper identity gate (before acquisition or kernel delegation).** For non-ID paper\ninput — a bare title, title plus year, bibliography line, or paper URL — run\n`aiwg corpus resolve \"\u003Creference>\" --json` (add `--year YYYY` when known). Apply this\nalso to paper references extracted from issues, files and directory batches.\nContinue only on `status: resolved` (exit 0), using its canonical metadata and IDs.\nOn `ambiguous` (exit 2) or `unresolved` (exit 3), stop that source, show all candidates,\nfindings and `paths_tried`, and request a more specific reference; never guess or\nsend it to acquisition, task filing or `memory-ingest`. On `deferred` (exit 4),\nstop that source, show `paths_tried`, and retry later: incomplete lookup does not\nestablish absence. Batches pace clients and retry 429s with backoff\u002F`Retry-After`;\nbatch exit is the worst line (4 > 3 > 2 > 0); usage errors exit 1. Incomplete\nshort\u002Fgeneric titles require a verified ID; otherwise ask for year\u002Fauthor\u002FID.\nPreserve supplied titles\nand report title mismatch findings for review. Use `already_in_corpus` and\n`corpus_matches` to identify existing REFs. Once identity is resolved, retain the\n`memory-ingest --consumer research-complete` delegation described above.\n\n1. **Parse `\u003Ctarget>`** — determine input type (file, directory, URI, issue ref)\n2. **Collect sources**:\n   - **File\u002Fdirectory**: glob for `.md`, `.pdf`, `.txt`, `.yaml` files\n   - **URI**: fetch the resource; detect type (paper, doc page, repo, issue)\n   - **Issue reference**: fetch issue body and all comments via MCP or CLI\n3. **Deduplicate** — skip sources already present in the destination repo (if queryable)\n4. **Report discovery**:\n\n```\nFound 9 sources to induct:\n  3 Markdown stubs (.aiwg\u002Fresearch\u002Fqueue\u002F)\n  4 PDF papers (papers\u002F2024\u002F)\n  2 URI references\n  Skipping 1 (already inducted: REF-042)\n```\n\n---\n\n### Phase 2: Source Acquisition (acquire before analyze)\n\n**CRITICAL**: Never write analysis docs from metadata or abstracts alone. The pipeline is:\n**acquire full content → read full content → write analysis doc.**\n\nThis was learned from a session where 88 of 120 papers were inducted as shallow stubs\nwritten from arXiv abstract pages — not the actual papers. See #817.\n\nFor each source, ensure full content is available before analysis:\n\n**For PDFs \u002F full papers**:\n1. **Acquire the PDF** — call `\u002Fresearch-acquire \u003Curl> --extract-text` to download the PDF\n   to `sources\u002Fpdfs\u002Ffull\u002F` and extract full text to `sources\u002Ftext\u002F`\n2. **Verify acquisition** — confirm the PDF exists at the expected path and is non-empty\n3. **If the first path fails**, do NOT conclude the source is unavailable. Run the\n   unavailability gate below. Only after it completes may you record a deficit status,\n   and never write a full analysis doc from the abstract alone.\n\n**For URIs (web sources)**:\n1. **Fetch the full page** (WebFetch) — save to `sources\u002Fweb\u002F\u003Cslug>.html`\n2. **Classify**: paper, blog post, official docs, repo README, specification, news\n3. **If paper**: call `\u002Fresearch-acquire` to get the actual PDF — do not analyze from\n   the landing page HTML\n4. **If non-paper web source**: the fetched HTML\u002Ftext is the full content — proceed to analysis\n\n**For Markdown stubs** (from issue-planner queue files):\n- Read the stub content and relevance summary\n- If the stub references a paper URL: acquire the PDF first (same as above)\n- If the stub is a research brief with no external source: proceed as-is\n\n**For issue references**:\n- Read full issue body and comments\n- Extract referenced URLs, files, or topics\n- If URLs point to papers: acquire PDFs before analysis\n- If no external sources: treat as a research brief stub\n\n#### Unavailability gate (before recording any acquisition deficit)\n\nApplies to every source type above, not just PDFs. One failing request is not evidence of\nunavailability. Before recording\n`pending-acquisition` or `acquisition-deficit`, complete both steps and record what each\nreturned. Both are cheap; step B is cheaper than any network call.\n\n**A. Enumerate the host's access paths.** Try them in order rather than inventing one:\n\n| Host | Try, in order |\n|------|---------------|\n| Hugging Face | `resolve\u002Fmain\u002F\u003Cfile>`, `raw\u002Fmain\u002F\u003Cfile>`, `api\u002Fdatasets\u002F\u003Cid>`, `api\u002F...\u002Ftree\u002Fmain?recursive=true`, `api\u002F...\u002Fcroissant`, `datasets-server\u002Fsplits`, `hf-mirror.com` |\n| arXiv | `\u002Fabs\u002F\u003Cid>`, `\u002Fpdf\u002F\u003Cid>`, `\u002Fe-print\u002F\u003Cid>` |\n| Publisher DOI | publisher URL, Unpaywall, Europe PMC, Semantic Scholar `openAccessPdf`, arXiv full-text search, author\u002Flab pages, institutional repository |\n| Conference | ACL Anthology, PMLR, OpenReview, proceedings site |\n\nTwo traps worth naming, because both have produced false \"gated\" verdicts:\n\n- On Hugging Face, `raw\u002Fmain\u002FREADME.md` can return **401** while `resolve\u002Fmain\u002FREADME.md`\n  returns **200 with the complete card** — same repo, same revision, same anonymous client.\n  The API's `description` field is also truncated (~600 chars) where the card behind\n  `resolve\u002Fmain` is not.\n- `export.arxiv.org\u002Fapi\u002Fquery` returns **503** from some networks while `arxiv.org\u002Fabs`\n  serves fine with a browser UA. An API failure is not source unavailability.\n\n**B. Check the corpus before declaring unavailable.** Ask both, and record the answers:\n\n1. Does the corpus already hold a source that **introduces, specifies or evaluates** this\n   artifact? Benchmarks, datasets, models and tools are usually defined in a paper, and\n   that paper is often already inducted and text-extracted on local disk.\n2. Is there an **open-access companion** — preprint, technical report, or a same-group\n   paper on the same subject — covering the claim the citing document needed?\n\nBoth are `grep`\u002Findex queries against `sources\u002Ftext\u002F` and the corpus index.\n\n**Record the outcome as a named obstacle, not a bare flag.** `pending-acquisition` alone\nconflates four states that need different actions:\n\n| State | Means | Action |\n|-------|-------|--------|\n| `not-attempted` | ordinary backlog | do the work |\n| `credential-required` | one credential away (e.g. needs `HF_TOKEN`) | credential decision |\n| `structurally-unobtainable` | closed access, N services checked | subscription decision, or accept |\n| `artifact-absent` | the named artifact was never published | close as not-planned |\n\nWrite the state and the specific obstacle — `structurally-unobtainable: closed access;\nUnpaywall reports zero OA locations; Semantic Scholar reports the publisher elided the\nabstract; no arXiv preprint` — not `acquisition-failed: true`. A bare boolean cannot be\ntriaged, and the paths-tried record is what makes the verdict credible to a reader.\n\nFor tracker hand-off, mirror the state as a label (`blocked:credential-required`,\n`blocked:structurally-unobtainable`, `artifact-absent`) so the distinction survives into\ntriage instead of collapsing into one undifferentiated queue.\n\n### Phase 2.5: Per-Source Analysis (on full content)\n\nRead and follow [the analysis and verification gates](references\u002Fanalysis-verification.md)\nfor every source. This required companion preserves the full-content analysis, quality,\ncheap-verification and compiled-bibliography checks, including obstacle registration\nand citation direction verification.\n\n---\n\n### Phase 3: Induction Task Filing\n\nFor each analyzed source, file one induction task using the standard template.\n\n**Induction task body:**\n\n```markdown\n## Reference Induction\n\n**Source**: \u003CURL, file path, or issue reference>\n**Type**: \u003Cpaper | blog | docs | repo | spec | stub | issue>\n**GRADE**: \u003CA | B | C | D | unassessed>\n**Priority**: \u003Chigh | medium | low>\n**Tags**: \u003Ctopic1>, \u003Ctopic2>\n\n## Summary\n\u003C2–3 sentences: what this source covers and why it's relevant>\n\n## Key Claims \u002F Findings\n- \u003CSpecific claim or finding>\n- \u003CSpecific claim or finding>\n- \u003CSpecific claim or finding>\n\n## Relevance to Corpus\n\u003CHow this relates to existing research — cross-references to REF-XXX if applicable>\n\n## Induction Checklist\n- [ ] Read full source\n- [ ] Extract key insights as Zettelkasten notes\n- [ ] Cross-reference with existing corpus\n- [ ] Assign REF-XXX identifier\n- [ ] Tag with topic taxonomy\n- [ ] Assess with \u002Fresearch-quality\n- [ ] Archive with \u002Fresearch-archive (if paper\u002FPDF)\n- [ ] Add to citation graph with \u002Fresearch-cite\n\n### Cheap-verification gate\n- [ ] Venue confirmed against an independent record (not a LaTeX template), or demoted to `preprint`\n- [ ] Published version fetched and archived if peer-reviewed; diff vs preprint recorded\n- [ ] Every asserted code\u002Fproject\u002Fdataset URL probed\n- [ ] Retraction check run (source + date recorded, null result recorded as null)\n- [ ] Citation census run (source + date recorded)\n- [ ] Every surviving uncertainty registered as a declared check, not written as prose only\n\n### Bibliography\n- [ ] Edges taken from the compiled bibliography (`.bbl` \u002F inline \u002F PDF list), not the shipped `.bib`\n- [ ] Reference count states its counting method\n- [ ] Each edge's confirmation method recorded; `.bib`-only rejections recorded\n- [ ] Edge direction checked against publication dates\n\n## Origin\n- Surfaced by: \u003Cissue-planner | manual | other>\n- Surfaced for: \u003Cobjective or context>\n- Induction date: \u003CYYYY-MM-DD>\n```\n\n**Filing based on `--repo` target:**\n\n- **File path**: write `induct-\u003Cslug>.md` to destination directory\n- **Gitea URI\u002FMCP**: `mcp__gitea__issue_write` with label `research-induction`\n- **GitHub URI**: `gh issue create --label research-induction`\n- **Jira URI**: REST `POST \u002Frest\u002Fapi\u002F2\u002Fissue` with issue type Task\n- **Codehound MCP**: register URI in search index, create stub document\n\n---\n\n### Phase 3.5: Cross-Reference Fan-Out\n\nAfter creating each new literature note, update the broader corpus with bidirectional cross-references. This is what makes a corpus **compound** rather than just accumulate.\n\nCitation edges written here are subject to the **bibliography ground truth** rules in\nPhase 2.5: membership comes from the compiled bibliography, each edge records its\nconfirmation method, `.bib`-only rejections are recorded, and direction is checked against\npublication dates. Cross-referencing is where a fabricated edge becomes bidirectional and\ntherefore twice as expensive to unwind.\n\nFor each newly inducted source:\n\n1. **Search existing findings** for topically related REF-XXX notes:\n   - Match by shared tags\n   - Match by overlapping key claims or methodologies\n   - Match by citation overlap (both cite the same sources)\n\n2. **Add \"Related Sources\" cross-references**:\n   - In the **new note**: add a `## Related Sources` section listing existing REF-XXX notes and how they relate (confirms, contradicts, extends, prerequisite)\n   - In **existing notes**: append the new REF-XXX to their `## Related Sources` section with relationship type\n   - Before writing a citation edge in either direction, check the two publication dates.\n     A work cannot cite something published after it; if the dates say otherwise, the edge\n     is mis-directed or points at the wrong node.\n\n3. **Flag contradictions or confirmations**:\n   - If the new source contradicts an existing finding, add a `contradiction` marker to both notes\n   - If it confirms an existing finding, add a `confirms` marker\n\n4. **Update synthesis documents** in `.aiwg\u002Fresearch\u002Fsynthesis\u002F`:\n   - If a relevant synthesis document exists, append a note that new evidence is available\n\n**Example cross-reference entry:**\n\n```markdown\n## Related Sources\n\n- **REF-034** — Confirms: both identify prompt injection as the primary attack vector for LLM agents\n- **REF-042** — Extends: this source adds quantitative benchmarks missing from REF-042's qualitative analysis\n- **REF-067** — Contradicts: claims agent sandboxing overhead is \u003C5%, while REF-067 measured 15-20%\n```\n\n**Batch optimization**: When inducting multiple sources in a batch, defer cross-referencing until all new notes are created, then run a single fan-out pass across all new + existing notes. This avoids redundant searches.\n\n**Skip conditions**: Skip cross-referencing when:\n- `--dry-run` is set\n- Source is filed as a stub (not yet fully documented)\n- Fewer than 3 existing REF-XXX notes in the corpus (too early for meaningful cross-refs)\n\n---\n\n### Phase 4: Summary Report\n\n```\n## Induction Summary\n\n| # | Source | Type | Priority | Filed At |\n|---|--------|------|----------|----------|\n| 1 | RFC 9110 HTTP Semantics | spec | high | gitea#301 |\n| 2 | \"Dapper\" Google Tracing Paper | paper | high | gitea#302 |\n| 3 | opentelemetry.io\u002Fdocs | docs | medium | gitea#303 |\n| 4 | github.com\u002Fjaegertracing\u002Fjaeger | repo | medium | gitea#304 |\n| 5 | arxiv.org\u002Fabs\u002F2012.15161 | paper | low | gitea#305 |\n...\n\nInducted: 9\nSkipped: 1 (already present)\nDestination: gitea:roctinam\u002Fresearch\n\nNext steps:\n- \u002Fresearch-acquire \u003CURL> for any paper that needs PDF download\n- \u002Fresearch-document to annotate inducted sources\n- \u002Fresearch-quality to score GRADE for each inducted item\n```\n\n---\n\n## Target Resolution Logic\n\n```\nresolve_target(target):\n  if target starts with \"http:\u002F\u002F\" or \"https:\u002F\u002F\":\n    host = extract_host(target)\n    if host matches known_gitea_instances: use mcp__gitea__issue_write\n    if host == \"github.com\": use gh CLI\n    if host matches jira pattern: use Jira REST API\n    else: fetch as web resource, induct as URI reference\n\n  elif target matches \"gitea:\u003Cowner>\u002F\u003Crepo>#\u003Cn>\":\n    fetch issue via mcp__gitea__issue_read\n\n  elif target is a named MCP service (\"gitea\", \"codehound\", \"github\"):\n    use that service's write\u002Fregister tool directly\n\n  elif target is a file path:\n    if path is directory: glob for .md\u002F.pdf\u002F.txt files\n    if path is a file: induct single source\n```\n\n---\n\n## Batch Mode — Directory of Papers\n\nWhen target is a directory, process all supported files:\n\n```\n\u002Finduct-research papers\u002F2024\u002F --repo gitea --tag llm --recursive\n```\n\n```\n⏳ Scanning papers\u002F2024\u002F (recursive)...\n  Found 23 PDF files\n  Found 7 Markdown stubs\n  Found 2 YAML records\n  Deduplicating against gitea:roctinam\u002Fresearch...\n    Skipping 4 (already inducted)\n\n⏳ Analyzing 28 sources (parallel agents)...\n  ✓ Batch A (7 sources): complete\n  ✓ Batch B (7 sources): complete\n  ✓ Batch C (7 sources): complete\n  ✓ Batch D (7 sources): complete\n\n⏳ Filing 28 induction tasks to gitea:roctinam\u002Fresearch...\n✓ Inducted: 28 | Skipped: 4 | Total: 32\n```\n\n---\n\n## Integration with issue-planner\n\n`issue-planner --induct-research \u003Ctarget>` calls this skill's Phase 3 (filing) logic directly after Phase 2 research synthesis. The references are the URLs and sources discovered during the parallel research pass.\n\n`\u002Finduct-research` can also be invoked standalone to process:\n- Pre-existing queues: `\u002Finduct-research .aiwg\u002Fresearch\u002Fqueue\u002F`\n- Ad-hoc papers: `\u002Finduct-research https:\u002F\u002Farxiv.org\u002Fabs\u002F2307.09288`\n- Full directories: `\u002Finduct-research ~\u002FDownloads\u002Fpapers\u002F --repo gitea`\n\n---\n\n## Composition\n\n```\ninduct-research \u003Ctarget>\n    │\n    ├── Phase 1: Source discovery\n    │   ├── File\u002Fdirectory: glob + read\n    │   ├── URI: WebFetch + classify\n    │   └── Issue ref: mcp__gitea__issue_read or gh CLI\n    ├── Phase 2: Source acquisition (acquire before analyze)\n    │   ├── PDF\u002Fpaper → \u002Fresearch-acquire --extract-text\n    │   ├── URI → WebFetch full page → \u002Fresearch-acquire if paper\n    │   ├── Stub with URL → acquire referenced source\n    │   └── Unavailability gate before any deficit status\n    │       ├── A: enumerate the host's access paths, record each result\n    │       ├── B: corpus-first — introducing source? OA companion?\n    │       └── Record a named obstacle + state, never a bare flag\n    ├── Phase 2.5: Per-source analysis (on full content only)\n    │   ├── PDF agent → read full text, extract claims + GRADE\n    │   ├── Web agent → read full saved page, assess credibility\n    │   ├── Stub agent → parse relevance summary\n    │   ├── Quality gate: flag docs under 80 lines as potential stubs\n    │   ├── Cheap-verification gate: venue, published version, URLs, census\n    │   │   └── Residue registered as a declared check, not prose\n    │   └── Bibliography ground truth: compiled .bbl over shipped .bib\n    ├── Phase 3: Induction task filing\n    │   ├── File path → write .md task files\n    │   ├── Gitea URI\u002FMCP → mcp__gitea__issue_write\n    │   ├── GitHub URI → gh issue create\n    │   └── Codehound MCP → register in search index\n    ├── Phase 3.5: Cross-reference fan-out\n    │   ├── Search existing findings by tags + claims\n    │   ├── Add bidirectional Related Sources sections\n    │   ├── Flag contradictions \u002F confirmations\n    │   └── Update synthesis documents\n    └── Phase 4: Summary report\n```\n\n## References\n\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsdlc-complete\u002Fskills\u002Fissue-planner\u002FSKILL.md — Calls induct-research during Phase 2b\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fresearch-acquire\u002FSKILL.md — Full PDF acquisition (called for paper URIs)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fresearch-document\u002FSKILL.md — Annotate inducted sources\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fresearch-quality\u002FSKILL.md — GRADE scoring for inducted items\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsdlc-complete\u002Fskills\u002Faddress-issues\u002FSKILL.md — Analogous pattern for code issues\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Faddons\u002Faiwg-utils\u002Frules\u002Fsubagent-scoping.md — Parallel batch analysis constraints\n- @$AIWG_ROOT\u002Fdocs\u002Fverification-contracts.md — Declared checks; prose uncertainty must be registered as one (#2523)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Ftemplates\u002Fcitation-sidecar.md — `Confirmed by`, `Rejected Candidates`, `bibliography` and `acquisition-obstacle` fields (#2524, #2525)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Fsidecar-lint\u002FSKILL.md — Structural lint for the sidecars this skill writes\n- @$AIWG_ROOT\u002Ftools\u002Fresearch\u002Fbibliography-resolver.mjs — Applies the bibliography hierarchy mechanically (#2525)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fdocs\u002Fbibliographic-services.md — Per-service operating characteristics, the OpenAlex count trap, throttling budget (#2539)\n- @$AIWG_ROOT\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Flint\u002Funcertainty-registered.yaml — Flags uncertainty stated without an obstacle (#2523)\n\n## Storage Routing (#934, #968)\n\nThis skill's persistence flows through `resolveStorage('research')`. On the default `fs` backend the research corpus lives at `.aiwg\u002Fresearch\u002F`. **Heavy artifacts (papers, archived sources) can move to a secondary drive** by setting `roots.research` in `.aiwg\u002Fstorage.config` (one of the headline #934 use cases).\n\n```bash\naiwg research-store path                            # resolved root\naiwg research-store list --prefix sources\u002F\naiwg research-store get sources\u002Fpaper-123.md\n```\n",{"name":5,"namespace":56,"platforms":57,"commandHint":59,"description":7},"aiwg",[58],"all",{"model":32,"category":27,"modelRole":44,"modelTier":60,"allowedTools":61,"argumentHint":62},"standard","Read, Write, Glob, Grep, Bash, Agent, WebFetch, WebSearch, mcp__gitea__issue_write, mcp__gitea__issue_read, mcp__gitea__list_issues, mcp__hound__authenticate","\u003Ctarget> [--repo \u003Cdest>] [--dry-run] [--priority high|medium|low] [--tag \u003Ctopic>] [--recursive]","main","6754967c344ccb087a8de06972f55a41067b291b","agentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Finduct-research",36,"https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg","https:\u002F\u002Faiwg.io","https:\u002F\u002Fgithub.com\u002Fjmagly","https:\u002F\u002Fintegrolabs.io","ml\u002Fai, industrial automation, safety\u002Fsecurity, ssi\r\n\r\nmagly.net\r\nintegrolabs.io\r\naiwg.io\r\nfortemi.com\r\npagenary.com\r\nbytecask.com","2026-11-12 00:33:10",{"source":8,"skillName":5,"commands":74,"prompt":84,"zipAvailable":85},[75,78,81],{"tool":76,"command":77},"npx","npx skills add jmagly\u002Faiwg --skill induct-research",{"tool":79,"command":80},"bunx","bunx skills add jmagly\u002Faiwg --skill induct-research",{"tool":82,"command":83},"pnpm","pnpm dlx skills add jmagly\u002Faiwg --skill induct-research","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Finduct-research\u002FSKILL.md",true,[87],{"path":88,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":91,"sourceHtmlUrl":92},"references\u002Fanalysis-verification.md","REFERENCE","参考文档",9998,"https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fresearch-complete\u002Fskills\u002Finduct-research\u002Freferences\u002Fanalysis-verification.md",[94,120,143,149,156,170],{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":101,"publishedAt":51},"01M70QA0BSYJ49EES9V4RE8QH1","host-hardening","Read-only system hardening baseline and plan-first host hardening recommendations for SSH, Docker bind addresses, firewall persistence, datastores, exporters and audit retention.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[100],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[102,103,104,41,105,106,107,108,109,110,45,111,112,113,114,115,116,117,118,119],"host","host hardening","hardening","re","recommendations","remediation","plan","port","verification","access","only","retention","audit","never","firewall","bind","secrets","request",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":130,"publishedAt":51},"01M70PNT2Z4HMZPRBTAF6073NN","exposure-analysis","Read-only firewall analysis and effective host exposure reconstruction for Docker published ports, UFW bypass, stale rules, CDN scope, IPv6 asymmetry and external probe allowlists.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fplugins\u002Fforensics\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[126,129],{"categoryNo":127,"categoryName":128,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[131,132,133,41,134,109,135,136,45,137,102,138,112,139,140,115,116,141,142,29],"exposure analysis","analysis","unknown","credentials","collection","ufw","ports","internet","local","scope","reconstruction","operator",{"skillNo":144,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":148,"publishedAt":51},"01M70P8QATMPKA78E4FT5D2TNA","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fsecurity-engineering\u002Fskills\u002Fhost-hardening\u002FSKILL.md",[147],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[104,102,103,111,41,119,107,106,114,108,109,110,45,118,112,113,105,115,116,117],{"skillNo":150,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":155,"publishedAt":51},"01M70NMPVJ5H0JH131P60FW4R8","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Fagentic\u002Fcode\u002Fframeworks\u002Fforensics-complete\u002Fskills\u002Fexposure-analysis\u002FSKILL.md",[153,154],{"categoryNo":127,"categoryName":128,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[132,131,115,134,109,135,45,133,102,138,112,139,140,41,116,137,136,141,142,29],{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":163,"publishedAt":51},"01M6CB4DDR0B4NNCFK7ZK7449H","fixture-skill","Exercise rule delivery.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Frule-delivery\u002Fskills\u002Ffixture-skill\u002FSKILL.md",[162],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[164,165,166,167,168,169],"fixture skill","fixture","rule","delivery","true","exercise",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":174,"categories":175,"keywords":177,"publishedAt":51},"01M6CB4AVK1W76MFMPP0JP32CJ","pi-local","Pi-local duplicate-precedence fixture.","https:\u002F\u002Fgithub.com\u002Fjmagly\u002Faiwg\u002Fblob\u002Fmain\u002Ftest\u002Ffixtures\u002Fproviders\u002Fpi\u002Fproject\u002F.pi\u002Fskills\u002Fpi-local\u002FSKILL.md",[176],{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},[178,179,139,180,165],"pi","pi local","duplicate"]