superdev-cli 0.1.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/.claude-plugin/marketplace.json +33 -0
- package/.claude-plugin/plugin.json +21 -0
- package/.codex-plugin/plugin.json +27 -0
- package/CODE_OF_CONDUCT.md +109 -0
- package/CONTRIBUTING.md +205 -0
- package/LICENSE +202 -0
- package/NOTICE +11 -0
- package/README.md +1051 -0
- package/SECURITY.md +135 -0
- package/THIRD-PARTY-NOTICES.md +253 -0
- package/hooks/hooks.json +61 -0
- package/hooks/run.mjs +88 -0
- package/package.json +65 -0
- package/references/confidentiality.md +48 -0
- package/references/evidence-and-risk.md +73 -0
- package/references/operating-model.md +105 -0
- package/references/platform-capabilities.md +51 -0
- package/references/project-record.md +91 -0
- package/references/provider-contracts.md +102 -0
- package/scripts/doctor/doctor.mjs +539 -0
- package/scripts/privacy/scan-history.mjs +163 -0
- package/scripts/privacy/scan.mjs +368 -0
- package/scripts/validate/README.md +94 -0
- package/scripts/validate/common.mjs +149 -0
- package/scripts/validate/data-model.mjs +225 -0
- package/scripts/validate/dependencies.mjs +69 -0
- package/scripts/validate/docs-templates.mjs +99 -0
- package/scripts/validate/footprint.mjs +78 -0
- package/scripts/validate/imports.mjs +61 -0
- package/scripts/validate/manifests.mjs +173 -0
- package/scripts/validate/markdown.mjs +123 -0
- package/scripts/validate/migrations.mjs +187 -0
- package/scripts/validate/no-tests.mjs +136 -0
- package/scripts/validate/privacy.mjs +115 -0
- package/scripts/validate/record-links.mjs +127 -0
- package/scripts/validate/skill-commands.mjs +190 -0
- package/scripts/validate/skills.mjs +112 -0
- package/scripts/validate/specification.mjs +88 -0
- package/scripts/validate/style.mjs +78 -0
- package/scripts/validate/validate-all.mjs +175 -0
- package/skills/debug/SKILL.md +68 -0
- package/skills/decision/SKILL.md +99 -0
- package/skills/docs/SKILL.md +86 -0
- package/skills/docs/assets/fragments/api/events.md +14 -0
- package/skills/docs/assets/fragments/api/graphql.md +14 -0
- package/skills/docs/assets/fragments/api/local-only.md +13 -0
- package/skills/docs/assets/fragments/api/rest.md +13 -0
- package/skills/docs/assets/fragments/api/rpc.md +13 -0
- package/skills/docs/assets/fragments/async/event-bus.md +13 -0
- package/skills/docs/assets/fragments/async/none.md +11 -0
- package/skills/docs/assets/fragments/async/platform-jobs.md +13 -0
- package/skills/docs/assets/fragments/async/queue.md +13 -0
- package/skills/docs/assets/fragments/async/scheduler.md +13 -0
- package/skills/docs/assets/fragments/auth/detected-provider.md +15 -0
- package/skills/docs/assets/fragments/auth/neutral-base.md +14 -0
- package/skills/docs/assets/fragments/data/document.md +13 -0
- package/skills/docs/assets/fragments/data/external-saas.md +13 -0
- package/skills/docs/assets/fragments/data/key-value.md +13 -0
- package/skills/docs/assets/fragments/data/none.md +12 -0
- package/skills/docs/assets/fragments/data/sql-orm.md +13 -0
- package/skills/docs/assets/fragments/data/sql-plain.md +13 -0
- package/skills/docs/assets/fragments/env/conventional.md +13 -0
- package/skills/docs/assets/fragments/env/envx.md +13 -0
- package/skills/docs/assets/fragments/env/managed-platform.md +13 -0
- package/skills/docs/assets/fragments/env/none.md +11 -0
- package/skills/docs/assets/fragments/ui/api-only.md +13 -0
- package/skills/docs/assets/fragments/ui/cli.md +14 -0
- package/skills/docs/assets/fragments/ui/desktop.md +14 -0
- package/skills/docs/assets/fragments/ui/mobile.md +14 -0
- package/skills/docs/assets/fragments/ui/web.md +14 -0
- package/skills/docs/assets/templates/adr.md +62 -0
- package/skills/docs/assets/templates/api.md +30 -0
- package/skills/docs/assets/templates/architecture.md +52 -0
- package/skills/docs/assets/templates/change-impact-drift-report.md +29 -0
- package/skills/docs/assets/templates/compliance.md +29 -0
- package/skills/docs/assets/templates/data-schema.md +43 -0
- package/skills/docs/assets/templates/feature.md +43 -0
- package/skills/docs/assets/templates/foundations.md +55 -0
- package/skills/docs/assets/templates/jobs-webhooks.md +36 -0
- package/skills/docs/assets/templates/module-inventory.md +19 -0
- package/skills/docs/assets/templates/module.md +50 -0
- package/skills/docs/assets/templates/nfr.md +22 -0
- package/skills/docs/assets/templates/observability.md +28 -0
- package/skills/docs/assets/templates/pages-ui-actions.md +47 -0
- package/skills/docs/assets/templates/project-summary.md +44 -0
- package/skills/docs/assets/templates/roles-permissions.md +26 -0
- package/skills/docs/assets/templates/test-plan.md +23 -0
- package/skills/docs/assets/templates/workflow-state-machine.md +43 -0
- package/skills/docs/references/adr-authoring.md +24 -0
- package/skills/docs/references/apis-and-data.md +23 -0
- package/skills/docs/references/capability-fragments.md +25 -0
- package/skills/docs/references/change-tracking.md +62 -0
- package/skills/docs/references/diagrams.md +31 -0
- package/skills/docs/references/discovery.md +59 -0
- package/skills/docs/references/edge-cases.md +45 -0
- package/skills/docs/references/foundations-modules.md +18 -0
- package/skills/docs/references/ingestion.md +52 -0
- package/skills/docs/references/initialize-adopt.md +25 -0
- package/skills/docs/references/module-decomposition.md +38 -0
- package/skills/docs/references/profiles.md +60 -0
- package/skills/docs/references/quality-attributes.md +27 -0
- package/skills/docs/references/reverse-engineer.md +21 -0
- package/skills/docs/references/spec-depths.md +31 -0
- package/skills/docs/references/summarize.md +18 -0
- package/skills/docs/references/surfaces-and-actions.md +24 -0
- package/skills/docs/references/validation.md +47 -0
- package/skills/docs/references/workflows-and-jobs.md +25 -0
- package/skills/docs/scripts/ingest.mjs +984 -0
- package/skills/docs/scripts/profile-detect.mjs +299 -0
- package/skills/docs/scripts/screen.mjs +96 -0
- package/skills/docs/scripts/template-lint.mjs +143 -0
- package/skills/docs/scripts/validate-docs.mjs +363 -0
- package/skills/doctor/SKILL.md +167 -0
- package/skills/feature/SKILL.md +132 -0
- package/skills/init/SKILL.md +137 -0
- package/skills/project/SKILL.md +261 -0
- package/skills/project/references/commands.md +213 -0
- package/skills/resume/SKILL.md +79 -0
- package/skills/review/SKILL.md +91 -0
- package/skills/status/SKILL.md +85 -0
- package/skills/task/SKILL.md +183 -0
- package/src/cli/product-map.mjs +468 -0
- package/src/cli/render.mjs +544 -0
- package/src/cli.mjs +2774 -0
- package/src/cloud/crypto.mjs +118 -0
- package/src/cloud/merge.mjs +186 -0
- package/src/cloud/policy.mjs +115 -0
- package/src/cloud/sync.mjs +512 -0
- package/src/cloud/transport.mjs +116 -0
- package/src/db/connect.mjs +189 -0
- package/src/db/maintenance.mjs +419 -0
- package/src/db/migrate.mjs +188 -0
- package/src/db/migrations/001_initial.sql +1024 -0
- package/src/db/migrations/002_docs_coverage.sql +126 -0
- package/src/db/migrations/003_memory_retrieval_and_integrity.sql +168 -0
- package/src/db/migrations/004_task_categories.sql +59 -0
- package/src/db/migrations/005_executable_evidence.sql +32 -0
- package/src/db/migrations/006_module_and_feature_boundaries.sql +27 -0
- package/src/db/migrations/007_drop_redundant_module_users.sql +13 -0
- package/src/db/migrations/008_changes_assumptions_test_plans_api_services.sql +166 -0
- package/src/db/migrations/009_retired_documents.sql +54 -0
- package/src/db/migrations/010_test_plan_evidence.sql +20 -0
- package/src/db/migrations/011_criterion_waiver.sql +13 -0
- package/src/db/migrations/012_synchronization.sql +56 -0
- package/src/db/store.mjs +327 -0
- package/src/decisions/record.mjs +167 -0
- package/src/docs/proposals.mjs +871 -0
- package/src/docs/render.mjs +1424 -0
- package/src/docs/templates.mjs +1281 -0
- package/src/features/acceptance.mjs +315 -0
- package/src/features/specify.mjs +248 -0
- package/src/init/discovery.mjs +901 -0
- package/src/init/index.mjs +784 -0
- package/src/init/questions.mjs +562 -0
- package/src/memory/benchmark.mjs +171 -0
- package/src/memory/capture.mjs +135 -0
- package/src/memory/consolidate.mjs +255 -0
- package/src/memory/index.mjs +810 -0
- package/src/model/ids.mjs +185 -0
- package/src/model/screening.mjs +150 -0
- package/src/model/toolkit.mjs +258 -0
- package/src/model/vocabulary.mjs +190 -0
- package/src/product/assumptions.mjs +120 -0
- package/src/product/changes.mjs +180 -0
- package/src/product/test-plans.mjs +183 -0
- package/src/progress/index.mjs +1364 -0
- package/src/runtime/harness.mjs +264 -0
- package/src/runtime/hooks.mjs +1021 -0
- package/src/runtime/identity.mjs +305 -0
- package/src/runtime/resume.mjs +343 -0
- package/src/runtime/session.mjs +679 -0
- package/src/runtime/version.mjs +315 -0
- package/src/service/assets/control-center.html +206 -0
- package/src/service/assets/control-center.manifest.json +7 -0
- package/src/service/manage.mjs +542 -0
- package/src/service/mutations.mjs +860 -0
- package/src/service/read-model.mjs +1557 -0
- package/src/service/server.mjs +783 -0
- package/src/tasks/categories.mjs +154 -0
- package/src/tasks/derive.mjs +977 -0
- package/src/tasks/lifecycle.mjs +830 -0
- package/src/verify/index.mjs +236 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Writing style. Superdev never generates or persists em dash characters or
|
|
2
|
+
// emoji, and the rule is enforced at the storage boundary so nothing new can
|
|
3
|
+
// land. This validator covers what is already on disk, and proves a clean tree
|
|
4
|
+
// stays clean.
|
|
5
|
+
//
|
|
6
|
+
// Scope is files this project owns. Vendored material, build output and the
|
|
7
|
+
// append-only ledgers are excluded: rewriting someone else's prose is not this
|
|
8
|
+
// tool's business, and editing a record of what actually happened so it reads
|
|
9
|
+
// as compliant is the dishonest reading of a policy about honesty.
|
|
10
|
+
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
import { ERROR, finding, ownedFiles, readText } from "./common.mjs";
|
|
13
|
+
import { EMOJI_PATTERN } from "../../src/model/screening.mjs";
|
|
14
|
+
|
|
15
|
+
export const name = "style";
|
|
16
|
+
|
|
17
|
+
// Written as an escape on purpose. A literal here would make this file fail its
|
|
18
|
+
// own rule and every scan of the repository would report the scanner.
|
|
19
|
+
const EM_DASH = "\u2014";
|
|
20
|
+
// Imported, never restated. This validator once carried its own narrower idea
|
|
21
|
+
// of emoji, so an arrow or a check mark passed the scan and was then refused by
|
|
22
|
+
// the storage boundary: a file could be clean by the tool that judges the tree
|
|
23
|
+
// and unstorable by the code that judges a record. One definition, one verdict.
|
|
24
|
+
const EMOJI = new RegExp(EMOJI_PATTERN, "gu");
|
|
25
|
+
|
|
26
|
+
// Build output only.
|
|
27
|
+
//
|
|
28
|
+
// The four talks/ ledger paths that used to sit here were left over from the
|
|
29
|
+
// file-based architecture: history lives in the database now, and talks/ is a
|
|
30
|
+
// generated projection whose content came through the storage boundary, so it
|
|
31
|
+
// is already clean and stays in scope as proof.
|
|
32
|
+
//
|
|
33
|
+
// The compiled control centre is different. It is build output that embeds
|
|
34
|
+
// third party code, and a minified Markdown parser carries a packed HTML entity
|
|
35
|
+
// table whose index bytes land in Unicode blocks with emoji presentation. Those
|
|
36
|
+
// are not emoji any reader will ever see; they are offsets in someone else's
|
|
37
|
+
// lookup table. Rewriting a vendored library to satisfy a rule about the prose
|
|
38
|
+
// this project writes would be the tail wagging the dog. The authored text in
|
|
39
|
+
// that bundle is scanned at its source under ui/src, which is where a real
|
|
40
|
+
// breach would be introduced and where it will still fail.
|
|
41
|
+
const EXCLUDED = [/^dist\//, /^src\/service\/assets\/control-center\.html$/];
|
|
42
|
+
|
|
43
|
+
export const isExcluded = (path) => EXCLUDED.some((pattern) => pattern.test(path));
|
|
44
|
+
|
|
45
|
+
export function inspect(path, text) {
|
|
46
|
+
const findings = [];
|
|
47
|
+
text.split("\n").forEach((line, index) => {
|
|
48
|
+
let at = line.indexOf(EM_DASH);
|
|
49
|
+
while (at !== -1) {
|
|
50
|
+
findings.push(finding("ST-001", ERROR, `${path}:${index + 1}:${at + 1}`,
|
|
51
|
+
"em dash character; use a comma, colon, semicolon, parentheses or a hyphen"));
|
|
52
|
+
at = line.indexOf(EM_DASH, at + 1);
|
|
53
|
+
}
|
|
54
|
+
EMOJI.lastIndex = 0;
|
|
55
|
+
let match;
|
|
56
|
+
while ((match = EMOJI.exec(line)) !== null) {
|
|
57
|
+
findings.push(finding("ST-002", ERROR, `${path}:${index + 1}:${match.index + 1}`,
|
|
58
|
+
"emoji, which Superdev never generates"));
|
|
59
|
+
if (match.index === EMOJI.lastIndex) EMOJI.lastIndex++;
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return findings;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function run(root) {
|
|
66
|
+
const findings = [];
|
|
67
|
+
const files = ownedFiles(root).filter((path) => !isExcluded(path));
|
|
68
|
+
if (!files.length) {
|
|
69
|
+
findings.push(finding("ST-000", ERROR, ".", "no project-owned text files found; there is nothing to scan"));
|
|
70
|
+
return { name, findings };
|
|
71
|
+
}
|
|
72
|
+
for (const path of files) {
|
|
73
|
+
const text = readText(join(root, path));
|
|
74
|
+
if (text === null) continue;
|
|
75
|
+
findings.push(...inspect(path, text));
|
|
76
|
+
}
|
|
77
|
+
return { name, findings };
|
|
78
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The validation entry point. Runs every deterministic validator against one
|
|
3
|
+
// repository root and reports what each of them found.
|
|
4
|
+
//
|
|
5
|
+
// Exit codes: 0 no findings, 1 findings, 2 usage error.
|
|
6
|
+
//
|
|
7
|
+
// A validator that throws is itself a finding. Swallowing the error would turn
|
|
8
|
+
// a broken validator into a passing run, which is the single most expensive
|
|
9
|
+
// failure mode a gate can have.
|
|
10
|
+
|
|
11
|
+
import { existsSync, mkdirSync, renameSync, statSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { dirname, join, resolve } from "node:path";
|
|
13
|
+
import { parseArgs } from "node:util";
|
|
14
|
+
import { pathToFileURL } from "node:url";
|
|
15
|
+
import { realpathSync } from "node:fs";
|
|
16
|
+
import { ERROR, finding } from "./common.mjs";
|
|
17
|
+
|
|
18
|
+
import * as manifests from "./manifests.mjs";
|
|
19
|
+
import * as skills from "./skills.mjs";
|
|
20
|
+
import * as docsTemplates from "./docs-templates.mjs";
|
|
21
|
+
import * as migrations from "./migrations.mjs";
|
|
22
|
+
import * as markdown from "./markdown.mjs";
|
|
23
|
+
import * as style from "./style.mjs";
|
|
24
|
+
import * as privacy from "./privacy.mjs";
|
|
25
|
+
import * as imports from "./imports.mjs";
|
|
26
|
+
import * as dependencies from "./dependencies.mjs";
|
|
27
|
+
import * as noTests from "./no-tests.mjs";
|
|
28
|
+
import * as footprint from "./footprint.mjs";
|
|
29
|
+
import * as dataModel from "./data-model.mjs";
|
|
30
|
+
import * as recordLinks from "./record-links.mjs";
|
|
31
|
+
import * as skillCommands from "./skill-commands.mjs";
|
|
32
|
+
import * as specification from "./specification.mjs";
|
|
33
|
+
|
|
34
|
+
/** Declaration order is report order, so two runs read the same way. */
|
|
35
|
+
export const VALIDATORS = [
|
|
36
|
+
manifests, skills, docsTemplates, migrations, markdown,
|
|
37
|
+
style, privacy, imports, dependencies, noTests, footprint, dataModel, recordLinks, skillCommands, specification,
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const USAGE = `Usage: node validate-all.mjs [--root <path>] [--only <name,...>] [--json] [--out <file>] [--help]
|
|
41
|
+
--root <path> repository root to validate (default: current directory)
|
|
42
|
+
--only <names> comma separated validator names, run only these
|
|
43
|
+
--json machine-readable JSON on stdout
|
|
44
|
+
--out <file> also write the JSON report to this exact path
|
|
45
|
+
--help show this help
|
|
46
|
+
|
|
47
|
+
Validators: ${VALIDATORS.map((v) => v.name).join(", ")}
|
|
48
|
+
|
|
49
|
+
Exit codes: 0 clean, 1 findings, 2 usage error.`;
|
|
50
|
+
|
|
51
|
+
export async function runAll(root, { only = [] } = {}) {
|
|
52
|
+
const selected = only.length ? VALIDATORS.filter((v) => only.includes(v.name)) : VALIDATORS;
|
|
53
|
+
const results = [];
|
|
54
|
+
for (const validator of selected) {
|
|
55
|
+
try {
|
|
56
|
+
const result = await validator.run(root);
|
|
57
|
+
results.push({ name: result.name ?? validator.name, findings: result.findings ?? [] });
|
|
58
|
+
} catch (err) {
|
|
59
|
+
results.push({
|
|
60
|
+
name: validator.name,
|
|
61
|
+
findings: [finding("VA-001", ERROR, ".", `the ${validator.name} validator threw: ${String(err?.stack ?? err?.message ?? err)}`)],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return results;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** --out writes exactly the machine-readable report, atomically. */
|
|
69
|
+
function writeReport(outPath, report) {
|
|
70
|
+
if (!outPath) return;
|
|
71
|
+
const target = resolve(outPath);
|
|
72
|
+
const tmp = join(dirname(target), `.tmp-validate-${process.pid}`);
|
|
73
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
74
|
+
writeFileSync(tmp, JSON.stringify(report, null, 2) + "\n");
|
|
75
|
+
renameSync(tmp, target);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function printTable(results) {
|
|
79
|
+
const rows = results.map((result) => ({
|
|
80
|
+
name: result.name,
|
|
81
|
+
errors: result.findings.filter((f) => f.severity === ERROR).length,
|
|
82
|
+
warnings: result.findings.filter((f) => f.severity !== ERROR).length,
|
|
83
|
+
}));
|
|
84
|
+
const width = Math.max(9, ...rows.map((row) => row.name.length));
|
|
85
|
+
console.log(`${"validator".padEnd(width)} errors warnings result`);
|
|
86
|
+
console.log(`${"-".repeat(width)} ------ -------- ------`);
|
|
87
|
+
for (const row of rows) {
|
|
88
|
+
const verdict = row.errors || row.warnings ? "findings" : "clean";
|
|
89
|
+
console.log(
|
|
90
|
+
`${row.name.padEnd(width)} ${String(row.errors).padStart(6)} ${String(row.warnings).padStart(8)} ${verdict}`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function main() {
|
|
96
|
+
let parsed;
|
|
97
|
+
try {
|
|
98
|
+
parsed = parseArgs({
|
|
99
|
+
options: {
|
|
100
|
+
root: { type: "string", default: "." },
|
|
101
|
+
only: { type: "string" },
|
|
102
|
+
json: { type: "boolean", default: false },
|
|
103
|
+
out: { type: "string" },
|
|
104
|
+
help: { type: "boolean", default: false },
|
|
105
|
+
},
|
|
106
|
+
allowPositionals: true,
|
|
107
|
+
});
|
|
108
|
+
} catch (err) {
|
|
109
|
+
console.error(String(err.message ?? err));
|
|
110
|
+
console.error(USAGE);
|
|
111
|
+
process.exit(2);
|
|
112
|
+
}
|
|
113
|
+
if (parsed.values.help) {
|
|
114
|
+
console.log(USAGE);
|
|
115
|
+
process.exit(0);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const root = resolve(parsed.positionals[0] ?? parsed.values.root);
|
|
119
|
+
if (!existsSync(root) || !statSync(root).isDirectory() || !existsSync(join(root, "package.json"))) {
|
|
120
|
+
console.error(`root is not a repository directory: ${parsed.positionals[0] ?? parsed.values.root}`);
|
|
121
|
+
console.error(USAGE);
|
|
122
|
+
process.exit(2);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const only = (parsed.values.only ?? "").split(",").map((n) => n.trim()).filter(Boolean);
|
|
126
|
+
const unknown = only.filter((n) => !VALIDATORS.some((v) => v.name === n));
|
|
127
|
+
if (unknown.length) {
|
|
128
|
+
console.error(`unknown validator(s): ${unknown.join(", ")}`);
|
|
129
|
+
console.error(USAGE);
|
|
130
|
+
process.exit(2);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const results = await runAll(root, { only });
|
|
134
|
+
const findings = results.flatMap((result) => result.findings.map((f) => ({ validator: result.name, ...f })));
|
|
135
|
+
const errors = findings.filter((f) => f.severity === ERROR).length;
|
|
136
|
+
const report = { version: 1, root, results, findings, errors };
|
|
137
|
+
|
|
138
|
+
if (parsed.values.json) {
|
|
139
|
+
console.log(JSON.stringify(report, null, 2));
|
|
140
|
+
} else {
|
|
141
|
+
printTable(results);
|
|
142
|
+
for (const result of results) {
|
|
143
|
+
if (!result.findings.length) continue;
|
|
144
|
+
console.log(`\n${result.name}`);
|
|
145
|
+
for (const item of result.findings) {
|
|
146
|
+
console.log(` [${item.code}] ${item.severity} ${item.path}: ${item.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
console.log(findings.length ? `\n${findings.length} finding(s)` : "\nclean");
|
|
150
|
+
if (errors === 0 && findings.length > 0) {
|
|
151
|
+
// Said out loud rather than left to the exit code, so a warning is not
|
|
152
|
+
// quietly treated as nothing.
|
|
153
|
+
console.log("No errors. The findings above are warnings and did not fail this run.");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
writeReport(parsed.values.out, report);
|
|
158
|
+
// Errors fail the run; warnings are reported and do not.
|
|
159
|
+
//
|
|
160
|
+
// This used to exit on any finding, which made the whole gate fail on every
|
|
161
|
+
// fresh clone: the project database is git-ignored by design, so the three
|
|
162
|
+
// validators that read it correctly warn that they had nothing to check, and a
|
|
163
|
+
// release workflow running this on a checkout would have failed every time
|
|
164
|
+
// without anything being wrong.
|
|
165
|
+
//
|
|
166
|
+
// The distinction is not a relaxation. An error is a claim the repository makes
|
|
167
|
+
// that is false, and none of those is tolerated. A warning is something worth
|
|
168
|
+
// a reader's attention that does not make the tree incorrect, and a gate that
|
|
169
|
+
// cannot tell the two apart teaches people to ignore it.
|
|
170
|
+
process.exit(errors > 0 ? 1 : 0);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Main-module guard: realpath both sides, because Node resolves symlinks when
|
|
174
|
+
// it builds import.meta.url for the entry module and /tmp is one on macOS.
|
|
175
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(realpathSync(process.argv[1])).href) await main();
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: debug
|
|
3
|
+
description: Investigate a failure to its root cause before anything is changed. Use for "why is this failing?", "this broke", "it works locally but not in production", a stack trace, a flaky test, corrupted output, or unexpected behavior. Assembles the evidence packet (exact reproduction, redacted logs, recent changes, environment differences, the feature and contracts involved, governing decisions), routes to the systematic-debugging provider when it is available, requires root-cause evidence that accounts for every important symptom before a fix, fixes at the layer all callers share, and verifies under the original failing conditions with a regression test. No feature interview for a defect.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Debugging
|
|
7
|
+
|
|
8
|
+
A symptom report names where it hurts, not what is wrong. Evidence first, then
|
|
9
|
+
the fix, then proof under the conditions that originally failed.
|
|
10
|
+
|
|
11
|
+
`SD` means the installed `superdev` command, with `--root <project>` on
|
|
12
|
+
every call.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
|
|
16
|
+
1. **Build the evidence packet.**
|
|
17
|
+
- The exact reproduction, including what makes it stop reproducing.
|
|
18
|
+
- Errors and logs verbatim, with secrets redacted before they are pasted
|
|
19
|
+
anywhere or stored.
|
|
20
|
+
- Recent changes: diff, commits, dependency and configuration moves.
|
|
21
|
+
- Environment differences between where it works and where it does not.
|
|
22
|
+
- The product context: `SD task show <TASK-id>` if the failure has a task,
|
|
23
|
+
the feature and the contracts involved, and `SD decision list --json` for
|
|
24
|
+
the decisions that govern the area.
|
|
25
|
+
- `SD memory search "<symptom or component>"` for whether this has
|
|
26
|
+
been seen before. Recall is a lead, never a conclusion; verify it.
|
|
27
|
+
2. **Track it as work.** A defect that takes more than a moment gets a task
|
|
28
|
+
linked to the feature and contract it breaks, so the investigation and its
|
|
29
|
+
outcome survive the session. See the `task` skill.
|
|
30
|
+
3. **Route to the provider.** Superpowers systematic debugging owns this
|
|
31
|
+
methodology. Check readiness with `SD doctor`. If it is not ready, apply the
|
|
32
|
+
falsification discipline directly and say the specialist pass did not run:
|
|
33
|
+
symptoms verbatim, at least three hypotheses before testing any, evidence
|
|
34
|
+
that discriminates between them, the cheapest high-information check first,
|
|
35
|
+
one variable per experiment, failed experiments reverted.
|
|
36
|
+
4. **Respect environment safety.** In an envx-managed project, run commands
|
|
37
|
+
through its stage runner rather than exporting values by hand. Never decrypt
|
|
38
|
+
or print a secret. Distinguish a missing-access failure from an application
|
|
39
|
+
failure; they look alike and are not.
|
|
40
|
+
5. **Require root-cause evidence before any fix.** The explanation must account
|
|
41
|
+
for every important symptom, including the ones that do not fit neatly. A
|
|
42
|
+
plausible story that explains three of four symptoms is not a root cause.
|
|
43
|
+
6. **Fix at the layer every caller shares.** Before editing, find every caller
|
|
44
|
+
of the function you are about to change. One guard in the shared path is
|
|
45
|
+
both the smaller diff and the correct fix; patching only the path the report
|
|
46
|
+
named leaves the siblings broken.
|
|
47
|
+
7. **Verify under the original failing conditions**, add a regression test to
|
|
48
|
+
the product's own suite, and read the final diff.
|
|
49
|
+
8. **Record the outcome.** `SD task evidence <TASK-id> --summary "<root cause
|
|
50
|
+
and fix>" --reference "<the failing case that now passes>"`, then complete with the verification as evidence. Update the
|
|
51
|
+
specification only when the intended behavior or operations actually changed:
|
|
52
|
+
a pure defect fix is not a specification change.
|
|
53
|
+
|
|
54
|
+
## Boundaries
|
|
55
|
+
|
|
56
|
+
- Never change a test so it passes without first proving the test was wrong.
|
|
57
|
+
- Two failures of the same shape mean the problem model is wrong. Stop varying
|
|
58
|
+
details and re-examine the model.
|
|
59
|
+
- Evidence of data corruption or a security compromise stops the work and gets
|
|
60
|
+
reported before anything else continues.
|
|
61
|
+
- The regression test belongs to the product, from its accepted test plan. The
|
|
62
|
+
Superdev plugin has no test suite; never tell anyone to run tests for it.
|
|
63
|
+
- Report an unproven cause as unproven. "Probably fixed" is not a result.
|
|
64
|
+
|
|
65
|
+
*Standalone note: on skills.sh, install the generated `superdev` package. It
|
|
66
|
+
carries the orchestrator, the Docs capability and the runtime, and needs no
|
|
67
|
+
repository. A single skill copied out on its own has no runtime; say which
|
|
68
|
+
command was unavailable rather than working around it silently.*
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: decision
|
|
3
|
+
description: Find, record, revisit or supersede a project decision. Use for "what did we decide about X?", "why do we use Y?", "record this decision", "can we switch to Z now?", "can we add package P?" when it was declined before, or whenever proposed work conflicts with something already decided. Reads the decision records and their transitions from the database, checks whether a request follows, extends, conflicts with, triggers a revisit of or supersedes each active decision, and presents the owner with a bounded choice. History is append-only, so a decision is superseded with its scope named, never edited into a different past.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Decisions
|
|
7
|
+
|
|
8
|
+
A decision record explains why the product is the way it is, so the same
|
|
9
|
+
argument is not had twice and a reversal is deliberate rather than accidental.
|
|
10
|
+
|
|
11
|
+
`SD` means the installed `superdev` command, with `--root <project>` on
|
|
12
|
+
every call.
|
|
13
|
+
|
|
14
|
+
## Reading
|
|
15
|
+
|
|
16
|
+
`SD decision list --json` returns decisions with status, scope, links and the
|
|
17
|
+
supersession chain. Statuses are Proposed, Accepted, Rejected, Deferred,
|
|
18
|
+
Superseded and Deprecated, and each one carries a transition history that only
|
|
19
|
+
appends.
|
|
20
|
+
|
|
21
|
+
The ADR Markdown under `talks/decisions/` is generated from those rows. Reading
|
|
22
|
+
it is fine. Editing it does not change the decision: the edit becomes a proposal
|
|
23
|
+
that a person reviews, and accepting the proposal updates the database first.
|
|
24
|
+
`SD docs diff` shows any that are waiting.
|
|
25
|
+
|
|
26
|
+
## Before consequential work: the conflict check
|
|
27
|
+
|
|
28
|
+
1. Search the active decisions for the capability, dependency, file path,
|
|
29
|
+
surface or topic the work touches.
|
|
30
|
+
2. For each match, classify the request: **follows** it, **extends** it,
|
|
31
|
+
**conflicts** with it, **triggers its revisit condition**, **supersedes** it,
|
|
32
|
+
or is **unrelated**.
|
|
33
|
+
3. On a conflict, present exactly this and stop:
|
|
34
|
+
- the active decision, its rationale and its scope;
|
|
35
|
+
- its revisit triggers;
|
|
36
|
+
- what evidence has actually changed since;
|
|
37
|
+
- the consequences of each way forward.
|
|
38
|
+
4. Offer exactly four options: preserve the decision, narrow the request to fit
|
|
39
|
+
it, run a time-boxed experiment that would produce the missing evidence, or
|
|
40
|
+
record a superseding decision.
|
|
41
|
+
|
|
42
|
+
Never proceed past a conflict because the new work seems obviously better. The
|
|
43
|
+
earlier decision had reasons; make them visible and let the owner choose.
|
|
44
|
+
|
|
45
|
+
## Recording a decision
|
|
46
|
+
|
|
47
|
+
A decision record carries: context; evidence with its epistemic label (measured,
|
|
48
|
+
observed, reported, assumed) and where it came from; the criteria used; the
|
|
49
|
+
options considered with why each was rejected; the decision itself; observable
|
|
50
|
+
rationale (never private reasoning); consequences, positive, negative and
|
|
51
|
+
neutral; risks and their mitigations; enforcement points; how it is verified;
|
|
52
|
+
and its revisit triggers.
|
|
53
|
+
|
|
54
|
+
Declined and deferred outcomes are first-class records. "Declined, not
|
|
55
|
+
forgotten" is the point: a rejected option with a recorded reason and a revisit
|
|
56
|
+
condition is what stops the same suggestion arriving every month.
|
|
57
|
+
|
|
58
|
+
Decisions become records through the accepted-planning flow, the same as every
|
|
59
|
+
other accepted content, and status changes are append-only transitions. Run
|
|
60
|
+
`SD decision --help` for the subcommands this build exposes, and use the control
|
|
61
|
+
center's decision view when a person is deciding interactively. Then
|
|
62
|
+
`SD docs generate` renders the ADR.
|
|
63
|
+
|
|
64
|
+
## Superseding
|
|
65
|
+
|
|
66
|
+
- The new record names what it supersedes and why.
|
|
67
|
+
- The old record gains a superseded-by pointer and stays readable, unedited.
|
|
68
|
+
- **Partial supersession** names the exact scope that fell and the exact scope
|
|
69
|
+
that still stands. A vague partial supersession is worse than none, because
|
|
70
|
+
nobody can tell afterwards which half survived.
|
|
71
|
+
- Never edit an earlier decision body to make it agree with the present. The
|
|
72
|
+
record is a history, and rewriting it destroys the only evidence of why the
|
|
73
|
+
reversal happened.
|
|
74
|
+
|
|
75
|
+
## A previously declined dependency, requested again
|
|
76
|
+
|
|
77
|
+
1. Find the record that declined it and read its actual reasons.
|
|
78
|
+
2. Check whether each reason still holds. Reasons expire; assume nothing.
|
|
79
|
+
3. Present the new evidence, or say plainly that there is none.
|
|
80
|
+
4. Get explicit confirmation before adding it.
|
|
81
|
+
5. Record a superseding decision if the direction changes, so the next agent
|
|
82
|
+
sees a reversal rather than a contradiction.
|
|
83
|
+
|
|
84
|
+
Never install a declined dependency because it would be convenient right now.
|
|
85
|
+
|
|
86
|
+
## Boundaries
|
|
87
|
+
|
|
88
|
+
- One owner question at a time, with the recommendation stated.
|
|
89
|
+
- A decision that governs work in flight blocks that work until it is resolved.
|
|
90
|
+
Report it; do not route around it.
|
|
91
|
+
- Store observable rationale only. Never private model reasoning, secrets,
|
|
92
|
+
personal data or absolute machine paths.
|
|
93
|
+
- Superdev decides its own conflicts. No transport, sync or external tool
|
|
94
|
+
arbitrates a decision by overwriting it.
|
|
95
|
+
|
|
96
|
+
*Standalone note: on skills.sh, install the generated `superdev` package. It
|
|
97
|
+
carries the orchestrator, the Docs capability and the runtime, and needs no
|
|
98
|
+
repository. A single skill copied out on its own has no runtime; say which
|
|
99
|
+
command was unavailable rather than working around it silently.*
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: docs
|
|
3
|
+
description: Superdev's first-party documentation engine. Use for documenting or specifying a project ("document this project", "write the spec for X", "give me a complete Markdown summary"), classifying a project or discovering/clarifying requirements ("what questions should we answer before building?"), defining features, pages, UI actions, APIs, schemas, workflows, jobs, permissions, observability, compliance, NFRs, or test plans, ingesting source material ("process these notes/requirements"), reverse-engineering docs from code, initializing or adopting documentation without restructuring it, computing change impact, syncing docs after code changes, creating or superseding ADRs, validating documentation ("check docs against code", "find drift"), or generating doc indexes. Profile-aware - works with the talks/ default, module-based docs, legacy flat docs, or a custom structure through an adapter, never duplicating an existing source of truth.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Docs Engine - Router
|
|
7
|
+
|
|
8
|
+
Classify the operation, load only the reference it needs, run deterministic scripts for fragile work. Reference and asset paths below are relative to this skill directory. **Script invocation:** in plugin mode run scripts as `node "${CLAUDE_PLUGIN_ROOT}/skills/docs/scripts/<name>.mjs"` - never as a bare relative path, whose meaning would depend on the current working directory. On a standalone skill install (no plugin root), resolve `scripts/`, `references/`, and `assets/` relative to the directory containing this SKILL.md.
|
|
9
|
+
|
|
10
|
+
## Writing style, always
|
|
11
|
+
|
|
12
|
+
Superdev never generates or persists the em dash character (U+2014) or emoji.
|
|
13
|
+
Use a period, comma, colon, semicolon, parentheses, or a simple hyphen instead.
|
|
14
|
+
|
|
15
|
+
This binds everything Superdev writes: documentation, record descriptions, ADRs
|
|
16
|
+
and change records, dashboard copy, generated Markdown, generated source
|
|
17
|
+
comments, summaries, reports, templates, and commit messages it drafts. It also
|
|
18
|
+
binds text taken from a provider: sanitize it or ask for a compliant rewrite
|
|
19
|
+
before storing or displaying it.
|
|
20
|
+
|
|
21
|
+
Enforcement is real, not advisory. Canonical record and operational state writes
|
|
22
|
+
are checked and refused with the exact file, record and field
|
|
23
|
+
(`E_STYLE_EM_DASH`, `E_STYLE_EMOJI`). Run the style scanner (`node "${CLAUDE_PLUGIN_ROOT}/scripts/style/style.mjs" scan`)
|
|
24
|
+
to check a tree, and `fix --apply` to rewrite existing content. Never delete a
|
|
25
|
+
sentence to satisfy the rule; rewrite its punctuation.
|
|
26
|
+
|
|
27
|
+
## Always first
|
|
28
|
+
|
|
29
|
+
1. **Profile:** read `talks/project.yaml` (documentation adapter) if present; otherwise run `node "${CLAUDE_PLUGIN_ROOT}/skills/docs/scripts/profile-detect.mjs" --root <project>` and report its evidence and confidence - never silently guess. Profiles: `references/profiles.md`.
|
|
30
|
+
2. **State and decisions:** read `talks/state/` and active decisions if present; surface conflicts before mutating anything.
|
|
31
|
+
3. **Authority:** current-state docs vs immutable history vs recall follow `${CLAUDE_PLUGIN_ROOT}/references/operating-model.md` §5. Epistemic labels per `${CLAUDE_PLUGIN_ROOT}/references/evidence-and-risk.md` §1. Record schemas (activity events, session summaries, decision fields) per `${CLAUDE_PLUGIN_ROOT}/references/project-record.md` §6.
|
|
32
|
+
|
|
33
|
+
## Operation router
|
|
34
|
+
|
|
35
|
+
| Requested operation | Load |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Initialize documentation / adopt existing docs | `references/initialize-adopt.md` |
|
|
38
|
+
| Ingest source material (engine-backed) | `references/ingestion.md` |
|
|
39
|
+
| Classify project / discover or clarify requirements | `references/discovery.md` |
|
|
40
|
+
| Cited Markdown project summary | `references/summarize.md` |
|
|
41
|
+
| Foundations / module inventory | `references/foundations-modules.md` |
|
|
42
|
+
| Define a feature (pick spec depth) | `references/spec-depths.md` |
|
|
43
|
+
| Deep module decomposition | `references/module-decomposition.md` |
|
|
44
|
+
| Pages, UI surfaces, action/state inventories | `references/surfaces-and-actions.md` |
|
|
45
|
+
| APIs / data and schema | `references/apis-and-data.md` |
|
|
46
|
+
| Workflows, state machines, async jobs, webhooks | `references/workflows-and-jobs.md` |
|
|
47
|
+
| Roles/permissions, observability, compliance, NFRs, test plans | `references/quality-attributes.md` |
|
|
48
|
+
| Create or supersede an ADR | `references/adr-authoring.md` |
|
|
49
|
+
| Reverse-engineer existing code | `references/reverse-engineer.md` |
|
|
50
|
+
| Change impact / doc sync / drift report / indexes | `references/change-tracking.md` |
|
|
51
|
+
| Validate structure, links, or implementation parity | `references/validation.md` |
|
|
52
|
+
|
|
53
|
+
Cross-cutting method references (loaded by the above, or directly when the task is exactly this): `references/edge-cases.md`, `references/diagrams.md`, `references/profiles.md`.
|
|
54
|
+
|
|
55
|
+
## Deterministic scripts (run these; do not improvise their jobs)
|
|
56
|
+
|
|
57
|
+
- `node "${CLAUDE_PLUGIN_ROOT}/skills/docs/scripts/profile-detect.mjs" --root <project> [--json] [--out <file>]` - profile evidence + confidence.
|
|
58
|
+
- `node "${CLAUDE_PLUGIN_ROOT}/skills/docs/scripts/validate-docs.mjs" --root <project> [--profile <id>] [--baseline <file>] [--json] [--out <file>]` - structure, links, content rules; stable finding codes; writes nothing without `--out`.
|
|
59
|
+
- `node "${CLAUDE_PLUGIN_ROOT}/skills/docs/scripts/template-lint.mjs" [--dir <path>] [--json]` - checks templates and fragments against known vendor/latency/region/regime/env-var patterns (a denylist scan: catches known violations, does not prove absence).
|
|
60
|
+
|
|
61
|
+
Templates live in `assets/templates/` (universal, provider-neutral). Capability fragments live in `assets/fragments/` and activate **only** on detected code/configuration evidence or an accepted decision - never by default; the fragment inventory and activation rules are in `references/capability-fragments.md`. Fragment activation is recorded with its evidence.
|
|
62
|
+
|
|
63
|
+
## Mutation and approval rules
|
|
64
|
+
|
|
65
|
+
- Drafts before acceptance: generated or ingested content is a draft until the user approves it; accepted specs change only with approval.
|
|
66
|
+
- No silent edits. Exceptions (still logged at the next checkpoint): typo fixes and user-facing copy corrections that change no meaning.
|
|
67
|
+
- Consequential generation (new doc set, restructure, migration) requires explicit confirmation of the exact plan first.
|
|
68
|
+
- Existing documentation is adopted through the profile adapter - never moved, rewritten, or duplicated without a separately approved migration.
|
|
69
|
+
- History is immutable: superseded content gets status and banner, never deletion or rewriting; drift is marked (`Contradicted`/`Drift`), never silently resolved.
|
|
70
|
+
- Change tracking is always on: after any accepted mutation, follow `references/change-tracking.md` (identify → classify → confirm → rewrite → record → ADR-if-architectural → re-verify).
|
|
71
|
+
|
|
72
|
+
## Record-engine commands (durable state, events, sessions, indexes)
|
|
73
|
+
|
|
74
|
+
The record engine is live - use it, never hand-assemble record files: `node "${CLAUDE_PLUGIN_ROOT}/scripts/talks/<cmd>.mjs"` where `<cmd>` is `init`/`adopt` (plan by default, `--apply` to write), `state` (get/set), `events` (append/list/verify - immutable, collision-safe), `session` (append/list - whitelisted fields only), `index` (rebuild/check - deterministic generated views incl. claims/contradictions/questions), `ownership` (validate/match/reverse), `migrate` (inspect/plan/apply/restore), `id` (mint/validate), `questions` (add/list/answer/defer - durable owner-question packets), `risk` (score - deterministic R0–R4 tiering; `gate` - enforces a tier's required artifacts by reading real records), `decisions` (ADR lifecycle, conflict search, declined-dependency check), `impact` (diff-to-impact analysis), `sync` (drift/plan/apply), `complete` (executable completion gate). Ingestion runs through `node "${CLAUDE_PLUGIN_ROOT}/skills/docs/scripts/ingest.mjs"` (inventory/ingest/propose/approve/reject/resolve/verify/list).
|
|
75
|
+
|
|
76
|
+
## Pre-delivery verification checklist (every Docs operation, before claiming done)
|
|
77
|
+
|
|
78
|
+
1. Profile respected - no structure imposed from a different profile; no duplicate source of truth created.
|
|
79
|
+
2. Every load-bearing claim labeled and cited (file paths for code-derived claims).
|
|
80
|
+
3. No invented stack specifics: vendors, frameworks, budgets, regions, and compliance scopes appear only from evidence or accepted decisions.
|
|
81
|
+
4. Links resolve (`validate-docs.mjs` per the script rule above); touched specs pass parity checks where implementation exists.
|
|
82
|
+
5. Mutations approved, drafts marked as drafts, history untouched, drift marked not erased.
|
|
83
|
+
6. Change-tracking artifacts updated or explicitly reported pending; nothing claimed complete with required sync missing.
|
|
84
|
+
7. Model-private reasoning absent - observable rationale only.
|
|
85
|
+
|
|
86
|
+
*Standalone install note: this skill's own `references/`, `scripts/`, and `assets/` travel with it. The shared contracts under `${CLAUDE_PLUGIN_ROOT}/references/` ship with the Superdev plugin; on a standalone single-skill install state which shared contract was unavailable.*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Fragment: Event-Driven API
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** event/message contracts (topic definitions, event schema files, publisher/subscriber code) - record the paths found. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the "Style specifics" section of the API template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Event name/topic:** naming convention as used; version suffix policy.
|
|
10
|
+
- **Payload contract:** schema source cited; required vs optional fields; payload owner.
|
|
11
|
+
- **Producers and consumers:** both sides named (modules/services), matching module event steps.
|
|
12
|
+
- **Delivery semantics:** at-least-once/at-most-once as configured - stated honestly; consumer idempotency expectations.
|
|
13
|
+
- **Ordering:** guarantees (per-key, none) and how consumers handle disorder.
|
|
14
|
+
- **Schema evolution:** compatibility rules (additive-only, versioned topics) from project convention.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Fragment: GraphQL API
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** a GraphQL schema (SDL files, code-first schema builders, generated schema artifacts) - record the paths found. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the "Style specifics" section of the API template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Operation type:** query / mutation / subscription and its schema name.
|
|
10
|
+
- **Schema types:** input and payload types (cite the schema source; do not duplicate it).
|
|
11
|
+
- **Authorization points:** where field/operation authorization is enforced (resolver guards, directive, middleware) - must match the permission matrices.
|
|
12
|
+
- **N+1 and batching:** data-loader/batching behavior where the project has it (evidence).
|
|
13
|
+
- **Error convention:** the project's error shape (error codes in extensions, union results, etc.) from evidence.
|
|
14
|
+
- **Deprecation:** `@deprecated` usage and the migration expectation.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Fragment: Local-Only API (in-process contracts)
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** no network API surface - capabilities exposed as in-process module interfaces (exported functions/classes consumed across module boundaries). Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the "Style specifics" section of the API template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Contract location:** the exported interface (file, symbol) - the type signature is the contract.
|
|
10
|
+
- **Consumers:** which modules import it (module boundaries still apply in-process).
|
|
11
|
+
- **Error convention:** exceptions vs result types, as the project does it.
|
|
12
|
+
- **Stability:** which interfaces are internal-stable (cross-module) vs private (may change freely).
|
|
13
|
+
- **Statement:** the doc records explicitly that no network API exists for this capability - absence is a documented fact, not an omission.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Fragment: REST API
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** HTTP route definitions with method verbs (route files, controller decorators, OpenAPI documents) - record the paths found. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the "Style specifics" section of the API template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Method and path:** `{{VERB}} {{/resource/path}}` - resource-oriented naming; path params vs query params stated.
|
|
10
|
+
- **Status codes:** success code(s) and each error code with its meaning and body shape.
|
|
11
|
+
- **Content types:** request/response media types; pagination convention (cursor/offset) as used in this project.
|
|
12
|
+
- **Caching:** cache headers/etags if the project uses them (evidence required).
|
|
13
|
+
- **OpenAPI:** if a spec file exists, it is the contract source; the doc cites it and does not duplicate it.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Fragment: RPC API
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** procedure-style API definitions (typed procedure routers, RPC framework configs, IDL files) - record the paths found. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the "Style specifics" section of the API template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Procedure:** namespace/router path and procedure name; call semantics (query vs mutation vs stream) per the framework in use.
|
|
10
|
+
- **Input/output types:** cite the type definitions (schema-validation source is the contract).
|
|
11
|
+
- **Middleware chain:** auth/logging/validation middleware applying to this procedure, in order.
|
|
12
|
+
- **Transport:** how procedures are exposed (HTTP path convention, batching) from the project's configuration.
|
|
13
|
+
- **Client usage:** how callers invoke it (generated client, hook convention) as evidenced in the codebase.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Fragment: Event Bus
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** pub/sub topic configuration, event-bus client code, subscription definitions - record the paths found. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the mechanism sections of the jobs/webhooks template; pairs with the events API fragment when events are also the API style.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Topics and subscriptions:** topic map with publishers and every subscriber (a topic with unknown subscribers is a finding).
|
|
10
|
+
- **Fan-out semantics:** per-subscriber delivery and failure isolation (one failing subscriber must not block others - verified from configuration).
|
|
11
|
+
- **Ordering:** per-key ordering guarantees if any; consumer tolerance otherwise.
|
|
12
|
+
- **Replay:** whether history is replayable, retention window, and the re-subscription procedure.
|
|
13
|
+
- **Schema governance:** how event payload changes propagate to subscribers without breakage.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Fragment: No Async System
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** no queue, scheduler, event bus, or background-job mechanism configured. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the mechanism sections of the jobs/webhooks template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Statement:** all work happens synchronously in request/interaction scope - recorded explicitly.
|
|
10
|
+
- **Consequences documented:** long operations block their caller; the UI states for slow paths (edge-case category 11) matter more, not less.
|
|
11
|
+
- **Boundaries:** operations currently near timeout limits are listed - they are the trigger list for introducing async later (becomes a decision when it happens).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Fragment: Platform-Managed Jobs
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** platform job/function definitions (serverless background functions, platform cron, managed workflow definitions) - record the paths found. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the mechanism sections of the jobs/webhooks template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Job definitions:** where each platform job is declared (config file, dashboard-as-code) and its trigger.
|
|
10
|
+
- **Platform limits:** execution timeout, payload size, concurrency - from the platform's documented limits for the configured tier, cited.
|
|
11
|
+
- **Retry behavior:** the platform's retry policy as configured; what the platform does on final failure.
|
|
12
|
+
- **Local development:** how jobs run locally (emulator, manual trigger) so behavior is testable.
|
|
13
|
+
- **Observability:** where platform logs/metrics for these jobs live and who can access them.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Fragment: Queue-Based Async
|
|
2
|
+
|
|
3
|
+
**Activates on evidence:** queue client configuration, producer/consumer code, queue infrastructure definitions - record the paths found. Or an accepted decision.
|
|
4
|
+
|
|
5
|
+
**Fills:** the mechanism sections of the jobs/webhooks template.
|
|
6
|
+
|
|
7
|
+
## Sections supplied
|
|
8
|
+
|
|
9
|
+
- **Queues:** each queue's name, message contract, producers, and consumers.
|
|
10
|
+
- **Delivery:** the queue system's actual guarantee (at-least-once typically) - consumer idempotency is therefore mandatory and documented per job.
|
|
11
|
+
- **Retry/backoff:** configured policy per queue; poison-message handling (dead-letter destination and its monitoring).
|
|
12
|
+
- **Visibility/locking:** in-flight semantics (visibility timeout, lock duration) and what happens on consumer crash.
|
|
13
|
+
- **Throughput controls:** concurrency limits, batch sizes, rate limits from configuration.
|