AgentStack
SKILL unreviewed MIT Self-run

Answer From Corpus

skill-chrisgagne-grounded-forge-answer-from-corpus · by chrisgagne

Source-grounded answer to a question via shape-aware retrieval: classifies the query as a named lookup, a diagnostic, or a synthesis, then runs the right protocol (direct route, task-index → distillations → deeps, or three-pass index/Chroma → lights → deeps). Stops on sub-claim coverage, not on counts.

No reviews yet
0 installs
7 views
0.0% view→install

Install

$ agentstack add skill-chrisgagne-grounded-forge-answer-from-corpus

Open-source listing — not yet scanned by AgentStack. Follow the source repository for install instructions.

Security review

⚠ Flagged

1 finding(s); flagged for manual review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures
  • high Dangerous shell/eval execution.

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution Used

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Answer From Corpus? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Answer from library

Source-grounded answer protocol for any substantive question the library may cover. The library is the assembled body of references and distillations the skill is searching; the matrix is the architectural pattern (reference × task projection) that pre-shapes how the library is organised. Invoke this skill to operationalise the bundled CLAUDE.md's grounding directive: CLAUDE.md sets the principle (search before reasoning from priors; cite or admit guessing), this protocol runs it as executable steps: shape-classification, traceability, citation density, library breadth.

Procedure

Path convention. Every path in this skill is written from the source-repo perspective: corpus.commons/demo/{file}. When /answer-from-corpus runs inside a deployed application (any subdir of corpus.commons/demo/apps/, e.g., apps/decision/, apps/stakeholder/, apps/software-business/), the corpus.commons/demo/ prefix is stripped one-to-one: reference-index.json resolves as ./reference-index.json, distillations/{task}/task-index.json as ./distillations/{task}/task-index.json, references/{slug}.md as ./references/{slug}.md, and so on. The rest of every path is unchanged. The deployed-app CLAUDE.md documents the bare-path layout from the app's own perspective; this skill's corpus.commons/demo/ literals are the source-repo equivalents. Translate at read time; do not paginate or grep for files the literal path-string fails to find.

--corpus {slug} flag. When the operator passes --corpus my-corpus in the invocation (e.g., /answer-from-corpus --corpus demo What is a definition of done?), the skill targets corpus.commons/{slug}/ or corpus.local/{slug}/ instead of the default. Use the flag in two cases: (a) the source repo carries more than one commons or local corpus and the active one is ambiguous; (b) the operator wants to route a query against a specific named corpus regardless of CWD. Default resolution: if the CWD is inside a deployed app, use the bundled corpus (bare paths); if the CWD is inside the source repo and exactly one commons corpus exists, use it; if more than one corpus exists and no flag is passed, refuse with a one-line list of available corpora and ask. The trace footer names the corpus resolved-against: corpus: demo or corpus: my-corpus.

Step 0: Classify the query shape

Before any reads, classify the question:

  • Named lookup. The user names a specific framework, author, work, or concept ("walk me through the OpenStax Principles of Management chapter structure", "what does TC 25-20 say about the AAR cycle", "tell me about Dekker's Just Culture as treated in the corpus"). Signal: the answer reduces to what does this one source say. → Protocol N.
  • Diagnostic. The user describes a situation that needs reference-mediated guidance ("how do I handle a stakeholder conflict", "I need to make a decision under uncertainty"). Signal: there's a task domain in play, and the corpus has distillations for it. → Protocol D.
  • Synthesis. The user asks what the corpus says about a broad topic ("what is Agile", "what does the library say about employee motivation"). Signal: the answer benefits from breadth across multiple authors/traditions and the question is not a named lookup or in-task diagnostic. → Protocol S.

When ambiguous, default to the more expansive protocol (S over N, D over N). Never ask the user to disambiguate unless genuinely unclear.

Step 0.5: Lens-applicability check

After classifying the query and before any reads, check whether a lens materially reweights what's salient for this query.

Skip this step for Protocol N. Named lookups answer what does this one source say; a lens would distort, not clarify.

For Protocols D and S:

  1. Read [lens-index.json](../../../lens-index.json) unconditionally. The lens index is a small curated runtime artefact (one entry per lens under lenses.{slug}). Each entry carries kind, spec_path, purpose, reach_for_when, and a structured salience block (notices_first, recedes, native_vocabulary as a list of phrases) that primes the lens's vocabulary at a glance. Read it the way the task-axis indexes are read: as a map, not a search target. Always read it for Protocols D and S; do not short-circuit on a query that seems lens-neutral, because the detection in step 2 is what reads the entries against the query, and that detection needs the index loaded. The companion operator-inspection view at lenses/LENS-INDEX.md carries the same data in prose form; the JSON is the runtime source of truth.
  2. Detect the lens-shaped signal. The deliverable is lens-shaped when it asks for role-specific guidance, a perspective-bound read, an artefact aimed at a named reader-type (CTO, PM, executive, builder), a query asking for a named living person's voice or for their published framings to be applied to the artefact (real-person lens), an AAR/retro write-up where reader-role is load-bearing, a coaching brief, or process/RACI documentation where role-and-circumstance is the unit of analysis. If the query is lens-neutral (a generic synthesis question with no reader-bound output), no lens applies and the rest of the protocol runs unmodified.
  3. Name the lens(es) the index surfaces and confirm with the operator before proceeding when more than one lens could apply or when the choice changes the deliverable's shape materially. When exactly one lens fits unambiguously, name it in the trace and proceed without asking.
  4. For most lens-shaped queries, the index entry is sufficient: the salience block carries enough of the lens's vocabulary (notices-first / recedes / native-vocabulary) to apply at retrieval time. Read the full spec at the path under lenses.{slug}.spec_path (e.g., lenses/cto.md) only when the query needs the lens's grounding contract, fire-list, or trust-breaking-failure-mode reasoning, i.e. when why this lens reads what it does is material, not just what it reads. Citation-grade synthesis, real-person voice fidelity, and high-stakes artefact shaping are the typical cases.
  5. At retrieval, prefer a pre-projected (source, task, lens) distillation when one exists. If the distillation is lens-neutral in this build, apply the lens at query time via the index entry's salience block (and the full spec's Salience and vocabulary section if Step 4 says read the full spec): the retrieval-time fallback documented in [projection-protocol.md](../creating-distillations/projection-protocol.md) §Retrieval-time fallback.

Lens application shapes salience and voice; the matrix-axis reads (task index → distillations → deeps) run unchanged. The trace footer names the lens used (or "no lens" when the deliverable was lens-neutral).

**Step 0.5 runs before sub-claim decomposition.** The lens shapes what the sub-claims should be: a CTO-lens memo and a builder-lens runbook decompose the same source question into different sub-claim lists. Decompose after the lens is named, not before.

Sub-claim decomposition (Protocols D and S)

For Protocols D and S, before reading reference files, decompose the question into the 3-10 sub-claims the answer will need to make. Write the sub-claim list out explicitly. Examples:

  • "What is Agile?" → origin/motivation; key principles; methodology family; common failure modes; critique/limits; evolution post-Agile.
  • "How do I handle a stakeholder conflict?" → identify positions vs interests; surface the conflict safely; structure the conversation; close to commitment.

The sub-claim list is the coverage map for retrieval. Stop reading when every sub-claim has at least one strong source AND the next read would only thicken existing coverage.

Skip decomposition for Protocol N: a named lookup has one sub-claim by construction.

Protocol N: Named lookup

  1. Route directly. Read the corpus catalogue at reference-index.json: top-level shape is {schema_version, corpus, generated_from, refs}; the per-entry catalogue lives under the refs field, keyed by 3-character slug-ID (e.g., refs["00h"]) with each entry carrying {slug, author, year, title, primary_topic, concept_tags, lines_light, lines_deep, scope}. To resolve a named source: scan refs entries for an author/title/concept_tags match, take the entry's slug field, then read references/{slug}.md and {slug}-deep.md. The ID is the join key for concept-index and task-index cross-references; the slug is the file-path key. For task-bound named references also read the relevant task-axis index at distillations/{task}/task-index.json.
  2. Read the light first. references/{slug}.md for orientation.
  3. Read the deep. references/{slug}-deep.md if the question needs citations or substantive treatment. For "what is X" questions and for full-coverage signals ("walk me through", "every section", "full map") read the deep regardless of regime. For "remind me of X" questions, the light alone may suffice. Pick the regime (Citation-grade / Depth-over-breadth / Orientation: table under Protocol S Pass 3) the same way Protocol S does; for a Named lookup with explicit "with citations" or scholarly context, or with a defensibility-critical / under-legal-review framing, fire Citation-grade and surface evidence-classification markers. Long-deep pagination: if reference-index.json's refs[id].lines_deep for the slug exceeds ~400, apply the EOF-successive-reads pattern under Pass 1's cap-aware surfaces and label each read in the trace.
  4. Read the distillation if the question is task-bound: distillations/{task}/{slug}-{task}.md.
  5. Stop. No triage, no breadth sweep.

Protocol D: Diagnostic

  1. Decompose the question into 3-6 sub-claims (see above).
  2. Read the task-axis index at distillations/{task}/task-index.json. The JSON partitions the task into named phases or situations (each a section) and lists which references apply to each (rows as [need, slug-id, when] triples). Resolve each slug-ID via references/slug-table.json (top-level shape {schema_version, corpus, generated, next_id, slugs}; the id → slug mapping lives under slugs.{id}) or via reference-index.json["refs"][id].slug; either gets you the file-path key for references/{slug}.md, {slug}-deep.md, and distillations/{task}/{slug}-{task}.md. Note: the larger task-axis indexes exceed the Read tool's 25k cap: see Pass 1's cap-aware surfaces and the EOF-successive-reads pattern; for Protocol D prefer the python3 query against sections[].rows since you know the phase from step 3.

Unlike Protocol S Pass 1, Protocol D does not require the corpus-level indexes (reference-index.json, concept-index.json) by default: the task-axis index plus the slug-table resolve the candidate sources. Read the corpus-level indexes only if the task-axis index doesn't surface a match or the question crosses the task axis.

  1. Identify the relevant phase or situation for the question.
  2. Lean-mode check (when --lean is passed). If the index surfaces ≤ 2 sources for the identified situation, skip Step 5 (distillations read) and proceed directly to Step 7 (deep refs against the named sources). The index has already done the routing the distillations would do; on canonical material with good filename hygiene, reading the distillations is content-routing overhead. The default (without --lean) is to read the distillations regardless. The flag is the operator's opt-in to the cost-collapse hypothesis: that the curated index is sufficient to route directly to deep refs when it points at one or two sources for a situation. Hypothesis under test: collapsing this step on canonical material brings D's tokens within ~1.5× of Method C without rubric-quality loss; on non-canonical material the distillations layer is doing real work and lean-mode should hurt. Run the eval suite to test.
  3. Read every distillation the index surfaces for that phase/situation (typically 2-5 in this corpus). Distillations at distillations/{task}/{slug}-{task}.md are pre-projected for exactly this shape; trust the projection.
  4. Tag each distillation against the sub-claim list. Stop when every sub-claim has at least one strong source AND the next distillation would only restate.
  5. Read the deep ref for any author whose argument is doing real work in the answer: references/{slug}-deep.md. The threshold is "would I cite this author?": yes → read the deep. Pick the regime (Citation-grade / Depth-over-breadth / Orientation: table under Protocol S Pass 3) and apply its Pass-3 behaviour; for diagnostic queries the Depth-over-breadth regime is the default, and the distillation-carries-projected-citations calibration applies. The Citation-grade regime fires under D step 7 when the query carries defensibility-critical signals (legal review, audit context, "with citations", manager-pushback): when it fires, apply the Pass-3 read-scope rule under Protocol S Pass 3 (full deep vs targeted re-validation per defensibility unit). Long-deep pagination: if reference-index.json's refs[id].lines_deep for the slug exceeds ~400, apply the EOF-successive-reads pattern under Pass 1's cap-aware surfaces and label each read in the trace.

Protocol S: Synthesis

Three explicit passes:

Pass 1: Routing. Decompose the question into 5-10 sub-claims. Then route:

  • Precondition gate: read three corpus-level JSON indexes plus the task-axis index(es) for the domain(s) in play.

Corpus-level (always loaded):

  • references/slug-table.json: slug ↔ ID mapping; load once per session. The id → slug map lives under the top-level slugs key (full shape: {schema_version, corpus, generated, next_id, slugs}).
  • reference-index.json: file catalogue (one entry per reference: author, year, title, primarytopic, concepttags, scope, line counts). The catalogue's per-ID entries live under the top-level refs key (full shape: {schema_version, corpus, generated_from, refs}); query as ri["refs"][id].
  • concept-index.json: concept axis with aliases and per-source pointers (entries under top-level concepts). Schema: every source entry carries {id} and most carry {context}; the {section, md_line} pair is best-effort, present when the build's mechanical match resolved (~57% of source mentions on the demo corpus, ~65% of concepts have at least one pointer), absent when it didn't. When the pointer is absent, fall through to grep -n against the deep ref to find the passage.

Task-axis (load when the question fits a domain):

  • distillations/{task}/task-index.json: situation router. For grounded-forge's shipped axes (decision-making, stakeholder-engagement, software-business), read the index for each domain that applies; for synthesis questions that span both decision-making and stakeholder-engagement, read both.

Cap-aware surfaces. Several runtime artefacts in the demo corpus either exceed or sit close to the Read tool's 25k single-call cap; each has a specific access pattern:

  • concept-index.json (~22k tokens): query a specific concept with python3 -c "import json; ci = json.load(open('concept-index.json')); c = ci.get('concepts', ci); print(json.dumps(c.get('{slug}'), indent=2))". Concept slugs are kebab-case canonical names (e.g., after-action-review, just-culture, dual-process-theory). Aliases live inside the canonical entry's aliases array, not as top-level keys: to resolve an alias (e.g., aarafter-action-review), reverse-lookup with python3 -c "import json; ci = json.load(open('concept-index.json'))['concepts']; alias = 'aar'; print(next((k for k, v in ci.items() if alias in v.get('aliases', [])), None))" then probe the canonical key. Try both singular and plural forms; aliases are typically stored singular. Bash querying preserves the index's structure cheaper than pagina

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.