@xenos1996/usat 1.1.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bootstrap/catalog.d.ts +41 -0
- package/dist/bootstrap/catalog.d.ts.map +1 -0
- package/dist/bootstrap/catalog.js +366 -0
- package/dist/bootstrap/catalog.js.map +1 -0
- package/dist/bootstrap/index.d.ts +36 -0
- package/dist/bootstrap/index.d.ts.map +1 -0
- package/dist/bootstrap/index.js +174 -0
- package/dist/bootstrap/index.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +49 -0
- package/dist/cli.js.map +1 -1
- package/dist/engine/audit.d.ts.map +1 -1
- package/dist/engine/audit.js +18 -1
- package/dist/engine/audit.js.map +1 -1
- package/dist/util/project.d.ts +10 -0
- package/dist/util/project.d.ts.map +1 -1
- package/dist/util/project.js +19 -4
- package/dist/util/project.js.map +1 -1
- package/docs/adr/0012-self-extension-via-bootstrap.md +56 -0
- package/docs/adr/README.md +14 -13
- package/docs/ci-integration.md +12 -11
- package/docs/configuration.md +14 -0
- package/docs/reference/cli.md +5 -0
- package/docs/release.md +87 -0
- package/docs/rule-packs.md +17 -0
- package/package.json +1 -1
- package/rules/core/security.yaml +3 -1
package/docs/release.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Releasing USAT — operations runbook
|
|
2
|
+
|
|
3
|
+
The release pipeline is fully automated. Normal operation requires nothing
|
|
4
|
+
beyond merging PRs. This file exists so future-you (or a successor) can
|
|
5
|
+
reconstruct _why_ every piece is shaped the way it is, and what to do when
|
|
6
|
+
something breaks. It is the durable memory of the sessions that built it.
|
|
7
|
+
|
|
8
|
+
## The chain (normal operation — nothing to do)
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
conventional commit on master
|
|
12
|
+
│ feat → minor · fix → patch · BREAKING CHANGE → major
|
|
13
|
+
│ (docs/chore/test ride along without bumping)
|
|
14
|
+
▼
|
|
15
|
+
release-please opens/updates ONE Release PR
|
|
16
|
+
(version bump + CHANGELOG entries as a reviewable diff)
|
|
17
|
+
│ human merges it ← the only manual step, and it is code review
|
|
18
|
+
▼
|
|
19
|
+
tag vX.Y.Z cut automatically
|
|
20
|
+
▼
|
|
21
|
+
release.yml publishes: OIDC → npmjs (+ provenance + SBOM artifact),
|
|
22
|
+
then mirrors the same tarball to GitHub Packages (repo Packages tab)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
What you do: write conventional titles, review PRs, merge the Release PR.
|
|
26
|
+
Everything else — bump arithmetic, CHANGELOG entries, tags, publishing,
|
|
27
|
+
provenance, SBOM — happens on its own.
|
|
28
|
+
|
|
29
|
+
## One-time setups (done — do not redo unless broken)
|
|
30
|
+
|
|
31
|
+
| # | Setup | Where / state |
|
|
32
|
+
| --- | ------------------------------------------------------------- | --------------------------------------------------------- |
|
|
33
|
+
| 1 | Package exists on npmjs as `@xenos1996/usat` (scoped: the | Done at 1.0.0. Never republish a version. |
|
|
34
|
+
| | bare name `usat` is blocked by the typosquat filter) | |
|
|
35
|
+
| 2 | OIDC trusted publisher (org `Er-Sajan-PLG`, repo | Package page → Settings → Trusted Publisher. |
|
|
36
|
+
| | `software-auditing-template`, workflow `release.yml`, no env) | Exact basename — full paths do not match. |
|
|
37
|
+
| 3 | Trusted publisher may **publish directly** | Same page (checkbox). Without it, PUTs 404. |
|
|
38
|
+
| 4 | Publishing access: strictest (2FA required, no bypass tokens) | Same page. OIDC works with either option. |
|
|
39
|
+
| 5 | `RELEASE_PLEASE_TOKEN`: fine-grained PAT, this repo only — | Repo Settings → Secrets → Actions. **Check its expiry** |
|
|
40
|
+
| | Contents + PRs + Issues read+write | (Settings → Developer settings → Tokens): when it lapses, |
|
|
41
|
+
| | | Release PRs silently stop appearing. Rotate yearly. |
|
|
42
|
+
|
|
43
|
+
The bootstrap token used for the first manual publish is deleted. No
|
|
44
|
+
static credential that can publish exists anymore — only OIDC (CI) and
|
|
45
|
+
2FA (humans).
|
|
46
|
+
|
|
47
|
+
## Recurring (calendar, not automation)
|
|
48
|
+
|
|
49
|
+
- **PAT expiry** — the one thing that silently breaks releases. Check the
|
|
50
|
+
date when the reminder fires; generate a replacement with identical
|
|
51
|
+
scope, swap the secret, delete the old token.
|
|
52
|
+
- **First-run review of each Release PR** — read the CHANGELOG diff;
|
|
53
|
+
release-please derives it from titles, so a sloppy title ships a sloppy
|
|
54
|
+
note. Fix by amending the title before merge (it recalculates).
|
|
55
|
+
- **Scorecard / Security tab** — glance monthly; the workflow already runs.
|
|
56
|
+
|
|
57
|
+
## Troubleshooting (every failure hit so far, in order)
|
|
58
|
+
|
|
59
|
+
| Symptom | Cause | Fix |
|
|
60
|
+
| ------------------------------------------------------ | ------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
61
|
+
| `403 … too similar to existing packages` on publish | npm typosquat filter on the bare name | Scoped name (`@xenos1996/usat`). Decided, shipped. |
|
|
62
|
+
| `bin[usat]` "invalid and removed" warning on publish | npm v12 rejects `./`-prefixed bin targets; tarball ships with **no executable** | `bin` value is `dist/cli.js` (no prefix). Never re-add `./`. |
|
|
63
|
+
| `npm sbom -o` → `EUNKNOWNCONFIG` | No `-o` flag exists; SBOM goes to stdout | Redirect: `npm sbom … > sbom.cdx.json`, after a clean `npm ci` (partial trees fail with `ESBOMPROBLEMS`). |
|
|
64
|
+
| PUT 404 with provenance signed fine | Runner npm too old for the registry OIDC exchange (needs npm ≥ 11.5.1 / Node ≥ 22.14) | `release.yml` pins Node 24 + `npm@^11.15.0` floor. Do not downgrade. |
|
|
65
|
+
| Tag cut, GitHub Release created, **nothing published** | Tags pushed by `GITHUB_TOKEN` never fire downstream workflows (loop prevention) | release-please uses the PAT, never the default token. |
|
|
66
|
+
| Release PR lint red on `CHANGELOG.md` | release-please writes double blank lines; prettier wants single | `CHANGELOG.md` is prettier-ignored (machine-written). |
|
|
67
|
+
| `Unable to resolve action ossf/scorecard-action@v2` | Upstream publishes no `v2` major tag | Pinned exact `v2.4.4`. Check for newer semver occasionally. |
|
|
68
|
+
| `usat --help` audited the repo | Arg parser files `--flags`, never positionals; the switch cases were dead code | Fixed in `cli.ts` with regression tests. Do not reintroduce flag handling without a test. |
|
|
69
|
+
| `SEC-003` failing on `https://` URLs (pre-1.0 history) | Pattern used `https?://` for a plaintext-HTTP rule | Fixed to `http://`; rule carries a `NOTE:` comment. See `tests/rules.test.ts`. |
|
|
70
|
+
|
|
71
|
+
## Manual fallback
|
|
72
|
+
|
|
73
|
+
If automation ever wedges: Actions → **Release** → Run workflow (on
|
|
74
|
+
`master`) publishes whatever `package.json` holds. Safe to re-run — a
|
|
75
|
+
duplicate version fails closed at the registry with nothing mutated.
|
|
76
|
+
Never push `v*` tags by hand; the tag is the release act and belongs to
|
|
77
|
+
release-please (bootstrap tag `v1.0.0` excepted).
|
|
78
|
+
|
|
79
|
+
## Decisions with permanent consequences
|
|
80
|
+
|
|
81
|
+
- **No moving `v1` tag.** It would retrigger `release.yml` (`v*` matches)
|
|
82
|
+
and fail on the duplicate version. Docs pin exact versions instead.
|
|
83
|
+
- **No semantic-release.** Rule-pack content keeps its human gate; fully
|
|
84
|
+
automatic publishing is the wrong risk profile here (see ROADMAP.md).
|
|
85
|
+
- **npmjs is the source of truth; GitHub Packages is a mirror.** Old
|
|
86
|
+
versions were never backfilled to GPR — two sources of truth for dead
|
|
87
|
+
versions is worse than a thin Packages tab for one cycle.
|
package/docs/rule-packs.md
CHANGED
|
@@ -276,3 +276,20 @@ usat audit . --include stacks/mobile --depth deep
|
|
|
276
276
|
|
|
277
277
|
A pack with a YAML syntax error is skipped with a warning on stderr — the audit never
|
|
278
278
|
crashes because of a bad rule file.
|
|
279
|
+
|
|
280
|
+
## Starting from `usat bootstrap`
|
|
281
|
+
|
|
282
|
+
For a language with no shipped pack, `usat bootstrap <path> [--out <dir>]`
|
|
283
|
+
drafts a starter pack from the curated catalog (or generic judgement
|
|
284
|
+
prompts for unknown languages). The draft is a proposal, not a verdict —
|
|
285
|
+
see ADR-0012. The acceptance ritual before registering it in
|
|
286
|
+
`rules/index.yaml`:
|
|
287
|
+
|
|
288
|
+
1. Read every pattern; delete any that misfires on the target codebase.
|
|
289
|
+
2. Audit one project WITH the problem and one WITHOUT it; both runs must
|
|
290
|
+
behave (`usat audit --rules-dir` accepts an unregistered pack dir, so
|
|
291
|
+
the review never pollutes the shipped registry).
|
|
292
|
+
3. Add FP _and_ FN regression tests to `tests/rules.test.ts`.
|
|
293
|
+
4. Register the reviewed file in `rules/index.yaml` and watch the
|
|
294
|
+
self-audit-adjacent gates (`check-docs` rule floor, e2e uniqueness)
|
|
295
|
+
stay green.
|
package/package.json
CHANGED
package/rules/core/security.yaml
CHANGED
|
@@ -136,7 +136,9 @@ rules:
|
|
|
136
136
|
# bare alternative also matched `regex.exec(body)`, and a bare `body`
|
|
137
137
|
# matched document.body / res.body — both flagged ordinary code. The
|
|
138
138
|
# lookbehind drops the method-call form; req./params/input keep signal.
|
|
139
|
-
|
|
139
|
+
# The quote lookbehind on `eval` drops prose mentions ('eval() does X'
|
|
140
|
+
# in docs and rule descriptions); real calls are never quote-prefixed.
|
|
141
|
+
pattern: '\b((?<![''"`])eval\s*\(|new Function\s*\(|execSync\s*\(\s*[^\n)]*\$\{|(?<!\.)exec\s*\(\s*[^\n)]*(req\.|params|input)|setTimeout\s*\(\s*[''"`])'
|
|
140
142
|
include: ['**/*.{ts,tsx,js,jsx,mjs,cjs,py,php,rs}']
|
|
141
143
|
exclude: ['**/*.test.*', '**/*.spec.*', '**/test/**', '**/tests/**', '**/scripts/**']
|
|
142
144
|
why: 'eval and friends turn untrusted strings into executable code. Almost every RCE starts here.'
|