User Input
$ARGUMENTS
The User Input above decides how this command runs. Read it before proceeding.
Outline
You are giving Lagune a new specialty: a focused, language-agnostic security specialization the detect and verify phases load on demand, listed by the catalog and loaded directly with npx --yes lagune catalog <name>. You distill the user's source or topic into it. A specialization audits and explains a risk area, it never rewrites the user's code, and it never produces an attack input. The shape lives in template.md, next to this file, and the built-in specializations regex, javascript, and browser are worked examples to mirror, each read with npx --yes lagune catalog <name> from the project root.
The result is the specialization at .lagune/catalog/<name>.md and its one-line entry in the project's index, the catalog list in .lagune/configs.json, which the catalog merges with the built-ins. You write both, and both stay under version control with the rest of .lagune/. You never touch the user's source.
Step 1: Read the input
Take the User Input as the security source or topic to specialize in. It may be a pasted article or reference, or a short phrase such as "prototype pollution in our cache layer" or "GraphQL injection". If it is empty, ask the user what security concern the specialization should cover, then stop until they answer. Never invent a topic.
Step 2: Defense-only gate
This command is defense only. If the topic asks for offensive tooling, a working exploit, an attack payload, or detection evasion, refuse and explain that a specialization audits and explains, it never produces an attack input. Dual-use content is acceptable only in a clearly defensive framing.
Step 3: Settle the terrain and name, decide create or refine
First settle the terrain: what the specialization covers, never the vulnerability. The terrain is what the knowledge is about, and the attacks are what it teaches you to defend, so when the topic names an attack, settle on the surface that attack targets. For example, the built-ins set the rule: the regex specialization covers ReDoS, yet its terrain is regex, not redos. This same terrain is the title in Step 5 and the tags in Step 6, so name it once here.
The name is that terrain as a safe filename: lowercase, replace every run of characters outside a-z 0-9 - with a single -, trim leading and trailing -, and collapse repeats. Derive it from the terrain you settled, never from the raw topic, so an attack topic never becomes the name. If the terrain is unclear, ask the user for a short name for it. This name is also the identity of its entry in .lagune/configs.json.
List what the project already uses by running the catalog from the project root:
npx --yes lagune catalog
Then run npx --yes lagune catalog <name>. It prints the specialization the project resolves under that name, its own first and then the built-in, or reports that no specialization has that name.
- It exists (a built-in like
regex, or one you specialized before): this is a refine. Use what it printed as the base. Reconcile, never append: fold the new knowledge into the existing sections, keep what still holds, rewrite what changed, and preserve the file's shape. Never replace a built-in from scratch and never blindly clobber an earlier version.
- It is new: author from the template in Step 5.
Step 4: Gather scope
In plain language, work out what the specialization must check, what distinguishes a real finding from a false one, and what the safer shapes are. Ask the user only what you need to author it well. Keep everything readable by a non-developer.
Step 5: Author from the template
Fill in template.md, next to this file:
- Set the
# [SPECIALIZATION_DOMAIN] vulnerabilities title to the terrain you settled in Step 3.
- Keep the purpose line, the two rules under
## Rules, and the detect/verify shape under ## How to act on the result verbatim.
- Credit the source, when there is one. If the material the user gave you has an identifiable origin (an article title, an author, a link, a standard), keep the optional
> - Source: ... quote and fill it with a short plain credit. If the input was just a topic, or has no attributable source, drop that line entirely. Never invent a source.
- Under
## What to look for, add one ### block per risk class in scope, each in plain language: what the dangerous pattern is, why it matters, and how to make it safe (the Safer shape: line, or the bullet list / #### Common safer shapes variants the template's comments allow). Where a popular control is commonly mistaken for the fix, add the optional Does not close it: line, naming that decoy and why it leaves the risk open so it is never accepted as closing the finding. It may reference an existing deterministic hook only if one genuinely fits, never invent a new hook.
On a refine, apply these to the existing file rather than a blank one. Write no frontmatter: the tags live in the index, not the .md.
Step 6: Propose tags, the user confirms
Derive 2 to 4 tags by the same terrain principle as the name (Step 3): the terrain or ecosystem the specialization lives in, an abbreviation, its variation, the plain name, never the vulnerability itself. The built-ins set the shallow style: regex carries RegExp, Regular Expression; javascript carries JavaScript, Node.js, Deno, Bun; browser carries Browser, DOM, Navigator. Propose a flat list of candidate tags and let the user add and drop any freely, never a fixed set to pick one from. On a refine, start from the existing entry's tags and reconcile them the same way.
Step 7: Write the files
-
Ensure .lagune/catalog/ exists, then write .lagune/catalog/<name>.md with the authored or reconciled content. An existing name is reconciled from its current content first, so this never discards a built-in or an earlier version unseen. On a refine of a built-in, this file becomes the project's own version and shadows the built-in from then on.
-
Update .lagune/configs.json. If the file or its catalog list is absent, create it. Add the { "name": "<name>", "tags": [...] } entry to that list, or on a refine rewrite that one entry, preserving every other entry and every other field untouched.
-
Run the catalog again from the project root and confirm it lists the entry with the tags the user confirmed:
npx --yes lagune catalog
Step 8: Summarize
In plain language, tell the user the specialization's name, its tags, what it covers, and that the detect and verify phases now load it on demand (and they can load it directly with npx --yes lagune catalog <name>), mentioning it shadows any built-in of the same name on a refine. Suggest a commit message such as feat: specialize Lagune in <name>. Say it as a suggestion, not a mandate.