Skip to content

Decisions

This project keeps a firm line between a decision — a hard-to-reverse commitment — and a finding that has not yet hardened into one. Only the first belongs here; the rest is research.

Adopt the Agent Skills standard; do not invent a format. A skill is a SKILL.md directory with name and description, per agentskills.io. Inventing an alternative beside a working one buys nothing and costs a migration — it was this project’s own first mistake. The format has since been adopted unchanged by a major vendor, which makes it the obviously right call.

Conform where a convention works; reject what cannot be reconciled; propose only the unclaimed part. Where an ecosystem already has a convention, emit into it rather than arriving with a rival layout. Where a convention exists but carries a defect this project has measured — the in-jar bundling that drops out of an Android AAR, the scan-everything-into-context loading model that has no aggregate budget — do not adopt it, and say why with evidence. The one genuinely unclaimed part, an index that makes many skills usable at scale, is proposed everywhere.

Get library content from what already ships. Library documentation is obtained from the -sources.jar every library already publishes (93–98% adoption), the first-party source tree, and the git repository named in the POM — never a bespoke artifact. The sidecar approach is abandoned. This settles getting the content; parsing, storing and querying it are the next stages.

Library content never reaches the instruction channel, and the transitive tail is off by default. An agent that reads harvested library documentation can be redirected by an instruction planted in it. We measured this across agents from several vendors, and the result is architectural: presenting the text as quoted, untrusted data helps, but it is not sufficient — moving the same text into the system channel defeats it outright, and a payload that simply argues the untrusted-data framing is a test defeats it on models it otherwise protects. Since no property of the agent can be relied on, the control has to sit in the codex: library prose is placed where it cannot be followed, and the transitive tail — the bulk of the surface — is excluded unless asked for. This is a negative result about this project’s own proposal, and it is published with the mitigation rather than after it. One honest gap in it: excluding the tail has been justified twice, for selection and for security, and on neither occasion was the cost measured. What that exclusion loses is under investigation.

Since then (September 2026). The lookup we are now trying departs from this on two points, as an experiment rather than a reversal. It covers everything a project’s code can import by default, because when measured 11 of 17 capabilities a developer reached for lived only in the tail. And it hands an agent a library’s own skill as written — marked as the authors’ documentation, served only for libraries the project chose and for the version it resolved, never as permission to run or install anything — rather than a rewrite. That gives up the codex’s control in exchange for a far smaller surface: text a library’s own authors wrote for this purpose, not every comment in its source. The measurement above still says framing alone is not sufficient; whether the narrower surface holds is part of what the trial is for.

Publish security findings as observations, not verdicts. Per-model results are reported as what was measured, on what date, at what sample size — never as a trust judgement about a vendor’s model, because the samples are small and the cost of over-claiming lands on someone else. Conclusions that generalise are stated about architecture, which every agent tested supports. Payloads published with the work demonstrate the class and are never tuned to maximise bypass rates. Named vendors are told before the results go out and are offered a right of reply, as a courtesy rather than an embargo — prompt injection is a known, unfixed class, so there is no patch to wait for.

Current research directions, not commitments:

  • Parsing, storing and querying the content. Getting the content is decided; extracting the documentation from the carrier (reusing the API-extraction tooling IDEs already run at scale), storing it as a codex and serving it are the next stages. The measurement underneath them — whether harvested documentation actually changes what an agent writes — has since been run, and it does; what remains is building the pipeline against real corpora rather than synthetic ones.

  • A two-layer index — a small always-present trigger, plus an on-demand catalogue that maps a need to a library and records which one this project reaches for. Several vendors have independently converged on the shape. Retrieval has now been measured in both layers, so what is still open is the engineering rather than the premise.

  • Information-flow control as the trust model. The injection mitigation above is positional — it puts library prose where it cannot be followed — but it still depends on the agent declining to act, which is where the measurement found the weakness. A published alternative labels content and enforces policy before a sensitive tool runs, so persuasion cannot reach anything that matters. A codex cannot enforce at the agent, but it is the natural place to compute the labels. The falsifiable experiment has now been run. Enforcement does prevent the harm — under both policies the planted credential never reached a log. But the crude implementation, tracking labels across the whole conversation, also blocked the developer’s own work every time, because the attack causes the read that taints the context that refuses the write. Harm prevented, nothing done. So label granularity is a requirement rather than a refinement, and nothing is committed to yet. Two cheaper controls beat it on both axes in the same test: a tool-less paraphraser in front of the agent, and shipping the agent no prose at all — just the symbol and signature.

    The related idea — that a harvester could refuse content outright at the one boundary it owns, where documentation enters the index — has been measured and dropped. Checking documentation against the code it ships with catches only about a third of attacks from an independent benchmark, and the misses are structural: data leaving through the agent’s own output, config poisoning, resource abuse, encoded payloads. A control that misses two thirds cannot justify removing real capability, so the gate was not built. The signal was briefly kept as a warning, then withdrawn as well: on a real dependency graph its false-positive rate is twenty times what five hand-picked libraries suggested, because one library family links its issue tracker from nearly every doc comment.

  • A capability server, local first, as a query front-end over the corpus. What injection means for it is now settled above; what remains open is the server’s own shape.

  • How the lighter half is packaged. A library’s skill ships in its sources jar with a few lines of build configuration (how our libraries do it), so no build plugin is needed for that. What a developer installs to read it — a command, an MCP server registered once per machine, or the lookup carried inside an agent skill as a script — is open, and so is whether our Gradle and Maven plugins are published at all.

The full trail is in the research. When a direction hardens into a commitment, it graduates to a decision and moves up here.

Text on this site is licensedCC BY 4.0; source code underApache 2.0. © 2026 Brill Pappin.