Contributing Skylos Audit - osama1998H/Moca GitHub Wiki
Skylos Static Analysis Audit
Cross-language dead-code detection plus SAST for the Go backend and the
desk/React-TS frontend.
Why
Moca ships with two audit surfaces. The Go side is mostly covered by golangci-lint (unused, govet, errcheck, staticcheck). The desk/ submodule previously had no dead-code or security linting — just tsc --noEmit. Skylos (Apache-2.0) fills that gap: dead-code across Go and TS/TSX, plus XSS/JWT/secret/SCA rules on the frontend.
One-time install
Skylos is a Python CLI. Use pipx so it lives in an isolated venv:
pipx install skylos
skylos doctor # confirms the install
pip install skylos works too, but pipx avoids polluting the system Python.
Running the audit
From the repo root:
make audit # Both audits (Go backend + desk/)
make audit-go # Go only — pkg/, cmd/, internal/ (desk/, wiki/, apps/ excluded)
make audit-desk # desk/ submodule only
The first two run with -a (all checks: dead code, danger, secrets, quality, SCA) and --baseline, so only new dead-code findings fail. Security/quality/SCA findings surface every run and are advisory today.
Overriding the skylos binary
If Skylos is not on PATH, export SKYLOS=/full/path/to/skylos and the Makefile targets pick it up.
Baselines
Baselines accept existing debt so CI gates only on regressions. They are committed to git:
| Baseline | Owned by |
|---|---|
.skylos/baseline.json |
Parent repo |
desk/.skylos/baseline.json |
desk/ submodule (osama1998H/moca-desk) |
Skylos only baselines the dead-code category. Danger, secrets, quality, and SCA findings are always reported.
When to refresh a baseline
Regenerate after a PR intentionally pays down dead-code debt:
make audit-go-baseline # Re-snapshot Go
make audit-desk-baseline # Re-snapshot desk/
Commit the updated baseline.json as part of the same PR. For desk/, the commit lives in the submodule repo — push it first, then bump the submodule pointer in the parent.
CI gate
A Skylos Audit (advisory) job runs on every push and PR as part of .github/workflows/ci.yml. The job installs Skylos (pinned to the same version the repo was tested against) and runs the same make audit-go and make audit-desk targets contributors use locally.
Current posture: advisory
The job carries continue-on-error: true, so Skylos findings cannot block a PR today. The red/green status is still visible on the PR — treat it as a signal, not a gate — but merges proceed either way. This lets us curate baselines and understand the false-positive rate without gumming up velocity.
Promotion to a required check
Remove continue-on-error: true in .github/workflows/ci.yml once:
- The job has been green on
mainfor one full week (no manual dismissals). - The two baselines (
.skylos/baseline.jsonanddesk/.skylos/baseline.json) reflect debt the team is willing to accept. - Branch protection is updated to mark
Skylos Audit (advisory)(rename the job to drop the suffix on the same commit) as a required status check.
What the gate blocks once it's promoted
- New dead-code findings (i.e., anything not in the committed baseline).
- Any security/secret/SCA/quality finding the
-apass surfaces — Skylos does not baseline these, so every new one is a regression by definition. Tune noise with--severity highin the Makefile targets if medium/low findings prove noisy.
Pinning
CI pins skylos==4.3.2 to match the version used to generate the committed baselines. Bumping requires regenerating both baselines in the same PR; mismatched baseline/tool versions can produce spurious diffs.
Suppressing false positives
Inline, per-line: // skylos: ignore
Per-rule, in config: ignore = ["SKY-XXX"]
Per-block: // skylos: ignore-start … // skylos: ignore-end
Prefer fixing the underlying finding to suppressing it. When suppression is unavoidable, include a short comment explaining why.
Troubleshooting
skylos: command not found— runpipx install skylos(orpip install skylos).- Unexpected new findings after pulling main — someone else may have refreshed a baseline. Re-run
make auditaftergit pull --recurse-submodules. - Cache issues —
skylos cleaninside the scanned directory removes.skylos/cache/.