@metasession.co/devaudit-cli 0.1.1 → 0.1.3

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 (69) hide show
  1. package/README.md +13 -10
  2. package/dist/index.js +17 -5
  3. package/dist/index.js.map +1 -1
  4. package/package.json +9 -5
  5. package/scripts/upload-evidence.sh +225 -0
  6. package/sdlc/CLAUDE.md +73 -0
  7. package/sdlc/HOST_ADAPTER.md +127 -0
  8. package/sdlc/SKILLS.md +137 -0
  9. package/sdlc/STACK_ADAPTER.md +130 -0
  10. package/sdlc/ai-rules/INSTRUCTIONS-SDLC.md +172 -0
  11. package/sdlc/ai-rules/README.md +103 -0
  12. package/sdlc/ai-rules/SDLC_RULES.md +584 -0
  13. package/sdlc/ai-rules/claude/CLAUDE.md +192 -0
  14. package/sdlc/ai-rules/cursor/.cursorrules +167 -0
  15. package/sdlc/ai-rules/windsurf/.windsurfrules +167 -0
  16. package/sdlc/article.md +219 -0
  17. package/sdlc/files/_common/0-project-setup.md +410 -0
  18. package/sdlc/files/_common/1-plan-requirement.md +381 -0
  19. package/sdlc/files/_common/2-implement-and-test.md +276 -0
  20. package/sdlc/files/_common/3-compile-evidence.md +603 -0
  21. package/sdlc/files/_common/4-submit-for-review.md +362 -0
  22. package/sdlc/files/_common/5-deploy-main.md +251 -0
  23. package/sdlc/files/_common/Periodic_Security_Review_Schedule.md +169 -0
  24. package/sdlc/files/_common/README_TEMPLATE.md +441 -0
  25. package/sdlc/files/_common/Test_Architecture.md +461 -0
  26. package/sdlc/files/_common/Test_Plan_TEMPLATE.md +311 -0
  27. package/sdlc/files/_common/Test_Policy.md +277 -0
  28. package/sdlc/files/_common/Test_Strategy.md +359 -0
  29. package/sdlc/files/_common/github/ISSUE_TEMPLATE/bug.yml +75 -0
  30. package/sdlc/files/_common/github/ISSUE_TEMPLATE/config.yml +11 -0
  31. package/sdlc/files/_common/github/ISSUE_TEMPLATE/requirement.yml +75 -0
  32. package/sdlc/files/_common/github/ISSUE_TEMPLATE/task.yml +48 -0
  33. package/sdlc/files/_common/github/pull_request_template.md +69 -0
  34. package/sdlc/files/_common/implementing-an-sdlc-issue.md +413 -0
  35. package/sdlc/files/_common/scripts/derive-release-version.sh +40 -0
  36. package/sdlc/files/_common/scripts/derive-release-version.test.sh +98 -0
  37. package/sdlc/files/_common/scripts/submit-for-uat-review.sh +162 -0
  38. package/sdlc/files/_common/scripts/validate-commits.sh +83 -0
  39. package/sdlc/files/_common/scripts/validate-compliance-artifacts.sh +202 -0
  40. package/sdlc/files/_common/scripts/validate-compliance-artifacts.test.sh +202 -0
  41. package/sdlc/files/_common/skills/_schema/skill.schema.json +36 -0
  42. package/sdlc/files/_common/skills/e2e-test-engineer/SKILL.md +254 -0
  43. package/sdlc/files/_common/skills/e2e-test-engineer/references/bootstrap.md +244 -0
  44. package/sdlc/files/_common/skills/e2e-test-engineer/references/evidence.ts +40 -0
  45. package/sdlc/files/_common/skills/sdlc-implementer/SKILL.md +189 -0
  46. package/sdlc/files/_common/skills/sdlc-implementer/references/call-graph.md +64 -0
  47. package/sdlc/files/_common/skills/sdlc-implementer/references/change-request-loop.md +192 -0
  48. package/sdlc/files/_common/skills/sdlc-implementer/references/compliance-constraints.md +81 -0
  49. package/sdlc/files/ci/check-release-approval.yml.template +201 -0
  50. package/sdlc/files/ci/ci-status-fallback.yml.template +41 -0
  51. package/sdlc/files/ci/ci.yml.template +390 -0
  52. package/sdlc/files/ci/compliance-evidence.yml.template +161 -0
  53. package/sdlc/files/ci/compliance-validation.yml.template +34 -0
  54. package/sdlc/files/ci/post-deploy-prod.yml.template +159 -0
  55. package/sdlc/files/ci/python/ci.yml.template +335 -0
  56. package/sdlc/files/hosts/_schema/adapter.schema.json +103 -0
  57. package/sdlc/files/hosts/railway/adapter.json +32 -0
  58. package/sdlc/files/sdlc-config.example.json +74 -0
  59. package/sdlc/files/stacks/_schema/adapter.schema.json +151 -0
  60. package/sdlc/files/stacks/node/adapter.json +54 -0
  61. package/sdlc/files/stacks/node/hooks/.prettierrc.json +9 -0
  62. package/sdlc/files/stacks/node/hooks/commit-msg +7 -0
  63. package/sdlc/files/stacks/node/hooks/commitlint.config.mjs +64 -0
  64. package/sdlc/files/stacks/node/hooks/lint-staged.config.mjs +16 -0
  65. package/sdlc/files/stacks/node/hooks/pre-commit +13 -0
  66. package/sdlc/files/stacks/node/hooks/pre-push +15 -0
  67. package/sdlc/files/stacks/node/scripts/check-requirement-jsdoc.sh +54 -0
  68. package/sdlc/files/stacks/python/adapter.json +36 -0
  69. package/sdlc/files/stacks/python/hooks/.pre-commit-config.yaml +51 -0
@@ -0,0 +1,103 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://devaudit.metasession.co/sdlc/hosts/adapter.schema.json",
4
+ "title": "Host adapter manifest",
5
+ "description": "Declares a hosting platform's deploy trigger, production-URL resolution, and post-deploy hooks. One adapter per platform — railway, vercel, fly, kubernetes, self-hosted-docker, etc.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "name",
10
+ "description",
11
+ "deploy_trigger",
12
+ "production_url_from"
13
+ ],
14
+ "properties": {
15
+ "$schema": {
16
+ "type": "string",
17
+ "description": "Optional self-reference to the schema URL for editor tooling."
18
+ },
19
+ "name": {
20
+ "type": "string",
21
+ "pattern": "^[a-z0-9][a-z0-9-]{0,31}$",
22
+ "description": "Lowercase identifier — matches the parent directory under sdlc/files/hosts/ and the `host` key in sdlc-config.json."
23
+ },
24
+ "description": {
25
+ "type": "string",
26
+ "minLength": 1,
27
+ "description": "One-line human summary of what this host is and how it deploys."
28
+ },
29
+ "deploy_trigger": {
30
+ "type": "string",
31
+ "enum": ["push_to_main", "git_tag", "manual", "ci_step"],
32
+ "description": "What triggers a production deploy on this host. `push_to_main` (Railway), `git_tag` (some Vercel setups), `manual` (operator clicks), `ci_step` (workflow runs an explicit deploy command)."
33
+ },
34
+ "production_url_from": {
35
+ "type": "string",
36
+ "enum": ["secret", "static", "api_lookup", "env"],
37
+ "description": "Where the production URL comes from. `secret` — name configured per-project via sdlc-config.json. `static` — hardcoded in adapter. `api_lookup` — resolved by calling the host's API. `env` — read from an env var in the running workflow."
38
+ },
39
+ "production_url_secret_key": {
40
+ "type": "string",
41
+ "description": "When `production_url_from` is `secret`, the sdlc-config.json key whose value names the GitHub Secret holding the URL. Typically `production_url_secret`."
42
+ },
43
+ "production_url_static": {
44
+ "type": "string",
45
+ "description": "When `production_url_from` is `static`, the literal URL (or template string)."
46
+ },
47
+ "wait_for_deploy": {
48
+ "type": "string",
49
+ "minLength": 1,
50
+ "description": "Optional shell command snippet that blocks until the deploy is live and healthy. Embedded into post-deploy-prod.yml.template at sync time. Omit for hosts where deploy is synchronous (e.g. push-to-main on Railway typically completes by the time CI re-runs)."
51
+ },
52
+ "post_deploy_hook": {
53
+ "type": "string",
54
+ "minLength": 1,
55
+ "description": "Optional shell command snippet that runs after a successful deploy — e.g. cache warmup, smoke test, host-specific bookkeeping. Embedded into post-deploy-prod.yml.template."
56
+ },
57
+ "required_secrets": {
58
+ "type": "array",
59
+ "items": { "type": "string", "minLength": 1 },
60
+ "uniqueItems": true,
61
+ "description": "GitHub Secrets the host adapter expects to be set on the consumer repo. Sync may warn if missing; CI workflows will fail at runtime if they're not present."
62
+ },
63
+ "required_env": {
64
+ "type": "array",
65
+ "items": { "type": "string", "minLength": 1 },
66
+ "uniqueItems": true,
67
+ "description": "Environment variables the consumer must set (typically populated from sdlc-config.json fields). Separate from `required_secrets` because env vars are non-sensitive identifiers (app names, region IDs)."
68
+ },
69
+ "config_keys": {
70
+ "type": "object",
71
+ "additionalProperties": false,
72
+ "properties": {
73
+ "required": {
74
+ "type": "array",
75
+ "items": { "type": "string" },
76
+ "uniqueItems": true
77
+ },
78
+ "optional": {
79
+ "type": "array",
80
+ "items": { "type": "string" },
81
+ "uniqueItems": true
82
+ },
83
+ "defaults": { "type": "object" }
84
+ },
85
+ "description": "sdlc-config.json keys this host adapter consumes. `required` keys must be present; `optional` are tolerated; `defaults` provides fallback values."
86
+ },
87
+ "notes": {
88
+ "type": "array",
89
+ "items": { "type": "string", "minLength": 1 },
90
+ "description": "Free-form notes about the host's quirks — backed up here so future maintainers don't have to rediscover them. Not consumed by templates."
91
+ }
92
+ },
93
+ "allOf": [
94
+ {
95
+ "if": { "properties": { "production_url_from": { "const": "secret" } } },
96
+ "then": { "required": ["production_url_secret_key"] }
97
+ },
98
+ {
99
+ "if": { "properties": { "production_url_from": { "const": "static" } } },
100
+ "then": { "required": ["production_url_static"] }
101
+ }
102
+ ]
103
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "../_schema/adapter.schema.json",
3
+ "name": "railway",
4
+ "description": "Railway-hosted services. Push-to-main auto-deploy; production URL from a repo secret; deploys verified by curling the URL until it responds 2xx/3xx.",
5
+ "deploy_trigger": "push_to_main",
6
+ "production_url_from": "secret",
7
+ "production_url_secret_key": "production_url_secret",
8
+ "wait_for_deploy": "for i in $(seq 1 30); do HTTP_CODE=$(curl -s -o /dev/null -w \"%{http_code}\" \"${PROD_URL}/\" || echo \"000\"); if [ \"$HTTP_CODE\" -ge 200 ] && [ \"$HTTP_CODE\" -lt 400 ]; then echo \"Production is up (HTTP ${HTTP_CODE})\"; break; fi; echo \"Attempt ${i}/30: HTTP ${HTTP_CODE} — waiting 10s...\"; sleep 10; done",
9
+ "required_secrets": [
10
+ "DEVAUDIT_API_KEY"
11
+ ],
12
+ "config_keys": {
13
+ "required": [
14
+ "production_url_secret",
15
+ "runner"
16
+ ],
17
+ "optional": [
18
+ "database_service",
19
+ "database_image",
20
+ "database_port",
21
+ "database_env"
22
+ ],
23
+ "defaults": {
24
+ "runner": "ubuntu-latest"
25
+ }
26
+ },
27
+ "notes": [
28
+ "Railway auto-deploys on push to main; no explicit deploy step needed in CI.",
29
+ "Production URL is set as a repo secret (name configured per-project via production_url_secret in sdlc-config.json).",
30
+ "Test-time database services are declared per-project (database_service, database_image, database_port, database_env) so CI can spin up a matching container alongside the app container."
31
+ ]
32
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "_comment": "SDLC project configuration — used by `devaudit install` / `devaudit update` to generate CI workflows",
3
+
4
+ "project_slug": "your-project-slug",
5
+ "production_url_secret": "YOUR_PROJECT_PROD_URL",
6
+ "node_version": 20,
7
+ "runner": "self-hosted",
8
+
9
+ "source_dirs": "app/ lib/ src/",
10
+ "sast_baseline": 0,
11
+ "accepted_dep_risks": "",
12
+
13
+ "database_service": "mongodb",
14
+ "database_image": "mongo:7",
15
+ "database_port": "27017",
16
+ "database_env": {
17
+ "MONGODB_URI": "mongodb://localhost:27017",
18
+ "MONGODB_DB_NAME": "your_test_db"
19
+ },
20
+
21
+ "app_env": {
22
+ "NODE_ENV": "test",
23
+ "NEXT_PUBLIC_APP_URL": "http://localhost:3000",
24
+ "NEXT_PUBLIC_API_URL": "http://localhost:3000/api"
25
+ },
26
+
27
+ "build_env": {
28
+ "MONGODB_URI": "mongodb://localhost:27017",
29
+ "MONGODB_DB_NAME": "placeholder"
30
+ },
31
+
32
+ "e2e_project": "chromium",
33
+ "e2e_start_command": "npm run dev",
34
+
35
+ "paths_ignore": [
36
+ ".github/workflows/**",
37
+ "SDLC/**",
38
+ "compliance/**",
39
+ "*.md",
40
+ ".cursorrules",
41
+ ".windsurfrules",
42
+ "sdlc-config.json",
43
+ "scripts/upload-evidence.sh",
44
+ "scripts/validate-compliance-artifacts.sh",
45
+ "scripts/validate-commits.sh",
46
+ "scripts/check-requirement-jsdoc.sh"
47
+ ],
48
+
49
+ "_comment_devaudit": "DevAudit destination. base_url lives in git so URL changes are visible in PR review. Falls back to repo Variable DEVAUDIT_BASE_URL if base_url is empty (deprecated in v1.23.0).",
50
+ "devaudit": {
51
+ "base_url": "https://devaudit.metasession.co",
52
+ "project_slug": "",
53
+ "api_key_secret": "DEVAUDIT_API_KEY"
54
+ },
55
+
56
+ "_comment_uat": "UAT-environment verification (Stage 3 Step 10). Opt-in: enabled=false skips Step 10 entirely. When enabled, only requirements whose risk class is listed in required_risk_classes go through UAT-env verification.",
57
+ "uat": {
58
+ "enabled": false,
59
+ "url": "",
60
+ "required_risk_classes": ["payment", "destructive_migration", "realtime", "physical_ux"]
61
+ },
62
+
63
+ "_comment_approval": "Four-eyes release approval policy (Stage 3 Step 11). dual_actor = DevAudit enforces approver ≠ release_creator. solo_with_gap = self-approval allowed with documented control gap in compliance/risk-register.md. auto_low_risk = LOW-risk auto-approved by CI, MEDIUM/HIGH require human.",
64
+ "approval": {
65
+ "mode": "dual_actor",
66
+ "auto_low_risk_threshold": "LOW"
67
+ },
68
+
69
+ "_comment_production_review": "Post-deploy production review gate (Stage 5). terminal_status='prod_review' (default, Option A) means post-deploy-prod.yml stops at prod_review; a human in the portal clicks 'Approve Production' (→ prod_approved) then 'Mark as Released' (→ released) for an explicit two-event audit trail. terminal_status='released' (Option B) preserves the v1.21.x auto-release behaviour — workflow PATCHes straight to released with no human click. Closes #138.",
70
+ "production_review": {
71
+ "enabled": true,
72
+ "terminal_status": "prod_review"
73
+ }
74
+ }
@@ -0,0 +1,151 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://devaudit.metasession.co/sdlc/stacks/adapter.schema.json",
4
+ "title": "Stack adapter manifest",
5
+ "description": "Declares a stack's quality-gate commands, hooks framework, and per-stack scripts. One adapter per language/package-manager combination — e.g. node, python, go.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "required": [
9
+ "name",
10
+ "description",
11
+ "manifest_file",
12
+ "hook_framework",
13
+ "hook_install_dir",
14
+ "install",
15
+ "type_check",
16
+ "sast",
17
+ "dep_audit",
18
+ "test",
19
+ "build",
20
+ "evidence_paths",
21
+ "runtime_setup"
22
+ ],
23
+ "properties": {
24
+ "$schema": {
25
+ "type": "string",
26
+ "description": "Optional self-reference to the schema URL for editor tooling."
27
+ },
28
+ "name": {
29
+ "type": "string",
30
+ "pattern": "^[a-z0-9][a-z0-9-]{0,31}$",
31
+ "description": "Lowercase identifier — matches the parent directory under sdlc/files/stacks/ and the `stack` key in sdlc-config.json."
32
+ },
33
+ "description": {
34
+ "type": "string",
35
+ "minLength": 1,
36
+ "description": "One-line human summary of what this stack is."
37
+ },
38
+ "manifest_file": {
39
+ "type": "string",
40
+ "minLength": 1,
41
+ "description": "The dependency manifest the consuming project carries — package.json, pyproject.toml, go.mod, Cargo.toml, etc."
42
+ },
43
+ "hook_framework": {
44
+ "type": "string",
45
+ "enum": ["husky", "pre-commit", "lefthook", "cargo-husky"],
46
+ "description": "Which git-hooks framework the consuming project uses. Determines which hook files are placed and where."
47
+ },
48
+ "hook_install_dir": {
49
+ "type": "string",
50
+ "minLength": 1,
51
+ "description": "Directory the hook framework manages — e.g. .husky, .git/hooks. Sync only writes hooks if this directory exists in the consumer (so projects opt in by bootstrapping the framework first)."
52
+ },
53
+ "hooks": {
54
+ "type": "array",
55
+ "items": { "type": "string" },
56
+ "uniqueItems": true,
57
+ "description": "Hook filenames to place under hook_install_dir/. Each must exist at sdlc/files/stacks/<name>/hooks/<filename>."
58
+ },
59
+ "hook_config_files": {
60
+ "type": "array",
61
+ "items": { "type": "string" },
62
+ "uniqueItems": true,
63
+ "description": "Hook framework config files placed at the consumer's repo root — e.g. commitlint.config.mjs for husky+commitlint, .pre-commit-config.yaml for pre-commit."
64
+ },
65
+ "stack_scripts": {
66
+ "type": "array",
67
+ "items": { "type": "string" },
68
+ "uniqueItems": true,
69
+ "description": "Stack-specific helper scripts copied to the consumer's scripts/ directory. Each must exist at sdlc/files/stacks/<name>/scripts/<filename>."
70
+ },
71
+ "required_dev_dependencies": {
72
+ "type": "array",
73
+ "items": { "type": "string", "minLength": 1 },
74
+ "uniqueItems": true,
75
+ "description": "Dev-time dependencies the adapter assumes are present (e.g. husky for node). Sync may auto-install them or warn if missing — implementation detail of the sync script."
76
+ },
77
+ "install": {
78
+ "type": "string",
79
+ "minLength": 1,
80
+ "description": "Command CI runs once to fetch dependencies — `npm ci`, `pip install -e \".[dev]\"`, `go mod download`, etc."
81
+ },
82
+ "type_check": {
83
+ "type": "string",
84
+ "minLength": 1,
85
+ "description": "Command that returns non-zero if static type-checking fails. MUST output 0 errors on a green build."
86
+ },
87
+ "sast": {
88
+ "type": "string",
89
+ "minLength": 1,
90
+ "description": "Command that runs the SAST scanner and writes results to evidence_paths.sast. MUST exit 0 unless the scanner itself failed (findings above baseline are caught by downstream evaluation, not by this command's exit code)."
91
+ },
92
+ "dep_audit": {
93
+ "type": "string",
94
+ "minLength": 1,
95
+ "description": "Command that runs the dependency audit and writes results to evidence_paths.dep_audit. Same exit-code semantics as `sast`."
96
+ },
97
+ "test": {
98
+ "type": "string",
99
+ "minLength": 1,
100
+ "description": "Command that runs the full test suite (unit + integration). MUST exit 0 only if every test passes. Should also produce machine-readable output at evidence_paths.test."
101
+ },
102
+ "build": {
103
+ "type": "string",
104
+ "minLength": 1,
105
+ "description": "Command that produces the deployable artifact. MUST exit 0 only on a successful build."
106
+ },
107
+ "evidence_paths": {
108
+ "type": "object",
109
+ "additionalProperties": false,
110
+ "required": ["sast", "dep_audit", "test"],
111
+ "properties": {
112
+ "sast": { "type": "string", "minLength": 1 },
113
+ "dep_audit": { "type": "string", "minLength": 1 },
114
+ "test": { "type": "string", "minLength": 1 }
115
+ },
116
+ "description": "Repo-relative paths where each gate's machine-readable output lands. The compliance-evidence upload workflow reads these to know what to publish to DevAudit."
117
+ },
118
+ "runtime_setup": {
119
+ "type": "object",
120
+ "additionalProperties": false,
121
+ "required": ["action", "with"],
122
+ "properties": {
123
+ "action": {
124
+ "type": "string",
125
+ "pattern": "^[^@]+@v[0-9]+$",
126
+ "description": "GitHub Actions reference — e.g. actions/setup-node@v4, actions/setup-python@v5."
127
+ },
128
+ "with": {
129
+ "type": "object",
130
+ "additionalProperties": { "type": "string" }
131
+ }
132
+ },
133
+ "description": "GitHub Actions step that installs the language runtime in CI. Embedded into ci.yml.template at sync time."
134
+ },
135
+ "config_keys": {
136
+ "type": "object",
137
+ "additionalProperties": false,
138
+ "properties": {
139
+ "required": {
140
+ "type": "array",
141
+ "items": { "type": "string" },
142
+ "uniqueItems": true
143
+ },
144
+ "defaults": {
145
+ "type": "object"
146
+ }
147
+ },
148
+ "description": "sdlc-config.json keys this stack consumes. `required` lists keys that must be present; `defaults` provides values the adapter will fall back to when a key is absent."
149
+ }
150
+ }
151
+ }
@@ -0,0 +1,54 @@
1
+ {
2
+ "$schema": "../_schema/adapter.schema.json",
3
+ "name": "node",
4
+ "description": "Node.js / npm / TypeScript stack with husky hooks, commitlint, ESLint, Prettier, Playwright E2E.",
5
+ "manifest_file": "package.json",
6
+ "hook_framework": "husky",
7
+ "hook_install_dir": ".husky",
8
+ "hooks": ["commit-msg", "pre-commit", "pre-push"],
9
+ "hook_config_files": ["commitlint.config.mjs", "lint-staged.config.mjs", ".prettierrc.json"],
10
+ "stack_scripts": ["check-requirement-jsdoc.sh"],
11
+ "required_dev_dependencies": [
12
+ "husky",
13
+ "@commitlint/cli",
14
+ "@commitlint/config-conventional",
15
+ "lint-staged",
16
+ "prettier",
17
+ "eslint",
18
+ "typescript",
19
+ "@playwright/test"
20
+ ],
21
+ "install": "npm ci",
22
+ "type_check": "npx tsc --noEmit",
23
+ "sast": "npx semgrep scan --config auto --json",
24
+ "dep_audit": "npm audit --json --audit-level=high",
25
+ "test": "npm test",
26
+ "build": "npm run build",
27
+ "evidence_paths": {
28
+ "sast": "ci-evidence/sast-results.json",
29
+ "dep_audit": "ci-evidence/dependency-audit.json",
30
+ "test": "ci-evidence/e2e-results.json"
31
+ },
32
+ "runtime_setup": {
33
+ "action": "actions/setup-node@v4",
34
+ "with": { "node-version": "{{NODE_VERSION}}", "cache": "npm" }
35
+ },
36
+ "config_keys": {
37
+ "required": [
38
+ "node_version",
39
+ "source_dirs",
40
+ "sast_baseline",
41
+ "accepted_dep_risks",
42
+ "e2e_project",
43
+ "e2e_start_command"
44
+ ],
45
+ "defaults": {
46
+ "node_version": 20,
47
+ "source_dirs": "app/ lib/",
48
+ "sast_baseline": 0,
49
+ "accepted_dep_risks": "",
50
+ "e2e_project": "chromium",
51
+ "e2e_start_command": "npm run dev"
52
+ }
53
+ }
54
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "printWidth": 100,
5
+ "tabWidth": 2,
6
+ "trailingComma": "all",
7
+ "arrowParens": "always",
8
+ "endOfLine": "lf"
9
+ }
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env bash
2
+ # Husky commit-msg hook — runs commitlint to validate commit message format.
3
+ # Enforces Conventional Commits and checks for SDLC trailers.
4
+ #
5
+ # Install: cp this file to .husky/commit-msg && chmod +x .husky/commit-msg
6
+
7
+ npx commitlint --edit "$1"
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Commitlint configuration for Metasession SDLC.
3
+ *
4
+ * Enforces:
5
+ * - Conventional Commits format (feat, fix, docs, test, refactor, chore, compliance, security)
6
+ * - Co-Authored-By tag presence (warning — not every commit is AI-generated)
7
+ * - Ref: REQ-XXX trailer presence (warning — trivial commits skip requirements)
8
+ *
9
+ * Install:
10
+ * npm install --save-dev @commitlint/cli @commitlint/config-conventional
11
+ * cp this file to your project root as commitlint.config.mjs
12
+ */
13
+
14
+ export default {
15
+ extends: ['@commitlint/config-conventional'],
16
+ rules: {
17
+ // Allow SDLC-specific commit types beyond the conventional set
18
+ 'type-enum': [
19
+ 2,
20
+ 'always',
21
+ [
22
+ 'feat',
23
+ 'fix',
24
+ 'docs',
25
+ 'test',
26
+ 'refactor',
27
+ 'chore',
28
+ 'compliance',
29
+ 'security',
30
+ 'perf',
31
+ 'ci',
32
+ 'build',
33
+ 'revert',
34
+ ],
35
+ ],
36
+ // Warn (not error) when body is missing — some commits are one-liners
37
+ 'body-empty': [1, 'never'],
38
+ },
39
+ plugins: [
40
+ {
41
+ rules: {
42
+ 'trailer-ref-requirement': ({ raw }) => {
43
+ // Warn if Ref: REQ-XXX is missing — trivial commits don't need it
44
+ const hasRef = /Ref:\s*REQ-\d+/i.test(raw);
45
+ return [
46
+ hasRef,
47
+ 'Commit should include "Ref: REQ-XXX" for tracked requirements',
48
+ ];
49
+ },
50
+ 'trailer-co-authored-by': ({ raw }) => {
51
+ // Warn if Co-Authored-By is missing — not every commit is AI-generated
52
+ const hasCoAuthor = /Co-Authored-By:/i.test(raw);
53
+ return [
54
+ hasCoAuthor,
55
+ 'AI-generated commits should include a "Co-Authored-By:" tag',
56
+ ];
57
+ },
58
+ },
59
+ },
60
+ ],
61
+ // Apply custom rules as warnings (level 1), not errors
62
+ // Override in your project if you want stricter enforcement
63
+ helpUrl: 'https://www.conventionalcommits.org/',
64
+ };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * lint-staged configuration for Metasession SDLC node-stack consumers.
3
+ *
4
+ * Runs on staged files only via the pre-commit husky hook:
5
+ * - TS/JS sources: ESLint --fix then Prettier --write
6
+ * - Other files: Prettier --write
7
+ *
8
+ * Consumer projects can override by replacing this file. The sync script
9
+ * re-copies it on every run, so persistent local overrides should live
10
+ * in a separate file (.lintstagedrc.json, etc.) which takes precedence.
11
+ */
12
+
13
+ export default {
14
+ '*.{ts,tsx,js,jsx}': ['eslint --fix', 'prettier --write'],
15
+ '*.{json,css,md,yml,yaml}': ['prettier --write'],
16
+ };
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+ # Husky pre-commit hook — runs lint-staged on staged files.
3
+ # Catches linting issues before they enter the commit history.
4
+ #
5
+ # Install: cp this file to .husky/pre-commit && chmod +x .husky/pre-commit
6
+ #
7
+ # Requires lint-staged config in package.json:
8
+ # "lint-staged": {
9
+ # "*.{ts,tsx}": ["eslint --fix"],
10
+ # "*.{ts,tsx,js,jsx,json,md}": ["prettier --write"]
11
+ # }
12
+
13
+ npx lint-staged
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+ # Husky pre-push hook — runs TypeScript check as a fast gate before push.
3
+ # The full test suite (E2E, SAST, dependency audit) runs in CI.
4
+ #
5
+ # Install: cp this file to .husky/pre-push && chmod +x .husky/pre-push
6
+
7
+ echo "Pre-push: running TypeScript check..."
8
+ npx tsc --noEmit
9
+ if [ $? -ne 0 ]; then
10
+ echo ""
11
+ echo "ERROR: TypeScript check failed. Fix type errors before pushing."
12
+ echo "Run 'npx tsc --noEmit' to see all errors."
13
+ exit 1
14
+ fi
15
+ echo "Pre-push: TypeScript check passed."
@@ -0,0 +1,54 @@
1
+ #!/bin/bash
2
+ # check-requirement-jsdoc.sh — Validates that modified source files contain @requirement JSDoc tags.
3
+ #
4
+ # Usage:
5
+ # ./scripts/check-requirement-jsdoc.sh [base-branch]
6
+ #
7
+ # Checks files changed between base-branch and HEAD for @requirement REQ-XXX JSDoc comments.
8
+ # Reports warnings for files missing the tag. Exits 0 (warnings only) by default.
9
+ # Set STRICT=1 to exit non-zero on missing tags.
10
+ #
11
+ # Install: cp this file to your project's scripts/ directory && chmod +x scripts/check-requirement-jsdoc.sh
12
+ # CI usage: add as a step in your PR validation job.
13
+
14
+ set -euo pipefail
15
+
16
+ BASE_BRANCH="${1:-origin/main}"
17
+ STRICT="${STRICT:-0}"
18
+ EXIT_CODE=0
19
+
20
+ # Get source files changed in this branch (exclude test files, configs, compliance docs)
21
+ CHANGED_FILES=$(git diff --name-only --diff-filter=ACMR "$BASE_BRANCH"...HEAD -- \
22
+ '*.ts' '*.tsx' \
23
+ ':!*.spec.ts' ':!*.spec.tsx' ':!*.test.ts' ':!*.test.tsx' \
24
+ ':!*.config.*' ':!*.d.ts' \
25
+ ':!compliance/' ':!e2e/' ':!__tests__/' ':!tests/' \
26
+ 2>/dev/null || true)
27
+
28
+ if [ -z "$CHANGED_FILES" ]; then
29
+ echo "No source files changed — skipping @requirement check."
30
+ exit 0
31
+ fi
32
+
33
+ MISSING_COUNT=0
34
+ TOTAL_COUNT=0
35
+
36
+ while IFS= read -r file; do
37
+ [ -f "$file" ] || continue
38
+ TOTAL_COUNT=$((TOTAL_COUNT + 1))
39
+
40
+ if ! grep -q '@requirement REQ-' "$file"; then
41
+ echo "WARNING: Missing @requirement JSDoc tag: $file"
42
+ MISSING_COUNT=$((MISSING_COUNT + 1))
43
+ fi
44
+ done <<< "$CHANGED_FILES"
45
+
46
+ echo ""
47
+ echo "Checked $TOTAL_COUNT source files: $((TOTAL_COUNT - MISSING_COUNT)) have @requirement, $MISSING_COUNT missing."
48
+
49
+ if [ "$MISSING_COUNT" -gt 0 ] && [ "$STRICT" = "1" ]; then
50
+ echo "STRICT mode: failing due to missing @requirement tags."
51
+ EXIT_CODE=1
52
+ fi
53
+
54
+ exit $EXIT_CODE
@@ -0,0 +1,36 @@
1
+ {
2
+ "$schema": "../_schema/adapter.schema.json",
3
+ "name": "python",
4
+ "description": "Python stack (3.11+) with pre-commit hooks, ruff (lint + format), mypy --strict, pytest, pip-audit, semgrep.",
5
+ "manifest_file": "pyproject.toml",
6
+ "hook_framework": "pre-commit",
7
+ "hook_install_dir": ".git/hooks",
8
+ "hooks": [],
9
+ "hook_config_files": [".pre-commit-config.yaml"],
10
+ "stack_scripts": [],
11
+ "required_dev_dependencies": ["pytest", "ruff", "mypy", "pip-audit", "pre-commit"],
12
+ "install": "pip install -e \".[dev]\"",
13
+ "type_check": "mypy src/",
14
+ "sast": "semgrep scan --config auto --json",
15
+ "dep_audit": "pip-audit --format=json --strict",
16
+ "test": "pytest --junit-xml=ci-evidence/junit.xml",
17
+ "build": "python -m build",
18
+ "evidence_paths": {
19
+ "sast": "ci-evidence/sast-results.json",
20
+ "dep_audit": "ci-evidence/dependency-audit.json",
21
+ "test": "ci-evidence/junit.xml"
22
+ },
23
+ "runtime_setup": {
24
+ "action": "actions/setup-python@v5",
25
+ "with": { "python-version": "{{PYTHON_VERSION}}", "cache": "pip" }
26
+ },
27
+ "config_keys": {
28
+ "required": ["python_version", "source_dirs", "sast_baseline", "accepted_dep_risks"],
29
+ "defaults": {
30
+ "python_version": "3.11",
31
+ "source_dirs": "src/",
32
+ "sast_baseline": 0,
33
+ "accepted_dep_risks": ""
34
+ }
35
+ }
36
+ }