ai-project-maintainer 0.4.0 → 0.4.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.
Files changed (51) hide show
  1. package/README.md +16 -6
  2. package/ai-project-maintainer/agents/openai.yaml +6 -6
  3. package/ai-project-maintainer/references/ci-guardrails.md +55 -55
  4. package/ai-project-maintainer/references/database.md +60 -60
  5. package/ai-project-maintainer/references/electron-desktop.md +43 -43
  6. package/ai-project-maintainer/references/incident-response.md +52 -52
  7. package/ai-project-maintainer/references/security.md +48 -48
  8. package/ai-project-maintainer/references/tool-router.md +53 -53
  9. package/ai-project-maintainer/scripts/bootstrap-local-tools.ps1 +109 -109
  10. package/ai-project-maintainer/scripts/ci-smoke-gate.mjs +26 -26
  11. package/ai-project-maintainer/scripts/init-project.mjs +30 -18
  12. package/ai-project-maintainer/scripts/lib/check-registry.mjs +10 -9
  13. package/ai-project-maintainer/scripts/lib/checks.mjs +22 -10
  14. package/ai-project-maintainer/scripts/lib/command-runner.mjs +17 -3
  15. package/ai-project-maintainer/scripts/lib/policy.mjs +6 -4
  16. package/ai-project-maintainer/scripts/lib/report.mjs +56 -32
  17. package/assets/demo-90s-storyboard.svg +98 -0
  18. package/assets/demo-90s.gif +0 -0
  19. package/assets/social-preview.png +0 -0
  20. package/assets/social-preview.svg +55 -0
  21. package/docs/DEMO.md +68 -61
  22. package/docs/DEMO.zh-CN.md +75 -69
  23. package/docs/GITHUB-LAUNCH-CHECKLIST.md +11 -11
  24. package/docs/POLICY-AND-EXCEPTIONS.zh-CN.md +1 -1
  25. package/docs/PROMOTION.md +49 -21
  26. package/docs/SECURITY-WORKFLOW.md +61 -59
  27. package/docs/UPGRADE-ROADMAP.zh-CN.md +58 -58
  28. package/docs/demo-output/90-second-demo.html +187 -0
  29. package/docs/demo-output/before-after-case.md +91 -0
  30. package/docs/demo-output/security-report.md +62 -61
  31. package/docs/superpowers/plans/2026-06-29-ci-dogfooding.md +200 -200
  32. package/examples/demo-ai-app/.ai-maintainer/business-flows.yml +14 -14
  33. package/examples/demo-ai-app/.ai-maintainer/db-migration-policy.yml +6 -6
  34. package/examples/demo-ai-app/.ai-maintainer/evidence-sources.yml +18 -18
  35. package/examples/demo-ai-app/.ai-maintainer/exceptions.yml +1 -1
  36. package/examples/demo-ai-app/.ai-maintainer/incident-runbook.md +11 -11
  37. package/examples/demo-ai-app/.ai-maintainer/observability-checklist.yml +7 -7
  38. package/examples/demo-ai-app/.ai-maintainer/policy.yml +27 -27
  39. package/examples/demo-ai-app/.ai-maintainer/project-profile.yml +15 -15
  40. package/examples/demo-ai-app/.ai-maintainer/release-checklist.yml +7 -7
  41. package/examples/demo-ai-app/.ai-maintainer/risk-policy.yml +5 -5
  42. package/examples/demo-ai-app/.ai-maintainer/threat-model.md +18 -18
  43. package/examples/demo-ai-app/README.md +38 -38
  44. package/examples/demo-ai-app/package-lock.json +15 -15
  45. package/examples/demo-ai-app/package.json +16 -16
  46. package/examples/demo-ai-app/scripts/build.mjs +18 -18
  47. package/examples/demo-ai-app/scripts/create-before-state.mjs +86 -86
  48. package/examples/demo-ai-app/scripts/run-demo-gate.mjs +95 -95
  49. package/examples/demo-ai-app/src/order-risk.js +28 -28
  50. package/examples/demo-ai-app/test/order-risk.test.mjs +24 -24
  51. package/package.json +2 -1
@@ -17,7 +17,7 @@ function gradeForScore(score) {
17
17
  return "F";
18
18
  }
19
19
 
20
- function buildMaintenanceSummary({ blockers, warnings, coverageGaps, invalidExceptions }) {
20
+ function buildMaintenanceSummary({ blockers, warnings, coverageGaps, invalidExceptions }) {
21
21
  const score = Math.max(
22
22
  0,
23
23
  Math.min(100, 100 - blockers.length * 25 - warnings.length * 3 - coverageGaps.length * 2 - invalidExceptions.length * 20),
@@ -31,10 +31,17 @@ function buildMaintenanceSummary({ blockers, warnings, coverageGaps, invalidExce
31
31
  coverageGaps: coverageGaps.length,
32
32
  invalidExceptions: invalidExceptions.length,
33
33
  },
34
- };
35
- }
36
-
37
- export function buildJsonReport({
34
+ };
35
+ }
36
+
37
+ function buildOverallStatus({ blockers, warnings, coverageGaps, invalidExceptions, userDecisionCount }) {
38
+ if (blockers.length || invalidExceptions.length) return "FAIL";
39
+ if (coverageGaps.length || userDecisionCount > 0) return "PASS_WITH_GAPS";
40
+ if (warnings.length) return "PASS_WITH_WARNINGS";
41
+ return "PASS";
42
+ }
43
+
44
+ export function buildJsonReport({
38
45
  root,
39
46
  mode,
40
47
  probe,
@@ -44,19 +51,26 @@ export function buildJsonReport({
44
51
  invalidExceptions = [],
45
52
  generatedAt = new Date().toISOString(),
46
53
  }) {
47
- const blockers = checks.filter((check) => check.blocking);
48
- const warnings = checks.filter((check) => !check.blocking && ["fail", "error", "missing", "skipped", "gap", "user_decision"].includes(statusKey(check.status)));
49
- const coverageGaps = checks.filter((check) => check.coverageGap || ["missing", "skipped", "gap"].includes(statusKey(check.status)));
50
- const exceptionUsage = checks.filter((check) => check.exception).map((check) => ({
51
- check: check.name,
52
- exception: check.exception,
53
- }));
54
-
55
- return {
56
- schemaVersion: 1,
57
- root,
58
- mode,
59
- passed: blockers.length === 0 && invalidExceptions.length === 0,
54
+ const blockers = checks.filter((check) => check.blocking);
55
+ const warnings = checks.filter((check) => !check.blocking && ["fail", "error", "missing", "skipped", "gap", "user_decision"].includes(statusKey(check.status)));
56
+ const coverageGaps = checks.filter((check) => check.coverageGap || ["missing", "skipped", "gap"].includes(statusKey(check.status)));
57
+ const userDecisionCount = checks.filter((check) => statusKey(check.status) === "user_decision").length + (audit?.userDecisions || []).length;
58
+ const exceptionUsage = checks.filter((check) => check.exception).map((check) => ({
59
+ check: {
60
+ checkId: check.checkId || null,
61
+ name: check.name,
62
+ group: check.group,
63
+ },
64
+ exception: check.exception,
65
+ }));
66
+ const overallStatus = buildOverallStatus({ blockers, warnings, coverageGaps, invalidExceptions, userDecisionCount });
67
+
68
+ return {
69
+ schemaVersion: 1,
70
+ root,
71
+ mode,
72
+ overallStatus,
73
+ passed: blockers.length === 0 && invalidExceptions.length === 0,
60
74
  blockerCount: blockers.length + invalidExceptions.length,
61
75
  warningCount: warnings.length,
62
76
  coverageGapCount: coverageGaps.length,
@@ -76,9 +90,10 @@ export function buildJsonReport({
76
90
  };
77
91
  }
78
92
 
79
- export function toMarkdown(report) {
80
- const lines = [];
81
- lines.push(`# Local Security Gate: ${report.passed ? "PASS" : "FAIL"}`);
93
+ export function toMarkdown(report) {
94
+ const lines = [];
95
+ const overallStatus = report.overallStatus || (report.passed ? "PASS" : "FAIL");
96
+ lines.push(`# Local Security Gate: ${overallStatus}`);
82
97
  lines.push("");
83
98
  lines.push(`Root: ${report.root}`);
84
99
  lines.push(`Mode: strict=${Boolean(report.mode?.strict)}, release=${Boolean(report.mode?.release)}, production=${Boolean(report.mode?.production)}`);
@@ -154,20 +169,29 @@ export function toMarkdown(report) {
154
169
  }
155
170
  lines.push("");
156
171
 
157
- lines.push("## Exceptions");
158
- if (!report.exceptions.used.length && !report.exceptions.invalid.length) lines.push("- None");
159
- for (const item of report.exceptions.used) {
160
- lines.push(`- ${item.exception.id}: applied to ${item.check}, expires ${item.exception.expires}`);
161
- }
172
+ lines.push("## Exceptions");
173
+ if (!report.exceptions.used.length && !report.exceptions.invalid.length) lines.push("- None");
174
+ for (const item of report.exceptions.used) {
175
+ const checkName = typeof item.check === "string" ? item.check : `${item.check.checkId || item.check.name} (${item.check.group})`;
176
+ lines.push(`- ${item.exception.id}: applied to ${checkName}, expires ${item.exception.expires}`);
177
+ }
162
178
  for (const item of report.exceptions.invalid) {
163
179
  lines.push(`- ${item.id || "(missing id)"}: invalid, ${item.reason}`);
164
180
  }
165
- lines.push("");
166
-
167
- lines.push("## Next Step");
168
- lines.push(report.passed ? "- Gate passed. Keep this command in CI before release." : "- Fix blocking checks or add narrow, owner-approved exceptions, then rerun the gate.");
169
- return lines.join("\n");
170
- }
181
+ lines.push("");
182
+
183
+ lines.push("## Next Step");
184
+ if (!report.passed) {
185
+ lines.push("- Fix blocking checks or add narrow, owner-approved exceptions, then rerun the gate.");
186
+ } else if (overallStatus === "PASS_WITH_GAPS") {
187
+ lines.push("- No blocking checks failed, but release-readiness gaps or user decisions remain. Fill evidence, accept risk explicitly, or enable block_on_coverage_gaps before release.");
188
+ } else if (overallStatus === "PASS_WITH_WARNINGS") {
189
+ lines.push("- Gate has no blockers or release-readiness gaps. Review warnings, then keep this command in CI before release.");
190
+ } else {
191
+ lines.push("- Gate passed without blockers, warnings, or release-readiness gaps. Keep this command in CI before release.");
192
+ }
193
+ return lines.join("\n");
194
+ }
171
195
 
172
196
  export function toSarif(report) {
173
197
  const rules = new Map();
@@ -0,0 +1,98 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1280" height="720" viewBox="0 0 1280 720" role="img" aria-labelledby="title desc">
2
+ <title id="title">AI Project Maintainer 90-second demo storyboard</title>
3
+ <desc id="desc">Animated storyboard showing project profile, broken before state, fixed tests, production gate, evidence report, and security workflow.</desc>
4
+ <defs>
5
+ <linearGradient id="bg" x1="0" x2="1" y1="0" y2="1">
6
+ <stop offset="0" stop-color="#0f172a"/>
7
+ <stop offset="0.55" stop-color="#111827"/>
8
+ <stop offset="1" stop-color="#0f766e"/>
9
+ </linearGradient>
10
+ <style>
11
+ .label { font: 700 48px system-ui, -apple-system, Segoe UI, sans-serif; fill: #f8fafc; }
12
+ .subtitle { font: 600 25px system-ui, -apple-system, Segoe UI, sans-serif; fill: #bae6fd; }
13
+ .body { font: 600 27px ui-monospace, SFMono-Regular, Consolas, monospace; fill: #e5e7eb; }
14
+ .muted { font: 600 21px system-ui, -apple-system, Segoe UI, sans-serif; fill: #94a3b8; }
15
+ .pass { fill: #34d399; }
16
+ .fail { fill: #fb7185; }
17
+ .gap { fill: #fbbf24; }
18
+ .panel { opacity: 0; animation: reveal 90s linear infinite; }
19
+ #s1 { animation-delay: 0s; }
20
+ #s2 { animation-delay: 15s; }
21
+ #s3 { animation-delay: 30s; }
22
+ #s4 { animation-delay: 45s; }
23
+ #s5 { animation-delay: 60s; }
24
+ #s6 { animation-delay: 75s; }
25
+ @keyframes reveal {
26
+ 0%, 15% { opacity: 1; }
27
+ 16%, 100% { opacity: 0; }
28
+ }
29
+ .bar { animation: progress 90s linear infinite; transform-origin: 120px 642px; }
30
+ @keyframes progress {
31
+ from { transform: scaleX(0); }
32
+ to { transform: scaleX(1); }
33
+ }
34
+ </style>
35
+ </defs>
36
+
37
+ <rect width="1280" height="720" fill="url(#bg)"/>
38
+ <rect x="72" y="56" width="1136" height="560" rx="28" fill="#111827" opacity="0.93" stroke="#334155" stroke-width="2"/>
39
+ <text x="120" y="124" class="label">AI Project Maintainer</text>
40
+ <text x="120" y="168" class="subtitle">90-second production-readiness demo for AI-coded projects</text>
41
+
42
+ <g id="s1" class="panel">
43
+ <text x="120" y="245" class="body">1. Start with project profile</text>
44
+ <text x="120" y="304" class="body">npx ai-project-maintainer init-audit .\examples\demo-ai-app</text>
45
+ <text x="120" y="365" class="muted">The maintainer declares project facts, business flows, evidence sources, and risk policy.</text>
46
+ <rect x="120" y="420" width="210" height="56" rx="12" fill="#0f766e"/>
47
+ <text x="146" y="456" class="body">PROFILE</text>
48
+ <rect x="360" y="420" width="210" height="56" rx="12" fill="#1d4ed8"/>
49
+ <text x="386" y="456" class="body">EVIDENCE</text>
50
+ <rect x="600" y="420" width="210" height="56" rx="12" fill="#6d28d9"/>
51
+ <text x="626" y="456" class="body">POLICY</text>
52
+ </g>
53
+
54
+ <g id="s2" class="panel">
55
+ <text x="120" y="245" class="body">2. Before state: behavior is broken</text>
56
+ <text x="120" y="304" class="body">node .\examples\demo-ai-app\scripts\create-before-state.mjs</text>
57
+ <text x="120" y="365" class="body fail">FAIL expensive orders require manual review</text>
58
+ <text x="120" y="410" class="body fail">FAIL orders cannot release without stock</text>
59
+ <text x="120" y="470" class="muted">No fake secrets are committed. The bad copy lives only under the OS temp directory.</text>
60
+ </g>
61
+
62
+ <g id="s3" class="panel">
63
+ <text x="120" y="245" class="body">3. Fix deterministic blockers</text>
64
+ <text x="120" y="304" class="body">npm test --prefix .\examples\demo-ai-app</text>
65
+ <text x="120" y="365" class="body pass">PASS checkout quote preserves customer-visible total</text>
66
+ <text x="120" y="410" class="body pass">PASS expensive orders require manual review</text>
67
+ <text x="120" y="455" class="body pass">PASS paid order release respects payment, stock, and risk</text>
68
+ </g>
69
+
70
+ <g id="s4" class="panel">
71
+ <text x="120" y="245" class="body">4. Run production gate</text>
72
+ <text x="120" y="304" class="body">npx ai-project-maintainer gate . --production --strict --release</text>
73
+ <text x="120" y="365" class="body pass">PASS tests, build, secrets, dependencies, SAST, CI checks</text>
74
+ <text x="120" y="410" class="body gap">GAP release approval, monitoring, logs, metrics, alerts</text>
75
+ <text x="120" y="470" class="muted">Checked failures block. Missing production evidence stays visible by default.</text>
76
+ </g>
77
+
78
+ <g id="s5" class="panel">
79
+ <text x="120" y="245" class="body">5. Produce evidence report</text>
80
+ <text x="120" y="304" class="body">reports/security-report.json</text>
81
+ <text x="120" y="349" class="body">reports/security-report.md</text>
82
+ <text x="120" y="394" class="body">reports/security-report.sarif</text>
83
+ <text x="120" y="439" class="body">reports/sbom.cdx.json</text>
84
+ <text x="120" y="500" class="muted">Codex can fix blockers, rerun, and leave maintainer decisions explicit.</text>
85
+ </g>
86
+
87
+ <g id="s6" class="panel">
88
+ <text x="120" y="245" class="body">6. Dogfood in GitHub Actions</text>
89
+ <text x="120" y="304" class="body pass">CI: green</text>
90
+ <text x="120" y="349" class="body pass">Security: green</text>
91
+ <text x="120" y="394" class="body">Gitleaks / Trivy / Semgrep / OSV / Syft / Grype / actionlint / zizmor</text>
92
+ <text x="120" y="470" class="subtitle">Let AI write fast. Make release readiness explicit.</text>
93
+ </g>
94
+
95
+ <rect x="120" y="642" width="1040" height="12" rx="6" fill="#334155"/>
96
+ <rect class="bar" x="120" y="642" width="1040" height="12" rx="6" fill="#38bdf8"/>
97
+ <text x="120" y="684" class="muted">project profile -> before failure -> fixed tests -> production gate -> evidence report -> CI security</text>
98
+ </svg>
Binary file
Binary file
@@ -0,0 +1,55 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="1280" height="640" viewBox="0 0 1280 640" role="img" aria-labelledby="title desc">
2
+ <title id="title">AI Project Maintainer</title>
3
+ <desc id="desc">Production-readiness gate for AI-coded projects</desc>
4
+ <defs>
5
+ <linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
6
+ <stop offset="0%" stop-color="#0f172a"/>
7
+ <stop offset="58%" stop-color="#111827"/>
8
+ <stop offset="100%" stop-color="#0f766e"/>
9
+ </linearGradient>
10
+ <linearGradient id="accent" x1="0" y1="0" x2="1" y2="0">
11
+ <stop offset="0%" stop-color="#38bdf8"/>
12
+ <stop offset="55%" stop-color="#2dd4bf"/>
13
+ <stop offset="100%" stop-color="#a7f3d0"/>
14
+ </linearGradient>
15
+ <marker id="arrow" markerWidth="12" markerHeight="12" refX="9" refY="6" orient="auto" markerUnits="strokeWidth">
16
+ <path d="M2 2 L10 6 L2 10 Z" fill="#5eead4"/>
17
+ </marker>
18
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
19
+ <feDropShadow dx="0" dy="20" stdDeviation="24" flood-color="#000000" flood-opacity="0.35"/>
20
+ </filter>
21
+ </defs>
22
+ <rect width="1280" height="640" fill="url(#bg)"/>
23
+ <path d="M0 514 C210 448 322 575 520 501 C768 408 882 521 1280 390 L1280 640 L0 640 Z" fill="#0b1220" opacity="0.52"/>
24
+ <rect x="72" y="70" width="1136" height="500" rx="34" fill="#0b1020" opacity="0.72" filter="url(#shadow)"/>
25
+ <rect x="100" y="98" width="1080" height="444" rx="24" fill="#111827" stroke="#334155" stroke-width="2"/>
26
+
27
+ <text x="152" y="178" fill="#e5f7ff" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="64" font-weight="800" letter-spacing="0">AI Project Maintainer</text>
28
+ <text x="154" y="236" fill="#bae6fd" font-family="Inter, Segoe UI, Arial, sans-serif" font-size="33" font-weight="650" letter-spacing="0">Production-readiness gate for AI-coded projects</text>
29
+ <rect x="154" y="278" width="972" height="4" rx="2" fill="url(#accent)"/>
30
+
31
+ <g font-family="Inter, Segoe UI, Arial, sans-serif" font-size="27" font-weight="750" text-anchor="middle">
32
+ <rect x="154" y="336" width="208" height="76" rx="18" fill="#172554" stroke="#38bdf8" stroke-width="2"/>
33
+ <text x="258" y="383" fill="#dbeafe">Project profile</text>
34
+
35
+ <line x1="386" y1="374" x2="424" y2="374" stroke="#5eead4" stroke-width="4" stroke-linecap="round" marker-end="url(#arrow)"/>
36
+
37
+ <rect x="448" y="336" width="178" height="76" rx="18" fill="#134e4a" stroke="#2dd4bf" stroke-width="2"/>
38
+ <text x="537" y="383" fill="#ccfbf1">Audit plan</text>
39
+
40
+ <line x1="650" y1="374" x2="688" y2="374" stroke="#5eead4" stroke-width="4" stroke-linecap="round" marker-end="url(#arrow)"/>
41
+
42
+ <rect x="712" y="336" width="150" height="76" rx="18" fill="#1e293b" stroke="#94a3b8" stroke-width="2"/>
43
+ <text x="787" y="383" fill="#e2e8f0">CI gate</text>
44
+
45
+ <line x1="886" y1="374" x2="924" y2="374" stroke="#5eead4" stroke-width="4" stroke-linecap="round" marker-end="url(#arrow)"/>
46
+
47
+ <rect x="948" y="336" width="216" height="76" rx="18" fill="#064e3b" stroke="#34d399" stroke-width="2"/>
48
+ <text x="1056" y="383" fill="#d1fae5">Evidence report</text>
49
+ </g>
50
+
51
+ <g font-family="Inter, Segoe UI, Arial, sans-serif" font-weight="650">
52
+ <text x="154" y="472" fill="#cbd5e1" font-size="24" letter-spacing="0">PASS / FAIL / WARN / GAP / N/A / USER_DECISION</text>
53
+ <text x="154" y="510" fill="#94a3b8" font-size="23" letter-spacing="0">Let AI write fast. Make release readiness explicit.</text>
54
+ </g>
55
+ </svg>
package/docs/DEMO.md CHANGED
@@ -1,69 +1,76 @@
1
- # Demo: From AI-Coded Repo to Production Audit Report
2
-
3
- This demo uses the runnable project in `examples/demo-ai-app`. It does not require any paid account or external API.
4
-
5
- ## 1. Run The Healthy Demo App
6
-
7
- ```powershell
8
- npm test --prefix .\examples\demo-ai-app
9
- npm run build --prefix .\examples\demo-ai-app
10
- ```
11
-
12
- The app is intentionally small: it quotes orders and decides whether paid orders can be released. The tests protect the business behavior that must not break.
13
-
14
- ## 2. Generate A Broken Before State
15
-
16
- ```powershell
17
- node .\examples\demo-ai-app\scripts\create-before-state.mjs
18
- ```
19
-
20
- The command prints a temporary directory. Run this in that copied project:
21
-
22
- ```powershell
23
- npm test
24
- ```
25
-
26
- You should see the business tests fail. This is the "AI-coded project looks complete, but behavior is broken" stage. The broken copy is created under the OS temp directory, so the repository does not commit fake secrets or intentionally bad source files.
27
-
28
- ## 3. Run The Reproducible Demo Gate
29
-
30
- ```powershell
31
- node .\examples\demo-ai-app\scripts\run-demo-gate.mjs
32
- ```
33
-
34
- This script runs the real AI Project Maintainer gate with temporary scanner shims, so the sample report is stable even on a machine that has not installed Gitleaks, Trivy, Semgrep, OSV-Scanner, Syft, Grype, actionlint, zizmor, or Scorecard yet.
35
-
36
- Expected result:
37
-
1
+ # Demo: From AI-Coded Repo to Production Audit Report
2
+
3
+ This demo uses the runnable project in `examples/demo-ai-app`. It does not require any paid account or external API.
4
+
5
+ Visual materials:
6
+
7
+ - [90-second GIF storyboard](../assets/demo-90s.gif)
8
+ - [90-second browser demo](demo-output/90-second-demo.html)
9
+ - [Before/after case](demo-output/before-after-case.md)
10
+
11
+ ## 1. Run The Healthy Demo App
12
+
13
+ ```powershell
14
+ npm test --prefix .\examples\demo-ai-app
15
+ npm run build --prefix .\examples\demo-ai-app
16
+ ```
17
+
18
+ The app is intentionally small: it quotes orders and decides whether paid orders can be released. The tests protect the business behavior that must not break.
19
+
20
+ ## 2. Generate A Broken Before State
21
+
22
+ ```powershell
23
+ node .\examples\demo-ai-app\scripts\create-before-state.mjs
24
+ ```
25
+
26
+ The command prints a temporary directory. Run this in that copied project:
27
+
28
+ ```powershell
29
+ npm test
30
+ ```
31
+
32
+ You should see the business tests fail. This is the "AI-coded project looks complete, but behavior is broken" stage. The broken copy is created under the OS temp directory, so the repository does not commit fake secrets or intentionally bad source files.
33
+
34
+ ## 3. Run The Reproducible Demo Gate
35
+
36
+ ```powershell
37
+ node .\examples\demo-ai-app\scripts\run-demo-gate.mjs
38
+ ```
39
+
40
+ This script runs the real AI Project Maintainer gate with temporary scanner shims, so the sample report is stable even on a machine that has not installed Gitleaks, Trivy, Semgrep, OSV-Scanner, Syft, Grype, actionlint, zizmor, or Scorecard yet.
41
+
42
+ Expected result:
43
+
38
44
  ```text
39
- Local Security Gate: PASS
45
+ Local Security Gate: PASS_WITH_GAPS
40
46
  Blocking Checks: None
41
47
  Coverage Gaps:
42
48
  - Production release approval
43
49
  - Error monitoring
44
- - Production logs
45
- - Production metrics
46
- - Production alerts
50
+ - Production logs
51
+ - Production metrics
52
+ - Production alerts
47
53
  ```
48
54
 
49
55
  See the generated-style [sample report](demo-output/security-report.md).
50
-
51
- ## 4. Run The Real Gate
52
-
53
- After installing scanner CLIs, use the same command a real project would use:
54
-
55
- ```powershell
56
- npx ai-project-maintainer gate .\examples\demo-ai-app --production --strict --release --output reports/security-report.json
57
- ```
58
-
59
- The point is not to pretend the project is perfect. The point is to make the checked failures and missing production evidence explicit before release.
60
-
61
- ## 5. Let Codex Fix Blockers
62
-
63
- Ask Codex:
64
-
65
- ```text
66
- $ai-project-maintainer run the production gate for this project, fix blockers, and rerun until it passes.
67
- ```
68
-
69
- Codex can handle deterministic blockers. The maintainer still owns business decisions such as critical flows, accepted risks, and production evidence.
56
+ `PASS_WITH_GAPS` means deterministic blockers are clear, but production evidence still needs to be filled in or explicitly accepted before release.
57
+
58
+ ## 4. Run The Real Gate
59
+
60
+ After installing scanner CLIs, use the same command a real project would use:
61
+
62
+ ```powershell
63
+ npx ai-project-maintainer gate .\examples\demo-ai-app --production --strict --release --output reports/security-report.json
64
+ ```
65
+
66
+ The point is not to pretend the project is perfect. The point is to make the checked failures and missing production evidence explicit before release.
67
+
68
+ ## 5. Let Codex Fix Blockers
69
+
70
+ Ask Codex:
71
+
72
+ ```text
73
+ $ai-project-maintainer run the production gate for this project, fix blockers, and rerun until it passes.
74
+ ```
75
+
76
+ Codex can handle deterministic blockers. The maintainer still owns business decisions such as critical flows, accepted risks, and production evidence.
@@ -1,69 +1,75 @@
1
- # 演示:从 AI 写出的项目到生产审查报告
2
-
3
- 这个演示使用仓库里的真实项目:`examples/demo-ai-app`。不需要付费账号,也不需要外部 API。
4
-
5
- ## 1. 跑健康态项目
6
-
7
- ```powershell
8
- npm test --prefix .\examples\demo-ai-app
9
- npm run build --prefix .\examples\demo-ai-app
10
- ```
11
-
12
- 这个项目很小:它负责订单报价和订单释放判断。测试覆盖的是不能被 AI 修改坏的核心业务行为。
13
-
14
- ## 2. 生成坏掉的 before 状态
15
-
16
- ```powershell
17
- node .\examples\demo-ai-app\scripts\create-before-state.mjs
18
- ```
19
-
20
- 命令会输出一个临时目录。进入那个复制出来的项目后运行:
21
-
22
- ```powershell
23
- npm test
24
- ```
25
-
26
- 你会看到业务测试失败。这代表“AI 写出来看起来完整,但关键行为已经坏了”的阶段。坏代码只存在于系统临时目录,仓库不会提交假 secret 或故意脆弱的源码。
27
-
28
- ## 3. 跑可复现的 demo gate
29
-
30
- ```powershell
31
- node .\examples\demo-ai-app\scripts\run-demo-gate.mjs
32
- ```
33
-
34
- 这个脚本会运行真实的 AI Project Maintainer gate,但会临时创建扫描器 mock,所以即使本机还没安装 Gitleaks、Trivy、Semgrep、OSV-Scanner、Syft、Grype、actionlint、zizmor、Scorecard,也能稳定生成示例报告。
35
-
36
- 预期结果:
37
-
38
- ```text
39
- Local Security Gate: PASS
40
- Blocking Checks: None
41
- Coverage Gaps:
42
- - Production release approval
43
- - Error monitoring
44
- - Production logs
45
- - Production metrics
46
- - Production alerts
47
- ```
48
-
49
- 示例报告见:[sample report](demo-output/security-report.md)。
50
-
51
- ## 4. 跑真实 gate
52
-
53
- 安装扫描器 CLI 后,可以用真实项目同款命令:
54
-
55
- ```powershell
56
- npx ai-project-maintainer gate .\examples\demo-ai-app --production --strict --release --output reports/security-report.json
57
- ```
58
-
59
- 这个工具不是为了假装项目完美,而是把已经检查失败的项和缺少的生产证据在发布前明确展示出来。
60
-
61
- ## 5. 让 Codex 修阻断项
62
-
63
- 可以这样要求 Codex:
64
-
65
- ```text
66
- $ai-project-maintainer run the production gate for this project, fix blockers, and rerun until it passes.
67
- ```
68
-
69
- Codex 适合处理确定性的阻断项。维护者仍然负责业务决策、风险接受和生产证据确认。
1
+ # 演示:从 AI 写出的项目到生产审查报告
2
+
3
+ 这个演示使用仓库里的真实项目:`examples/demo-ai-app`。不需要付费账号,也不需要外部 API。
4
+
5
+ 演示素材:
6
+
7
+ - [90 秒 GIF 故事板](../assets/demo-90s.gif)
8
+ - [90 秒浏览器演示页](demo-output/90-second-demo.html)
9
+ - [before/after 案例](demo-output/before-after-case.md)
10
+
11
+ ## 1. 跑健康态项目
12
+
13
+ ```powershell
14
+ npm test --prefix .\examples\demo-ai-app
15
+ npm run build --prefix .\examples\demo-ai-app
16
+ ```
17
+
18
+ 这个项目很小:它负责订单报价和订单释放判断。测试覆盖的是不能被 AI 修改坏的核心业务行为。
19
+
20
+ ## 2. 生成坏掉的 before 状态
21
+
22
+ ```powershell
23
+ node .\examples\demo-ai-app\scripts\create-before-state.mjs
24
+ ```
25
+
26
+ 命令会输出一个临时目录。进入那个复制出来的项目后运行:
27
+
28
+ ```powershell
29
+ npm test
30
+ ```
31
+
32
+ 你会看到业务测试失败。这代表“AI 写出来看起来完整,但关键行为已经坏了”的阶段。坏代码只存在于系统临时目录,仓库不会提交假 secret 或故意脆弱的源码。
33
+
34
+ ## 3. 跑可复现的 demo gate
35
+
36
+ ```powershell
37
+ node .\examples\demo-ai-app\scripts\run-demo-gate.mjs
38
+ ```
39
+
40
+ 这个脚本会运行真实的 AI Project Maintainer gate,但会临时创建扫描器 mock,所以即使本机还没安装 Gitleaks、Trivy、Semgrep、OSV-Scanner、Syft、Grype、actionlint、zizmor、Scorecard,也能稳定生成示例报告。
41
+
42
+ 预期结果:
43
+
44
+ ```text
45
+ Local Security Gate: PASS_WITH_GAPS
46
+ Blocking Checks: None
47
+ Coverage Gaps:
48
+ - Production release approval
49
+ - Error monitoring
50
+ - Production logs
51
+ - Production metrics
52
+ - Production alerts
53
+ ```
54
+
55
+ 示例报告见:[sample report](demo-output/security-report.md)。
56
+
57
+ ## 4. 跑真实 gate
58
+
59
+ 安装扫描器 CLI 后,可以用真实项目同款命令:
60
+
61
+ ```powershell
62
+ npx ai-project-maintainer gate .\examples\demo-ai-app --production --strict --release --output reports/security-report.json
63
+ ```
64
+
65
+ 这个工具不是为了假装项目完美,而是把已经检查失败的项和缺少的生产证据在发布前明确展示出来。
66
+
67
+ ## 5. 让 Codex 修阻断项
68
+
69
+ 可以这样要求 Codex
70
+
71
+ ```text
72
+ $ai-project-maintainer run the production gate for this project, fix blockers, and rerun until it passes.
73
+ ```
74
+
75
+ Codex 适合处理确定性的阻断项。维护者仍然负责业务决策、风险接受和生产证据确认。
@@ -31,17 +31,17 @@ ai-agents
31
31
 
32
32
  Upload a social preview image in repository settings.
33
33
 
34
- Recommended source:
35
-
36
- ```text
37
- assets/social-preview.png
38
- ```
39
-
40
- Editable source:
41
-
42
- ```text
43
- assets/social-preview.svg
44
- ```
34
+ Recommended source:
35
+
36
+ ```text
37
+ assets/social-preview.png
38
+ ```
39
+
40
+ Editable source:
41
+
42
+ ```text
43
+ assets/social-preview.svg
44
+ ```
45
45
 
46
46
  If GitHub asks for PNG/JPG, export the SVG to PNG at `1280x640`.
47
47
 
@@ -58,7 +58,7 @@ warn_on:
58
58
  ```yaml
59
59
  exceptions:
60
60
  - id: "example-dev-only-vuln"
61
- check: "npm audit"
61
+ check: "package-audit"
62
62
  reason: "dev-only transitive dependency, not shipped"
63
63
  expires: "2026-09-01"
64
64
  owner: "repo-owner"