induct-research
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.
- License 许可
- MIT
- 所属仓库
- jmagly/aiwg
- 最近更新
- 2026-11-12
- Stars
- ★ 229
- Forks
- 36
01 前言 Front Matter
- name
- induct-research
- namespace
- aiwg
- platforms
- [ "all" ]
- commandHint
- { "model": "sonnet", "category": "research", "modelRole": "coding", "modelTier": "standard", "allowedTools": "Read, Write, Glob, Grep, Bash, Agent, WebFetch, WebSearch, mcp__gitea__issue_write, mcp__gitea__issue_read, mcp__gitea__list_issues, mcp__hound__authenticate", "argumentHint": "<target> [--repo <dest>] [--dry-run] [--priority high|medium|low] [--tag <topic>] [--recursive]" }
- description
- 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.
02 资源文件 1
- 参考文档references/analysis-verification.md9.8 KB
03 SKILL.md 正文
Induct Research
Before dispatch, apply the shared context engineering contract and verification contract. Missing source, fixity, sidecar, GRADE, or lint evidence makes the result incomplete or blocked, never complete.
Process 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.
Kernel Delegation
As of ADR-021,
induct-researchdelegates core ingest mechanics to the semantic memory kernel.
Delegation pattern:
induct-researchretains its public name and interactive research-induction UX- Internal ingest mechanics delegate to
memory-ingest --consumer research-complete - Research-specific layers remain in this wrapper:
- GRADE quality assessment (via
ingestRequires: ["grade-quality"]) - Citation validation (via
ingestRequires: ["provenance"]) - Research-specific page templates
- GRADE quality assessment (via
- Cross-references written as
@-mentionsper consumer schema
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.
Backward compatibility: No UX changes. Existing invocations work identically.
@agentic/code/addons/semantic-memory/skills/memory-ingest/SKILL.md
Triggers
- "induct this paper" → single file induction
- "induct a research paper" → single paper induction
- "add a paper to the corpus" → corpus induction
- "induct the research queue" → batch directory induction
- "add these references to the research repo" → URI or file-path induction
- "process the research from issue-planner" → induct
.aiwg/research/queue/ - "induct research into gitea" → named MCP service target
/induct-research <target>→ direct invocation
Parameters
<target> (required)
What to induct. Supported formats:
| Format | Example | Behavior |
|---|---|---|
| Partial paper reference | Self-supervised representation learning (2024) |
Resolve identity before acquisition |
| File path | .aiwg/research/queue/ |
Read all .md files in the directory |
| Single file | .aiwg/research/queue/ref-dapper.md |
Induct one source |
| URI | https://arxiv.org/abs/2307.09288 |
Fetch and induct the paper at that URL |
| Directory glob | papers/**/*.pdf |
Induct all matched files recursively |
| Issue reference | gitea:roctinam/research#42 |
Read the issue body as a research stub |
--repo <dest> (optional)
Where to file induction tasks. Accepts the same three formats as --induct-research in issue-planner:
| Format | Example | Behavior |
|---|---|---|
| File path | --repo .aiwg/research/inducted/ |
Write task .md files locally |
| URI | --repo https://git.integrolabs.net/roctinam/research |
File issues to that Gitea/GitHub/Jira instance |
| Named MCP | --repo gitea |
Use mcp__gitea__issue_write directly |
| Named MCP | --repo codehound |
Register in Hound search index |
Falls back to AIWG_RESEARCH_REPO env var if --repo is omitted.
--dry-run (optional)
List what would be inducted and where, without writing or filing anything.
--priority high|medium|low (optional)
Override the suggested priority for all inducted items. Default: assessed per source.
--tag <topic> (optional)
Apply a topic tag to all inducted items. Repeatable: --tag llm --tag evaluation.
--recursive (optional)
When target is a directory, recurse into subdirectories. Default: top-level only.
Execution Flow
Phase 1: Source Discovery
Paper identity gate (before acquisition or kernel delegation). For non-ID paper
input — a bare title, title plus year, bibliography line, or paper URL — run
aiwg corpus resolve "<reference>" --json (add --year YYYY when known). Apply this
also to paper references extracted from issues, files and directory batches.
Continue only on status: resolved (exit 0), using its canonical metadata and IDs.
On ambiguous (exit 2) or unresolved (exit 3), stop that source, show all candidates,
findings and paths_tried, and request a more specific reference; never guess or
send it to acquisition, task filing or memory-ingest. On deferred (exit 4),
stop that source, show paths_tried, and retry later: incomplete lookup does not
establish absence. Batches pace clients and retry 429s with backoff/Retry-After;
batch exit is the worst line (4 > 3 > 2 > 0); usage errors exit 1. Incomplete
short/generic titles require a verified ID; otherwise ask for year/author/ID.
Preserve supplied titles
and report title mismatch findings for review. Use already_in_corpus and
corpus_matches to identify existing REFs. Once identity is resolved, retain the
memory-ingest --consumer research-complete delegation described above.
- Parse
<target>— determine input type (file, directory, URI, issue ref) - Collect sources:
- File/directory: glob for
.md,.pdf,.txt,.yamlfiles - URI: fetch the resource; detect type (paper, doc page, repo, issue)
- Issue reference: fetch issue body and all comments via MCP or CLI
- File/directory: glob for
- Deduplicate — skip sources already present in the destination repo (if queryable)
- Report discovery:
Found 9 sources to induct:
3 Markdown stubs (.aiwg/research/queue/)
4 PDF papers (papers/2024/)
2 URI references
Skipping 1 (already inducted: REF-042)
Phase 2: Source Acquisition (acquire before analyze)
CRITICAL: Never write analysis docs from metadata or abstracts alone. The pipeline is: acquire full content → read full content → write analysis doc.
This was learned from a session where 88 of 120 papers were inducted as shallow stubs written from arXiv abstract pages — not the actual papers. See #817.
For each source, ensure full content is available before analysis:
For PDFs / full papers:
- Acquire the PDF — call
/research-acquire <url> --extract-textto download the PDF tosources/pdfs/full/and extract full text tosources/text/ - Verify acquisition — confirm the PDF exists at the expected path and is non-empty
- If the first path fails, do NOT conclude the source is unavailable. Run the unavailability gate below. Only after it completes may you record a deficit status, and never write a full analysis doc from the abstract alone.
For URIs (web sources):
- Fetch the full page (WebFetch) — save to
sources/web/<slug>.html - Classify: paper, blog post, official docs, repo README, specification, news
- If paper: call
/research-acquireto get the actual PDF — do not analyze from the landing page HTML - If non-paper web source: the fetched HTML/text is the full content — proceed to analysis
For Markdown stubs (from issue-planner queue files):
- Read the stub content and relevance summary
- If the stub references a paper URL: acquire the PDF first (same as above)
- If the stub is a research brief with no external source: proceed as-is
For issue references:
- Read full issue body and comments
- Extract referenced URLs, files, or topics
- If URLs point to papers: acquire PDFs before analysis
- If no external sources: treat as a research brief stub
Unavailability gate (before recording any acquisition deficit)
Applies to every source type above, not just PDFs. One failing request is not evidence of
unavailability. Before recording
pending-acquisition or acquisition-deficit, complete both steps and record what each
returned. Both are cheap; step B is cheaper than any network call.
A. Enumerate the host's access paths. Try them in order rather than inventing one:
| Host | Try, in order |
|---|---|
| Hugging Face | resolve/main/<file>, raw/main/<file>, api/datasets/<id>, api/.../tree/main?recursive=true, api/.../croissant, datasets-server/splits, hf-mirror.com |
| arXiv | /abs/<id>, /pdf/<id>, /e-print/<id> |
| Publisher DOI | publisher URL, Unpaywall, Europe PMC, Semantic Scholar openAccessPdf, arXiv full-text search, author/lab pages, institutional repository |
| Conference | ACL Anthology, PMLR, OpenReview, proceedings site |
Two traps worth naming, because both have produced false "gated" verdicts:
- On Hugging Face,
raw/main/README.mdcan return 401 whileresolve/main/README.mdreturns 200 with the complete card — same repo, same revision, same anonymous client. The API'sdescriptionfield is also truncated (~600 chars) where the card behindresolve/mainis not. export.arxiv.org/api/queryreturns 503 from some networks whilearxiv.org/absserves fine with a browser UA. An API failure is not source unavailability.
B. Check the corpus before declaring unavailable. Ask both, and record the answers:
- Does the corpus already hold a source that introduces, specifies or evaluates this artifact? Benchmarks, datasets, models and tools are usually defined in a paper, and that paper is often already inducted and text-extracted on local disk.
- Is there an open-access companion — preprint, technical report, or a same-group paper on the same subject — covering the claim the citing document needed?
Both are grep/index queries against sources/text/ and the corpus index.
Record the outcome as a named obstacle, not a bare flag. pending-acquisition alone
conflates four states that need different actions:
| State | Means | Action |
|---|---|---|
not-attempted |
ordinary backlog | do the work |
credential-required |
one credential away (e.g. needs HF_TOKEN) |
credential decision |
structurally-unobtainable |
closed access, N services checked | subscription decision, or accept |
artifact-absent |
the named artifact was never published | close as not-planned |
Write the state and the specific obstacle — structurally-unobtainable: closed access; Unpaywall reports zero OA locations; Semantic Scholar reports the publisher elided the abstract; no arXiv preprint — not acquisition-failed: true. A bare boolean cannot be
triaged, and the paths-tried record is what makes the verdict credible to a reader.
For tracker hand-off, mirror the state as a label (blocked:credential-required,
blocked:structurally-unobtainable, artifact-absent) so the distinction survives into
triage instead of collapsing into one undifferentiated queue.
Phase 2.5: Per-Source Analysis (on full content)
Read and follow the analysis and verification gates for every source. This required companion preserves the full-content analysis, quality, cheap-verification and compiled-bibliography checks, including obstacle registration and citation direction verification.
Phase 3: Induction Task Filing
For each analyzed source, file one induction task using the standard template.
Induction task body:
## Reference Induction
**Source**: <URL, file path, or issue reference>
**Type**: <paper | blog | docs | repo | spec | stub | issue>
**GRADE**: <A | B | C | D | unassessed>
**Priority**: <high | medium | low>
**Tags**: <topic1>, <topic2>
## Summary
<2–3 sentences: what this source covers and why it's relevant>
## Key Claims / Findings
- <Specific claim or finding>
- <Specific claim or finding>
- <Specific claim or finding>
## Relevance to Corpus
<How this relates to existing research — cross-references to REF-XXX if applicable>
## Induction Checklist
- [ ] Read full source
- [ ] Extract key insights as Zettelkasten notes
- [ ] Cross-reference with existing corpus
- [ ] Assign REF-XXX identifier
- [ ] Tag with topic taxonomy
- [ ] Assess with /research-quality
- [ ] Archive with /research-archive (if paper/PDF)
- [ ] Add to citation graph with /research-cite
### Cheap-verification gate
- [ ] Venue confirmed against an independent record (not a LaTeX template), or demoted to `preprint`
- [ ] Published version fetched and archived if peer-reviewed; diff vs preprint recorded
- [ ] Every asserted code/project/dataset URL probed
- [ ] Retraction check run (source + date recorded, null result recorded as null)
- [ ] Citation census run (source + date recorded)
- [ ] Every surviving uncertainty registered as a declared check, not written as prose only
### Bibliography
- [ ] Edges taken from the compiled bibliography (`.bbl` / inline / PDF list), not the shipped `.bib`
- [ ] Reference count states its counting method
- [ ] Each edge's confirmation method recorded; `.bib`-only rejections recorded
- [ ] Edge direction checked against publication dates
## Origin
- Surfaced by: <issue-planner | manual | other>
- Surfaced for: <objective or context>
- Induction date: <YYYY-MM-DD>
Filing based on --repo target:
- File path: write
induct-<slug>.mdto destination directory - Gitea URI/MCP:
mcp__gitea__issue_writewith labelresearch-induction - GitHub URI:
gh issue create --label research-induction - Jira URI: REST
POST /rest/api/2/issuewith issue type Task - Codehound MCP: register URI in search index, create stub document
Phase 3.5: Cross-Reference Fan-Out
After creating each new literature note, update the broader corpus with bidirectional cross-references. This is what makes a corpus compound rather than just accumulate.
Citation edges written here are subject to the bibliography ground truth rules in
Phase 2.5: membership comes from the compiled bibliography, each edge records its
confirmation method, .bib-only rejections are recorded, and direction is checked against
publication dates. Cross-referencing is where a fabricated edge becomes bidirectional and
therefore twice as expensive to unwind.
For each newly inducted source:
-
Search existing findings for topically related REF-XXX notes:
- Match by shared tags
- Match by overlapping key claims or methodologies
- Match by citation overlap (both cite the same sources)
-
Add "Related Sources" cross-references:
- In the new note: add a
## Related Sourcessection listing existing REF-XXX notes and how they relate (confirms, contradicts, extends, prerequisite) - In existing notes: append the new REF-XXX to their
## Related Sourcessection with relationship type - Before writing a citation edge in either direction, check the two publication dates. A work cannot cite something published after it; if the dates say otherwise, the edge is mis-directed or points at the wrong node.
- In the new note: add a
-
Flag contradictions or confirmations:
- If the new source contradicts an existing finding, add a
contradictionmarker to both notes - If it confirms an existing finding, add a
confirmsmarker
- If the new source contradicts an existing finding, add a
-
Update synthesis documents in
.aiwg/research/synthesis/:- If a relevant synthesis document exists, append a note that new evidence is available
Example cross-reference entry:
## Related Sources
- **REF-034** — Confirms: both identify prompt injection as the primary attack vector for LLM agents
- **REF-042** — Extends: this source adds quantitative benchmarks missing from REF-042's qualitative analysis
- **REF-067** — Contradicts: claims agent sandboxing overhead is <5%, while REF-067 measured 15-20%
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.
Skip conditions: Skip cross-referencing when:
--dry-runis set- Source is filed as a stub (not yet fully documented)
- Fewer than 3 existing REF-XXX notes in the corpus (too early for meaningful cross-refs)
Phase 4: Summary Report
## Induction Summary
| # | Source | Type | Priority | Filed At |
|---|--------|------|----------|----------|
| 1 | RFC 9110 HTTP Semantics | spec | high | gitea#301 |
| 2 | "Dapper" Google Tracing Paper | paper | high | gitea#302 |
| 3 | opentelemetry.io/docs | docs | medium | gitea#303 |
| 4 | github.com/jaegertracing/jaeger | repo | medium | gitea#304 |
| 5 | arxiv.org/abs/2012.15161 | paper | low | gitea#305 |
...
Inducted: 9
Skipped: 1 (already present)
Destination: gitea:roctinam/research
Next steps:
- /research-acquire <URL> for any paper that needs PDF download
- /research-document to annotate inducted sources
- /research-quality to score GRADE for each inducted item
Target Resolution Logic
resolve_target(target):
if target starts with "http://" or "https://":
host = extract_host(target)
if host matches known_gitea_instances: use mcp__gitea__issue_write
if host == "github.com": use gh CLI
if host matches jira pattern: use Jira REST API
else: fetch as web resource, induct as URI reference
elif target matches "gitea:<owner>/<repo>#<n>":
fetch issue via mcp__gitea__issue_read
elif target is a named MCP service ("gitea", "codehound", "github"):
use that service's write/register tool directly
elif target is a file path:
if path is directory: glob for .md/.pdf/.txt files
if path is a file: induct single source
Batch Mode — Directory of Papers
When target is a directory, process all supported files:
/induct-research papers/2024/ --repo gitea --tag llm --recursive
⏳ Scanning papers/2024/ (recursive)...
Found 23 PDF files
Found 7 Markdown stubs
Found 2 YAML records
Deduplicating against gitea:roctinam/research...
Skipping 4 (already inducted)
⏳ Analyzing 28 sources (parallel agents)...
✓ Batch A (7 sources): complete
✓ Batch B (7 sources): complete
✓ Batch C (7 sources): complete
✓ Batch D (7 sources): complete
⏳ Filing 28 induction tasks to gitea:roctinam/research...
✓ Inducted: 28 | Skipped: 4 | Total: 32
Integration with issue-planner
issue-planner --induct-research <target> 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.
/induct-research can also be invoked standalone to process:
- Pre-existing queues:
/induct-research .aiwg/research/queue/ - Ad-hoc papers:
/induct-research https://arxiv.org/abs/2307.09288 - Full directories:
/induct-research ~/Downloads/papers/ --repo gitea
Composition
induct-research <target>
│
├── Phase 1: Source discovery
│ ├── File/directory: glob + read
│ ├── URI: WebFetch + classify
│ └── Issue ref: mcp__gitea__issue_read or gh CLI
├── Phase 2: Source acquisition (acquire before analyze)
│ ├── PDF/paper → /research-acquire --extract-text
│ ├── URI → WebFetch full page → /research-acquire if paper
│ ├── Stub with URL → acquire referenced source
│ └── Unavailability gate before any deficit status
│ ├── A: enumerate the host's access paths, record each result
│ ├── B: corpus-first — introducing source? OA companion?
│ └── Record a named obstacle + state, never a bare flag
├── Phase 2.5: Per-source analysis (on full content only)
│ ├── PDF agent → read full text, extract claims + GRADE
│ ├── Web agent → read full saved page, assess credibility
│ ├── Stub agent → parse relevance summary
│ ├── Quality gate: flag docs under 80 lines as potential stubs
│ ├── Cheap-verification gate: venue, published version, URLs, census
│ │ └── Residue registered as a declared check, not prose
│ └── Bibliography ground truth: compiled .bbl over shipped .bib
├── Phase 3: Induction task filing
│ ├── File path → write .md task files
│ ├── Gitea URI/MCP → mcp__gitea__issue_write
│ ├── GitHub URI → gh issue create
│ └── Codehound MCP → register in search index
├── Phase 3.5: Cross-reference fan-out
│ ├── Search existing findings by tags + claims
│ ├── Add bidirectional Related Sources sections
│ ├── Flag contradictions / confirmations
│ └── Update synthesis documents
└── Phase 4: Summary report
References
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/skills/issue-planner/SKILL.md — Calls induct-research during Phase 2b
- @$AIWG_ROOT/agentic/code/frameworks/research-complete/skills/research-acquire/SKILL.md — Full PDF acquisition (called for paper URIs)
- @$AIWG_ROOT/agentic/code/frameworks/research-complete/skills/research-document/SKILL.md — Annotate inducted sources
- @$AIWG_ROOT/agentic/code/frameworks/research-complete/skills/research-quality/SKILL.md — GRADE scoring for inducted items
- @$AIWG_ROOT/agentic/code/frameworks/sdlc-complete/skills/address-issues/SKILL.md — Analogous pattern for code issues
- @$AIWG_ROOT/agentic/code/addons/aiwg-utils/rules/subagent-scoping.md — Parallel batch analysis constraints
- @$AIWG_ROOT/docs/verification-contracts.md — Declared checks; prose uncertainty must be registered as one (#2523)
- @$AIWG_ROOT/agentic/code/frameworks/research-complete/templates/citation-sidecar.md —
Confirmed by,Rejected Candidates,bibliographyandacquisition-obstaclefields (#2524, #2525) - @$AIWG_ROOT/agentic/code/frameworks/research-complete/skills/sidecar-lint/SKILL.md — Structural lint for the sidecars this skill writes
- @$AIWG_ROOT/tools/research/bibliography-resolver.mjs — Applies the bibliography hierarchy mechanically (#2525)
- @$AIWG_ROOT/agentic/code/frameworks/research-complete/docs/bibliographic-services.md — Per-service operating characteristics, the OpenAlex count trap, throttling budget (#2539)
- @$AIWG_ROOT/agentic/code/frameworks/research-complete/lint/uncertainty-registered.yaml — Flags uncertainty stated without an obstacle (#2523)
Storage Routing (#934, #968)
This skill's persistence flows through resolveStorage('research'). On the default fs backend the research corpus lives at .aiwg/research/. Heavy artifacts (papers, archived sources) can move to a secondary drive by setting roots.research in .aiwg/storage.config (one of the headline #934 use cases).
aiwg research-store path # resolved root
aiwg research-store list --prefix sources/
aiwg research-store get sources/paper-123.md
04 同仓库更多 Skills
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.
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.
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.
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.
fixture-skill
Exercise rule delivery.
pi-local
Pi-local duplicate-precedence fixture.