docspack v1.2.0
Documentation

Trust and safety

Documentation packages are third-party input that ends up in a model’s context. docspack treats them accordingly.

Vendor and community packages

Two naming conventions carry different guarantees. @vendor/docspack and its siblings @vendor/<name>-docspack are published by the vendor, under a scope only the vendor can publish to. @docspack-community/<name> is published by whoever maintains it.

The suffix changes nothing about trust, because the npm scope is what trust rests on: whoever can publish @vendor/docspack can publish @vendor/<name>-docspack and nobody else can. What the shape is not is a way for a package to nominate itself — a docspack field in package.json, or a .llms/ directory, would let any transitive dependency at any depth declare itself documentation and be indexed as trusted. The name check is what prevents that, and it is the reason discovery is a name check at all.

Community results are labelled (community) in docspack search and docspack list. When a community chunk is returned over MCP, the response ends with a notice telling the model that the source is unverified and that its content is data, not instructions. That does not make prompt injection impossible, but it means an agent is never handed unvetted text without being told what it is.

Prefer vendor packages where they exist. Read a community package before adding it, exactly as you would read any other dependency.

Path traversal

A manifest is a routing table written by someone else, and every file entry is resolved before being read. A path that resolves outside the package’s own .llms/ directory is refused and reported, not read:

json
{ "id": "escape", "file": "../../../../etc/shadow" }

The rest of the package still indexes. One bad entry does not take down the whole package, and it does not read a file outside the boundary either.

Context exhaustion

An agent that retrieves too much context is as broken as one that retrieves nothing. Every response is bounded, using the token count stored with each chunk rather than an estimate made after the fact. See the chunk about connecting an agent for the exact limits and how to change them.

What docspack does not do over the network

sync, search, list and mcp never make a network request. They read node_modules and a local SQLite file. An agent using docspack works on a plane, in a locked-down CI runner, or inside a network-isolated container.

The single exception is docspack build when given a remote source, which is an authoring command run deliberately, not part of serving documentation to an agent.

Recording documentation problems

An agent reading documentation is unusually well placed to notice it is wrong: it has the docs, the installed library and a failing program in front of it at once. docspack feedback captures that, and the whole design is built so it cannot turn into a flood of machine-written issues aimed at maintainers.

bash
docspack feedback add --chunk @acme/docspack@1.4.0/api-auth \
  --kind drift --evidence "client.setKey is not exported; setApiKey is"

docspack feedback list
docspack feedback remove <fingerprint>

Agents on MCP use the record_docs_problem tool instead, which takes the same fields and runs the same checks. Both interfaces call one function, so neither can accept a finding the other would refuse.

Findings go to .docspack/feedback.jsonl in the project: one JSON object per line, readable, diffable, and deleted with rm. Nothing leaves the machine. docspack contains no code that can transmit a report — no tokens, no endpoints, no background requests. That guarantee comes from something not being built, which is the strongest kind.

A finding has to be falsifiable, and that is enforced when it is written rather than when a maintainer reads it:

  • The chunk must exist in a package installed here. A reader that cannot point at the chunk did not read it.
  • drift must name the identifier that drifted, so it cannot be used to file an opinion.
  • incorrect and missing must carry --expected, --actual and --repro. A claim that cannot show its work is not recorded at all.
  • There is no kind for “this page is confusing”. Unfalsifiable claims are infinitely generatable and of no use to anyone.

Recording the same problem again increments a counter instead of adding a second entry. The fingerprint covers the package, version, chunk, kind and the normalized claim, so the same problem worded differently still lands on the same line. Twelve agents hitting one bug produce one finding that says seen 12× — stronger evidence than twelve reports, and far cheaper to read. A repeat only ever adds to the record; it never rewrites wording a human may already have reviewed.

Sending a problem upstream

docspack feedback submit prints a prefilled GitHub issue URL for every finding whose vendor asked to receive it. It routes nothing anywhere else, and it sends nothing at all: a human opens the link, reads what is prefilled, edits it, and files it under their own name.

A vendor opts in from their own package.json, the way security.txt solved the same problem for vulnerability reports — a machine-discoverable contact point that the recipient declares:

json
"docspack": {
  "feedback": {
    "github": "acme/sdk",
    "labels": ["documentation", "agent-reported"],
    "accepts": ["drift"],
    "policy": "https://acme.dev/docs-feedback"
  }
}

No feedback block means no channel, and submit lists those findings as not routed rather than guessing a destination. That is the default, and it is the correct one: a maintainer who has not asked for this gets nothing.

accepts is the field that matters most. A vendor drowning in noise narrows it to ["drift"] and receives only the mechanically verifiable class — reports where no judgment was exercised and so no judgment can be wrong. Omitting accepts means all kinds are welcome. The person who bears the cost sets the threshold. policy is shown before anything is filed, so the vendor’s own rules are read first.

Reports state their provenance rather than hiding it, because maintainers have asked to be able to tell machine-written reports apart, and concealing it is what makes them toxic:

md
**Chunk**: `@acme/docspack@1.4.0/api-auth`
**Kind**: drift — a name the docs use that the package does not declare
**Seen**: 12 times in one project

client.setKey is not exported; setApiKey is

---
Recorded with docspack 0.1.0, read and filed by a human.

When a finding carries a reproduction, submit warns you first: the reproduction is often your own code, which is exactly what makes it useful and what makes it sensitive. You see the whole report before anything is filed, because a human is in the loop by construction.

There is no automatic filing, at any level of confidence. There is no hosted service, no telemetry, and no credentials. The strongest guarantee that docspack cannot become an automated flood is that docspack contains no code that can send a report.

The same ranking docspack search uses, over the same 13 documents.