11# Story 12.1: Add New Language Ecosystem (Template)
22
3- Status: backlog
3+ Status: ready-for-dev
4+
5+ <!-- Note: Validation is optional. Run validate-create-story for quality check before dev-story. -->
6+ <!-- TEMPLATE STORY: Clone this file and replace [LANGUAGE]/[language] with the target language before development. -->
47
58## Story
69
@@ -10,50 +13,191 @@ so that I get the same DevRail experience as all other supported languages.
1013
1114## Acceptance Criteria
1215
13- 1 . The dev-toolchain container includes all [ LANGUAGE] tools (linter, formatter, security scanner, test runner)
14- 2 . The Makefile supports [ LANGUAGE] with lint, format, test, security, and fix targets
15- 3 . A canonical standards document exists at ` standards/[language].md `
16- 4 . The devrail.dev site includes a [ LANGUAGE] standards page
17- 5 . Both template repos include [ LANGUAGE] pre-commit hooks (commented out)
18- 6 . ` .devrail.yml ` schema supports the new language entry
19- 7 . ` make check ` passes across all repos
20- 8 . A release is cut with the new language
16+ 1 . ** Given** the dev-toolchain container, ** When** a project declares ` [language] ` in ` .devrail.yml ` , ** Then** ` make lint ` runs the [ LANGUAGE] linter and reports results
17+ 2 . ** Given** the dev-toolchain container, ** When** a project declares ` [language] ` in ` .devrail.yml ` , ** Then** ` make format ` checks [ LANGUAGE] formatting and ` make fix ` applies fixes
18+ 3 . ** Given** the dev-toolchain container, ** When** a project declares ` [language] ` in ` .devrail.yml ` , ** Then** ` make test ` runs the [ LANGUAGE] test runner (gated on presence of test files/config)
19+ 4 . ** Given** the dev-toolchain container, ** When** a project declares ` [language] ` in ` .devrail.yml ` , ** Then** ` make security ` runs [ LANGUAGE] -specific security scanning (gated on lock file/config presence)
20+ 5 . ** Given** ` standards/[language].md ` , ** Then** it follows the consistent structure: Tools, Configuration, Makefile Targets, Pre-Commit Hooks, Notes
21+ 6 . ** Given** ` devrail-yml-schema.md ` , ** Then** ` [language] ` appears in the Allowed Values list and the Language Support Matrix
22+ 7 . ** Given** the template repos, ** Then** ` .pre-commit-config.yaml ` includes [ LANGUAGE] hooks (commented out by default)
23+ 8 . ** Given** ` devrail init --languages [language] ` , ** Then** the init script scaffolds [ LANGUAGE] config files and uncommments the pre-commit hooks
24+ 9 . ** Given** all changes merged, ** Then** ` make check ` passes on all 5 DevRail repos (dev-toolchain, development-standards, github-repo-template, gitlab-repo-template, devrail.dev)
25+ 10 . ** Given** all changes merged to dev-toolchain, ** Then** a new semver release is tagged and the container image is published to GHCR
2126
2227## Tasks / Subtasks
2328
24- - [ ] Task 1: Create install script (` dev-toolchain/scripts/install-[language].sh ` )
25- - [ ] Task 2: Create test script (` dev-toolchain/tests/test-[language].sh ` )
26- - [ ] Task 3: Update Dockerfile with language dependencies and install
27- - [ ] Task 4: Update Makefile with ` HAS_[LANGUAGE] ` detection and targets
28- - [ ] Task 5: Write ` standards/[language].md `
29- - [ ] Task 6: Write ` devrail.dev/content/docs/standards/[language].md `
30- - [ ] Task 7: Update both template ` .pre-commit-config.yaml ` files
31- - [ ] Task 8: Update both template ` .devrail.yml ` files
32- - [ ] Task 9: Update ` devrail-yml-schema.md ` with new language
33- - [ ] Task 10: Update ` devrail.dev ` docs index and language matrix
34- - [ ] Task 11: Update ` STABILITY.md ` and ` README.md ` in dev-toolchain
35- - [ ] Task 12: Run ` make check ` on all repos
36- - [ ] Task 13: Cut release
29+ - [ ] Task 1: Create install script (AC: 1, 2, 3, 4)
30+ - [ ] 1.1 Create ` dev-toolchain/scripts/install-[language].sh ` following the mandatory pattern (header, set -euo pipefail, lib sourcing, --help, cleanup trap, idempotent install functions, require_cmd verification)
31+ - [ ] 1.2 Install the linter: [ LINTER] (idempotent: ` command -v [linter] ` or language-specific check before install)
32+ - [ ] 1.3 Install the formatter: [ FORMATTER] (if different from linter)
33+ - [ ] 1.4 Install the security scanner: [ SCANNER] (if language-specific, beyond trivy)
34+ - [ ] 1.5 Install the test runner: [ TEST_RUNNER] (if not built-in to the language SDK)
35+ - [ ] 1.6 Verify all tools with ` require_cmd ` at end of each install function
36+
37+ - [ ] Task 2: Create verification test script (AC: 1, 2, 3, 4)
38+ - [ ] 2.1 Create ` dev-toolchain/tests/test-[language].sh ` using ` assert_cmd ` and ` assert_version ` helpers
39+ - [ ] 2.2 Verify linter is installed and runs: ` assert_cmd [linter] `
40+ - [ ] 2.3 Verify formatter is installed and runs: ` assert_cmd [formatter] `
41+ - [ ] 2.4 Verify test runner is available: ` assert_cmd [test-runner] `
42+ - [ ] 2.5 Verify security tool is available (if language-specific)
43+
44+ - [ ] Task 3: Update Dockerfile (AC: 1, 2, 3, 4)
45+ - [ ] 3.1 Add builder stage if language requires SDK COPY (pattern: Go, Rust, Node.js, Swift)
46+ - [ ] 3.2 Add ` COPY scripts/install-[language].sh /tmp/scripts/ ` and ` RUN bash /tmp/scripts/install-[language].sh ` to runtime stage
47+ - [ ] 3.3 Add environment variables if needed (e.g., JAVA_HOME, SWIFT_PATH)
48+ - [ ] 3.4 Build container and verify: ` docker build . `
49+
50+ - [ ] Task 4: Update Makefile targets (AC: 1, 2, 3, 4)
51+ - [ ] 4.1 Add ` HAS_[LANGUAGE] := $(filter [language],$(LANGUAGES)) ` detection variable
52+ - [ ] 4.2 Add [ LANGUAGE] block to ` _lint ` target with proper error handling and fail-fast support
53+ - [ ] 4.3 Add [ LANGUAGE] block to ` _format ` target (check mode)
54+ - [ ] 4.4 Add [ LANGUAGE] block to ` _fix ` target (write mode)
55+ - [ ] 4.5 Add [ LANGUAGE] block to ` _test ` target (gated on test file/config presence)
56+ - [ ] 4.6 Add [ LANGUAGE] block to ` _security ` target (gated on lock file/config presence)
57+ - [ ] 4.7 Add [ LANGUAGE] scaffolding to ` _init ` target (create default config files)
58+ - [ ] 4.8 Sync Makefile to both template repos
59+
60+ - [ ] Task 5: Write standards document (AC: 5)
61+ - [ ] 5.1 Create ` standards/[language].md ` with sections: Tools, Configuration, Makefile Targets, Pre-Commit Hooks, Notes
62+ - [ ] 5.2 Include annotated configuration examples for each tool
63+ - [ ] 5.3 Document gating conditions (which files must exist for each tool to run)
64+
65+ - [ ] Task 6: Update schema and documentation (AC: 6)
66+ - [ ] 6.1 Add ` [language] ` to Allowed Values in ` standards/devrail-yml-schema.md `
67+ - [ ] 6.2 Add [ LANGUAGE] column to Language Support Matrix in ` devrail-yml-schema.md `
68+ - [ ] 6.3 Add ` [language] ` row to ` README.md ` standards table
69+ - [ ] 6.4 Add ` [language] ` scope to ` DEVELOPMENT.md ` conventional commits scopes
70+
71+ - [ ] Task 7: Update devrail.dev documentation site (AC: 6)
72+ - [ ] 7.1 Create ` devrail.dev/content/docs/standards/[language].md ` with Hugo/Docsy front matter
73+ - [ ] 7.2 Update ` devrail.dev/content/docs/standards/_index.md ` (matrix, target mapping, per-language links)
74+
75+ - [ ] Task 8: Configure pre-commit hooks (AC: 7)
76+ - [ ] 8.1 Find appropriate community pre-commit hooks for [ LANGUAGE] (linter + formatter)
77+ - [ ] 8.2 Add hooks to both template repos' ` .pre-commit-config.yaml ` (commented out by default)
78+ - [ ] 8.3 Pin hook versions explicitly
79+
80+ - [ ] Task 9: Update devrail init (AC: 8)
81+ - [ ] 9.1 Add [ LANGUAGE] to the language validation list in ` devrail-init.sh `
82+ - [ ] 9.2 Add [ LANGUAGE] config file scaffolding
83+ - [ ] 9.3 Add [ LANGUAGE] pre-commit hook uncommenting logic
84+
85+ - [ ] Task 10: Update conventional commit scopes (AC: 9)
86+ - [ ] 10.1 Add ` [language] ` to the pre-commit-conventional-commits hook's valid scopes
87+ - [ ] 10.2 Tag a new version of the hook
88+ - [ ] 10.3 Update hook version in all repos' ` .pre-commit-config.yaml `
89+
90+ - [ ] Task 11: Validate across all repos (AC: 9)
91+ - [ ] 11.1 Run ` make check ` on dev-toolchain
92+ - [ ] 11.2 Run ` make check ` on development-standards
93+ - [ ] 11.3 Run ` make check ` on github-repo-template
94+ - [ ] 11.4 Run ` make check ` on gitlab-repo-template
95+ - [ ] 11.5 Run ` make check ` on devrail.dev
96+
97+ - [ ] Task 12: Cut release (AC: 10)
98+ - [ ] 12.1 Update ` STABILITY.md ` in dev-toolchain
99+ - [ ] 12.2 Run ` make release VERSION=X.Y.0 `
100+ - [ ] 12.3 Verify GHCR image published
101+ - [ ] 12.4 Verify floating ` v1 ` tag updated
37102
38103## Dev Notes
39104
40- - This is a ** template story** — clone and customize for each new language (Elixir, Java, C#, etc.)
41- - Follow the complete checklist in ` standards/contributing.md ` and the "Adding a New Language" section in MEMORY.md
42- - Pattern: COPY SDK from official image in builder stage → install-[ language] .sh verifies (Go, Rust) or installs (Ruby, JS)
43- - Pre-commit hooks: find appropriate community hooks or use local hooks
44- - The conventional-commits hook (v1.1.0) already accepts all current language scopes — new languages need a scope added
105+ ** This is a TEMPLATE STORY.** To use it:
106+ 1 . Clone this file as ` 12-N-add-[language]-language-ecosystem.md `
107+ 2 . Replace all ` [LANGUAGE] ` with the language name (title case) and ` [language] ` with the identifier (lowercase)
108+ 3 . Replace ` [LINTER] ` , ` [FORMATTER] ` , ` [SCANNER] ` , ` [TEST_RUNNER] ` with actual tool names
109+ 4 . Adjust tasks based on the language's specific tooling needs
110+
111+ ### Architecture Patterns to Follow
112+
113+ ** Container Strategy (choose one based on language):**
114+ - ** SDK COPY pattern** (Go, Rust, Node.js, Swift): Multi-stage build, COPY SDK from official slim image to runtime stage. install-[ language] .sh is verify-only.
115+ - ** Package manager install pattern** (Ruby, JavaScript): Runtime install via gem/npm. install-[ language] .sh runs ` gem install ` or ` npm install -g ` .
116+ - ** System package pattern** (Python, Bash): Install via apt or pip. install-[ language] .sh runs apt-get/pip install.
117+
118+ ** Makefile Target Pattern:**
119+ ``` makefile
120+ # Detection variable
121+ HAS_[LANGUAGE] := $(filter [language],$(LANGUAGES ) )
122+
123+ # Inside each target (_lint, _format, _fix, _test, _security):
124+ if [ -n "$(HAS_[LANGUAGE])" ]; then \
125+ ran_languages ="$${ran_languages}\"[language]\","; \
126+ [command] || { overall_exit=1; failed_languages="$${failed_languages}\"[language]\","; }; \
127+ if [ "$(DEVRAIL_FAIL_FAST ) " = "1" ] && [ $$overall_exit -ne 0 ]; then \
128+ # ... fail-fast JSON output ... \
129+ exit $$overall_exit; \
130+ fi; \
131+ fi;
132+ `` `
133+
134+ ** Gating Conditions (common patterns):**
135+ - Lint/Format: gate on ` *.[ext]` files existing
136+ - Test: gate on test files AND config file (e.g., ` Package.swift` , ` build.gradle.kts` , ` Cargo.toml` )
137+ - Security: gate on lock/dependency file (e.g., ` Package.resolved` , ` Cargo.lock` , ` go.sum` , ` package-lock.json` )
138+
139+ ** Install Script Mandatory Structure:**
140+ ` `` bash
141+ # !/usr/bin/env bash
142+ # scripts/install-[language].sh -- Install [LANGUAGE] tooling for DevRail
143+ set -euo pipefail
144+ SCRIPT_DIR ="$(cd "$(dirname "${BASH_SOURCE[0]}" ) " && pwd ) "
145+ DEVRAIL_LIB ="${DEVRAIL_LIB:-${SCRIPT_DIR}/../lib}"
146+ source "${DEVRAIL_LIB}/log.sh"
147+ source "${DEVRAIL_LIB}/platform.sh"
148+ # --help flag, cleanup trap, idempotent install functions, require_cmd verification
149+ ```
150+
151+ ### Multi-Repo PR Strategy
152+
153+ Submit PRs in this order (dependency chain):
154+ 1 . ** pre-commit-conventional-commits** -- add ` [language] ` scope, tag new version
155+ 2 . ** dev-toolchain** -- install script + Dockerfile + Makefile + tests + release
156+ 3 . ** development-standards** -- standards doc + schema update
157+ 4 . ** github-repo-template** -- pre-commit hooks + .devrail.yml
158+ 5 . ** gitlab-repo-template** -- pre-commit hooks + .devrail.yml
159+ 6 . ** devrail.dev** -- standards page + blog post
160+
161+ ### Previous Language Additions (Reference)
162+
163+ | Language | Container Pattern | Install Pattern | Key Gotchas |
164+ | ---| ---| ---| ---|
165+ | Ruby | System Ruby 3.1 | ` gem install ` | bookworm ships 3.1 not 3.4; reek version pinning |
166+ | Go | COPY from ` golang ` image | verify-only | SDK needed at runtime for govulncheck |
167+ | JavaScript | COPY from ` node:22-bookworm-slim ` | ` npm install -g ` | manual npm/npx symlinks needed |
168+ | Rust | COPY from ` rust:1-slim-bookworm ` | verify-only | no curl in base; clippy/rustfmt need rustup component add |
169+ | Swift | COPY from ` swift:6.1-slim-bookworm ` | verify-only (planned) | xcodebuild macOS-only; SPM-first |
170+ | Kotlin | COPY JDK from ` eclipse-temurin:21-jdk ` | binary downloads | Android Lint needs Android SDK (CI-only) |
45171
46172### References
47173
48- - [ Source: standards/contributing.md] — full checklist for adding a language
49- - [ Source: MEMORY.md → Adding a New Language — Checklist] — file-level checklist
174+ - [ Source: standards/contributing.md] -- authoritative 8-step checklist with code examples
175+ - [ Source: MEMORY.md -> Adding a New Language -- Checklist] -- file-level checklist
176+ - [ Source: dev-toolchain/scripts/install-rust.sh] -- verify-only install pattern
177+ - [ Source: dev-toolchain/scripts/install-ruby.sh] -- gem install pattern
178+ - [ Source: dev-toolchain/scripts/install-javascript.sh] -- npm install pattern
179+ - [ Source: standards/rust.md] -- most recent language standards doc format
180+ - [ Source: devrail.dev/content/docs/standards/go.md] -- Hugo page format
50181
51182## Dev Agent Record
52183
53184### Agent Model Used
54185
186+ Claude Opus 4.6
187+
55188### Debug Log References
56189
190+ - Analyzed all 10 existing language ecosystems for pattern extraction
191+ - Cross-referenced standards/contributing.md 8-step checklist
192+ - Extracted architecture constraints from architecture.md
193+ - Compiled previous language addition gotchas from MEMORY.md
194+
57195### Completion Notes List
58196
197+ - Story enhanced from skeleton template to comprehensive dev agent guide
198+ - Includes concrete code patterns for Makefile targets, install scripts, and gating conditions
199+ - Previous language addition reference table prevents known gotchas
200+ - Multi-repo PR strategy documents dependency chain
201+ - All 12 tasks decomposed into atomic subtasks with AC traceability
202+
59203### File List
0 commit comments