Skip to content

Plan annotation work

Use the annotation worklist to decide which files still need an annotation. GuardLink 2.5.0 separates this work from parsing: excluding a file from annotation work does not erase annotations already written there.

  • GuardLink 2.5.0 installed.
  • A local repository. The output below comes from the ticket fixture, plus an unannotated src/worker.js, an SVG at public/assets/logo.svg, and a .gitignore containing node_modules/. The fixture is committed in Git.
Terminal window
guardlink unannotated . --json
{
"schema": "guardlink.annotation-worklist/v1",
"view": "git",
"summary": {
"worklist": 1,
"annotated": 1,
"excluded": 2,
"excluded_by_reason": {
"unsupported-extension": 1,
"asset": 1
}
},
"worklist": [
{
"path": "src/worker.js",
"reason": "unannotated"
}
],
"annotated": [
"src/users.js"
],
"excluded": [
{
"path": ".gitignore",
"reason": "unsupported-extension",
"detail": "no file extension, so no comment syntax to read"
},
{
"path": "public/assets/logo.svg",
"reason": "asset",
"detail": "SVG under `public/`; keep it with `worklist.keep` in .guardlink/config.json if it is a template"
}
]
}

worklist is the in-scope files with no annotation. annotated is the in-scope files already covered. excluded names why each other file is left out. view is git in this repository and walk outside a Git worktree.

For the text exclusion inventory:

Terminal window
guardlink unannotated . --excluded
⚠ 1 source file(s) with no annotations:
src/worker.js
2 file(s) left out of annotation work (.gitignore and .gitattributes read):
1 unsupported-extension
1 asset
.gitignore [unsupported-extension] no file extension, so no comment syntax to read
public/assets/logo.svg [asset] SVG under `public/`; keep it with `worklist.keep` in .guardlink/config.json if it is a template

Write this configuration:

.guardlink/config.json
{"include":["**/*.js"],"exclude":["src/users.js"]}

Run the JSON worklist again. The fixture’s exclusion inventory now includes:

{
"path": "src/users.js",
"reason": "config-exclude",
"detail": ".guardlink/config.json exclude `src/users.js`",
"annotated": true
}

Truncated to that entry. The model still contains the user’s asset, exposure and ticket. source_files counts in-scope files plus every annotated file; unannotated_files is this worklist. File coverage measures annotation scope, not how much code was security tested.

Patterns without / match at any depth; patterns with / are relative to the root. A matched directory covers its children.

An SVG under an asset directory is normally excluded as asset. To annotate this SVG as a template, replace the example config with:

.guardlink/config.json
{"worklist":{"keep":["public/assets/logo.svg"]}}

Run the worklist again. In the fixture, public/assets/logo.svg moves into worklist, with reason: "unannotated". This keeps a file from the automatic asset/generated-output rules; it does not turn the annotation scope into a parsing filter.

The JSON worklist also serves agents: guardlink_unannotated accepts format: "json". The compact guardlink_parse response omits both unannotated_files and annotation_scope by default; request include_unannotated: true for both. The graph response omits the scope inventory.

See Annotate an existing codebase for the writing step, and the MCP reference for the machine interfaces.