Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.altnautica.com/llms.txt

Use this file to discover all available pages before exploring further.

ados plugin lint runs the same static-analysis rule set the registry applies at submission time. Run it locally before you push a tag.

Quickstart

ados plugin lint dist/com.example.thermal-1.0.0.signed.adosplug
Output:
plugin com.example.thermal 1.0.0
archive size: 18432 bytes
score: 100/100
verdict: pass

no findings.
JSON form for CI:
ados plugin lint --json dist/com.example.thermal-1.0.0.signed.adosplug \
  | jq '.data.score, .data.passed'
Exit code 0 means pass. Non-zero means at least one finding at severity error or critical.

What it checks

The linter unpacks the archive and walks every entry. Findings are keyed by rule id with severity and the source location.

Python rules

RuleSeverityWhat it flags
PY001-os-systemerroros.system() call
PY002-os-popenerroros.popen() call
PY003-evalerroreval() call
PY004-execerrorexec() call
PY005-subprocess-shellerrorsubprocess.Popen(..., shell=True)
PY006-raw-socketerrorsocket.socket(...)
PY007-pickle-loaderrorpickle.loads() on untrusted input
PY008-marshal-loadserrormarshal.loads()
PY009-ctypes-loaderrorNative library load via ctypes.CDLL
PY020-requestswarnNetwork library imported without network.outbound
FS001-open-writeinfoFile opened for writing (verify the path is under ctx.data_dir)
FS002-shutil-rmtreeinfoshutil.rmtree() (verify scope is the plugin’s own directory)

GCS bundle rules

RuleSeverityWhat it flags
GCS001-top-locationwarnReads top.location or parent.location
GCS002-document-cookiewarnReads document.cookie
GCS003-localstoragewarnReads localStorage or sessionStorage
GCS004-evalwarneval() call in the bundle
GCS005-function-ctorwarnnew Function(...)
GCS006-fetch-directwarnDirect fetch() call (use the host bridge)
GCS007-xhr-directwarnDirect XMLHttpRequest
GCS008-websocket-directwarnDirect WebSocket

Manifest and archive rules

RuleSeverityWhat it flags
ARC001-archive-sizeerrorArchive exceeds the 100 MB cap
ARC002-entry-sizeerrorA single entry exceeds the per-entry cap
SIG001-unsignedwarnArchive does not carry a SIGNATURE file
VND001-vendor-binaryinfoManifest declares contains_vendor_binary
PERM001-high-riskinfoManifest declares a high-risk capability (vehicle.command, vehicle.payload.actuate, filesystem.host, mavlink.command.send)
info findings are advisory and do not affect the verdict. warn findings show in the report but still pass. error findings fail.

Score

Each finding deducts points:
SeverityPenalty
info0
warn2
error10
critical25
Floor at 0. The registry uses the same score; the auto-publish gate expects 90 or above plus zero error findings.

Network imports versus permissions

If your plugin imports requests, httpx, or aiohttp, the linter warns unless the manifest declares network.outbound. The host enforces this at runtime regardless. Declare the permission and the warning disappears.

False positives

The linter is conservative. If a finding is wrong for your case (the SDK wraps a syscall the rule did not learn yet, your eval is in a data file the linter mistakes for code), open an issue with the archive and the finding so the rule can be tightened.

Running before every release

Recommended pre-tag check:
./scripts/pack.sh my-plugin
ADOS_SIGNING_KEY=keys/altnautica-2026-A.pem ./scripts/sign.sh \
  extensions/my-plugin/dist/com.example.my-plugin-1.0.0.adosplug
ados plugin lint \
  extensions/my-plugin/dist/com.example.my-plugin-1.0.0.signed.adosplug
Wire this into your release workflow as a CI step before the GitHub Release upload. A failing lint should block the release.

See also