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.
- package/README.md +16 -6
- package/ai-project-maintainer/agents/openai.yaml +6 -6
- package/ai-project-maintainer/references/ci-guardrails.md +55 -55
- package/ai-project-maintainer/references/database.md +60 -60
- package/ai-project-maintainer/references/electron-desktop.md +43 -43
- package/ai-project-maintainer/references/incident-response.md +52 -52
- package/ai-project-maintainer/references/security.md +48 -48
- package/ai-project-maintainer/references/tool-router.md +53 -53
- package/ai-project-maintainer/scripts/bootstrap-local-tools.ps1 +109 -109
- package/ai-project-maintainer/scripts/ci-smoke-gate.mjs +26 -26
- package/ai-project-maintainer/scripts/init-project.mjs +30 -18
- package/ai-project-maintainer/scripts/lib/check-registry.mjs +10 -9
- package/ai-project-maintainer/scripts/lib/checks.mjs +22 -10
- package/ai-project-maintainer/scripts/lib/command-runner.mjs +17 -3
- package/ai-project-maintainer/scripts/lib/policy.mjs +6 -4
- package/ai-project-maintainer/scripts/lib/report.mjs +56 -32
- package/assets/demo-90s-storyboard.svg +98 -0
- package/assets/demo-90s.gif +0 -0
- package/assets/social-preview.png +0 -0
- package/assets/social-preview.svg +55 -0
- package/docs/DEMO.md +68 -61
- package/docs/DEMO.zh-CN.md +75 -69
- package/docs/GITHUB-LAUNCH-CHECKLIST.md +11 -11
- package/docs/POLICY-AND-EXCEPTIONS.zh-CN.md +1 -1
- package/docs/PROMOTION.md +49 -21
- package/docs/SECURITY-WORKFLOW.md +61 -59
- package/docs/UPGRADE-ROADMAP.zh-CN.md +58 -58
- package/docs/demo-output/90-second-demo.html +187 -0
- package/docs/demo-output/before-after-case.md +91 -0
- package/docs/demo-output/security-report.md +62 -61
- package/docs/superpowers/plans/2026-06-29-ci-dogfooding.md +200 -200
- package/examples/demo-ai-app/.ai-maintainer/business-flows.yml +14 -14
- package/examples/demo-ai-app/.ai-maintainer/db-migration-policy.yml +6 -6
- package/examples/demo-ai-app/.ai-maintainer/evidence-sources.yml +18 -18
- package/examples/demo-ai-app/.ai-maintainer/exceptions.yml +1 -1
- package/examples/demo-ai-app/.ai-maintainer/incident-runbook.md +11 -11
- package/examples/demo-ai-app/.ai-maintainer/observability-checklist.yml +7 -7
- package/examples/demo-ai-app/.ai-maintainer/policy.yml +27 -27
- package/examples/demo-ai-app/.ai-maintainer/project-profile.yml +15 -15
- package/examples/demo-ai-app/.ai-maintainer/release-checklist.yml +7 -7
- package/examples/demo-ai-app/.ai-maintainer/risk-policy.yml +5 -5
- package/examples/demo-ai-app/.ai-maintainer/threat-model.md +18 -18
- package/examples/demo-ai-app/README.md +38 -38
- package/examples/demo-ai-app/package-lock.json +15 -15
- package/examples/demo-ai-app/package.json +16 -16
- package/examples/demo-ai-app/scripts/build.mjs +18 -18
- package/examples/demo-ai-app/scripts/create-before-state.mjs +86 -86
- package/examples/demo-ai-app/scripts/run-demo-gate.mjs +95 -95
- package/examples/demo-ai-app/src/order-risk.js +28 -28
- package/examples/demo-ai-app/test/order-risk.test.mjs +24 -24
- 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
|
-
|
|
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
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
169
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
```powershell
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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:
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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.
|
package/docs/DEMO.zh-CN.md
CHANGED
|
@@ -1,69 +1,75 @@
|
|
|
1
|
-
# 演示:从 AI 写出的项目到生产审查报告
|
|
2
|
-
|
|
3
|
-
这个演示使用仓库里的真实项目:`examples/demo-ai-app`。不需要付费账号,也不需要外部 API。
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
```powershell
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|