elspais 0.9.1__tar.gz → 0.9.3__tar.gz
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.
- {elspais-0.9.1 → elspais-0.9.3}/CHANGELOG.md +25 -0
- {elspais-0.9.1 → elspais-0.9.3}/PKG-INFO +52 -15
- {elspais-0.9.1 → elspais-0.9.3}/README.md +47 -9
- elspais-0.9.3/docs/roadmap/llm-reformatting-integration.md +113 -0
- elspais-0.9.3/docs/roadmap/new-format.md +193 -0
- elspais-0.9.3/docs/roadmap/plantuml-diagram-support.md +90 -0
- elspais-0.9.3/docs/roadmap/requirements-format-enhancements.md +160 -0
- {elspais-0.9.1 → elspais-0.9.3}/docs/rules.md +18 -0
- {elspais-0.9.1 → elspais-0.9.3}/pyproject.toml +1 -7
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/cli.py +25 -1
- elspais-0.9.3/src/elspais/commands/changed.py +160 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/validate.py +37 -2
- elspais-0.9.3/src/elspais/core/git.py +352 -0
- elspais-0.9.3/tests/test_git.py +292 -0
- {elspais-0.9.1 → elspais-0.9.3}/.gitignore +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/LICENSE +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/docs/configuration.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/docs/multi-repo.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/docs/patterns.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/__main__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/analyze.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/config_cmd.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/edit.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/hash_cmd.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/index.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/init.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/rules_cmd.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/commands/trace.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/config/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/config/defaults.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/config/loader.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/core/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/core/content_rules.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/core/hasher.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/core/models.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/core/parser.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/core/patterns.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/core/rules.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/mcp/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/mcp/__main__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/mcp/context.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/mcp/serializers.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/mcp/server.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/testing/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/testing/config.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/testing/mapper.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/testing/result_parser.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/src/elspais/testing/scanner.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/conftest.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/assertions/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/assertions/spec/dev-impl.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/assertions/spec/prd-sample.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/associated-repo/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/associated-repo/spec/dev-sponsor.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/associated-repo/spec/prd-sponsor.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/fda-style/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/fda-style/spec/dev-impl.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/fda-style/spec/prd-core.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/hht-like/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/hht-like/database/schema.sql +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/hht-like/spec/INDEX.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/hht-like/spec/dev-impl.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/hht-like/spec/ops-deploy.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/hht-like/spec/prd-core.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/invalid/broken-links/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/invalid/broken-links/spec/broken.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/invalid/circular-deps/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/invalid/circular-deps/spec/circular.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/invalid/missing-hash/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/invalid/missing-hash/spec/missing.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/jira-style/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/jira-style/requirements/features.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/named-reqs/.elspais.toml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/fixtures/named-reqs/spec/features.md +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/mcp/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/mcp/test_context.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/mcp/test_serializers.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_config.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_content_rules.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_doc_sync.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_edit.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_hash_bugs.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_hasher.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_models.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_parser.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_parser_resilience.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_patterns.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_rules.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/test_validate_json.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/__init__.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/fixtures/junit_results.xml +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/fixtures/pytest_results.json +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/fixtures/sample_test.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/test_config.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/test_mapper.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/test_result_parser.py +0 -0
- {elspais-0.9.1 → elspais-0.9.3}/tests/testing/test_scanner.py +0 -0
|
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.9.3] - 2026-01-05
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Git-based change detection with new `changed` command
|
|
14
|
+
- `elspais changed`: Show uncommitted changes to spec files
|
|
15
|
+
- `elspais changed --json`: JSON output for programmatic use
|
|
16
|
+
- `elspais changed --all`: Include all changed files, not just spec/
|
|
17
|
+
- `elspais changed --base-branch`: Compare vs different branch
|
|
18
|
+
- New `src/elspais/core/git.py` module with functions:
|
|
19
|
+
- `get_git_changes()`: Main entry point for git change detection
|
|
20
|
+
- `get_modified_files()`: Detect modified/untracked files via git status
|
|
21
|
+
- `get_changed_vs_branch()`: Files changed vs main/master branch
|
|
22
|
+
- `detect_moved_requirements()`: Detect requirements moved between files
|
|
23
|
+
- 23 new tests for git functionality
|
|
24
|
+
|
|
25
|
+
## [0.9.2] - 2026-01-05
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- `id.duplicate` rule documentation in `docs/rules.md`
|
|
29
|
+
- Dynamic version detection using `importlib.metadata`
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
- Enhanced ParseResult API documentation in CLAUDE.md to explain warning handling
|
|
33
|
+
- Updated CLAUDE.md with git.py module description
|
|
34
|
+
|
|
10
35
|
## [0.9.1] - 2026-01-03
|
|
11
36
|
|
|
12
37
|
### Changed
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: elspais
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.3
|
|
4
4
|
Summary: Requirements validation and traceability tools - L-Space connects all libraries
|
|
5
|
-
|
|
6
|
-
Author: Anspar
|
|
7
|
-
Author-email: dev@anspar.io
|
|
8
|
-
License: MIT
|
|
5
|
+
Project-URL: Homepage, https://github.com/anspar/elspais
|
|
9
6
|
Project-URL: Documentation, https://github.com/anspar/elspais#readme
|
|
10
7
|
Project-URL: Repository, https://github.com/anspar/elspais
|
|
11
8
|
Project-URL: Issues, https://github.com/anspar/elspais/issues
|
|
12
9
|
Project-URL: Changelog, https://github.com/anspar/elspais/blob/main/CHANGELOG.md
|
|
10
|
+
Author-email: Anspar <dev@anspar.io>
|
|
11
|
+
License-File: LICENSE
|
|
13
12
|
Keywords: documentation,requirements,specifications,traceability,validation
|
|
14
13
|
Classifier: Development Status :: 4 - Beta
|
|
15
14
|
Classifier: Environment :: Console
|
|
@@ -57,18 +56,50 @@ Description-Content-Type: text/markdown
|
|
|
57
56
|
|
|
58
57
|
## Installation
|
|
59
58
|
|
|
59
|
+
### For End Users
|
|
60
|
+
|
|
60
61
|
```bash
|
|
62
|
+
# Standard installation
|
|
61
63
|
pip install elspais
|
|
64
|
+
|
|
65
|
+
# Recommended for CLI tools: Isolated installation
|
|
66
|
+
pipx install elspais
|
|
62
67
|
```
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
### For Development
|
|
65
70
|
|
|
66
71
|
```bash
|
|
67
72
|
git clone https://github.com/anspar/elspais.git
|
|
68
73
|
cd elspais
|
|
69
|
-
pip install -e .
|
|
74
|
+
pip install -e ".[dev]"
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### For Docker and CI/CD
|
|
78
|
+
|
|
79
|
+
For faster installation in containerized environments, consider [uv](https://github.com/astral-sh/uv):
|
|
80
|
+
|
|
81
|
+
```dockerfile
|
|
82
|
+
# Example Dockerfile
|
|
83
|
+
FROM python:3.11-slim
|
|
84
|
+
|
|
85
|
+
# Copy uv binary
|
|
86
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
87
|
+
|
|
88
|
+
# Install elspais (10-100x faster than pip)
|
|
89
|
+
RUN uv pip install --system --no-cache elspais==0.9.1
|
|
70
90
|
```
|
|
71
91
|
|
|
92
|
+
```yaml
|
|
93
|
+
# Example GitHub Actions
|
|
94
|
+
- name: Install uv
|
|
95
|
+
uses: astral-sh/setup-uv@v2
|
|
96
|
+
|
|
97
|
+
- name: Install elspais
|
|
98
|
+
run: uv pip install --system elspais==0.9.1
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Note:** For regulated/medical software projects, always pin the exact version for reproducibility.
|
|
102
|
+
|
|
72
103
|
## Quick Start
|
|
73
104
|
|
|
74
105
|
### Initialize a Repository
|
|
@@ -185,22 +216,28 @@ See [docs/configuration.md](docs/configuration.md) for full reference.
|
|
|
185
216
|
elspais expects requirements in Markdown format:
|
|
186
217
|
|
|
187
218
|
```markdown
|
|
188
|
-
|
|
219
|
+
# REQ-d00001: Requirement Title
|
|
189
220
|
|
|
190
|
-
**Level**: Dev | **
|
|
221
|
+
**Level**: Dev | **Status**: Active | **Implements**: REQ-p00001
|
|
191
222
|
|
|
192
|
-
|
|
223
|
+
## Assertions
|
|
193
224
|
|
|
194
|
-
|
|
225
|
+
A. The system SHALL provide user authentication via email/password.
|
|
226
|
+
B. Sessions SHALL expire after 30 minutes of inactivity.
|
|
195
227
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
228
|
+
## Rationale
|
|
229
|
+
|
|
230
|
+
Security requires identity verification.
|
|
199
231
|
|
|
200
232
|
*End* *Requirement Title* | **Hash**: a1b2c3d4
|
|
201
233
|
---
|
|
202
234
|
```
|
|
203
235
|
|
|
236
|
+
Key format elements:
|
|
237
|
+
- **Assertions section**: Labeled A-Z, each using SHALL for normative statements
|
|
238
|
+
- **One-way traceability**: Children reference parents via `Implements:`
|
|
239
|
+
- **Hash footer**: SHA-256 hash for change detection
|
|
240
|
+
|
|
204
241
|
## ID Pattern Examples
|
|
205
242
|
|
|
206
243
|
elspais supports multiple ID formats:
|
|
@@ -18,18 +18,50 @@
|
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
|
+
### For End Users
|
|
22
|
+
|
|
21
23
|
```bash
|
|
24
|
+
# Standard installation
|
|
22
25
|
pip install elspais
|
|
26
|
+
|
|
27
|
+
# Recommended for CLI tools: Isolated installation
|
|
28
|
+
pipx install elspais
|
|
23
29
|
```
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
### For Development
|
|
26
32
|
|
|
27
33
|
```bash
|
|
28
34
|
git clone https://github.com/anspar/elspais.git
|
|
29
35
|
cd elspais
|
|
30
|
-
pip install -e .
|
|
36
|
+
pip install -e ".[dev]"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### For Docker and CI/CD
|
|
40
|
+
|
|
41
|
+
For faster installation in containerized environments, consider [uv](https://github.com/astral-sh/uv):
|
|
42
|
+
|
|
43
|
+
```dockerfile
|
|
44
|
+
# Example Dockerfile
|
|
45
|
+
FROM python:3.11-slim
|
|
46
|
+
|
|
47
|
+
# Copy uv binary
|
|
48
|
+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv
|
|
49
|
+
|
|
50
|
+
# Install elspais (10-100x faster than pip)
|
|
51
|
+
RUN uv pip install --system --no-cache elspais==0.9.1
|
|
31
52
|
```
|
|
32
53
|
|
|
54
|
+
```yaml
|
|
55
|
+
# Example GitHub Actions
|
|
56
|
+
- name: Install uv
|
|
57
|
+
uses: astral-sh/setup-uv@v2
|
|
58
|
+
|
|
59
|
+
- name: Install elspais
|
|
60
|
+
run: uv pip install --system elspais==0.9.1
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Note:** For regulated/medical software projects, always pin the exact version for reproducibility.
|
|
64
|
+
|
|
33
65
|
## Quick Start
|
|
34
66
|
|
|
35
67
|
### Initialize a Repository
|
|
@@ -146,22 +178,28 @@ See [docs/configuration.md](docs/configuration.md) for full reference.
|
|
|
146
178
|
elspais expects requirements in Markdown format:
|
|
147
179
|
|
|
148
180
|
```markdown
|
|
149
|
-
|
|
181
|
+
# REQ-d00001: Requirement Title
|
|
150
182
|
|
|
151
|
-
**Level**: Dev | **
|
|
183
|
+
**Level**: Dev | **Status**: Active | **Implements**: REQ-p00001
|
|
152
184
|
|
|
153
|
-
|
|
185
|
+
## Assertions
|
|
154
186
|
|
|
155
|
-
|
|
187
|
+
A. The system SHALL provide user authentication via email/password.
|
|
188
|
+
B. Sessions SHALL expire after 30 minutes of inactivity.
|
|
156
189
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
190
|
+
## Rationale
|
|
191
|
+
|
|
192
|
+
Security requires identity verification.
|
|
160
193
|
|
|
161
194
|
*End* *Requirement Title* | **Hash**: a1b2c3d4
|
|
162
195
|
---
|
|
163
196
|
```
|
|
164
197
|
|
|
198
|
+
Key format elements:
|
|
199
|
+
- **Assertions section**: Labeled A-Z, each using SHALL for normative statements
|
|
200
|
+
- **One-way traceability**: Children reference parents via `Implements:`
|
|
201
|
+
- **Hash footer**: SHA-256 hash for change detection
|
|
202
|
+
|
|
165
203
|
## ID Pattern Examples
|
|
166
204
|
|
|
167
205
|
elspais supports multiple ID formats:
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# LLM-Assisted Reformatting Integration
|
|
2
|
+
|
|
3
|
+
**Parent**: [requirements-format-enhancements.md](./requirements-format-enhancements.md)
|
|
4
|
+
**Date**: 2026-01-04
|
|
5
|
+
**Ticket**: CUR-514
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Decision
|
|
10
|
+
|
|
11
|
+
Integrate reformatting capability into elspais with custom handler fallback.
|
|
12
|
+
|
|
13
|
+
## Problem
|
|
14
|
+
|
|
15
|
+
The `reformat_reqs` tool currently requires Claude Code. Users may want to use different LLMs or traditional scripts.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Solution Architecture
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
elspais reformat REQ-p00043
|
|
23
|
+
│
|
|
24
|
+
├── Claude Code available? → Use built-in Claude integration
|
|
25
|
+
│
|
|
26
|
+
└── Not available? → Check for custom handler
|
|
27
|
+
│
|
|
28
|
+
├── Handler configured? → Load and execute
|
|
29
|
+
│
|
|
30
|
+
└── Not configured? → Emit helpful error with options
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
```toml
|
|
38
|
+
# .elspais.toml
|
|
39
|
+
[reformat]
|
|
40
|
+
# Default: use Claude Code if available
|
|
41
|
+
# Custom: provide path to Python module with handler function
|
|
42
|
+
handler = "tools/custom_reformatter.py:reformat_requirement"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Custom Handler Interface
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
# tools/custom_reformatter.py
|
|
51
|
+
def reformat_requirement(
|
|
52
|
+
req_id: str,
|
|
53
|
+
title: str,
|
|
54
|
+
body: str,
|
|
55
|
+
rationale: str | None
|
|
56
|
+
) -> dict:
|
|
57
|
+
"""
|
|
58
|
+
Transform requirement content to assertion-based format.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
req_id: Requirement ID (e.g., "REQ-p00043")
|
|
62
|
+
title: Requirement title
|
|
63
|
+
body: Current requirement body text
|
|
64
|
+
rationale: Existing rationale if present
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
{
|
|
68
|
+
"rationale": str, # New or refined rationale
|
|
69
|
+
"assertions": list[str] # List of assertion statements
|
|
70
|
+
}
|
|
71
|
+
"""
|
|
72
|
+
# Implementation using any method:
|
|
73
|
+
# - Different LLM API (OpenAI, local model, etc.)
|
|
74
|
+
# - Rule-based transformation
|
|
75
|
+
# - Template-based approach
|
|
76
|
+
pass
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Error Message When No Handler
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
Error: Claude Code not configured and no custom handler specified.
|
|
85
|
+
|
|
86
|
+
To use LLM-assisted reformatting, either:
|
|
87
|
+
1. Configure Claude Code (see: https://claude.ai/code)
|
|
88
|
+
2. Provide a custom handler in .elspais.toml:
|
|
89
|
+
|
|
90
|
+
[reformat]
|
|
91
|
+
handler = "path/to/handler.py:function_name"
|
|
92
|
+
|
|
93
|
+
The handler function should accept (req_id, title, body, rationale)
|
|
94
|
+
and return {"rationale": str, "assertions": list[str]}
|
|
95
|
+
|
|
96
|
+
See: docs/elspais-custom-handlers.md for examples.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Implementation Phase
|
|
102
|
+
|
|
103
|
+
**Phase 4** (8-16 hours):
|
|
104
|
+
|
|
105
|
+
1. Integrate reformat_reqs functionality into elspais
|
|
106
|
+
2. Add custom handler fallback mechanism
|
|
107
|
+
3. Implement helpful error messages
|
|
108
|
+
4. Document custom handler interface
|
|
109
|
+
|
|
110
|
+
**Deliverables**:
|
|
111
|
+
- `elspais reformat` command
|
|
112
|
+
- Custom handler documentation
|
|
113
|
+
- Example handlers (OpenAI, rule-based)
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# ADR-010: Requirements Format Enhancements
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-01-04
|
|
4
|
+
**Deciders**: Development Team
|
|
5
|
+
**Compliance**: FDA 21 CFR Part 11, Requirement Traceability
|
|
6
|
+
|
|
7
|
+
## Status
|
|
8
|
+
|
|
9
|
+
Accepted
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Context
|
|
14
|
+
|
|
15
|
+
The current assertion-based requirements format provides strong foundations:
|
|
16
|
+
- Clear separation between normative (Assertions) and informative (Rationale) content
|
|
17
|
+
- Labeled assertions (A, B, C...) enable precise traceability
|
|
18
|
+
- SHALL-based prescriptive language enforces testability
|
|
19
|
+
- Hash-based change detection provides tamper-evidence
|
|
20
|
+
- Three-tier hierarchy: PRD → OPS → DEV with `Implements:` references
|
|
21
|
+
|
|
22
|
+
However, gaps exist:
|
|
23
|
+
- **Cross-Cutting Concerns**: Security, compliance, multi-sponsor requirements scattered across files with no matrix view to see how functions span components
|
|
24
|
+
- **Verification Tracking**: No explicit field indicating how a requirement is validated; mix of testable requirements and declared axioms without distinction
|
|
25
|
+
|
|
26
|
+
Industry standards (IEEE 29148, EARS, INCOSE, Planguage, IEC 62304) were evaluated for potential enhancements.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Decision
|
|
31
|
+
|
|
32
|
+
### 1. Add Type Field
|
|
33
|
+
|
|
34
|
+
Categorize requirements as artifacts (things) or functions (capabilities) to enable matrix views.
|
|
35
|
+
|
|
36
|
+
**Four Semantic Categories** (2 current, 2 reserved):
|
|
37
|
+
|
|
38
|
+
| Category | Status | Description | Allowed Synonyms |
|
|
39
|
+
|----------|--------|-------------|------------------|
|
|
40
|
+
| **Artifact** | Current | Instantiated, concrete things | `system`, `component`, `application`, `module`, `service` |
|
|
41
|
+
| **Function** | Current | Capabilities, characteristics | `feature`, `characteristic`, `capability`, `restriction`, `standard`, `regulation` |
|
|
42
|
+
| **Interface** | Reserved | Abstract definitions, not instantiated | TBD |
|
|
43
|
+
| **Constraint** | Reserved | Parameters separated from process | TBD |
|
|
44
|
+
|
|
45
|
+
**Matrix View Enabled**:
|
|
46
|
+
- Rows: Artifact-type requirements (system, component, ...)
|
|
47
|
+
- Columns: Function-type requirements (feature, regulation, ...)
|
|
48
|
+
- Cells: Child requirements that implement both an artifact AND a function
|
|
49
|
+
|
|
50
|
+
### 2. Add Validation Field (Optional)
|
|
51
|
+
|
|
52
|
+
Distinguish between testable requirements and declared axioms.
|
|
53
|
+
|
|
54
|
+
| Canonical | Synonyms | Status | Description |
|
|
55
|
+
|-----------|----------|--------|-------------|
|
|
56
|
+
| `test` | `tested`, `testing` | Current | Verified through automated or manual testing |
|
|
57
|
+
| `inspect` | `inspected`, `inspection` | Current | Verified through document/code review |
|
|
58
|
+
| `analysis` | - | Reserved | Verified through static analysis, modeling |
|
|
59
|
+
| `demonstration` | - | Reserved | Verified through proof-of-concept |
|
|
60
|
+
|
|
61
|
+
**Default**: If validation is omitted, defaults to `test`. Most requirements are testable.
|
|
62
|
+
|
|
63
|
+
### 3. Updated Header Format
|
|
64
|
+
|
|
65
|
+
**Current Format**:
|
|
66
|
+
```markdown
|
|
67
|
+
# REQ-p00043: Clinical Diary Mobile Application
|
|
68
|
+
|
|
69
|
+
**Level**: PRD | **Status**: Draft | **Implements**: p00044
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**New Format**:
|
|
73
|
+
```markdown
|
|
74
|
+
# REQ-p00043: Clinical Diary Mobile Application
|
|
75
|
+
**PRD** component - Draft
|
|
76
|
+
**Implements**: p00044
|
|
77
|
+
## end Clinical Diary Mobile Application
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Format Specification**:
|
|
81
|
+
- Line 1: `# REQ-{id}: {title}`
|
|
82
|
+
- Line 2: `**{LEVEL}** {type} [({validation})] - {status}`
|
|
83
|
+
- `{validation}` is optional; defaults to `test` if omitted
|
|
84
|
+
- Use `(inspect)` for declarations/definitions verified by review
|
|
85
|
+
- Line 3: `**Implements**: {parent_ids}` (only if has parents)
|
|
86
|
+
- End: `## end {title}`
|
|
87
|
+
|
|
88
|
+
### 4. Bidirectional Traceability via Tooling
|
|
89
|
+
|
|
90
|
+
Two-way links in files are error-prone and create maintenance burden. Software can derive bidirectional views from one-way data.
|
|
91
|
+
|
|
92
|
+
- Files maintain one-way `Implements:` references (current approach)
|
|
93
|
+
- elspais generates reverse lookup tables at runtime
|
|
94
|
+
- Traceability views show both directions without file redundancy
|
|
95
|
+
|
|
96
|
+
### 5. Rejected Enhancements
|
|
97
|
+
|
|
98
|
+
| Enhancement | Decision | Rationale |
|
|
99
|
+
|-------------|----------|-----------|
|
|
100
|
+
| **Tags** | Omit | Type field handles cross-cutting via multi-parent Implements |
|
|
101
|
+
| **Priority** | Omit | All spec'd requirements are necessary; no decision value |
|
|
102
|
+
| **Risk** | Omit | Belongs in ADRs, applies to decisions not requirements |
|
|
103
|
+
| **EARS syntax** | Omit | Limited value; natural writing produces these patterns |
|
|
104
|
+
| **Planguage** | Omit | Verbosity harms readability |
|
|
105
|
+
| **Owner field** | Omit | Tracked in tickets/project management |
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Consequences
|
|
110
|
+
|
|
111
|
+
### Positive
|
|
112
|
+
- Matrix views enable cross-cutting concern visualization
|
|
113
|
+
- Validation field distinguishes testable from declared requirements
|
|
114
|
+
- Compact header format improves readability
|
|
115
|
+
- No file redundancy from bidirectional links
|
|
116
|
+
- Synonym support allows natural writing while enabling tooling
|
|
117
|
+
|
|
118
|
+
### Negative
|
|
119
|
+
- Existing requirements need backfilling with Type and Validation
|
|
120
|
+
- elspais tooling requires updates
|
|
121
|
+
|
|
122
|
+
### Neutral
|
|
123
|
+
- Reserved categories (Interface, Constraint) available for future needs
|
|
124
|
+
- Risk assessment continues to belong in ADRs
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## elspais Configuration
|
|
129
|
+
|
|
130
|
+
```toml
|
|
131
|
+
# .elspais.toml
|
|
132
|
+
|
|
133
|
+
[metadata]
|
|
134
|
+
enabled = true
|
|
135
|
+
|
|
136
|
+
[metadata.type]
|
|
137
|
+
required = true
|
|
138
|
+
categories = ["artifact", "function", "interface", "constraint"]
|
|
139
|
+
artifact_synonyms = ["system", "component", "application", "module", "service"]
|
|
140
|
+
function_synonyms = ["feature", "characteristic", "capability", "restriction", "standard", "regulation"]
|
|
141
|
+
reserved_categories = ["interface", "constraint"]
|
|
142
|
+
|
|
143
|
+
[metadata.validation]
|
|
144
|
+
required = false
|
|
145
|
+
methods = ["test", "inspect", "analyze", "demonstrate"]
|
|
146
|
+
default = "test"
|
|
147
|
+
test_synonyms = ["test", "tested", "testing"]
|
|
148
|
+
inspect_synonyms = ["inspect", "inspected", "inspection"]
|
|
149
|
+
reserved_methods = ["analysis", "demonstration"]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Matrix View Generation
|
|
155
|
+
|
|
156
|
+
**Command**:
|
|
157
|
+
```bash
|
|
158
|
+
elspais matrix --format html > reports/requirement-matrix.html
|
|
159
|
+
elspais matrix --format csv > reports/requirement-matrix.csv
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Generated Matrix**:
|
|
163
|
+
|
|
164
|
+
| Artifact ↓ / Function → | Encryption | Audit Trail | Multi-Sponsor | Offline Sync |
|
|
165
|
+
|-------------------------|------------|-------------|---------------|--------------|
|
|
166
|
+
| **Diary App (p00043)** | p01070 | p01071 | p00008 | p00006 |
|
|
167
|
+
| **Web App (p01042)** | p01072 | p01073 | p00008 | - |
|
|
168
|
+
| **Portal (p00045)** | p01074 | p01075 | p00009 | - |
|
|
169
|
+
| **Database (p00046)** | p01076 | p00004 | p00003 | - |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Related Documents
|
|
174
|
+
|
|
175
|
+
- [PlantUML Diagram Support](../research/plantuml-diagram-support.md)
|
|
176
|
+
- [LLM Reformatting Integration](../research/llm-reformatting-integration.md)
|
|
177
|
+
- [Implementation Roadmap](https://github.com/elspais/docs/roadmap/requirements-format-enhancements.md)
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## References
|
|
182
|
+
|
|
183
|
+
### Industry Standards
|
|
184
|
+
- [IEEE SA - ISO/IEC/IEEE 29148-2018](https://standards.ieee.org/standard/29148-2018.html)
|
|
185
|
+
- [INCOSE Guide to Writing Requirements](https://www.incose.org/docs/default-source/working-groups/requirements-wg/rwg_products/incose_rwg_gtwr_summary_sheet_2022.pdf)
|
|
186
|
+
|
|
187
|
+
### Diagram Tools
|
|
188
|
+
- [PlantUML](https://plantuml.com/)
|
|
189
|
+
- [C4 Model with PlantUML](https://c4model.com/)
|
|
190
|
+
|
|
191
|
+
### Risk Management (for ADR context)
|
|
192
|
+
- [ISO 14971 - Medical Device Risk Management](https://www.iso.org/standard/72704.html)
|
|
193
|
+
- [FMEA Handbook](https://www.aiag.org/quality/automotive-core-tools/fmea)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# PlantUML Diagram Support
|
|
2
|
+
|
|
3
|
+
**Parent**: [requirements-format-enhancements.md](./requirements-format-enhancements.md)
|
|
4
|
+
**Date**: 2026-01-04
|
|
5
|
+
**Ticket**: CUR-514
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Decision
|
|
10
|
+
|
|
11
|
+
Implement PlantUML generation and potentially parsing.
|
|
12
|
+
|
|
13
|
+
## Rationale
|
|
14
|
+
|
|
15
|
+
- **Text-based**: version-controllable, diff-friendly
|
|
16
|
+
- **Widely supported**: renders in GitHub, IDEs, CI/CD
|
|
17
|
+
- **Linkable**: can annotate with requirement references
|
|
18
|
+
- **Infrastructure integration**: can map to/from Terraform IaC files
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Use Cases
|
|
23
|
+
|
|
24
|
+
1. **Generate from requirements**: `elspais diagram --format plantuml`
|
|
25
|
+
2. **Parse diagrams**: Extract requirement references from annotated diagrams
|
|
26
|
+
3. **Cross-reference**: Link diagrams to requirements, operations manuals
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Example Output
|
|
31
|
+
|
|
32
|
+
```plantuml
|
|
33
|
+
@startuml
|
|
34
|
+
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml
|
|
35
|
+
|
|
36
|
+
title Clinical Diary Platform - Requirement Hierarchy
|
|
37
|
+
|
|
38
|
+
package "Platform (REQ-p00044)" {
|
|
39
|
+
[Diary App\nREQ-p00043] as diary
|
|
40
|
+
[Web App\nREQ-p01042] as web
|
|
41
|
+
[Portal\nREQ-p00045] as portal
|
|
42
|
+
[Database\nREQ-p00046] as db
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
package "Cross-Cutting Functions" {
|
|
46
|
+
[Encryption\nREQ-p01009] as encrypt
|
|
47
|
+
[Audit Trail\nREQ-p00004] as audit
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
diary --> encrypt : implements
|
|
51
|
+
web --> encrypt : implements
|
|
52
|
+
portal --> audit : implements
|
|
53
|
+
db --> audit : implements
|
|
54
|
+
@enduml
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## elspais Configuration
|
|
60
|
+
|
|
61
|
+
```toml
|
|
62
|
+
# .elspais.toml
|
|
63
|
+
|
|
64
|
+
[diagram]
|
|
65
|
+
format = "plantuml"
|
|
66
|
+
output_dir = "docs/diagrams"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Implementation Phase
|
|
72
|
+
|
|
73
|
+
**Phase 3** (16-24 hours):
|
|
74
|
+
|
|
75
|
+
1. Implement `elspais diagram` command
|
|
76
|
+
2. Generate PlantUML from requirement hierarchy
|
|
77
|
+
3. Include Type-based coloring/grouping
|
|
78
|
+
4. Optionally parse PlantUML annotations back to requirements
|
|
79
|
+
|
|
80
|
+
**Deliverables**:
|
|
81
|
+
- PlantUML generation
|
|
82
|
+
- Diagram templates
|
|
83
|
+
- Integration documentation
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## References
|
|
88
|
+
|
|
89
|
+
- [PlantUML](https://plantuml.com/)
|
|
90
|
+
- [C4 Model with PlantUML](https://c4model.com/)
|