specky-sdd 3.4.0 → 3.6.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.
Files changed (114) hide show
  1. package/.apm/hooks/scripts/ears-validator.sh +56 -17
  2. package/.apm/prompts/specky-api.prompt.md +1 -1
  3. package/.apm/prompts/specky-research.prompt.md +2 -2
  4. package/.apm/skills/research-analyst/SKILL.md +2 -2
  5. package/.apm/skills/specky-onboarding/SKILL.md +6 -4
  6. package/CHANGELOG.md +58 -0
  7. package/README.md +39 -10
  8. package/SECURITY.md +15 -8
  9. package/apm.yml +1 -1
  10. package/config.yml +1 -1
  11. package/dist/cli/commands/serve.d.ts.map +1 -1
  12. package/dist/cli/commands/serve.js +3 -2
  13. package/dist/cli/commands/serve.js.map +1 -1
  14. package/dist/cli/index.js +3 -1
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/config.d.ts +24 -1
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +92 -6
  19. package/dist/config.js.map +1 -1
  20. package/dist/index.js +63 -14
  21. package/dist/index.js.map +1 -1
  22. package/dist/services/audit-logger.d.ts +54 -5
  23. package/dist/services/audit-logger.d.ts.map +1 -1
  24. package/dist/services/audit-logger.js +121 -9
  25. package/dist/services/audit-logger.js.map +1 -1
  26. package/dist/services/diagram-generator.d.ts +53 -4
  27. package/dist/services/diagram-generator.d.ts.map +1 -1
  28. package/dist/services/diagram-generator.js +565 -178
  29. package/dist/services/diagram-generator.js.map +1 -1
  30. package/dist/services/doc-generator.d.ts +44 -0
  31. package/dist/services/doc-generator.d.ts.map +1 -1
  32. package/dist/services/doc-generator.js +352 -50
  33. package/dist/services/doc-generator.js.map +1 -1
  34. package/dist/services/document-converter.d.ts +10 -7
  35. package/dist/services/document-converter.d.ts.map +1 -1
  36. package/dist/services/document-converter.js +113 -38
  37. package/dist/services/document-converter.js.map +1 -1
  38. package/dist/services/file-manager.d.ts.map +1 -1
  39. package/dist/services/file-manager.js +9 -3
  40. package/dist/services/file-manager.js.map +1 -1
  41. package/dist/services/iac-generator.d.ts +31 -3
  42. package/dist/services/iac-generator.d.ts.map +1 -1
  43. package/dist/services/iac-generator.js +509 -41
  44. package/dist/services/iac-generator.js.map +1 -1
  45. package/dist/services/pbt-generator.d.ts +12 -0
  46. package/dist/services/pbt-generator.d.ts.map +1 -1
  47. package/dist/services/pbt-generator.js +296 -145
  48. package/dist/services/pbt-generator.js.map +1 -1
  49. package/dist/services/state-machine.d.ts +15 -1
  50. package/dist/services/state-machine.d.ts.map +1 -1
  51. package/dist/services/state-machine.js +21 -3
  52. package/dist/services/state-machine.js.map +1 -1
  53. package/dist/services/test-generator.d.ts +8 -0
  54. package/dist/services/test-generator.d.ts.map +1 -1
  55. package/dist/services/test-generator.js +134 -33
  56. package/dist/services/test-generator.js.map +1 -1
  57. package/dist/services/test-traceability-mapper.d.ts.map +1 -1
  58. package/dist/services/test-traceability-mapper.js +8 -3
  59. package/dist/services/test-traceability-mapper.js.map +1 -1
  60. package/dist/services/work-item-exporter.d.ts +70 -9
  61. package/dist/services/work-item-exporter.d.ts.map +1 -1
  62. package/dist/services/work-item-exporter.js +115 -53
  63. package/dist/services/work-item-exporter.js.map +1 -1
  64. package/dist/templates/checklist.md +2 -3
  65. package/dist/templates/cross-analysis.md +2 -4
  66. package/dist/tools/audit.js +1 -1
  67. package/dist/tools/audit.js.map +1 -1
  68. package/dist/tools/documentation.d.ts.map +1 -1
  69. package/dist/tools/documentation.js +9 -3
  70. package/dist/tools/documentation.js.map +1 -1
  71. package/dist/tools/environment.d.ts.map +1 -1
  72. package/dist/tools/environment.js +75 -12
  73. package/dist/tools/environment.js.map +1 -1
  74. package/dist/tools/infrastructure.d.ts.map +1 -1
  75. package/dist/tools/infrastructure.js +7 -39
  76. package/dist/tools/infrastructure.js.map +1 -1
  77. package/dist/tools/input.js +4 -4
  78. package/dist/tools/input.js.map +1 -1
  79. package/dist/tools/integration.js +4 -4
  80. package/dist/tools/integration.js.map +1 -1
  81. package/dist/tools/pipeline.d.ts.map +1 -1
  82. package/dist/tools/pipeline.js +42 -4
  83. package/dist/tools/pipeline.js.map +1 -1
  84. package/dist/tools/quality.d.ts.map +1 -1
  85. package/dist/tools/quality.js +36 -9
  86. package/dist/tools/quality.js.map +1 -1
  87. package/dist/tools/rbac.d.ts.map +1 -1
  88. package/dist/tools/rbac.js +18 -11
  89. package/dist/tools/rbac.js.map +1 -1
  90. package/dist/tools/testing.d.ts +10 -0
  91. package/dist/tools/testing.d.ts.map +1 -1
  92. package/dist/tools/testing.js +66 -13
  93. package/dist/tools/testing.js.map +1 -1
  94. package/dist/tools/tool-enforcement.d.ts +15 -1
  95. package/dist/tools/tool-enforcement.d.ts.map +1 -1
  96. package/dist/tools/tool-enforcement.js +70 -9
  97. package/dist/tools/tool-enforcement.js.map +1 -1
  98. package/dist/tools/transcript.d.ts.map +1 -1
  99. package/dist/tools/transcript.js +66 -41
  100. package/dist/tools/transcript.js.map +1 -1
  101. package/dist/tools/utility.d.ts.map +1 -1
  102. package/dist/tools/utility.js +22 -12
  103. package/dist/tools/utility.js.map +1 -1
  104. package/dist/tools/visualization.d.ts +21 -0
  105. package/dist/tools/visualization.d.ts.map +1 -1
  106. package/dist/tools/visualization.js +130 -29
  107. package/dist/tools/visualization.js.map +1 -1
  108. package/dist/utils/token-table.d.ts +41 -0
  109. package/dist/utils/token-table.d.ts.map +1 -0
  110. package/dist/utils/token-table.js +103 -0
  111. package/dist/utils/token-table.js.map +1 -0
  112. package/package.json +1 -1
  113. package/templates/checklist.md +2 -3
  114. package/templates/cross-analysis.md +2 -4
@@ -3,36 +3,75 @@
3
3
  # Target: Claude Code (.claude/hooks/)
4
4
  # Type: Advisory | Trigger: PostToolUse | Phase: 2,3
5
5
  # Paper: arXiv:2601.03878 — EARS quality
6
+ #
7
+ # Advisory hook: missing EARS pattern types WARN but exit 0 — exit 1 is
8
+ # reserved for real failures (SPECIFICATION.md missing or unreadable).
9
+ # Body is POSIX-sh compatible (runs under dash/sh as well as bash), so
10
+ # plain `set -eu` instead of bash-only `set -o pipefail`.
6
11
 
7
- set -euo pipefail
12
+ set -eu
8
13
 
9
14
  LATEST=$(ls -td .specs/*/ 2>/dev/null | head -1 || true)
10
15
  [ -z "$LATEST" ] && exit 0
11
16
  SPEC="$LATEST/SPECIFICATION.md"
12
- [ -f "$SPEC" ] || exit 0
17
+
18
+ if [ ! -f "$SPEC" ] || [ ! -r "$SPEC" ]; then
19
+ echo "❌ EARS Validation: $SPEC is missing or unreadable."
20
+ echo " sdd_write_spec should have produced it — re-run the Specify phase."
21
+ exit 1
22
+ fi
13
23
 
14
24
  echo "🔍 EARS Validation: $SPEC"
15
25
 
16
- # Count each EARS pattern (POSIX ERE for macOS/Linux portability)
17
- UBIQ=$(grep -cE 'The system shall' "$SPEC" 2>/dev/null || echo "0")
18
- EVENT=$(grep -cE 'When .*, the system shall' "$SPEC" 2>/dev/null || echo "0")
19
- STATE=$(grep -cE 'While .*, the system shall' "$SPEC" 2>/dev/null || echo "0")
20
- OPTION=$(grep -cE 'Where .*, the system shall' "$SPEC" 2>/dev/null || echo "0")
21
- UNWANTED=$(grep -cE 'If .*, then the system shall' "$SPEC" 2>/dev/null || echo "0")
22
- COMPLEX=$(grep -cE 'While .*, when .*, the system shall' "$SPEC" 2>/dev/null || echo "0")
26
+ # Count one EARS pattern (POSIX ERE for macOS/Linux portability).
27
+ # grep -c prints the count but exits 1 when the count is 0; the old
28
+ # `|| echo "0"` appended a SECOND "0" line to the captured value, which
29
+ # broke the arithmetic below (and the whole hook, under set -e) for any
30
+ # spec missing even one pattern type. Capture the count and swallow the
31
+ # exit status instead.
32
+ count_pattern() {
33
+ _count=$(grep -cE "$1" "$SPEC" 2>/dev/null) || _count="${_count:-0}"
34
+ printf '%s' "${_count:-0}"
35
+ }
36
+
37
+ UBIQ=$(count_pattern 'The system shall')
38
+ EVENT=$(count_pattern 'When .*, the system shall')
39
+ STATE=$(count_pattern 'While .*, the system shall')
40
+ OPTION=$(count_pattern 'Where .*, the system shall')
41
+ UNWANTED=$(count_pattern 'If .*, then the system shall')
42
+ COMPLEX=$(count_pattern 'While .*, when .*, the system shall')
23
43
 
24
44
  TOTAL=$((UBIQ + EVENT + STATE + OPTION + UNWANTED + COMPLEX))
25
- REQS=$(grep -cE 'REQ-[A-Z]+-[0-9]+' "$SPEC" 2>/dev/null || echo "0")
26
-
27
- echo " Ubiquitous: $UBIQ"
28
- echo " Event-driven: $EVENT"
29
- echo " State-driven: $STATE"
30
- echo " Optional: $OPTION"
31
- echo " Unwanted: $UNWANTED"
32
- echo " Complex: $COMPLEX"
45
+ REQS=$(count_pattern 'REQ-[A-Z]+-[0-9]+')
46
+
47
+ # Per-pattern coverage report
48
+ PRESENT=0
49
+ MISSING=""
50
+ report_pattern() {
51
+ # $1 = padded label, $2 = count, $3 = pattern name for the warning line
52
+ echo " $1 $2"
53
+ if [ "$2" -gt 0 ]; then
54
+ PRESENT=$((PRESENT + 1))
55
+ else
56
+ MISSING="$MISSING $3"
57
+ fi
58
+ }
59
+
60
+ report_pattern "Ubiquitous: " "$UBIQ" "ubiquitous"
61
+ report_pattern "Event-driven:" "$EVENT" "event-driven"
62
+ report_pattern "State-driven:" "$STATE" "state-driven"
63
+ report_pattern "Optional: " "$OPTION" "optional"
64
+ report_pattern "Unwanted: " "$UNWANTED" "unwanted-behavior"
65
+ report_pattern "Complex: " "$COMPLEX" "complex"
33
66
  echo " ─────────────"
67
+ echo " Pattern coverage: $PRESENT/6 EARS pattern types present"
34
68
  echo " EARS total: $TOTAL / $REQS requirements"
35
69
 
70
+ if [ -n "$MISSING" ]; then
71
+ echo "⚠️ Pattern types with zero requirements:$MISSING"
72
+ echo " Not every spec needs all 6 EARS patterns — advisory only."
73
+ fi
74
+
36
75
  if [ "$TOTAL" -lt "$REQS" ]; then
37
76
  echo "⚠️ $((REQS - TOTAL)) requirements may not follow EARS notation."
38
77
  echo " Run sdd_validate_ears for detailed analysis."
@@ -12,4 +12,4 @@ Design an API using the Specky SDD pipeline.
12
12
  Please:
13
13
  1. Call @requirements-engineer to produce FRD + NFRD for the API
14
14
  2. Call @sdd-init with project_type=api
15
- 3. Proceed through research → specify → design phases
15
+ 3. Proceed through discover → specify → design phases
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: Run SDD research phase
2
+ description: Run SDD Discover phase (research)
3
3
  ---
4
- Run the SDD research phase for feature [FEATURE NUMBER].
4
+ Run the SDD Discover phase (research) for feature [FEATURE NUMBER].
5
5
 
6
6
  @research-analyst — scan the codebase, import relevant documents, run discovery questions, and produce RESEARCH.md.
@@ -214,10 +214,10 @@ Generate dependency graph and assess risk of each integration.
214
214
  Structure the research artifact as:
215
215
 
216
216
  ```markdown
217
- # Research Phase Report
217
+ # Discovery Phase Report
218
218
  **Project:** [name]
219
219
  **Date:** [YYYY-MM-DD]
220
- **Phase:** 1 - Research
220
+ **Phase:** 1 - Discover
221
221
  **Status:** Complete
222
222
 
223
223
  ## Executive Summary
@@ -130,9 +130,9 @@ Check for:
130
130
 
131
131
  **Utility (8):** sdd_get_status, sdd_get_template, sdd_write_bugfix, sdd_scan_codebase, sdd_amend, sdd_check_ecosystem, sdd_check_sync, sdd_metrics
132
132
 
133
- **Governance (3):** sdd_model_routing, sdd_context_status, sdd_check_access
133
+ **Governance (4):** sdd_model_routing, sdd_context_status, sdd_check_access, sdd_verify_audit
134
134
 
135
- ## 14 Hook Scripts
135
+ ## 16 Hook Scripts
136
136
 
137
137
  **Blocking (exit 2 = halt):**
138
138
  - artifact-validator.sh — Prerequisite .md files exist
@@ -142,9 +142,11 @@ Check for:
142
142
 
143
143
  **Advisory (exit 0 = warn):**
144
144
  - branch-validator.sh — Branch matches phase expectations
145
- - lgtm-gate.sh — Human review reminder at Phases 3/4/5
146
- - auto-checkpoint.sh — Suggest checkpoint after writes
145
+ - pipeline-guard.sh — Pipeline ordering / phase-skip guard
146
+ - lgtm-gate.sh — Human review reminder at Phases 2/4/5
147
+ - session-banner.sh — Session start pipeline-status banner
147
148
  - spec-sync.sh — Detect spec-code drift
149
+ - auto-checkpoint.sh — Suggest checkpoint after writes
148
150
  - spec-quality.sh — Specification quality metrics
149
151
  - ears-validator.sh — EARS pattern compliance
150
152
  - task-tracer.sh — Task dependency graph
package/CHANGELOG.md CHANGED
@@ -7,6 +7,64 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.6.0] - 2026-07-03
11
+
12
+ Delivery-honesty release. A black-box audit executed all 65 public product
13
+ promises against the real 3.5.0 server (`docs/AUDIT-DELIVERY-3.5.md` is the
14
+ full record: 30 delivered / 29 partial / 6 not delivered). This release fixes
15
+ every finding.
16
+
17
+ ### Fixed
18
+
19
+ - **`sdd_auto_pipeline` fabricated its quality gate** (hard-coded `APPROVE`/100% — the same defect fixed for other paths in 3.4.0 had survived here). It now runs the shared `AnalysisEngine`: real decision, real coverage, requirement-level traceability matrix in `ANALYSIS.md`. Auto-generated packages honestly report `CHANGES_NEEDED` until traceability is complete.
20
+ - **`sdd_get_status` reported a stale phase** (it preferred a per-feature state file no pipeline tool writes and fell back to a fresh default). Headline fields (current phase, progress, gate decision, next action) now reflect the state the pipeline actually persists.
21
+ - **Phase-skip loophole**: with no registered feature, `sdd_advance_phase` skipped every artifact check and could walk six phases with zero artifacts. Advancing past init now requires a registered feature.
22
+ - **Generated tests now compile/run**: pytest output was a Python syntax error (JS-style header); junit class names didn't match filenames and had duplicate methods; xunit had duplicate members; vitest/jest/playwright emitted markdown ToC noise as tests, traced to a nonexistent `REQ-000`, and truncated the `REQ-` prefix. All fixed, with structural (and where possible compile) tests.
23
+ - **PBT generators produce runnable property tests**: valid `fast-check` import, self-contained bodies (no undefined helpers), meaningful assertions, and real REQ IDs (never fabricated `REQ-GEN-00N` — untraceable items are skipped or explicitly labeled `UNTRACED-`).
24
+ - **`sdd_verify_tests` coverage scanned the wrong directories** (always 0%): it now scans where `sdd_generate_tests` writes (via a generated-tests manifest), so the REQ→test mapping and `next_steps` use real numbers.
25
+ - **Doc generators derive real content**: the "first 15 lines" summarizer (which captured only frontmatter + ToC) was replaced with requirement-aware extraction — generated docs now contain the actual EARS requirements; the runbook is derived from `DESIGN.md` (was 100% static template); onboarding explains the feature; API docs extract request/response examples from the design contracts (were always `{}`) and no longer duplicate endpoints from mermaid blocks; the journey doc joined the parallel batch and failures surface in the response.
26
+ - **Diagrams**: `er`/`dfd` emitted invalid Mermaid (unsanitized ids) — fixed; `class`/`state`/`c4_code` were byte-identical stubs regardless of input — now derived from the artifacts; `pie` fabricated numbers — now computed; `gantt` was header-only from spec/design and used a date syntax real Mermaid rejects — fixed; `sequence` derivation is readable (`Client->>System` per requirement). `sdd_generate_all_diagrams` now **writes `DIAGRAMS.md`** (it returned diagrams but wrote nothing) and covers c4_context + state (18 diagrams). ToC headings are no longer treated as architecture components; `sdd_figma_diagram` types differ structurally with meaningful edge labels.
27
+ - **Binary document imports fail honestly**: real (compressed) PDF/DOCX/PPTX used to import as gibberish flagged "success". Unsupported binaries now return a clear error pointing to md/txt conversion or the MarkItDown MCP; `sdd_batch_import` counts them as failed.
28
+ - **`sdd_export_work_items` payloads are target-specific** (GitHub `{title, body, labels}` / Jira `{fields: {project.key, issuetype…}}` / Azure Boards `System.*` fields + `area_path`/`iteration_path`) and honor the documented inputs that were silently discarded (`project_key`, `include_subtasks`, …).
29
+ - **Persisted `[TODO:]` placeholders**: `CHECKLIST.md` and `CROSS_ANALYSIS.md` now render the real items/alignment tables and recommendation (the data existed only in the JSON response).
30
+ - **Terraform generation emits real resources** parsed from the `DESIGN.md` tech stack (was a provider-only skeleton with four generic modules); devcontainer/local-env/codespaces honor the documented DESIGN.md fallback detection (`additional_services` is no longer always empty); the Codespaces payload no longer references a nonexistent `create_codespace` MCP tool.
31
+ - **`ears-validator.sh` hook** no longer fails (exit 1) whenever a spec lacks one of the 6 EARS pattern types — it reports per-pattern coverage as an advisory.
32
+ - **`sdd_figma_to_spec`** payload referenced nonexistent tool names (`sdd_gen_spec` → `sdd_write_spec` etc.).
33
+ - Cognitive-debt gate instrumentation resolved artifact paths against the process cwd instead of the workspace root, silently degrading in hosted (HTTP) mode.
34
+
35
+ ### Added
36
+
37
+ - **Opt-in server-side LGTM**: `pipeline.require_lgtm: true` in `.specky/config.yml` makes `sdd_advance_phase` refuse to pass the Specify/Design/Tasks gates without an explicit `lgtm: true` input. Default off; not flipped by the enterprise profile (human-review gating is a workflow choice, not a security control). Gate history records LGTM presence.
38
+ - **`docs/AUDIT-DELIVERY-3.5.md`** — the full promise-delivery audit as a public record.
39
+ - 6 new test suites (~112 new tests, 299 total) locking generated-content quality: compilable test output, valid Mermaid structure, target-specific export payloads, honest import failures, requirement-bearing docs, pipeline-state truthfulness.
40
+
41
+ ### Container publishing docs
42
+
43
+ - Expanded GHCR/container documentation across README, install, enterprise deployment, and publishing guidance.
44
+ - Updated GHCR publish automation to preserve multi-arch `linux/amd64` + `linux/arm64` images.
45
+
46
+ ## [3.5.0] - 2026-07-02
47
+
48
+ Enterprise mode — an **opt-in configuration profile** of the same 100%
49
+ open-source (MIT) package. Every control below ships in `specky-sdd` for
50
+ everyone, default-OFF, and the standard profile is byte-for-byte the same
51
+ experience as 3.4.0. See `docs/ENTERPRISE-DEPLOYMENT.md`.
52
+
53
+ ### Added
54
+
55
+ - **Enterprise profile.** `profile: enterprise` in `.specky/config.yml` — or `SPECKY_PROFILE=enterprise`, the `SPECKY_ENTERPRISE=1` shorthand, or `specky serve --profile=enterprise` (flag > env > file) — flips the *defaults* of `audit_enabled`, `rbac.enabled`, `rate_limit.enabled`, and the new `audit.fail_closed` to ON. Explicit config values always win, so any control can still be switched off individually. The server logs the resolved posture at startup.
56
+ - **Identity-based RBAC over HTTP.** `SDD_HTTP_TOKENS_FILE` points at a YAML token table (kept outside the workspace) mapping bearer tokens — plaintext or `token_sha256` — to a named `principal` and RBAC `role`. Tokens are constant-time compared; loading is fail-closed (a malformed table aborts startup instead of accepting everyone). Role precedence is now **authenticated token role > `SDD_ROLE` > `rbac.default_role`** — an authenticated request ignores `SDD_ROLE`, so a remote caller cannot out-vote its token. `sdd_check_access` and `access_denied` responses report the principal and role source. The legacy shared `SDD_HTTP_TOKEN` continues to work unchanged when no table is configured.
57
+ - **Tamper-evident audit trail.** With `SDD_AUDIT_HMAC_KEY` (or `SDD_AUDIT_HMAC_KEY_FILE`, key held outside the workspace) every audit entry is signed with HMAC-SHA256 over its serialized form — `previous_hash` included, so signatures chain. `sdd_verify_audit` now verifies both the hash chain and the signatures and reports `hmac_checked` / `signed_entries`; a workspace writer who rewrites the log and recomputes the plain chain is detected. Audit entries also record the authenticated `principal`. (Documented limit: tail truncation needs external anchoring of `current_hash`.)
58
+ - **Fail-closed auditing.** `audit.fail_closed: true` (enterprise default) refuses tool execution with `audit_unavailable` when the pre-execution audit entry cannot be written — no unaudited actions. Post-execution audit failures are surfaced on stderr without masking the tool result. Standard profile keeps the historical fail-open behavior.
59
+ - **`docs/ENTERPRISE-DEPLOYMENT.md`** — profiles, token table setup (with token/hash generation commands), HMAC audit + verification, hosted `serve --http` behind TLS (systemd/container examples), air-gapped tarball + private-registry installs, CI enforcement, the full enterprise env-var/config reference, and an honest out-of-scope list (no in-process TLS, no SSO yet, stdio has no auth layer).
60
+ - Tests: `config-profile` (profile precedence + explicit-wins), `audit-hmac` (signing, forged-rewrite detection, fail-closed, key resolution), `token-table` (load validation + identity resolution), and identity/fail-closed cases in `tool-enforcement`.
61
+
62
+ ### Changed
63
+
64
+ - `AuditLogger` accepts an options object (`{ exportFormat, maxFileSizeMb, hmacKey, failClosed }`); the old positional signature still works.
65
+ - RBAC denial responses and audit entries include the caller's `principal` when authenticated.
66
+ - README, SECURITY.md, CLI.md, INSTALL.md, and ENTERPRISE-CONTROLS.md updated for the profile, token table, and HMAC audit; API reference regenerated.
67
+
10
68
  ## [3.4.0] - 2026-07-02
11
69
 
12
70
  First stable `3.4.0` (supersedes the `3.4.0-rc.*` prereleases). Consolidates the
package/README.md CHANGED
@@ -57,7 +57,7 @@
57
57
  | **Enterprise** | [Compliance Frameworks](#compliance-frameworks) | HIPAA, SOC2, GDPR, PCI-DSS, ISO 27001 |
58
58
  | | [Enterprise Ready](#enterprise-ready) | Security, audit trail, quality gates |
59
59
  | **Platform** | [The SDD Platform](#the-spec-driven-development-platform) | Built on Spec-Kit, everything included |
60
- | | [Roadmap](#roadmap) | v3.4 current, v3.5+ planned |
60
+ | | [Roadmap](#roadmap) | v3.5 current, v3.6+ planned |
61
61
 
62
62
 
63
63
  ## What is Specky?
@@ -199,7 +199,7 @@ cd your-project
199
199
  specky install
200
200
  ```
201
201
 
202
- That's it. The CLI auto-detects Claude Code and/or GitHub Copilot and installs the 13 agents, 22 prompts, 8 skills, 16 hooks, the MCP server registration, and pre-authorizes all required tools.
202
+ That's it. The CLI auto-detects Claude Code and/or GitHub Copilot and installs the 13 agents, 22 prompts, 8 skills, 16 hooks, the MCP server registration, and pre-authorizes a least-privilege set of tools (the Specky MCP tools plus scoped `git`/`npm`/`npx` and file editing — not arbitrary shell or network).
203
203
 
204
204
  **Other install modes:**
205
205
 
@@ -352,7 +352,7 @@ The AI calls `sdd_import_document` → converts to Markdown, extracts sections,
352
352
 
353
353
  The AI calls `sdd_batch_import` → processes every supported file in the directory.
354
354
 
355
- > **Tip:** For best results with PDF/DOCX, install the optional `mammoth` and `pdfjs-dist` packages for enhanced formatting, table extraction, and image handling.
355
+ > **Honest note on binary formats:** the built-in extractor fully handles `md`/`txt` and simple uncompressed files. Real-world (compressed) PDF/DOCX/PPTX need one of: the optional `mammoth`/`pdfjs-dist` packages, or the recommended **MarkItDown MCP** integration. Since 3.6, unsupported binaries **fail with clear guidance** instead of silently importing garbage.
356
356
 
357
357
  ### 4. Figma Design (design-to-spec)
358
358
 
@@ -887,13 +887,22 @@ Create `.specky/config.yml` in your project root to customize Specky:
887
887
 
888
888
  ```yaml
889
889
  # .specky/config.yml
890
+ profile: standard # standard | enterprise (flips security defaults ON)
890
891
  templates_path: ./my-templates # Override built-in templates
891
892
  default_framework: vitest # Default test framework
892
893
  compliance_frameworks: [hipaa, soc2] # Frameworks to check
893
894
  audit_enabled: true # Enable audit trail
895
+ rbac:
896
+ enabled: false # Role checks (viewer/contributor/admin)
897
+ default_role: contributor
898
+ rate_limit:
899
+ enabled: false # HTTP token bucket (60 rpm, burst 10)
900
+ pipeline:
901
+ require_lgtm: false # Server-side LGTM: sdd_advance_phase refuses to pass
902
+ # the Specify/Design/Tasks gates unless lgtm: true
894
903
  ```
895
904
 
896
- When `templates_path` is set, Specky uses your custom templates instead of the built-in ones. When `audit_enabled` is true, tool invocations are logged locally.
905
+ When `templates_path` is set, Specky uses your custom templates instead of the built-in ones. When `audit_enabled` is true, tool invocations are logged locally. `profile: enterprise` turns audit, RBAC, rate limiting, and fail-closed auditing on by default (explicit values win) — see [docs/ENTERPRISE-DEPLOYMENT.md](docs/ENTERPRISE-DEPLOYMENT.md). With `pipeline.require_lgtm: true`, the LGTM quality gates become server-enforced instead of an agent convention: advancing past Specify/Design/Tasks requires the explicit `lgtm: true` input on `sdd_advance_phase`.
897
906
 
898
907
 
899
908
  ## MCP Integration Architecture
@@ -982,6 +991,12 @@ From any [input](#input-methods-6-ways-to-start) to production -- fully automate
982
991
 
983
992
  Specky is built with enterprise adoption in mind.
984
993
 
994
+ ### Enterprise profile (opt-in)
995
+
996
+ Specky is 100% open source (MIT) — enterprise mode is just an opt-in configuration profile of the same package: `profile: enterprise` (or `SPECKY_PROFILE=enterprise`, or `specky serve --profile=enterprise`) flips the governance defaults ON — hash-chained **audit trail** (fail-closed), **RBAC**, and HTTP **rate limiting** — while explicit config values still win. Add `SDD_HTTP_TOKENS_FILE` for **identity-based roles** (each bearer token maps to a named principal + role; audit entries record who did what) and `SDD_AUDIT_HMAC_KEY[_FILE]` for a **tamper-evident audit log** signed with a key the workspace never sees. The standard profile is untouched — all of this stays off unless you opt in.
997
+
998
+ → Full guide: [docs/ENTERPRISE-DEPLOYMENT.md](docs/ENTERPRISE-DEPLOYMENT.md) (hosted HTTP, tokens, HMAC audit, air-gapped installs, containers, CI gates)
999
+
985
1000
  ### Security Posture
986
1001
 
987
1002
  - **3 runtime dependencies** — minimal attack surface (`@modelcontextprotocol/sdk`, `zod`, `yaml`)
@@ -993,6 +1008,7 @@ Specky is built with enterprise adoption in mind.
993
1008
  - See [SECURITY.md](SECURITY.md) for full OWASP Top 10 coverage
994
1009
  - See [docs/SYSTEM-DESIGN.md](docs/SYSTEM-DESIGN.md) for complete security architecture
995
1010
  - See [docs/ENTERPRISE-CONTROLS.md](docs/ENTERPRISE-CONTROLS.md) for RBAC, audit trail, and tool-enforcement controls
1011
+ - See [docs/ENTERPRISE-DEPLOYMENT.md](docs/ENTERPRISE-DEPLOYMENT.md) for the enterprise profile, identity tokens, HMAC audit, and hosted/air-gapped deployment
996
1012
  - See [docs/DETERMINISM.md](docs/DETERMINISM.md) for reproducible-output guarantees
997
1013
  - See [docs/BRANCH-GOVERNANCE.md](docs/BRANCH-GOVERNANCE.md) for branch and release governance
998
1014
  - See [docs/EVIDENCE.md](docs/EVIDENCE.md) for the validation evidence pack
@@ -1004,7 +1020,7 @@ When using Specky, follow these practices to protect your data:
1004
1020
  | Practice | Why | How |
1005
1021
  |----------|-----|-----|
1006
1022
  | **Use stdio mode for local development** | No network exposure | `npx specky-sdd` (default) |
1007
- | **Never expose HTTP mode to public networks without TLS** | HTTP has optional bearer-token auth but no TLS | `--http` binds to `127.0.0.1` by default; set `SDD_HTTP_TOKEN` for bearer auth. For remote access, add a reverse proxy (nginx, Caddy) terminating TLS |
1023
+ | **Never expose HTTP mode to public networks without TLS** | HTTP has optional bearer-token auth but no TLS | `--http` binds to `127.0.0.1` by default; set `SDD_HTTP_TOKEN` (shared) or `SDD_HTTP_TOKENS_FILE` (per-user identity + role) for bearer auth. For remote access, add a reverse proxy (nginx, Caddy) terminating TLS |
1008
1024
  | **Protect the `.specs/` directory** | Contains your specification artifacts (architecture, API contracts, business logic) | Add `.specs/` to `.gitignore` if specs contain sensitive IP, or use a private repo |
1009
1025
  | **Protect checkpoints** | `.specs/{feature}/.checkpoints/` stores full artifact snapshots | Same as above — treat checkpoints like source code |
1010
1026
  | **Review auto-generated specs before committing** | Turnkey and auto-pipeline generate from natural language — may capture sensitive details | Review SPECIFICATION.md and DESIGN.md before `git add` |
@@ -1077,16 +1093,26 @@ npm run dev
1077
1093
  # Verify MCP handshake (quick smoke test)
1078
1094
  echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | node dist/index.js 2>/dev/null
1079
1095
 
1080
- # Build and run with Docker locally
1096
+ # Run the published image from GHCR (multi-arch: linux/amd64 + linux/arm64)
1097
+ docker pull ghcr.io/paulasilvatech/specky:latest # or pin a release: :3.5.0
1098
+ docker run --rm -p 3200:3200 ghcr.io/paulasilvatech/specky:latest
1099
+ curl http://localhost:3200/health # -> {"status":"ok","version":"3.5.0"}
1100
+
1101
+ # Or build and run locally from source
1081
1102
  docker build -t specky-sdd:dev .
1082
1103
  docker run -p 3200:3200 -v $(pwd):/workspace specky-sdd:dev
1083
1104
  curl http://localhost:3200/health
1084
1105
  ```
1085
1106
 
1107
+ The published image binds `0.0.0.0:3200` inside the container (so `-p` works)
1108
+ and serves an unauthenticated `GET /health`. For hardened/authenticated
1109
+ deployments (enterprise profile, token auth, TLS proxy, private packages) see
1110
+ [docs/ENTERPRISE-DEPLOYMENT.md](docs/ENTERPRISE-DEPLOYMENT.md).
1111
+
1086
1112
 
1087
1113
  ## Roadmap
1088
1114
 
1089
- ### v3.4 (current)
1115
+ ### v3.5 (current)
1090
1116
 
1091
1117
  | Capability | Status |
1092
1118
  |------------|--------|
@@ -1118,17 +1144,20 @@ curl http://localhost:3200/health
1118
1144
  | RBAC foundation (opt-in role-based access control) | Stable |
1119
1145
  | Rate limiting for HTTP transport (opt-in) | Stable |
1120
1146
  | HTTP transport: loopback bind by default, bearer-token auth (`SDD_HTTP_TOKEN`), DNS-rebinding protection | Stable |
1147
+ | Enterprise profile (`profile: enterprise` — audit/RBAC/rate-limit defaults ON, opt-in) | Stable |
1148
+ | Identity-based RBAC over HTTP (`SDD_HTTP_TOKENS_FILE`: token → principal + role) | Stable |
1149
+ | Tamper-evident audit trail (HMAC-signed entries, fail-closed mode, `sdd_verify_audit`) | Stable |
1121
1150
 
1122
- ### v3.5+ (planned)
1151
+ ### v3.6+ (planned)
1123
1152
 
1124
1153
  | Feature | Description |
1125
1154
  |---------|-------------|
1126
1155
  | Observability | OpenTelemetry metrics and structured logging |
1127
1156
  | Internationalization | Spec templates in PT-BR, ES, FR, DE, JA |
1128
1157
  | Automated shrinking | fast-check/Hypothesis shrinking feedback into spec refinement |
1129
- | Centralized audit log | SIEM-integrated tamper-evident audit trail |
1158
+ | Centralized audit log | SIEM export (syslog shipping, OTLP) of the tamper-evident audit trail |
1130
1159
  | Multi-tenant | Isolated workspaces for multiple teams |
1131
- | SSO / SAML | Federated identity for enterprise auth |
1160
+ | SSO / SAML | Federated identity for enterprise auth (beyond the static token table) |
1132
1161
 
1133
1162
  Have a feature request? [Open an issue](https://github.com/paulasilvatech/specky/issues).
1134
1163
 
package/SECURITY.md CHANGED
@@ -4,10 +4,10 @@
4
4
 
5
5
  | Version | Supported |
6
6
  | --- | --- |
7
- | 3.3.x | ✅ Active |
8
- | 3.0.x–3.2.x | ✅ Security fixes only |
9
- | 2.3.x | ❌ End of life |
10
- | 2.0.x | ❌ End of life |
7
+ | 3.5.x | ✅ Active |
8
+ | 3.4.x | ✅ Security fixes only |
9
+ | 3.0.x–3.3.x | ❌ End of life |
10
+ | 2.x | ❌ End of life |
11
11
  | 1.0.x | ❌ End of life |
12
12
 
13
13
  ## Reporting a Vulnerability
@@ -78,7 +78,7 @@ Runtime dependencies are kept intentionally small and are audited in CI.
78
78
  | A04 Insecure Design | State machine enforces phase ordering; thin tools / fat services separation |
79
79
  | A05 Security Misconfiguration | Minimal config surface; no default credentials; no admin endpoints |
80
80
  | A06 Vulnerable Components | 3 runtime deps only; Dependabot enabled; regular audits |
81
- | A07 Authentication Failures | stdio mode is process-isolated (no network). HTTP mode binds to `127.0.0.1` by default and supports optional bearer-token auth (`SDD_HTTP_TOKEN`, constant-time compared) plus DNS-rebinding protection |
81
+ | A07 Authentication Failures | stdio mode is process-isolated (no network). HTTP mode binds to `127.0.0.1` by default and supports optional bearer-token auth — a shared token (`SDD_HTTP_TOKEN`) or a named token table (`SDD_HTTP_TOKENS_FILE`, principal + RBAC role per token, sha256 storage supported) — all constant-time compared, plus DNS-rebinding protection |
82
82
  | A08 Data Integrity Failures | Atomic file writes via FileManager; Zod schema enforcement |
83
83
  | A09 Logging Failures | Structured stderr logging; no stdout pollution |
84
84
  | A10 SSRF | Zero outbound network requests |
@@ -101,8 +101,15 @@ We run `npm audit` in CI on every pull request. Any `high` or `critical` vulnera
101
101
  | --- | --- | --- |
102
102
  | `SDD_WORKSPACE` | Restricts file operations to this directory | Current working directory |
103
103
  | `PORT` | HTTP transport port (when using `--http` mode) | 3200 |
104
+ | `SPECKY_PROFILE` | `enterprise` flips audit/RBAC/rate-limit defaults to ON (explicit config wins) | `standard` |
105
+ | `SDD_HTTP_TOKEN` | Shared bearer token for `--http` (no identity) | unset (auth off) |
106
+ | `SDD_HTTP_TOKENS_FILE` | Named token table → principal + RBAC role (identity-based auth) | unset |
107
+ | `SDD_AUDIT_HMAC_KEY` / `SDD_AUDIT_HMAC_KEY_FILE` | Sign audit entries (tamper evidence); keep the key outside the workspace | unset (chain only) |
108
+ | `SDD_ROLE` | Local RBAC role for stdio use — ignored on authenticated HTTP requests | `rbac.default_role` |
104
109
 
105
- HTTP transport (`--http`) binds to `127.0.0.1` by default. Binding to a non-loopback address requires an explicit `--host` and prints a warning. Set `SDD_HTTP_TOKEN` to require an `Authorization: Bearer <token>` header on every `/mcp` request (the `/health` probe stays open). Even so, do not expose Specky to public networks without a TLS-terminating reverse proxy.
110
+ HTTP transport (`--http`) binds to `127.0.0.1` by default. Binding to a non-loopback address requires an explicit `--host` and prints a warning. Set `SDD_HTTP_TOKEN` (shared token) or `SDD_HTTP_TOKENS_FILE` (named tokens mapping to principal + role) to require an `Authorization: Bearer <token>` header on every `/mcp` request (the `/health` probe stays open). Even so, do not expose Specky to public networks without a TLS-terminating reverse proxy. Hosted, air-gapped, and container deployment patterns: [docs/ENTERPRISE-DEPLOYMENT.md](docs/ENTERPRISE-DEPLOYMENT.md).
111
+
112
+ The audit trail's plain hash chain detects corruption but not deliberate rewriting by a workspace writer; configure an HMAC key (held outside the workspace) to make entries tamper-evident, and anchor the `current_hash` from `sdd_verify_audit` externally to detect tail truncation.
106
113
 
107
114
  ## Secure Development Practices
108
115
 
@@ -119,7 +126,7 @@ HTTP transport (`--http`) binds to `127.0.0.1` by default. Binding to a non-loop
119
126
  | Practice | Details |
120
127
  | --- | --- |
121
128
  | **Use stdio mode by default** | `specky-sdd` (global install) — no network exposure, process-level isolation |
122
- | **Never expose HTTP mode publicly without TLS** | `--http` supports bearer-token auth (`SDD_HTTP_TOKEN`) and binds to `127.0.0.1` by default, but has no TLS. For remote access, set a token AND place it behind a reverse proxy (nginx, Caddy, Traefik) terminating TLS |
129
+ | **Never expose HTTP mode publicly without TLS** | `--http` supports bearer-token auth (`SDD_HTTP_TOKEN`, or `SDD_HTTP_TOKENS_FILE` for per-user identity + role) and binds to `127.0.0.1` by default, but has no TLS. For remote access, set tokens AND place it behind a reverse proxy (nginx, Caddy, Traefik) terminating TLS |
123
130
  | **Protect `.specs/` directory** | Contains architecture details, API contracts, security models. Add to `.gitignore` for sensitive projects, or use a private repository |
124
131
  | **Protect `.checkpoints/`** | Contains full copies of all spec artifacts. Treat like source code |
125
132
  | **Keep security-scan hook active** | `.claude/hooks/security-scan.sh` scans for hardcoded secrets and blocks commits (exit 2). Do not disable |
@@ -205,7 +212,7 @@ Running `npx -y specky-sdd@latest` without a pinned version downloads the latest
205
212
 
206
213
  ```bash
207
214
  # Install into a local vendor directory — no global write permissions needed
208
- npm install specky-sdd@3.4.0 --prefix ./vendor --ignore-scripts
215
+ npm install specky-sdd@3.5.0 --prefix ./vendor --ignore-scripts
209
216
  ./vendor/node_modules/.bin/specky install
210
217
  ./vendor/node_modules/.bin/specky doctor # integrity check
211
218
  ```
package/apm.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: specky-sdd
2
- version: 3.4.0
2
+ version: 3.6.0
3
3
  description: "Agentic Spec-Driven Development — 10-phase pipeline with 58 MCP tools, 13 agents, 22 prompts, 8 skills, 16 hooks, EARS notation, model routing, and enterprise security"
4
4
  author: Paula Silva
5
5
  license: MIT
package/config.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  audit_enabled: true
2
- version: "3.4.0"
2
+ version: "3.6.0"
3
3
  pipeline:
4
4
  phases: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
5
5
  phase_names:
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAalE"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAclE"}
@@ -7,8 +7,9 @@
7
7
  */
8
8
  export async function runServe(opts) {
9
9
  // We simply import the existing entry point which starts the MCP server.
10
- // Flags like --http are read from process.argv by the server module itself,
11
- // so we just set them back into argv for compatibility.
10
+ // Flags like --http, --host= and --profile= are read from process.argv by
11
+ // the server module itself, so we just set them back into argv for
12
+ // compatibility.
12
13
  const extra = [];
13
14
  if (opts.http)
14
15
  extra.push("--http");
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,yEAAyE;IACzE,4EAA4E;IAC5E,wDAAwD;IACxD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,6CAA6C;IAC7C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAE5B,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC/B,2CAA2C;IAC3C,OAAO,CAAC,CAAC;AACX,CAAC"}
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAkB;IAC/C,yEAAyE;IACzE,0EAA0E;IAC1E,mEAAmE;IACnE,iBAAiB;IACjB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,IAAI,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,6CAA6C;IAC7C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAE5B,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC/B,2CAA2C;IAC3C,OAAO,CAAC,CAAC;AACX,CAAC"}
package/dist/cli/index.js CHANGED
@@ -8,7 +8,7 @@
8
8
  * specky status
9
9
  * specky upgrade
10
10
  * specky hooks <list|test|run NAME>
11
- * specky serve [--http] [--port=N]
11
+ * specky serve [--http] [--port=N] [--profile=enterprise]
12
12
  * specky --version | -v
13
13
  * specky --help | -h
14
14
  *
@@ -70,6 +70,8 @@ Commands:
70
70
  --port=<N> HTTP port (default 3200)
71
71
  --host=<addr> HTTP bind address (default 127.0.0.1;
72
72
  set 0.0.0.0 only behind an auth proxy)
73
+ --profile=<standard|enterprise> Config profile (enterprise defaults
74
+ audit/RBAC/rate-limit to ON)
73
75
 
74
76
  --version, -v Print version
75
77
  --help, -h Print this help
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { z } from "zod";
2
2
  declare const configSchema: z.ZodObject<{
3
+ profile: z.ZodDefault<z.ZodEnum<{
4
+ standard: "standard";
5
+ enterprise: "enterprise";
6
+ }>>;
3
7
  templates_path: z.ZodDefault<z.ZodString>;
4
8
  default_framework: z.ZodDefault<z.ZodString>;
5
9
  compliance_frameworks: z.ZodDefault<z.ZodArray<z.ZodString>>;
@@ -16,6 +20,7 @@ declare const configSchema: z.ZodObject<{
16
20
  otlp: "otlp";
17
21
  }>>;
18
22
  max_file_size_mb: z.ZodDefault<z.ZodNumber>;
23
+ fail_closed: z.ZodDefault<z.ZodBoolean>;
19
24
  }, z.core.$strip>>;
20
25
  rbac: z.ZodDefault<z.ZodObject<{
21
26
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -25,13 +30,31 @@ declare const configSchema: z.ZodObject<{
25
30
  admin: "admin";
26
31
  }>>;
27
32
  }, z.core.$strip>>;
33
+ pipeline: z.ZodDefault<z.ZodObject<{
34
+ require_lgtm: z.ZodDefault<z.ZodBoolean>;
35
+ }, z.core.$strip>>;
28
36
  }, z.core.$strip>;
29
37
  export type SpeckyConfig = z.infer<typeof configSchema>;
38
+ export type SpeckyProfile = SpeckyConfig["profile"];
39
+ /** Inputs that can force the profile from outside config.yml (flag > env). */
40
+ export interface ProfileOverrides {
41
+ argv?: readonly string[];
42
+ env?: Record<string, string | undefined>;
43
+ }
44
+ /**
45
+ * Resolve the active profile. Precedence: `--profile=` flag > `SPECKY_PROFILE`
46
+ * env > `SPECKY_ENTERPRISE=1` shorthand > config.yml `profile:` > standard.
47
+ * Unknown values are ignored with a stderr warning (never crash the server).
48
+ */
49
+ export declare function resolveProfile(configProfile: SpeckyProfile, overrides?: ProfileOverrides): SpeckyProfile;
30
50
  /**
31
51
  * Load `.specky/config.yml` from workspace root. Returns defaults if the file
32
52
  * is absent, unparseable, or fails validation (a bad value never crashes the
33
53
  * server — it falls back to the safe defaults, with a stderr warning).
54
+ *
55
+ * `overrides` lets the server entry point (and tests) inject argv/env for
56
+ * profile resolution instead of reading globals.
34
57
  */
35
- export declare function loadConfig(workspaceRoot: string): SpeckyConfig;
58
+ export declare function loadConfig(workspaceRoot: string, overrides?: ProfileOverrides): SpeckyConfig;
36
59
  export {};
37
60
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;iBA0BR,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAIxD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,YAAY,CAyB9D"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCR,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AACxD,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;AAIpD,8EAA8E;AAC9E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;CAC1C;AAMD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,aAAa,EAAE,aAAa,EAC5B,SAAS,GAAE,gBAAqB,GAC/B,aAAa,CAsBf;AAgCD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,SAAS,GAAE,gBAAqB,GAAG,YAAY,CAyBhG"}