canship 0.7.1 → 0.8.0-rc.1

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/README-zh-CN.md CHANGED
@@ -1,20 +1,30 @@
1
1
  # canship
2
2
 
3
- 面向 JavaScript / TypeScript Web 应用的本地静态扫描器,检查凭据暴露、访问控制配置及请求输入风险。扫描不执行项目代码、不上传文件、不联网。
3
+ 面向 JavaScript / TypeScript Web 应用的本地静态扫描器,检测凭据暴露、访问控制配置错误及请求输入风险。
4
4
 
5
- [English](./README.md)
5
+ 静态扫描离线、只读,不执行项目代码。部署校验为独立功能,须显式确认请求计划。
6
6
 
7
- > 本文对应 `0.7.1`。使用 `npx canship --version` 确认已安装版本。
7
+ [English](./README.md) · [使用参考](./docs/reference-zh-CN.md) · [npm](https://www.npmjs.com/package/canship)
8
8
 
9
- ## 快速开始
9
+ > 候选版本 `0.8.0-rc.1` 使用 npm `next` 渠道。下方示例固定此预发布版本;稳定版 `0.7.1` 请参阅[发行版文档](https://github.com/Tasomei/canship/blob/v0.7.1/README-zh-CN.md)。
10
+
11
+ ## 扫描项目
12
+
13
+ 要求 Node.js ≥18,无运行时依赖;安装可能联网。
14
+
15
+ ```powershell
16
+ npx canship@0.8.0-rc.1
17
+ ```
18
+
19
+ 扫描其他目录:
10
20
 
11
21
  ```powershell
12
- npx canship
22
+ npx canship@0.8.0-rc.1 "./my-app"
13
23
  ```
14
24
 
15
- 默认扫描当前目录,也可指定路径。要求 Node.js ≥18,无运行时依赖,安装可能联网。Git 检查覆盖本地跟踪文件及提交历史,不访问远程仓库;历史无法读取时标记扫描不完整。
25
+ Git 检查读取本地跟踪文件及提交历史,不访问远程仓库;历史无法读取时标记覆盖不完整。
16
26
 
17
- 以下报告来自发布前开发构建,使用示例数据。
27
+ 以下截图使用开发构建及合成数据。
18
28
 
19
29
  ![终端报告](https://raw.githubusercontent.com/Tasomei/canship/main/docs/images/terminal.png)
20
30
 
@@ -22,93 +32,53 @@ npx canship
22
32
 
23
33
  | 类别 | 级别 | 范围 |
24
34
  |---|:---:|---|
25
- | 凭据 | `P0` | 硬编码密钥、私钥、含密码的数据库连接串、公开变量中的私密值、Supabase 管理员密钥、Git 跟踪或历史中的非模板 `.env` 文件 |
35
+ | 凭据 | `P0` | 硬编码凭据、公开环境变量暴露、Supabase 管理员密钥、Git 跟踪或历史中的非模板 `.env` 文件 |
26
36
  | API 访问 | `P0/P1` | 未识别到鉴权的数据库操作、服务端信任 Supabase `getSession()`、未验证的 Stripe webhook |
27
- | 数据库规则 | `P1/P2` | Supabase 表未启用 RLS、无条件放行策略、允许公开列出对象的存储桶;Firebase 开放规则及限时测试规则 |
37
+ | 数据库规则 | `P1/P2` | Supabase RLS、无条件放行策略及公开对象列表;Firebase 开放规则及测试模式到期时间 |
28
38
  | CORS | `P1/P2` | 携带凭据的来源回显或通配符配置 |
29
- | 请求输入 | `P1/P2` | 请求输入参与 SQL 或命令构造、调用方可控的请求主机和重定向目标 |
30
-
31
- 凭据格式包括 OpenAI、Anthropic、AWS、Stripe、GitHub、npm 等。Firebase 覆盖 Firestore、Storage、Realtime Database。`--list-rules` 列出规则 ID、范围及局限。
39
+ | 请求输入 | `P1/P2` | SQL 和命令构造、调用方可控的请求主机及重定向目标 |
32
40
 
33
- ### 服务端入口
41
+ 路由分析覆盖 Next.js、SvelteKit、Nuxt、Remix / React Router、Astro、Express、Hono、Fastify 的指定入口,不支持任意框架行为。详见[入口及限制](./docs/reference-zh-CN.md#服务端入口)。
34
42
 
35
- | 框架 | 入口 |
36
- |---|---|
37
- | Next.js | App Router 处理函数、Pages Router `/api`、`'use server'` 函数 |
38
- | SvelteKit | `+server` 端点、`+page.server` 表单 action |
39
- | Nuxt | `server/api`、`server/routes` |
40
- | Remix / React Router | `app/routes` 中的 `loader`、`action` 导出 |
41
- | Astro | `src/pages` 中的端点 |
42
- | Express | `app`/`Router` 路由,含 `.route()` 链、挂载的子路由和其他文件中的控制器 |
43
- | Hono | `app.get()` 等路由、链式调用、`basePath`,以及 `app.route()` 挂载的子应用 |
44
- | Fastify | 简写与 `route()` 声明、`register()` 前缀与封装作用域、`@fastify/autoload` 目录 |
43
+ ```powershell
44
+ npx canship@0.8.0-rc.1 --list-rules
45
+ ```
45
46
 
46
- 已识别的 Next.js/Astro 中间件可抑制匹配路由的鉴权结果;Server Function 需在函数内检查。Express/Hono/Fastify 仅接受已解析的拒绝逻辑或已知鉴权库。Fastify 装饰器和插件的保护证据限定于当前实例。
47
+ ## 审阅结果
47
48
 
48
- 会话校验及 webhook 验签(Stripe、Polar、Clerk、Svix、QStash)须在失败时拒绝请求,异步调用须等待或返回。项目辅助函数与包装器、SvelteKit hooks、Nuxt 中间件的间接证据可降低置信度;未解析的鉴权来源不能消除结果。
49
+ 报告正文为英文。`certain` 表示静态证据充分,`likely` 需人工审阅。测试和示例中的结果降为 `likely`;置信度不代表凭据有效或风险可被利用。
49
50
 
50
- 输入追踪支持赋值、解构、字符串构造及可解析的跨文件透传函数,不以辅助函数名称证明输入已净化。
51
+ 显示全部置信度及详细证据:
51
52
 
52
- Express、Hono、Fastify 路由会跟进被调项目函数中的写入,最多两层(处理函数 → service → model);文件约定路由只报告路由文件内的写入。路由分析不覆盖 SvelteKit 页面 load、remote function 和 Hono 的 `app.openapi()` 路由;凭据、CORS 等内容规则仍适用。
53
+ ```powershell
54
+ npx canship@0.8.0-rc.1 --all --verbose
55
+ ```
53
56
 
54
- ## 结果
57
+ 生成离线 HTML 报告:
55
58
 
56
- 报告正文为英文。终端按文件分组,`--verbose` 展开摘录、说明、证据和修复步骤。HTML 为自包含离线报告,支持筛选、分组、人工操作清单及修复提示复制。
59
+ ```powershell
60
+ npx canship@0.8.0-rc.1 --all --report
61
+ ```
57
62
 
58
63
  ![HTML 报告](https://raw.githubusercontent.com/Tasomei/canship/main/docs/images/report.png)
59
64
 
60
- `certain` 表示静态证据充分,`likely` 需人工审阅;测试和示例中的结果降为 `likely`。默认仅展示 `certain`,`--all` 显示全部。置信度仅反映静态证据,不代表凭据有效或风险已在运行时验证。
65
+ [合成 HTML 示例](https://github.com/Tasomei/canship/blob/main/docs/demo.html):下载文件后在本地打开,无需安装扫描器。
66
+
67
+ HTML 支持严重度及置信度筛选、稳定定位和修复提示复制。`--no-excerpts` 移除摘录,但保留路径等项目文本。`--share-summary` 仅输出计数及范围标记,分享前仍须审阅。
61
68
 
62
- | 退出码 | 含义 |
69
+ | 退出码 | 静态扫描结果 |
63
70
  |---|---|
64
71
  | `0` | 无结果,且扫描完整或由 `--best-effort` 接受 |
65
72
  | `1` | 至少一条 `certain` 的 P0/P1 结果 |
66
73
  | `2` | 其他结果,包括隐藏的 `likely` |
67
74
  | `3` | 参数错误、工具错误或未被接受的不完整扫描 |
75
+ | `130` / `143` | 收到 SIGINT / SIGTERM,不生成扫描报告 |
68
76
 
69
- 退出码基于规则筛选、忽略注释和基线处理后的结果。有结果时优先于扫描不完整;`--best-effort` 不改变 `1` 或 `2`。
70
-
71
- ## 命令行
72
-
73
- `npx canship [path] [options]`
74
-
75
- | 参数 | 作用 |
76
- |---|---|
77
- | `-a`、`--all` | 包含 `likely` 结果 |
78
- | `--verbose` | 展开终端结果 |
79
- | `--report[=file]` | 写入 HTML,默认 `canship-report.html` |
80
- | `--open` | 打开 `--report` 输出;CI 和非交互终端中禁用 |
81
- | `--json` | 输出 JSON |
82
- | `--sarif[=file]` | 写入 SARIF 2.1.0,默认 `canship.sarif` |
83
- | `--fix-prompt` | 输出修复指令及独立的人工操作清单 |
84
- | `--no-excerpts` | 移除所有报告中的摘录 |
85
- | `--changed-since=ref` | 展示变更文件结果,保留全量扫描退出码 |
86
- | `--only=ids` / `--skip=ids` | 选择或排除规则及命名空间,逗号分隔,可重复 |
87
- | `--list-rules` | 列出规则而不扫描,支持 `--json` |
88
- | `--baseline[=file]` / `--baseline-write[=file]` | 抑制或记录结果,默认 `canship-baseline.json` |
89
- | `--no-config` / `--no-ignore-markers` | 忽略项目配置或源码抑制注释 |
90
- | `--best-effort` | 允许没有结果的不完整扫描退出 `0` |
91
- | `-h`、`--help` / `-v`、`--version` | 显示帮助或版本 |
92
-
93
- `--json` 与 `--fix-prompt` 互斥,均可同时输出 HTML 和 SARIF。
94
-
95
- `--changed-since` 比较本地共同祖先与工作区,包含未被忽略的新文件,不拉取远程、不缩小扫描范围。缺少 Git、引用或共同历史时退出 `3`;不能与 `--baseline-write` 组合。
96
-
97
- ## 配置
98
-
99
- `canship.config.json` 支持 `baseline`、`only`、`skip`、`all`。命令行参数优先,`only` 与 `skip` 互斥。
100
-
101
- ```json
102
- { "skip": ["cors/wildcard-with-credentials"], "all": false }
103
- ```
104
-
105
- 独占行注释 `canship-ignore-file` 排除整个文件;`canship-ignore-next-line [rule]` 抑制下一行,可限定单条规则。报告披露排除项;主动抑制不标记扫描不完整,可能使退出码降为 `0`。扫描不可信项目时使用 `--no-config --no-ignore-markers`。
106
-
107
- 基线表示接受已有结果,不代表问题已修复。v2 格式不受行号移动影响,但凭据变化会重新报告。
77
+ 退出码基于规则选择、源码抑制及基线处理后的结果。有结果时优先于覆盖不完整;`--best-effort` 不改变 `1` 或 `2`。须另行检查 JSON 的 `partial`、`errors`、`skipped` 和 `filesScanned`。
108
78
 
109
- 默认路径相对扫描目录,显式路径相对工作目录;读取与写入互斥。缺失、无效或 v1 基线退出 `3`。写入成功退出 `0`,不完整或选择性扫描会提示。
79
+ 基线表示接受结果,不代表问题已修复。[基线管理](./docs/reference-zh-CN.md#配置)支持审阅已有记录、选择性接受、理由及到期时间。[报告比较](./docs/reference-zh-CN.md#命令行)提供终端、JSON 和离线 HTML 视图,区分新增、持续存在及本次未再出现,不将结果消失视为修复证明。
110
80
 
111
- ## GitHub Action
81
+ ## 接入 CI
112
82
 
113
83
  保存为 `.github/workflows/canship.yml`:
114
84
 
@@ -127,76 +97,39 @@ jobs:
127
97
  persist-credentials: false
128
98
  - uses: Tasomei/canship@7465c9560b8b3692777af080e8cc67b4be2335d7
129
99
  with:
130
- version: '0.7.1'
100
+ version: '0.8.0-rc.1'
131
101
  honor-ignore-markers: false
132
102
  ```
133
103
 
134
- 提交哈希固定 Action 实现,`version` 指定 npm 扫描器版本,不使用开发分支源码。Action 使用 Node.js 22,不安装或运行项目依赖,仅输出统计摘要。
104
+ 提交哈希固定 Action 实现;`version` 指定此 npm 候选版本,须在候选包公开后启用工作流。Action 使用 Node.js 22,不安装或运行项目依赖,仅输出统计摘要。
135
105
 
136
- | 输入 | 默认值 | 含义 |
106
+ | 输入 | 固定 Action 的默认值 | 含义 |
137
107
  |---|---|---|
138
- | `version` | `0.7.0` | 精确 npm 扫描器版本 |
108
+ | `version` | `0.7.0` | 精确 npm 版本;上例已覆盖 |
139
109
  | `fail-on` | `blocking` | `blocking`:确定的 P0/P1;`any`:全部结果;`none`:仅报告 |
140
110
 
141
- 扫描不完整或工具错误始终失败。默认不读取项目配置、不上传 SARIF。输入输出见 [action.yml](./action.yml)。
142
-
143
- 上传 SARIF 需 `security-events: write` 及代码扫描支持,fork PR 可能权限不足;上传前应审阅报告。不可信 PR 使用 `pull_request`,不要使用 `pull_request_target`。
111
+ 扫描不完整或工具错误始终失败。默认不读取项目配置、不上传 SARIF。上传需 `security-events: write` 及代码扫描支持,操作前须审阅报告。不可信 PR 使用 `pull_request`,不要使用 `pull_request_target`。详见 [Action 输入](https://github.com/Tasomei/canship/blob/main/action.yml)。
144
112
 
145
- ## API 与结构化输出
113
+ ## 进阶用法
146
114
 
147
- ```js
148
- import { scan, summarize } from 'canship'
149
-
150
- const result = await scan('./my-app', { noExcerpts: true })
151
- console.log(summarize(result))
152
- ```
115
+ [完整命令参考](./docs/reference-zh-CN.md#命令行)涵盖 JSON/SARIF、规则选择、配置、排除项、独立工作区、诊断及模板预览。[API](./docs/reference-zh-CN.md#api-与结构化输出)返回结构化结果,不加载项目配置、不写文件。
153
116
 
154
- `scan()` 返回全部置信度结果,支持 `only`、`skip`、`honorIgnoreMarkers`(默认 `true`)、`noExcerpts`(默认 `false`)。不加载配置、不应用基线、不写报告、不设置进程退出码;无效参数抛出异常。`listRules()` 返回规则目录。
117
+ pre-commit 模板扫描**工作区,而非暂存区快照**。部署校验默认关闭,仅支持无认证的 HTTPS 请求;使用前须审阅[范围与隐私限制](./docs/reference-zh-CN.md#部署校验)。
155
118
 
156
- JSON 使用 [schemaVersion 1](./schemas/scan-report-v1.schema.json)。须独立于退出码检查 `partial`、`errors`、`skipped`、`filesScanned`。SARIF 包含证据位置和执行诊断。
119
+ [VS Code 插件](https://github.com/Tasomei/canship/tree/main/extensions/vscode#readme)为独立开发预览,本地 VSIX 打包及已验证宿主范围见插件 README;尚未发布到 Marketplace。
157
120
 
158
121
  ## 隐私与限制
159
122
 
160
- - 静态检查可能误报或漏报,不验证业务授权、限流、依赖漏洞或线上配置。
161
- - 脱敏仅覆盖已识别格式,未知敏感值可能保留在摘录中;`--no-excerpts` 可移除摘录。路径、名称和基线描述仍可见。
162
- - Google/Firebase/Maps 的 `AIza…` 密钥按公开标识符处理,不单凭其值判定泄露。Supabase 检查依据本地迁移及支持的存储桶配置。
163
- - 评估快照获取和可选的 SARIF 上传可能联网。
164
- - 不跟随符号链接;嵌套仓库与子模块需单独扫描。范围内跳过项及分析超限标记扫描不完整;鉴权辅助函数解析超限不会隐藏结果,改为在受影响的结果上注明。默认排除的依赖和构建目录不计为扫描缺口。
165
-
166
- | 项目 | 上限 |
167
- |---|---|
168
- | 文件读取 | 单文件 2 MiB;单次 128 MiB、10,000 个文件,含探测 |
169
- | 目录遍历 | 50,000 个条目;16 层 |
170
- | 结果 | 每文件 100 条,优先保留高严重度、高置信度结果 |
171
- | Git 历史 | 每文件 100 个相关版本;单条命令 30 秒 |
172
- | 鉴权辅助函数解析 | 8 跳;每个辅助函数 64 个符号,每个路由文件共 1,024 个 |
173
- | 委托写入 | 调用 2 层;每个文件 256 个被调函数;超出部分的写入不报告 |
174
- | 身份/控制流 | 值解析 8 步;表达式 4,000 字符;每函数 512 个赋值/区域;区域嵌套 8 层 |
175
- | 请求输入追踪 | 值解析 8 步;512 个赋值/区域;单条表达式 64 KiB;URL 分析 8 层、静态前缀 200 字符 |
176
- | Supabase 策略/存储桶解析 | 单条语句 4,000 字符 |
177
-
178
- 证据链最多 24 步,截断时提示。
179
-
180
- ## 开发
181
-
182
- ```powershell
183
- npm ci
184
- ```
185
-
186
- ```powershell
187
- npm run prepublishOnly
188
- ```
123
+ - 静态分析可能误报或漏报,不验证业务授权、限流或依赖漏洞。
124
+ - 脱敏仅覆盖已识别格式,未知敏感值可能保留在摘录中;详细报告及基线应按内部材料处理。
125
+ - Google/Firebase/Maps 的 `AIza…` 密钥按公开标识符处理,不单凭其值判定泄露。
126
+ - 不跟随符号链接;嵌套仓库及子模块须单独扫描。范围内跳过项及分析上限会披露;默认排除的依赖和构建目录不计为覆盖缺口。
127
+ - 显式部署校验会访问已确认目标;安装、评估下载及可选 SARIF 上传也可能联网。静态扫描保持离线。
189
128
 
190
- ```powershell
191
- npm run test:package
192
- ```
193
-
194
- ```powershell
195
- npm run evaluate
196
- ```
129
+ 详见[资源上限与覆盖边界](./docs/reference-zh-CN.md#隐私与限制)。
197
130
 
198
- 新增规则需包含应检出和不应检出的 [夹具](./test/fixtures/)。固定项目评估见 [清单](./test/evaluation/projects.json)、[获取脚本](./scripts/fetch-evaluation-projects.mjs)、[评估器](./scripts/evaluate-projects.ts)。样本通过不代表真实检出率。
131
+ ## 开发与许可
199
132
 
200
- ## 许可
133
+ 分别运行 `npm ci`、`npm run prepublishOnly`、`npm run test:package`、`npm run evaluate`。新增规则须包含应检出和不应检出的夹具;样本通过不代表真实检出率。详见[开发参考](./docs/reference-zh-CN.md#开发)。
201
134
 
202
135
  [MIT](./LICENSE)。Supabase/Firebase 夹具保留 Apache-2.0,Next.js/`cors` 夹具保留 MIT。
package/README.md CHANGED
@@ -1,20 +1,30 @@
1
1
  # canship
2
2
 
3
- A local static scanner for JavaScript and TypeScript web apps. Checks exposed credentials, access-control configuration, and unsafe request-input flows. No project-code execution, uploads, or network requests during scanning.
3
+ A local static scanner for JavaScript and TypeScript web apps. Detects exposed credentials, access-control misconfiguration, and unsafe request-input flows.
4
4
 
5
- [简体中文](./README-zh-CN.md)
5
+ Static scans are offline, read-only, and execute no project code. Deployment probes are separate and require explicit plan confirmation.
6
6
 
7
- > Documentation for `0.7.1`. Check the installed version with `npx canship --version`.
7
+ [简体中文](./README-zh-CN.md) · [Reference](./docs/reference.md) · [npm](https://www.npmjs.com/package/canship)
8
8
 
9
- ## Quick start
9
+ > Release candidate `0.8.0-rc.1` for npm `next`. Examples below pin this prerelease. For stable `0.7.1`, see the [release documentation](https://github.com/Tasomei/canship/blob/v0.7.1/README.md).
10
+
11
+ ## Scan a project
12
+
13
+ Requires Node.js ≥18. No runtime dependencies; installation may use the network.
14
+
15
+ ```powershell
16
+ npx canship@0.8.0-rc.1
17
+ ```
18
+
19
+ To scan another directory:
10
20
 
11
21
  ```powershell
12
- npx canship
22
+ npx canship@0.8.0-rc.1 "./my-app"
13
23
  ```
14
24
 
15
- Scans the current directory or a specified path. Requires Node.js ≥18; no runtime dependencies. Installation may use the network. Git checks cover locally tracked files and commit history without contacting remotes; inaccessible history marks coverage incomplete.
25
+ Git checks inspect locally tracked files and commit history without contacting remotes. Unreadable history marks coverage incomplete.
16
26
 
17
- Output examples use sample data from a pre-release development build.
27
+ The following screenshots use synthetic data from a development build.
18
28
 
19
29
  ![Terminal report](https://raw.githubusercontent.com/Tasomei/canship/main/docs/images/terminal.png)
20
30
 
@@ -22,93 +32,53 @@ Output examples use sample data from a pre-release development build.
22
32
 
23
33
  | Category | Severity | Scope |
24
34
  |---|:---:|---|
25
- | Credentials | `P0` | Hardcoded keys, private keys, password-bearing database URLs, public env exposure, Supabase admin keys, non-template `.env` files tracked by Git or present in history |
35
+ | Credentials | `P0` | Hardcoded credentials, public env exposure, Supabase admin keys, non-template `.env` files tracked by Git or present in history |
26
36
  | API access | `P0/P1` | Database operations without recognised authentication, server-side trust in Supabase `getSession()`, unverified Stripe webhooks |
27
- | Database rules | `P1/P2` | Supabase tables without RLS, unconditional policies, public object listing in storage buckets; Firebase open rules and time-limited test rules |
37
+ | Database rules | `P1/P2` | Supabase RLS, unconditional policies and public object listing; Firebase open rules and test-mode expiry |
28
38
  | CORS | `P1/P2` | Reflected or wildcard origins with credentials |
29
- | Request input | `P1/P2` | Request input in SQL or command construction, caller-chosen request hosts and redirect targets |
30
-
31
- Credential formats include OpenAI, Anthropic, AWS, Stripe, GitHub, and npm. Firebase covers Firestore, Storage, and Realtime Database. `--list-rules` lists rule IDs, scope, and limitations.
39
+ | Request input | `P1/P2` | SQL and command construction, caller-controlled request hosts and redirect targets |
32
40
 
33
- ### Server entry points
41
+ Route analysis supports documented entry points in Next.js, SvelteKit, Nuxt, Remix / React Router, Astro, Express, Hono and Fastify—not arbitrary framework behaviour. See [entry points and limits](./docs/reference.md#server-entry-points).
34
42
 
35
- | Framework | Entry points |
36
- |---|---|
37
- | Next.js | App Router handlers, Pages Router `/api`, `'use server'` functions |
38
- | SvelteKit | `+server` endpoints and `+page.server` form actions |
39
- | Nuxt | `server/api`, `server/routes` |
40
- | Remix / React Router | `loader` and `action` exports in `app/routes` |
41
- | Astro | Endpoints in `src/pages` |
42
- | Express | `app`/`Router` routes, including `.route()` chains, mounted routers, and controllers in other files |
43
- | Hono | `app.get()`-style routes, chains, `basePath`, and sub-apps mounted with `app.route()` |
44
- | Fastify | Shorthand and `route()` declarations, `register()` prefixes and encapsulation, `@fastify/autoload` directories |
43
+ ```powershell
44
+ npx canship@0.8.0-rc.1 --list-rules
45
+ ```
45
46
 
46
- Recognised Next.js/Astro middleware may suppress covered auth findings; Server Functions need local checks. Express/Hono/Fastify require resolved rejection logic or known auth libraries. Fastify decorator and plugin evidence is scoped to the local instance.
47
+ ## Review results
47
48
 
48
- Session checks and webhook verification (Stripe, Polar, Clerk, Svix, QStash) must reject failures; asynchronous calls must be awaited or returned. Indirect evidence from project helpers/wrappers, SvelteKit hooks, or Nuxt middleware may lower confidence. Unresolved auth sources do not suppress findings.
49
+ Reports are in English. `certain` means strong static evidence; `likely` requires review. Tests and examples are downgraded to `likely`. Neither confidence level proves credential validity or exploitability.
49
50
 
50
- Input analysis follows assignments, destructuring, string construction, and resolvable cross-file passthrough helpers. Helper names alone do not prove sanitisation.
51
+ Show all confidence levels and detailed evidence:
51
52
 
52
- For Express, Hono, and Fastify routes, writes inside called project functions are followed two levels (handler → service → model); file-based routes report writes in the route file only. SvelteKit page loads, remote functions, and Hono `app.openapi()` routes are outside route analysis. Content-based checks, including credentials and CORS, still apply.
53
+ ```powershell
54
+ npx canship@0.8.0-rc.1 --all --verbose
55
+ ```
53
56
 
54
- ## Results
57
+ Generate an offline HTML report:
55
58
 
56
- Reports are in English. The terminal groups findings by file; `--verbose` adds excerpts, explanations, evidence, and fixes. HTML is a self-contained offline report with filters, grouping, manual steps, and copyable fix prompts.
59
+ ```powershell
60
+ npx canship@0.8.0-rc.1 --all --report
61
+ ```
57
62
 
58
63
  ![HTML report](https://raw.githubusercontent.com/Tasomei/canship/main/docs/images/report.png)
59
64
 
60
- `certain` indicates strong static evidence; `likely` requires review. Findings in tests and examples are downgraded to `likely`. Default output shows only `certain`; `--all` includes both. Confidence reflects static evidence, not credential validity or runtime verification.
65
+ [Synthetic HTML sample](https://github.com/Tasomei/canship/blob/main/docs/demo.html): download the file and open it locally; no scanner installation is required.
66
+
67
+ HTML provides severity/confidence filters, stable finding links, and copyable repair prompts. Use `--no-excerpts` to omit excerpts; paths and other project text remain. For counts without project text, use `--share-summary` and review before sharing.
61
68
 
62
- | Exit | Meaning |
69
+ | Exit | Static scan result |
63
70
  |---|---|
64
71
  | `0` | No findings; coverage complete or accepted with `--best-effort` |
65
72
  | `1` | At least one `certain` P0/P1 finding |
66
73
  | `2` | Other findings, including hidden `likely` results |
67
74
  | `3` | Invalid arguments, tool error, or unaccepted incomplete coverage |
75
+ | `130` / `143` | Interrupted by SIGINT / SIGTERM; no scan report generated |
68
76
 
69
- Status is calculated after rule selection, ignore comments, and baselines. Findings take precedence over incomplete coverage; `--best-effort` never changes `1` or `2`.
70
-
71
- ## CLI
72
-
73
- `npx canship [path] [options]`
74
-
75
- | Option | Effect |
76
- |---|---|
77
- | `-a`, `--all` | Include `likely` findings |
78
- | `--verbose` | Expand terminal findings |
79
- | `--report[=file]` | Write HTML; default `canship-report.html` |
80
- | `--open` | Open `--report` output; disabled in CI and non-interactive shells |
81
- | `--json` | Print JSON |
82
- | `--sarif[=file]` | Write SARIF 2.1.0; default `canship.sarif` |
83
- | `--fix-prompt` | Print repair instructions and separate manual actions |
84
- | `--no-excerpts` | Remove excerpts from all reports |
85
- | `--changed-since=ref` | Show changed-file findings; preserve full-scan status |
86
- | `--only=ids` / `--skip=ids` | Select/exclude rules or namespaces; comma-separated, repeatable |
87
- | `--list-rules` | List rules without scanning; supports `--json` |
88
- | `--baseline[=file]` / `--baseline-write[=file]` | Suppress/record findings; default `canship-baseline.json` |
89
- | `--no-config` / `--no-ignore-markers` | Ignore project configuration/source suppression comments |
90
- | `--best-effort` | Allow incomplete coverage with no findings to exit `0` |
91
- | `-h`, `--help` / `-v`, `--version` | Show help/version |
92
-
93
- `--json` and `--fix-prompt` are mutually exclusive; either supports HTML and SARIF output.
94
-
95
- `--changed-since` compares the local merge base with the working tree, including non-ignored untracked files. It does not fetch or narrow scan scope. Missing Git, refs, or shared history exits `3`; it cannot be combined with `--baseline-write`.
96
-
97
- ## Configuration
98
-
99
- `canship.config.json` accepts `baseline`, `only`, `skip`, and `all`. CLI options take precedence; `only` and `skip` are mutually exclusive.
100
-
101
- ```json
102
- { "skip": ["cors/wildcard-with-credentials"], "all": false }
103
- ```
104
-
105
- A standalone `canship-ignore-file` comment excludes a file. `canship-ignore-next-line [rule]` suppresses the next line, optionally for one rule. Exclusions are disclosed and may reduce status to `0` without marking coverage incomplete. For untrusted projects, use `--no-config --no-ignore-markers`.
106
-
107
- Baselines accept existing findings without fixing them. Format v2 tolerates line moves but reports credential changes.
77
+ Status is calculated after rule selection, source suppressions and baselines. Findings take precedence over incomplete coverage; `--best-effort` never changes `1` or `2`. Check JSON `partial`, `errors`, `skipped` and `filesScanned` separately.
108
78
 
109
- Default paths are relative to the scan directory; explicit paths are relative to the working directory. Read/write modes are mutually exclusive. Missing, invalid, or v1 baselines exit `3`. A successful write exits `0`, with a warning for incomplete or selective scans.
79
+ Baselines accept findings; they do not fix them. Review existing decisions, accept selected results, and set optional reasons or expiry through [baseline management](./docs/reference.md#configuration). [Saved-report comparison](./docs/reference.md#cli) provides terminal, JSON and offline HTML views of added, persisting and no-longer-observed records without claiming remediation.
110
80
 
111
- ## GitHub Action
81
+ ## Connect to CI
112
82
 
113
83
  Save as `.github/workflows/canship.yml`:
114
84
 
@@ -127,76 +97,39 @@ jobs:
127
97
  persist-credentials: false
128
98
  - uses: Tasomei/canship@7465c9560b8b3692777af080e8cc67b4be2335d7
129
99
  with:
130
- version: '0.7.1'
100
+ version: '0.8.0-rc.1'
131
101
  honor-ignore-markers: false
132
102
  ```
133
103
 
134
- The commit hash pins the Action implementation; `version` selects the npm scanner, not development-branch source. The Action uses Node.js 22, does not install or run project dependencies, and writes a counts-only summary.
104
+ The hash pins the Action implementation; `version` selects this npm release candidate. Enable the workflow after the candidate is public. The Action uses Node.js 22, does not install or run project dependencies, and writes a counts-only summary.
135
105
 
136
- | Input | Default | Meaning |
106
+ | Input | Pinned Action default | Meaning |
137
107
  |---|---|---|
138
- | `version` | `0.7.0` | Exact npm scanner version |
108
+ | `version` | `0.7.0` | Exact npm scanner version; overridden above |
139
109
  | `fail-on` | `blocking` | `blocking`: certain P0/P1; `any`: all findings; `none`: report only |
140
110
 
141
- Incomplete scans and tool errors always fail. Project configuration and SARIF upload are disabled by default. Inputs and outputs: [action.yml](./action.yml).
142
-
143
- SARIF upload requires `security-events: write` and code scanning support; fork PRs may lack permission. Review reports before upload. Use `pull_request`, not `pull_request_target`, for untrusted PRs.
144
-
145
- ## API and structured output
146
-
147
- ```js
148
- import { scan, summarize } from 'canship'
149
-
150
- const result = await scan('./my-app', { noExcerpts: true })
151
- console.log(summarize(result))
152
- ```
153
-
154
- `scan()` returns all confidence levels. Options: `only`, `skip`, `honorIgnoreMarkers` (default `true`), `noExcerpts` (default `false`). It does not load configuration, apply baselines, write reports, or set process exit status. Invalid arguments throw. `listRules()` returns the rule catalogue.
155
-
156
- JSON uses [schemaVersion 1](./schemas/scan-report-v1.schema.json). Check `partial`, `errors`, `skipped`, and `filesScanned` independently of exit status. SARIF includes evidence locations and execution diagnostics.
157
-
158
- ## Privacy and limits
111
+ Incomplete scans and tool errors always fail. Project configuration and SARIF upload are disabled by default. Upload requires `security-events: write` and code scanning support; review reports first. Use `pull_request`, not `pull_request_target`, for untrusted PRs. See [Action inputs](https://github.com/Tasomei/canship/blob/main/action.yml).
159
112
 
160
- - Static checks may miss issues or flag intentional configurations. Business authorisation, rate limiting, dependency vulnerabilities, and deployed settings are not verified.
161
- - Redaction covers recognised formats only. Unknown secrets may remain in excerpts; `--no-excerpts` omits excerpts. Paths, names, and baseline descriptions remain visible.
162
- - Google/Firebase/Maps `AIza…` keys are treated as public identifiers, not leak evidence alone. Supabase checks use local migrations and supported bucket configuration.
163
- - Evaluation snapshot downloads and optional SARIF uploads may use the network.
164
- - Symbolic links are not followed; nested repositories and submodules need separate scans. In-scope skipped paths and analysis limits mark coverage incomplete; auth helper resolution limits are noted on the affected finding instead, because they cannot hide findings. Dependency and build directories excluded by default do not count as coverage gaps.
113
+ ## Advanced use
165
114
 
166
- | Limit | Bound |
167
- |---|---|
168
- | File reads | 2 MiB per file; 128 MiB and 10,000 files per scan, including probes |
169
- | Directory discovery | 50,000 entries; 16 levels |
170
- | Findings | 100 per file, prioritising severity and confidence |
171
- | Git history | 100 relevant revisions per file; 30 seconds per command |
172
- | Auth helper resolution | 8 hops; 64 symbols per helper, 1,024 per route file |
173
- | Delegated writes | 2 call levels; 256 callees per file; writes beyond these limits are not reported |
174
- | Identity/control flow | 8 value hops; 4,000 expression characters; 512 assignments/regions per function; 8 nested regions |
175
- | Request-input tracking | 8 value hops; 512 assignments/regions; 64 KiB per expression; 8 URL-analysis levels; 200 static-prefix characters |
176
- | Supabase policy/bucket parsing | 4,000 characters per statement |
115
+ [Full CLI reference](./docs/reference.md#cli) covers JSON/SARIF output, rules, configuration, exclusions, independent workspaces, diagnostics and template previews. The [API](./docs/reference.md#api-and-structured-output) returns structured findings without loading project configuration or writing files.
177
116
 
178
- Evidence traces are capped at 24 steps and disclose truncation.
117
+ The pre-commit template scans the **working tree, not the staged snapshot**. Deployment probes are opt-in, HTTPS-only and unauthenticated; [review their scope and privacy limits](./docs/reference.md#deployment-probes) before use.
179
118
 
180
- ## Development
119
+ The [VS Code extension](https://github.com/Tasomei/canship/tree/main/extensions/vscode#readme) is a separate development preview. See its README for local VSIX packaging and verified host coverage. Marketplace publication is pending.
181
120
 
182
- ```powershell
183
- npm ci
184
- ```
185
-
186
- ```powershell
187
- npm run prepublishOnly
188
- ```
121
+ ## Privacy and limitations
189
122
 
190
- ```powershell
191
- npm run test:package
192
- ```
123
+ - Static analysis may miss issues or flag intentional configurations. It does not verify business authorisation, rate limiting or dependency vulnerabilities.
124
+ - Redaction covers recognised formats only. Unknown sensitive values may remain in excerpts; detailed reports and baselines should be treated as internal material.
125
+ - Google/Firebase/Maps `AIza…` keys are public identifiers, not leak evidence alone.
126
+ - Symbolic links are not followed. Nested repositories and submodules need separate scans. In-scope skips and analysis limits are disclosed; default dependency/build exclusions are not coverage gaps.
127
+ - Explicit deployment probes contact the approved target; installation, evaluation downloads and optional SARIF upload may also use the network. Static scans remain offline.
193
128
 
194
- ```powershell
195
- npm run evaluate
196
- ```
129
+ See [resource bounds and coverage limits](./docs/reference.md#privacy-and-limits).
197
130
 
198
- New rules require positive and negative [fixtures](./test/fixtures/). Pinned project evaluation: [manifest](./test/evaluation/projects.json), [fetch script](./scripts/fetch-evaluation-projects.mjs), [evaluator](./scripts/evaluate-projects.ts). Passing samples do not establish real-world detection rates.
131
+ ## Development and license
199
132
 
200
- ## License
133
+ Run `npm ci`, `npm run prepublishOnly`, `npm run test:package` and `npm run evaluate` separately. New rules require positive and negative fixtures; passing samples do not establish real-world detection rates. See [development reference](./docs/reference.md#development).
201
134
 
202
135
  [MIT](./LICENSE). Supabase/Firebase fixtures retain Apache-2.0; Next.js/`cors` fixtures retain MIT.