ai-saas-guard 0.13.0 → 0.14.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/README.md +4 -4
- package/README.zh-CN.md +5 -4
- package/dist/hosted/contracts.d.ts +66 -0
- package/dist/hosted/contracts.js +107 -0
- package/docs/github-action.md +1 -1
- package/docs/hosted-preimplementation-contracts.md +26 -0
- package/docs/npm-publishing.md +3 -3
- package/docs/project-handoff.md +6 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,8 +73,8 @@ The CLI is published on npm as `ai-saas-guard`, and the GitHub Action is availab
|
|
|
73
73
|
| JSON and SARIF output | Available |
|
|
74
74
|
| Composite GitHub Action | Available |
|
|
75
75
|
| Project config | `.ai-saas-guard.json` rule toggles, severity overrides, and fail thresholds |
|
|
76
|
-
| Versioned Action tags | `v0.
|
|
77
|
-
| npm package | `ai-saas-guard@0.
|
|
76
|
+
| Versioned Action tags | `v0.14.0`, `v0` |
|
|
77
|
+
| npm package | `ai-saas-guard@0.14.0` |
|
|
78
78
|
| npm publishing | Trusted Publisher/OIDC, no long-lived publish token |
|
|
79
79
|
|
|
80
80
|
## Quick Start
|
|
@@ -214,7 +214,7 @@ Hosted uninstall and data deletion behavior is documented in [docs/hosted-uninst
|
|
|
214
214
|
|
|
215
215
|
Hosted pricing and packaging boundaries are documented in [docs/hosted-pricing-packaging.md](docs/hosted-pricing-packaging.md). Core local scanning stays useful without an account; hosted plans may add workflow convenience, saved reports, team policy, and optional human review, but they do not gate local CLI scanning.
|
|
216
216
|
|
|
217
|
-
Hosted pre-implementation pure contracts are documented in [docs/hosted-preimplementation-contracts.md](docs/hosted-preimplementation-contracts.md). They now include a pull request webhook intake planner that verifies signatures before parsing or queueing, a durable scan queue planner that reuses queued, running, and completed jobs for the same trusted scan key,
|
|
217
|
+
Hosted pre-implementation pure contracts are documented in [docs/hosted-preimplementation-contracts.md](docs/hosted-preimplementation-contracts.md). They now include a pull request webhook intake planner that verifies signatures before parsing or queueing, a durable scan queue planner that reuses queued, running, and completed jobs for the same trusted scan key, a worker read-only scan planner that fixes the CLI command and requires repository `contents: read`, and a Check Run publication planner that requires repository `checks: write` and builds bounded check-only payloads from compact reports. They also cover queue-safe webhook event parsing, bounded check-run summary rendering, idempotent queue cleanup planning, worker checkout cleanup planning, and other service-free helpers exported from `ai-saas-guard/hosted/contracts`. PR comments remain a later workflow or paid hosted feature, not part of the hosted MVP contract.
|
|
218
218
|
|
|
219
219
|
A public hosted compact report schema fixture is available at [examples/hosted-compact-report.json](examples/hosted-compact-report.json). It is synthetic and public-safe: compact evidence only, no raw source, raw diffs, secrets, webhook payload bodies, customer payloads, private URLs, or worker checkout paths.
|
|
220
220
|
|
|
@@ -254,7 +254,7 @@ Use `suppressions` for narrower false-positive handling when one rule is noisy o
|
|
|
254
254
|
|
|
255
255
|
## GitHub Action
|
|
256
256
|
|
|
257
|
-
The repo includes a composite Action. Use `v0` for the latest compatible pre-1.0 Action, a specific release tag such as `v0.
|
|
257
|
+
The repo includes a composite Action. Use `v0` for the latest compatible pre-1.0 Action, a specific release tag such as `v0.14.0` for controlled upgrades, or pin a reviewed commit SHA for stricter supply-chain control:
|
|
258
258
|
|
|
259
259
|
```yaml
|
|
260
260
|
name: ai-saas-guard
|
package/README.zh-CN.md
CHANGED
|
@@ -55,7 +55,7 @@ AI 能很快把一个 SaaS 从想法做成可运行的产品。真正难的是
|
|
|
55
55
|
|
|
56
56
|
这个仓库是公开 GitHub 仓库。
|
|
57
57
|
|
|
58
|
-
CLI 已发布到 npm:`ai-saas-guard@0.
|
|
58
|
+
CLI 已发布到 npm:`ai-saas-guard@0.14.0`。GitHub Action 支持 `v0` 浮动标签,也支持固定版本标签,例如 `v0.14.0`。
|
|
59
59
|
|
|
60
60
|
| 模块 | 状态 |
|
|
61
61
|
| --- | --- |
|
|
@@ -66,8 +66,8 @@ CLI 已发布到 npm:`ai-saas-guard@0.13.0`。GitHub Action 支持 `v0` 浮动
|
|
|
66
66
|
| Markdown PR summary | 已可用 |
|
|
67
67
|
| GitHub Action | 已可用 |
|
|
68
68
|
| 项目配置 | `.ai-saas-guard.json` 支持规则开关、severity 覆盖和 fail threshold |
|
|
69
|
-
| 当前版本 | `0.
|
|
70
|
-
| Action 标签 | `v0.
|
|
69
|
+
| 当前版本 | `0.14.0` |
|
|
70
|
+
| Action 标签 | `v0.14.0`、`v0` |
|
|
71
71
|
| npm 发布 | GitHub Actions Trusted Publisher/OIDC,无需长期 npm token |
|
|
72
72
|
|
|
73
73
|
## 快速开始
|
|
@@ -257,11 +257,12 @@ jobs:
|
|
|
257
257
|
- worker read-only scan planner:只用 trusted identity 规划临时 worker checkout,要求 repository `contents: read`,固定运行 `ai-saas-guard pr-risk --json`,并忽略 PR 正文里的 repo 名、token scope 或命令
|
|
258
258
|
- webhook event parser
|
|
259
259
|
- check-run summary renderer
|
|
260
|
+
- Check Run publication planner:要求 repository `checks: write`,只从 compact report 生成有长度上限的 Check Run payload,包含 review categories、优先 review 文件、verification steps 和本地 CLI 复现命令;MVP 不发 PR comment
|
|
260
261
|
- queue cleanup planner
|
|
261
262
|
- worker checkout cleanup planner
|
|
262
263
|
- hosted compact report fixture:[examples/hosted-compact-report.json](examples/hosted-compact-report.json)
|
|
263
264
|
|
|
264
|
-
这些 helper 不会启动服务、不会调用 GitHub API、不会请求 installation token
|
|
265
|
+
这些 helper 不会启动服务、不会调用 GitHub API、不会请求 installation token、不会真实写 check run、不会发 PR comment,也不会上传源码。
|
|
265
266
|
|
|
266
267
|
## 它不是什么
|
|
267
268
|
|
|
@@ -388,6 +388,71 @@ export interface HostedCheckRunSummary {
|
|
|
388
388
|
modelTraining: "disabled";
|
|
389
389
|
};
|
|
390
390
|
}
|
|
391
|
+
export type HostedCheckRunPublicationRejectReason = InstallationScopeRejectReason | "checks_write_permission_required";
|
|
392
|
+
export interface HostedCheckRunPublicationInput {
|
|
393
|
+
identity: HostedScanIdentity;
|
|
394
|
+
report: CompactHostedReport;
|
|
395
|
+
jobKey: string;
|
|
396
|
+
requestedAt: string;
|
|
397
|
+
installationId: number;
|
|
398
|
+
selectedRepositoryIds: number[];
|
|
399
|
+
removedRepositoryIds?: number[];
|
|
400
|
+
installationTokenPermissions: {
|
|
401
|
+
checks?: string;
|
|
402
|
+
};
|
|
403
|
+
failOnSeverity?: HostedCheckRunSeverityThreshold;
|
|
404
|
+
maxMarkdownChars?: number;
|
|
405
|
+
rawSource?: string;
|
|
406
|
+
rawDiff?: string;
|
|
407
|
+
secretValues?: string[];
|
|
408
|
+
untrustedPrText?: string;
|
|
409
|
+
customerPayload?: unknown;
|
|
410
|
+
}
|
|
411
|
+
export interface HostedCheckRunApiPayload {
|
|
412
|
+
name: "AI SaaS Guard";
|
|
413
|
+
head_sha: string;
|
|
414
|
+
status: "completed";
|
|
415
|
+
conclusion: HostedCheckRunConclusion;
|
|
416
|
+
external_id: string;
|
|
417
|
+
output: {
|
|
418
|
+
title: string;
|
|
419
|
+
summary: string;
|
|
420
|
+
text: string;
|
|
421
|
+
annotations: HostedCheckRunAnnotation[];
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
export interface HostedCheckRunPublicationPlan {
|
|
425
|
+
accepted: boolean;
|
|
426
|
+
reason?: HostedCheckRunPublicationRejectReason;
|
|
427
|
+
jobKey: string;
|
|
428
|
+
requestedAt: string;
|
|
429
|
+
operation?: "create";
|
|
430
|
+
shouldWriteCheckRun: boolean;
|
|
431
|
+
shouldCreatePrComment: false;
|
|
432
|
+
shouldCallGitHubApi: false;
|
|
433
|
+
installationTokenScope?: {
|
|
434
|
+
installationId: number;
|
|
435
|
+
repositoryId: number;
|
|
436
|
+
permissions: {
|
|
437
|
+
checks: "write";
|
|
438
|
+
};
|
|
439
|
+
selectedRepositoryOnly: true;
|
|
440
|
+
};
|
|
441
|
+
request?: {
|
|
442
|
+
method: "POST";
|
|
443
|
+
endpoint: string;
|
|
444
|
+
payload: HostedCheckRunApiPayload;
|
|
445
|
+
};
|
|
446
|
+
privacy: {
|
|
447
|
+
includesRawSource: false;
|
|
448
|
+
includesRawDiffs: false;
|
|
449
|
+
includesSecrets: false;
|
|
450
|
+
includesCustomerPayloads: false;
|
|
451
|
+
includesUntrustedPrText: false;
|
|
452
|
+
createsPrComment: false;
|
|
453
|
+
modelTraining: "disabled";
|
|
454
|
+
};
|
|
455
|
+
}
|
|
391
456
|
export type HostedDeletionTrigger = "repository_removed" | "installation_deleted" | "repeated_cleanup";
|
|
392
457
|
export interface HostedDeletionPlanInput {
|
|
393
458
|
trigger: HostedDeletionTrigger;
|
|
@@ -443,6 +508,7 @@ export declare function resolveHostedRetentionDays(input?: {
|
|
|
443
508
|
}): number;
|
|
444
509
|
export declare function createCompactHostedReport(input: CompactHostedReportInput): CompactHostedReport;
|
|
445
510
|
export declare function createHostedCheckRunSummary(input: HostedCheckRunSummaryInput): HostedCheckRunSummary;
|
|
511
|
+
export declare function planHostedCheckRunPublication(input: HostedCheckRunPublicationInput): HostedCheckRunPublicationPlan;
|
|
446
512
|
export declare function getHostedDeletionIdempotencyKey(input: {
|
|
447
513
|
trigger: HostedDeletionTrigger;
|
|
448
514
|
installationId: number;
|
package/dist/hosted/contracts.js
CHANGED
|
@@ -494,6 +494,56 @@ export function createHostedCheckRunSummary(input) {
|
|
|
494
494
|
}
|
|
495
495
|
};
|
|
496
496
|
}
|
|
497
|
+
export function planHostedCheckRunPublication(input) {
|
|
498
|
+
const scopeDecision = authorizeInstallationTokenScope({
|
|
499
|
+
identity: input.identity,
|
|
500
|
+
installationId: input.installationId,
|
|
501
|
+
selectedRepositoryIds: input.selectedRepositoryIds,
|
|
502
|
+
removedRepositoryIds: input.removedRepositoryIds
|
|
503
|
+
});
|
|
504
|
+
if (!scopeDecision.authorized) {
|
|
505
|
+
return rejectHostedCheckRunPublication(input, scopeDecision.reason ?? "repository_not_installed");
|
|
506
|
+
}
|
|
507
|
+
if (input.installationTokenPermissions.checks !== "write") {
|
|
508
|
+
return rejectHostedCheckRunPublication(input, "checks_write_permission_required");
|
|
509
|
+
}
|
|
510
|
+
const summary = createHostedCheckRunSummary({
|
|
511
|
+
report: input.report,
|
|
512
|
+
failOnSeverity: input.failOnSeverity,
|
|
513
|
+
maxMarkdownChars: input.maxMarkdownChars
|
|
514
|
+
});
|
|
515
|
+
return {
|
|
516
|
+
accepted: true,
|
|
517
|
+
jobKey: input.jobKey,
|
|
518
|
+
requestedAt: input.requestedAt,
|
|
519
|
+
operation: "create",
|
|
520
|
+
shouldWriteCheckRun: true,
|
|
521
|
+
shouldCreatePrComment: false,
|
|
522
|
+
shouldCallGitHubApi: false,
|
|
523
|
+
installationTokenScope: {
|
|
524
|
+
installationId: input.identity.installationId,
|
|
525
|
+
repositoryId: input.identity.repositoryId,
|
|
526
|
+
permissions: { checks: "write" },
|
|
527
|
+
selectedRepositoryOnly: true
|
|
528
|
+
},
|
|
529
|
+
request: {
|
|
530
|
+
method: "POST",
|
|
531
|
+
endpoint: `/repos/${input.identity.repositoryFullName}/check-runs`,
|
|
532
|
+
payload: {
|
|
533
|
+
name: summary.name,
|
|
534
|
+
head_sha: input.identity.headSha,
|
|
535
|
+
status: "completed",
|
|
536
|
+
conclusion: summary.conclusion,
|
|
537
|
+
external_id: input.jobKey,
|
|
538
|
+
output: {
|
|
539
|
+
...summary.output,
|
|
540
|
+
annotations: summary.annotations
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
privacy: hostedCheckRunPublicationPrivacy()
|
|
545
|
+
};
|
|
546
|
+
}
|
|
497
547
|
export function getHostedDeletionIdempotencyKey(input) {
|
|
498
548
|
return [input.trigger, input.installationId, input.repositoryId ?? "all"].join(":");
|
|
499
549
|
}
|
|
@@ -627,6 +677,29 @@ function hostedWorkerReadOnlyScanPrivacy() {
|
|
|
627
677
|
acceptsCommandFromPrText: false
|
|
628
678
|
};
|
|
629
679
|
}
|
|
680
|
+
function rejectHostedCheckRunPublication(input, reason) {
|
|
681
|
+
return {
|
|
682
|
+
accepted: false,
|
|
683
|
+
reason,
|
|
684
|
+
jobKey: input.jobKey,
|
|
685
|
+
requestedAt: input.requestedAt,
|
|
686
|
+
shouldWriteCheckRun: false,
|
|
687
|
+
shouldCreatePrComment: false,
|
|
688
|
+
shouldCallGitHubApi: false,
|
|
689
|
+
privacy: hostedCheckRunPublicationPrivacy()
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
function hostedCheckRunPublicationPrivacy() {
|
|
693
|
+
return {
|
|
694
|
+
includesRawSource: false,
|
|
695
|
+
includesRawDiffs: false,
|
|
696
|
+
includesSecrets: false,
|
|
697
|
+
includesCustomerPayloads: false,
|
|
698
|
+
includesUntrustedPrText: false,
|
|
699
|
+
createsPrComment: false,
|
|
700
|
+
modelTraining: HOSTED_PRIVACY_DEFAULTS.modelTraining
|
|
701
|
+
};
|
|
702
|
+
}
|
|
630
703
|
function parseJsonPayload(payload) {
|
|
631
704
|
try {
|
|
632
705
|
return JSON.parse(Buffer.isBuffer(payload) ? payload.toString("utf8") : payload);
|
|
@@ -683,6 +756,8 @@ function formatCheckRunTitle(totalFindings, conclusion, failOnSeverity) {
|
|
|
683
756
|
return `AI SaaS Guard found ${totalFindings} finding${totalFindings === 1 ? "" : "s"} to review`;
|
|
684
757
|
}
|
|
685
758
|
function formatCheckRunMarkdown(report, conclusion, localCliCommand) {
|
|
759
|
+
const categories = getHostedCheckRunCategories(report);
|
|
760
|
+
const filesToReview = getHostedCheckRunFiles(report);
|
|
686
761
|
const findingLines = report.evidence.length === 0
|
|
687
762
|
? ["No findings in the compact hosted report."]
|
|
688
763
|
: [
|
|
@@ -702,6 +777,17 @@ function formatCheckRunMarkdown(report, conclusion, localCliCommand) {
|
|
|
702
777
|
"Summary:",
|
|
703
778
|
...severityOrder.map((severity) => `- ${capitalize(severity)}: ${report.summaryCounts[severity] ?? 0}`),
|
|
704
779
|
"",
|
|
780
|
+
"Review categories:",
|
|
781
|
+
...(categories.length === 0 ? ["- None"] : categories.map((category) => `- ${category}`)),
|
|
782
|
+
"",
|
|
783
|
+
"Files to review first:",
|
|
784
|
+
...(filesToReview.length === 0 ? ["- None"] : filesToReview.map((file) => `- ${file}`)),
|
|
785
|
+
"",
|
|
786
|
+
"Verification steps:",
|
|
787
|
+
"- Review each listed file before release or merge.",
|
|
788
|
+
"- Reproduce locally with the CLI command above.",
|
|
789
|
+
"- Treat findings as review prompts; confirm behavior with app-specific tests.",
|
|
790
|
+
"",
|
|
705
791
|
"Findings:",
|
|
706
792
|
...findingLines
|
|
707
793
|
].join("\n");
|
|
@@ -738,6 +824,27 @@ function annotationLevelForSeverity(severity) {
|
|
|
738
824
|
function formatFindingLocation(finding) {
|
|
739
825
|
return `${finding.file}${finding.line === undefined ? "" : `:${finding.line}`}`;
|
|
740
826
|
}
|
|
827
|
+
function getHostedCheckRunCategories(report) {
|
|
828
|
+
const categories = report.evidence.map((finding) => categoryForRuleId(finding.ruleId));
|
|
829
|
+
return [...new Set(categories)];
|
|
830
|
+
}
|
|
831
|
+
function categoryForRuleId(ruleId) {
|
|
832
|
+
const prefix = ruleId.split(".")[0] ?? "review";
|
|
833
|
+
const categoryNames = {
|
|
834
|
+
api: "API routes",
|
|
835
|
+
deploy: "Deploy config",
|
|
836
|
+
mcp: "MCP tools",
|
|
837
|
+
pr: "Pull request risk",
|
|
838
|
+
"pr-risk": "Pull request risk",
|
|
839
|
+
secrets: "Secrets and env",
|
|
840
|
+
stripe: "Stripe billing",
|
|
841
|
+
supabase: "Supabase data access"
|
|
842
|
+
};
|
|
843
|
+
return categoryNames[prefix] ?? capitalize(prefix);
|
|
844
|
+
}
|
|
845
|
+
function getHostedCheckRunFiles(report) {
|
|
846
|
+
return [...new Set(report.evidence.map((finding) => finding.file))].slice(0, 10);
|
|
847
|
+
}
|
|
741
848
|
function escapeMarkdownTableCell(value) {
|
|
742
849
|
return value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
743
850
|
}
|
package/docs/github-action.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`ai-saas-guard` ships as a composite GitHub Action for pull request and code scanning workflows.
|
|
4
4
|
|
|
5
|
-
Use `zr9959/ai-saas-guard@v0` for the latest compatible pre-1.0 Action. Use a specific tag such as `v0.
|
|
5
|
+
Use `zr9959/ai-saas-guard@v0` for the latest compatible pre-1.0 Action. Use a specific tag such as `v0.14.0` or a reviewed commit SHA when reproducibility is more important than automatic minor updates.
|
|
6
6
|
|
|
7
7
|
## PR Summary
|
|
8
8
|
|
|
@@ -117,6 +117,7 @@ Default behavior:
|
|
|
117
117
|
- include review-first language that tells readers to verify findings before release
|
|
118
118
|
- state that the result is not a full security audit, pentest, or certification
|
|
119
119
|
- include a local CLI link through the exact `npx ai-saas-guard@<version> pr-risk --root .` command
|
|
120
|
+
- include review categories, files to review first, and verification steps
|
|
120
121
|
- cap check-run text with bounded Markdown so oversized reports cannot create unbounded API payloads
|
|
121
122
|
|
|
122
123
|
Privacy boundaries:
|
|
@@ -126,6 +127,27 @@ Privacy boundaries:
|
|
|
126
127
|
- do not include raw source, raw diffs, secret values, webhook payload bodies, customer payloads, or private URLs
|
|
127
128
|
- preserve `modelTraining: disabled`
|
|
128
129
|
|
|
130
|
+
## Check-Run Publication Planner
|
|
131
|
+
|
|
132
|
+
The check-run publication planner turns a compact hosted report into a GitHub Checks API request plan. It is a pure planner only: it does not call GitHub, request installation tokens, write check runs, post PR comments, fetch repositories, or store report data.
|
|
133
|
+
|
|
134
|
+
Default behavior:
|
|
135
|
+
|
|
136
|
+
- authorize the same installation and selected-repository scope before planning a Check Run write
|
|
137
|
+
- require installation token permissions to include repository `checks: write`
|
|
138
|
+
- create a Check Run payload for the trusted head SHA
|
|
139
|
+
- use conservative conclusions from the summary renderer: `success` for no findings, `neutral` for review-needed findings, and `failure` only when a configured policy threshold is met
|
|
140
|
+
- include bounded Markdown, annotations, categories, verification steps, and the local CLI reproduction command
|
|
141
|
+
- keep PR comments disabled for the MVP
|
|
142
|
+
|
|
143
|
+
Privacy boundaries:
|
|
144
|
+
|
|
145
|
+
- plan a Check Run from compact report fields only
|
|
146
|
+
- do not include raw source, raw diffs, secret values, untrusted PR text, webhook payload bodies, customer payloads, private URLs, or worker checkout paths
|
|
147
|
+
- do not create issue comments, review comments, or PR comments
|
|
148
|
+
|
|
149
|
+
The exported helper is `planHostedCheckRunPublication`. It is intended to be the GitHub-API-independent contract for the first real Check Run writer. PR comments remain an explicit later workflow or paid hosted feature, not part of this MVP contract.
|
|
150
|
+
|
|
129
151
|
## Queue Cleanup Planner
|
|
130
152
|
|
|
131
153
|
The queue cleanup planner turns repository removal, installation deletion, and repeated cleanup events into a safe cancellation plan for hosted scan jobs. It is a pure planner only: it does not connect to a queue provider, mutate jobs, delete worker files, call GitHub, or retry work.
|
|
@@ -223,7 +245,11 @@ Automated tests must cover:
|
|
|
223
245
|
- untrusted PR text cannot override trusted identity
|
|
224
246
|
- check-run summary renderer conclusions stay success, neutral, or failure based on explicit compact-report rules
|
|
225
247
|
- bounded Markdown truncates large check-run text and points readers to the local CLI
|
|
248
|
+
- rendered summaries include categories, files to review first, and verification steps
|
|
226
249
|
- rendered summaries do not expose raw source, raw diffs, secret values, or customer payloads
|
|
250
|
+
- check-run publication planning requires repository `checks: write` permissions
|
|
251
|
+
- check-run publication planning creates bounded Check Run payloads from compact reports only
|
|
252
|
+
- check-run publication planning keeps PR comments disabled
|
|
227
253
|
- queue cleanup planner cancels only matching repository-scoped queued work
|
|
228
254
|
- queue cleanup planner handles installation-scoped cleanup without touching other installations
|
|
229
255
|
- idempotent repeated cleanup preserves terminal jobs and does not create duplicate cancellation work
|
package/docs/npm-publishing.md
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
## Current State
|
|
6
6
|
|
|
7
7
|
- Package name: `ai-saas-guard`
|
|
8
|
-
- Current version: `0.
|
|
8
|
+
- Current version: `0.14.0`
|
|
9
9
|
- npm registry state: published at <https://www.npmjs.com/package/ai-saas-guard>
|
|
10
10
|
- First npm-published version: `0.1.1`
|
|
11
|
-
- GitHub Release: `v0.
|
|
11
|
+
- GitHub Release: `v0.14.0`
|
|
12
12
|
- Publish workflow: `.github/workflows/npm-publish.yml`
|
|
13
13
|
- Trusted Publisher: GitHub Actions, `zr9959/ai-saas-guard`, workflow `npm-publish.yml`, allowed action `npm publish`
|
|
14
14
|
- Long-lived npm publish token: not required
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
|
|
18
18
|
Use GitHub Actions with npm Trusted Publisher/OIDC:
|
|
19
19
|
|
|
20
|
-
1. Create and review a release tag such as `v0.
|
|
20
|
+
1. Create and review a release tag such as `v0.14.0`.
|
|
21
21
|
2. Publish from the GitHub Release or run the `Publish npm` workflow manually with `ref` set to that tag.
|
|
22
22
|
3. Keep `permissions.id-token: write` in the workflow so npm can exchange the GitHub Actions OIDC identity for a short-lived publish credential.
|
|
23
23
|
4. Run `npm publish --access public` from the workflow. Trusted publishing automatically generates provenance for this public package from this public repository.
|
package/docs/project-handoff.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Project Handoff
|
|
2
2
|
|
|
3
|
-
Last updated: 2026-05-
|
|
3
|
+
Last updated: 2026-05-24
|
|
4
4
|
|
|
5
5
|
Use this public-safe document when moving `ai-saas-guard` into a new GitHub-facing ChatGPT/Codex Project or a new conversation.
|
|
6
6
|
|
|
@@ -57,7 +57,7 @@ Implemented surfaces:
|
|
|
57
57
|
- hosted operational release gate document requiring hosted CI, webhook replay, dependency and container scanning, privacy and retention verification, worker cleanup, monitoring and alerting, manual rollback, and incident response evidence before exposure
|
|
58
58
|
- hosted uninstall and data deletion document defining repository removal, full app uninstall, compact report deletion, queue cancellation, audit record retention, repeated cleanup idempotency, and user-facing deletion wording
|
|
59
59
|
- hosted pricing and packaging document defining open-source CLI boundaries, free/public repo hosted behavior, private repo hosted behavior, PR comments, saved reports, team policy, optional Launch Review, and no pentest/certification/full-audit claims
|
|
60
|
-
- hosted pre-implementation contracts document, hosted compact report fixture, and pure helpers for pull request webhook intake planning, durable scan queue upsert planning, worker read-only scan planning, queue-safe pull request event parsing from trusted GitHub event fields, bounded check-run summary rendering, idempotent queue cleanup planning, and worker checkout cleanup planning
|
|
60
|
+
- hosted pre-implementation contracts document, hosted compact report fixture, and pure helpers for pull request webhook intake planning, durable scan queue upsert planning, worker read-only scan planning, Check Run publication planning, queue-safe pull request event parsing from trusted GitHub event fields, bounded check-run summary rendering, idempotent queue cleanup planning, and worker checkout cleanup planning
|
|
61
61
|
- implementation-ready hosted GitHub App permission contract for required permissions, optional PR comment permissions, selected repository installation, and out-of-scope broad permissions
|
|
62
62
|
- pure hosted GitHub App contract helpers and tests for webhook intake order, webhook verification, installation token scoping, durable scan queue idempotency, compact reports, and retention limits
|
|
63
63
|
- GitHub issue templates for bug reports, false positives, false negatives, rule requests, and public-safe security reports
|
|
@@ -115,19 +115,20 @@ Current issue set:
|
|
|
115
115
|
|
|
116
116
|
- Closed hosted MVP issue: #24 webhook intake.
|
|
117
117
|
- Closed hosted MVP issue: #25 idempotent queue contract.
|
|
118
|
-
-
|
|
118
|
+
- Closed hosted MVP issue: #26 read-only worker checkout.
|
|
119
|
+
- Open hosted MVP roadmap issues: #27 Check summaries, #28 retention/uninstall cleanup, and #29 hosted operational release gate.
|
|
119
120
|
|
|
120
121
|
CI:
|
|
121
122
|
|
|
122
123
|
- Workflow: `.github/workflows/ci.yml`
|
|
123
124
|
- Runs on pull requests and pushes to `main`
|
|
124
125
|
- Uses `permissions: contents: read`
|
|
125
|
-
- Latest verified run for the hosted
|
|
126
|
+
- Latest verified run for the hosted read-only worker plan release succeeded
|
|
126
127
|
|
|
127
128
|
Publishing:
|
|
128
129
|
|
|
129
130
|
- npm package: `ai-saas-guard`
|
|
130
|
-
- Current release line: `v0.
|
|
131
|
+
- Current release line: `v0.14.0`
|
|
131
132
|
- Publish workflow: `.github/workflows/npm-publish.yml`
|
|
132
133
|
- Trusted Publisher: GitHub Actions for `zr9959/ai-saas-guard`, workflow `npm-publish.yml`
|
|
133
134
|
- Long-lived npm publish tokens should not be required.
|