medharness 0.1.0__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.
Files changed (108) hide show
  1. medharness-0.1.0/LICENSE +21 -0
  2. medharness-0.1.0/PKG-INFO +199 -0
  3. medharness-0.1.0/README.md +154 -0
  4. medharness-0.1.0/dhfkit/__init__.py +36 -0
  5. medharness-0.1.0/dhfkit/__main__.py +5 -0
  6. medharness-0.1.0/dhfkit/api.py +88 -0
  7. medharness-0.1.0/dhfkit/artifact_fetcher.py +509 -0
  8. medharness-0.1.0/dhfkit/change_requests.py +147 -0
  9. medharness-0.1.0/dhfkit/cli.py +366 -0
  10. medharness-0.1.0/dhfkit/document_generation.py +194 -0
  11. medharness-0.1.0/dhfkit/exceptions.py +6 -0
  12. medharness-0.1.0/dhfkit/id_generator.py +116 -0
  13. medharness-0.1.0/dhfkit/junit_parser.py +129 -0
  14. medharness-0.1.0/dhfkit/lifecycle.py +149 -0
  15. medharness-0.1.0/dhfkit/local_adapter.py +553 -0
  16. medharness-0.1.0/dhfkit/models/__init__.py +1 -0
  17. medharness-0.1.0/dhfkit/models/config.py +167 -0
  18. medharness-0.1.0/dhfkit/models/item.py +95 -0
  19. medharness-0.1.0/dhfkit/repository/__init__.py +1 -0
  20. medharness-0.1.0/dhfkit/repository/git.py +121 -0
  21. medharness-0.1.0/dhfkit/repository/loader.py +241 -0
  22. medharness-0.1.0/dhfkit/repository/saver.py +164 -0
  23. medharness-0.1.0/dhfkit/result_store.py +205 -0
  24. medharness-0.1.0/dhfkit/templates/AI-harness/context.md +36 -0
  25. medharness-0.1.0/dhfkit/templates/README.md +142 -0
  26. medharness-0.1.0/dhfkit/templates/config/doc_types/cr.yaml +83 -0
  27. medharness-0.1.0/dhfkit/templates/config/doc_types/crs.yaml +46 -0
  28. medharness-0.1.0/dhfkit/templates/config/doc_types/def.yaml +123 -0
  29. medharness-0.1.0/dhfkit/templates/config/doc_types/rcm.yaml +44 -0
  30. medharness-0.1.0/dhfkit/templates/config/doc_types/rel.yaml +50 -0
  31. medharness-0.1.0/dhfkit/templates/config/doc_types/risk.yaml +67 -0
  32. medharness-0.1.0/dhfkit/templates/config/doc_types/soup.yaml +45 -0
  33. medharness-0.1.0/dhfkit/templates/config/doc_types/srs.yaml +30 -0
  34. medharness-0.1.0/dhfkit/templates/config/doc_types/swdd.yaml +32 -0
  35. medharness-0.1.0/dhfkit/templates/config/doc_types/sys.yaml +77 -0
  36. medharness-0.1.0/dhfkit/templates/config/doc_types/sysarch.yaml +23 -0
  37. medharness-0.1.0/dhfkit/templates/config/doc_types/uc.yaml +15 -0
  38. medharness-0.1.0/dhfkit/templates/config/global.yaml +168 -0
  39. medharness-0.1.0/dhfkit/templates/github/prompts/cr-analyze.md +69 -0
  40. medharness-0.1.0/dhfkit/templates/github/prompts/cr-develop.md +21 -0
  41. medharness-0.1.0/dhfkit/templates/github/workflows/dhf/ci.yml +108 -0
  42. medharness-0.1.0/dhfkit/templates/github/workflows/dhf/cr-analyze.yml +166 -0
  43. medharness-0.1.0/dhfkit/templates/github/workflows/dhf/cr-develop.yml +190 -0
  44. medharness-0.1.0/dhfkit/templates/github/workflows/dhf/cr-spec-iterate.yml +52 -0
  45. medharness-0.1.0/dhfkit/templates/github/workflows/dhf/cr-transition.yml +88 -0
  46. medharness-0.1.0/dhfkit/templates/github/workflows/product/cr-complete.yml +57 -0
  47. medharness-0.1.0/dhfkit/templates/github/workflows/product/review-pr.yml +89 -0
  48. medharness-0.1.0/dhfkit/templates/items/00_uc/UC-001.yaml +5 -0
  49. medharness-0.1.0/dhfkit/templates/items/01_crs/CRS-001.yaml +9 -0
  50. medharness-0.1.0/dhfkit/templates/items/02_sys/SYS-001.yaml +11 -0
  51. medharness-0.1.0/dhfkit/templates/items/03_srs/SRS-001.yaml +7 -0
  52. medharness-0.1.0/dhfkit/templates/items/04_swdd/SWDD-001.yaml +7 -0
  53. medharness-0.1.0/dhfkit/templates/items/05_sysarch/SYSARCH-001.yaml +7 -0
  54. medharness-0.1.0/dhfkit/templates/items/06_cr/CR-001.yaml +8 -0
  55. medharness-0.1.0/dhfkit/templates/items/07_rel/REL-001.yaml +6 -0
  56. medharness-0.1.0/dhfkit/templates/items/08_soup/SOUP-001.yaml +11 -0
  57. medharness-0.1.0/dhfkit/templates/items/09_risk/RISK-001.yaml +10 -0
  58. medharness-0.1.0/dhfkit/templates/items/10_rcm/RCM-001.yaml +9 -0
  59. medharness-0.1.0/dhfkit/templates/items/11_def/DEF-001.yaml +5 -0
  60. medharness-0.1.0/dhfkit/templates/plans/configuration_management_plan.md +48 -0
  61. medharness-0.1.0/dhfkit/templates/plans/development_plan.md +226 -0
  62. medharness-0.1.0/dhfkit/templates/plans/integration_plan.md +35 -0
  63. medharness-0.1.0/dhfkit/templates/plans/maintenance_plan.md +28 -0
  64. medharness-0.1.0/dhfkit/templates/plans/risk_management_plan.md +46 -0
  65. medharness-0.1.0/dhfkit/templates/plans/validation_plan.md +18 -0
  66. medharness-0.1.0/dhfkit/templates/plans/verification_plan.md +30 -0
  67. medharness-0.1.0/dhfkit/templates/specs/architecture_design_specification.md.j2 +179 -0
  68. medharness-0.1.0/dhfkit/templates/specs/change_request_specification.md.j2 +129 -0
  69. medharness-0.1.0/dhfkit/templates/specs/customer_requirement_specification.md.j2 +172 -0
  70. medharness-0.1.0/dhfkit/templates/specs/rcm_specification.md.j2 +112 -0
  71. medharness-0.1.0/dhfkit/templates/specs/requirements_specification.md.j2 +98 -0
  72. medharness-0.1.0/dhfkit/templates/specs/risk_specification.md.j2 +120 -0
  73. medharness-0.1.0/dhfkit/templates/specs/styles/default.css +200 -0
  74. medharness-0.1.0/dhfkit/templates/specs/test_specification.md.j2 +123 -0
  75. medharness-0.1.0/dhfkit/templates/specs/traceability_matrix.md.j2 +83 -0
  76. medharness-0.1.0/dhfkit/traceability.py +214 -0
  77. medharness-0.1.0/medharness/__init__.py +5 -0
  78. medharness-0.1.0/medharness/__main__.py +5 -0
  79. medharness-0.1.0/medharness/_helpers.py +476 -0
  80. medharness-0.1.0/medharness/adapters/__init__.py +1 -0
  81. medharness-0.1.0/medharness/adapters/protocol.py +86 -0
  82. medharness-0.1.0/medharness/cli/__init__.py +31 -0
  83. medharness-0.1.0/medharness/cli/ci.py +320 -0
  84. medharness-0.1.0/medharness/cli/cr.py +157 -0
  85. medharness-0.1.0/medharness/cli/dhf.py +375 -0
  86. medharness-0.1.0/medharness/cli/init.py +11 -0
  87. medharness-0.1.0/medharness/client.py +69 -0
  88. medharness-0.1.0/medharness/commands/__init__.py +1 -0
  89. medharness-0.1.0/medharness/commands/cr.py +246 -0
  90. medharness-0.1.0/medharness/core.py +676 -0
  91. medharness-0.1.0/medharness/graph.py +228 -0
  92. medharness-0.1.0/medharness/services/__init__.py +1 -0
  93. medharness-0.1.0/medharness/services/ci.py +342 -0
  94. medharness-0.1.0/medharness/services/git.py +52 -0
  95. medharness-0.1.0/medharness/services/github_event.py +129 -0
  96. medharness-0.1.0/medharness/services/github_session.py +59 -0
  97. medharness-0.1.0/medharness/services/spec_validation.py +131 -0
  98. medharness-0.1.0/medharness/workflows/__init__.py +1 -0
  99. medharness-0.1.0/medharness/workflows/cr_intake.py +147 -0
  100. medharness-0.1.0/medharness/workflows/init.py +470 -0
  101. medharness-0.1.0/medharness.egg-info/PKG-INFO +199 -0
  102. medharness-0.1.0/medharness.egg-info/SOURCES.txt +106 -0
  103. medharness-0.1.0/medharness.egg-info/dependency_links.txt +1 -0
  104. medharness-0.1.0/medharness.egg-info/entry_points.txt +4 -0
  105. medharness-0.1.0/medharness.egg-info/requires.txt +24 -0
  106. medharness-0.1.0/medharness.egg-info/top_level.txt +2 -0
  107. medharness-0.1.0/pyproject.toml +80 -0
  108. medharness-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 CompliantFlow contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,199 @@
1
+ Metadata-Version: 2.4
2
+ Name: medharness
3
+ Version: 0.1.0
4
+ Summary: Open-source design-controlled development infrastructure for medical device and SaMD teams — includes dhfkit
5
+ Author: MedHarness Contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/itercharles/MedHarness
8
+ Project-URL: Source, https://github.com/itercharles/MedHarness
9
+ Project-URL: Bug Tracker, https://github.com/itercharles/MedHarness/issues
10
+ Project-URL: Documentation, https://github.com/itercharles/MedHarness#readme
11
+ Keywords: medical-device,iec-62304,iso-14971,iec-82304-1,dhf,design-history-file,traceability,compliance,samd
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Healthcare Industry
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Quality Assurance
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: pydantic>=2.0
25
+ Requires-Dist: click
26
+ Requires-Dist: networkx
27
+ Requires-Dist: pyyaml
28
+ Requires-Dist: python-frontmatter
29
+ Requires-Dist: jinja2
30
+ Requires-Dist: python-docx
31
+ Requires-Dist: gitpython
32
+ Requires-Dist: python-dateutil
33
+ Requires-Dist: python-dotenv
34
+ Requires-Dist: markdown
35
+ Provides-Extra: ai
36
+ Requires-Dist: google-genai; extra == "ai"
37
+ Provides-Extra: docs
38
+ Requires-Dist: weasyprint; extra == "docs"
39
+ Provides-Extra: dev
40
+ Requires-Dist: pytest; extra == "dev"
41
+ Requires-Dist: pytest-cov; extra == "dev"
42
+ Provides-Extra: full
43
+ Requires-Dist: medharness[ai,docs]; extra == "full"
44
+ Dynamic: license-file
45
+
46
+ # MedHarness
47
+
48
+ **AI harness and DHF tooling for medical device software teams.**
49
+
50
+ MedHarness is an open-source framework for building AI-driven engineering workflows on IEC 62304 /
51
+ FDA-regulated software projects. It combines two things:
52
+
53
+ 1. **`medharness`** — a CI harness that structures how AI agents (Claude Code) interact with a
54
+ Design History File: pre-computing context, enforcing approval gates, persisting decisions,
55
+ and generating audit-ready evidence.
56
+
57
+ 2. **`dhfkit`** — a standalone DHF engine for managing items, enforcing traceability
58
+ (UC → CRS → SRS → SWDD → TC), validating schema, and generating specification documents.
59
+
60
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
61
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://python.org)
62
+
63
+ > **Harness engineering:** Rather than prompting an AI to "do compliance," MedHarness
64
+ > pre-computes the DHF context, injects it into the agent environment, defines approval gates
65
+ > the agent must pass through, and captures the agent's decisions back into the DHF — so the
66
+ > engineer controls the loop, not the agent.
67
+
68
+ ---
69
+
70
+ ## Install
71
+
72
+ ```bash
73
+ # From source (not yet on PyPI):
74
+ git clone https://github.com/itercharles/MedHarness
75
+ cd MedHarness
76
+ pip install -e .
77
+ ```
78
+
79
+ Verify:
80
+
81
+ ```bash
82
+ medharness --help
83
+ dhfkit --help
84
+ ```
85
+
86
+ ---
87
+
88
+ ## Quick Start
89
+
90
+ ```bash
91
+ medharness init
92
+ ```
93
+
94
+ Interactively scaffolds two repos:
95
+
96
+ - **DHF repo** — `DHF/config/`, item YAML templates, spec/plan Jinja2 templates,
97
+ GitHub Actions workflows for CR analysis, design, and CI validation
98
+ - **Product repo files** — `CLAUDE.md`, `engineering-control.yml`, `cr-complete.yml`,
99
+ Claude Code skills (`.claude/skills/`)
100
+
101
+ ---
102
+
103
+ ## How it works
104
+
105
+ A Change Request flows through five AI-assisted stages, each enforced by GitHub Actions:
106
+
107
+ ```
108
+ Issue → cr-analyze (AI spec) → cr-design (AI DHF items) → cr-develop (AI code) → cr-complete
109
+ ```
110
+
111
+ At each stage MedHarness:
112
+ - **Pre-computes DHF context** (`medharness dhf context overview`) and injects it as `$DHF_CONTEXT`
113
+ - **Runs Claude** with `--dangerously-skip-permissions` inside the DHF repo
114
+ - **Commits transitions** back to the DHF (`medharness dhf item transition --commit --push`)
115
+ - **Stores session IDs** in PR comments for iterative review (`medharness ci claude-session put/get`)
116
+
117
+ ---
118
+
119
+ ## CLI surface
120
+
121
+ ```
122
+ medharness init
123
+
124
+ # DHF operations (run from DHF repo with --dhf DHF)
125
+ medharness --dhf DHF dhf item list|get|create|update|delete|transitions|transition
126
+ medharness --dhf DHF dhf validate schema|traceability
127
+ medharness --dhf DHF dhf doc list|generate|export
128
+ medharness --dhf DHF dhf test list
129
+ medharness --dhf DHF dhf context overview|implementation
130
+ medharness --dhf DHF dhf config doc-types
131
+
132
+ # CI gates (run from product repo)
133
+ medharness ci dhf-validate --dhf DHF
134
+ medharness ci test-coverage --dhf DHF
135
+ medharness ci evidence bundle --dhf DHF --out-dir ...
136
+ medharness ci artifacts generate --dhf DHF --out-dir ...
137
+
138
+ # GitHub Actions helpers
139
+ medharness ci github-event --github-output "$GITHUB_OUTPUT"
140
+ medharness ci claude-session put <pr_number> <session_id>
141
+ medharness ci claude-session get <pr_number>
142
+
143
+ # CR workflow
144
+ medharness cr workflow intake-github-issue-ci
145
+ medharness cr workflow complete-from-github-pr
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Python API
151
+
152
+ Use `dhfkit` directly in product repo automation without shelling out:
153
+
154
+ ```python
155
+ from medharness.client import DHFClient
156
+
157
+ client = DHFClient(Path("../my-project-DHF/DHF"))
158
+ cr = client.get_item("CR-034")
159
+ context = client.get_cr_context("CR-034") # {"cr": {...}, "spec": "..."}
160
+ client.transition_item("CR-034", "in_review", performed_by="alice")
161
+ ```
162
+
163
+ Or use `dhfkit` standalone (no dependency on `medharness`):
164
+
165
+ ```python
166
+ from dhfkit.local_adapter import LocalDHFAdapter
167
+
168
+ adapter = LocalDHFAdapter(Path("DHF"))
169
+ items = adapter.list_items("SRS")
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Repository layout
175
+
176
+ | Directory | Purpose |
177
+ |-----------|---------|
178
+ | `medharness/` | CLI harness, CI gates, CR workflows, `init` scaffolding |
179
+ | `dhfkit/` | DHF engine: items, lifecycle, traceability, document generation |
180
+ | `dhfkit/templates/` | Starter DHF scaffold — config, specs, plans, sample items |
181
+ | `docs/` | Architecture, ADRs, compatibility contracts, roadmap |
182
+
183
+ `dhfkit` has no dependency on `medharness` and can be used standalone.
184
+
185
+ ---
186
+
187
+ ## Docs
188
+
189
+ - [docs/roadmap.md](docs/roadmap.md) — vision and milestone plan
190
+ - [docs/architecture.md](docs/architecture.md) — packages, scaffold model, DHF lifecycle
191
+ - [docs/compatibility-contracts.md](docs/compatibility-contracts.md) — stable public contracts
192
+ - [docs/adr/](docs/adr/) — architecture decision records
193
+ - [CHANGELOG.md](CHANGELOG.md) — version history
194
+
195
+ ---
196
+
197
+ ## License
198
+
199
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,154 @@
1
+ # MedHarness
2
+
3
+ **AI harness and DHF tooling for medical device software teams.**
4
+
5
+ MedHarness is an open-source framework for building AI-driven engineering workflows on IEC 62304 /
6
+ FDA-regulated software projects. It combines two things:
7
+
8
+ 1. **`medharness`** — a CI harness that structures how AI agents (Claude Code) interact with a
9
+ Design History File: pre-computing context, enforcing approval gates, persisting decisions,
10
+ and generating audit-ready evidence.
11
+
12
+ 2. **`dhfkit`** — a standalone DHF engine for managing items, enforcing traceability
13
+ (UC → CRS → SRS → SWDD → TC), validating schema, and generating specification documents.
14
+
15
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
16
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://python.org)
17
+
18
+ > **Harness engineering:** Rather than prompting an AI to "do compliance," MedHarness
19
+ > pre-computes the DHF context, injects it into the agent environment, defines approval gates
20
+ > the agent must pass through, and captures the agent's decisions back into the DHF — so the
21
+ > engineer controls the loop, not the agent.
22
+
23
+ ---
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ # From source (not yet on PyPI):
29
+ git clone https://github.com/itercharles/MedHarness
30
+ cd MedHarness
31
+ pip install -e .
32
+ ```
33
+
34
+ Verify:
35
+
36
+ ```bash
37
+ medharness --help
38
+ dhfkit --help
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Quick Start
44
+
45
+ ```bash
46
+ medharness init
47
+ ```
48
+
49
+ Interactively scaffolds two repos:
50
+
51
+ - **DHF repo** — `DHF/config/`, item YAML templates, spec/plan Jinja2 templates,
52
+ GitHub Actions workflows for CR analysis, design, and CI validation
53
+ - **Product repo files** — `CLAUDE.md`, `engineering-control.yml`, `cr-complete.yml`,
54
+ Claude Code skills (`.claude/skills/`)
55
+
56
+ ---
57
+
58
+ ## How it works
59
+
60
+ A Change Request flows through five AI-assisted stages, each enforced by GitHub Actions:
61
+
62
+ ```
63
+ Issue → cr-analyze (AI spec) → cr-design (AI DHF items) → cr-develop (AI code) → cr-complete
64
+ ```
65
+
66
+ At each stage MedHarness:
67
+ - **Pre-computes DHF context** (`medharness dhf context overview`) and injects it as `$DHF_CONTEXT`
68
+ - **Runs Claude** with `--dangerously-skip-permissions` inside the DHF repo
69
+ - **Commits transitions** back to the DHF (`medharness dhf item transition --commit --push`)
70
+ - **Stores session IDs** in PR comments for iterative review (`medharness ci claude-session put/get`)
71
+
72
+ ---
73
+
74
+ ## CLI surface
75
+
76
+ ```
77
+ medharness init
78
+
79
+ # DHF operations (run from DHF repo with --dhf DHF)
80
+ medharness --dhf DHF dhf item list|get|create|update|delete|transitions|transition
81
+ medharness --dhf DHF dhf validate schema|traceability
82
+ medharness --dhf DHF dhf doc list|generate|export
83
+ medharness --dhf DHF dhf test list
84
+ medharness --dhf DHF dhf context overview|implementation
85
+ medharness --dhf DHF dhf config doc-types
86
+
87
+ # CI gates (run from product repo)
88
+ medharness ci dhf-validate --dhf DHF
89
+ medharness ci test-coverage --dhf DHF
90
+ medharness ci evidence bundle --dhf DHF --out-dir ...
91
+ medharness ci artifacts generate --dhf DHF --out-dir ...
92
+
93
+ # GitHub Actions helpers
94
+ medharness ci github-event --github-output "$GITHUB_OUTPUT"
95
+ medharness ci claude-session put <pr_number> <session_id>
96
+ medharness ci claude-session get <pr_number>
97
+
98
+ # CR workflow
99
+ medharness cr workflow intake-github-issue-ci
100
+ medharness cr workflow complete-from-github-pr
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Python API
106
+
107
+ Use `dhfkit` directly in product repo automation without shelling out:
108
+
109
+ ```python
110
+ from medharness.client import DHFClient
111
+
112
+ client = DHFClient(Path("../my-project-DHF/DHF"))
113
+ cr = client.get_item("CR-034")
114
+ context = client.get_cr_context("CR-034") # {"cr": {...}, "spec": "..."}
115
+ client.transition_item("CR-034", "in_review", performed_by="alice")
116
+ ```
117
+
118
+ Or use `dhfkit` standalone (no dependency on `medharness`):
119
+
120
+ ```python
121
+ from dhfkit.local_adapter import LocalDHFAdapter
122
+
123
+ adapter = LocalDHFAdapter(Path("DHF"))
124
+ items = adapter.list_items("SRS")
125
+ ```
126
+
127
+ ---
128
+
129
+ ## Repository layout
130
+
131
+ | Directory | Purpose |
132
+ |-----------|---------|
133
+ | `medharness/` | CLI harness, CI gates, CR workflows, `init` scaffolding |
134
+ | `dhfkit/` | DHF engine: items, lifecycle, traceability, document generation |
135
+ | `dhfkit/templates/` | Starter DHF scaffold — config, specs, plans, sample items |
136
+ | `docs/` | Architecture, ADRs, compatibility contracts, roadmap |
137
+
138
+ `dhfkit` has no dependency on `medharness` and can be used standalone.
139
+
140
+ ---
141
+
142
+ ## Docs
143
+
144
+ - [docs/roadmap.md](docs/roadmap.md) — vision and milestone plan
145
+ - [docs/architecture.md](docs/architecture.md) — packages, scaffold model, DHF lifecycle
146
+ - [docs/compatibility-contracts.md](docs/compatibility-contracts.md) — stable public contracts
147
+ - [docs/adr/](docs/adr/) — architecture decision records
148
+ - [CHANGELOG.md](CHANGELOG.md) — version history
149
+
150
+ ---
151
+
152
+ ## License
153
+
154
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,36 @@
1
+ """dhfkit — standalone data-layer package for DHF repositories.
2
+
3
+ Public API
4
+ ----------
5
+ Shared data types (safe to import anywhere):
6
+ Item, ProjectConfig, DocTypeConfig, ValidationError
7
+
8
+ DHF I/O utilities (for direct DHF-layer consumers such as tests and adapters):
9
+ ItemLoader, ResultStore, parse_junit_xml, ExecutionResult
10
+
11
+ Internal (not part of the public API):
12
+ ItemSaver, GitRepository, DocumentGenerator
13
+ — these are implementation details of the adapter layer.
14
+ """
15
+
16
+ from dhfkit.models.item import Item
17
+ from dhfkit.models.config import ProjectConfig, DocTypeConfig
18
+ from dhfkit.exceptions import ValidationError
19
+ from dhfkit.result_store import ResultStore
20
+ from dhfkit.junit_parser import parse_junit_xml, ExecutionResult
21
+ from dhfkit.repository.loader import ItemLoader
22
+ from dhfkit.artifact_fetcher import GitHubArtifactFetcher
23
+ from dhfkit.local_adapter import LocalDHFAdapter
24
+
25
+ __all__ = [
26
+ "Item",
27
+ "ProjectConfig",
28
+ "DocTypeConfig",
29
+ "ValidationError",
30
+ "ResultStore",
31
+ "parse_junit_xml",
32
+ "ExecutionResult",
33
+ "ItemLoader",
34
+ "GitHubArtifactFetcher",
35
+ "LocalDHFAdapter",
36
+ ]
@@ -0,0 +1,5 @@
1
+ """dhfkit standalone CLI entry point."""
2
+ from dhfkit.cli import main
3
+
4
+ if __name__ == "__main__":
5
+ main()
@@ -0,0 +1,88 @@
1
+ """dhfkit API — reusable Python functions for DHF operations.
2
+
3
+ All functions accept a DHF root path and return structured data.
4
+ No Click, no stdout/stderr, no CLI concerns.
5
+ """
6
+
7
+ from pathlib import Path
8
+ from typing import Optional
9
+
10
+ from dhfkit.local_adapter import LocalDHFAdapter
11
+
12
+
13
+ def _adapter(dhf_root: Path) -> LocalDHFAdapter:
14
+ return LocalDHFAdapter(dhf_root, auto_commit=False)
15
+
16
+
17
+ # -- Item operations ----------------------------------------------------------
18
+
19
+ def get_item(dhf_root: Path, item_id: str) -> Optional[dict]:
20
+ return _adapter(dhf_root).get_item(item_id)
21
+
22
+
23
+ def list_items(dhf_root: Path, doc_type: Optional[str] = None) -> list[dict]:
24
+ return _adapter(dhf_root).list_items(doc_type)
25
+
26
+
27
+ def create_item(dhf_root: Path, data: dict, author: str = "system",
28
+ cr_id: Optional[str] = None) -> dict:
29
+ return _adapter(dhf_root).create_item(data, author=author, cr_id=cr_id)
30
+
31
+
32
+ def update_item(dhf_root: Path, item_id: str, data: dict,
33
+ author: Optional[str] = None,
34
+ cr_id: Optional[str] = None) -> Optional[dict]:
35
+ return _adapter(dhf_root).update_item(item_id, data, author=author, cr_id=cr_id)
36
+
37
+
38
+ def delete_item(dhf_root: Path, item_id: str, author: Optional[str] = None) -> bool:
39
+ return _adapter(dhf_root).delete_item(item_id, author=author)
40
+
41
+
42
+ def get_item_transitions(dhf_root: Path, item_id: str) -> list[dict]:
43
+ return _adapter(dhf_root).get_available_transitions(item_id)
44
+
45
+
46
+ def transition_item(dhf_root: Path, item_id: str, to_state: str,
47
+ performed_by: Optional[str] = None) -> dict:
48
+ return _adapter(dhf_root).execute_transition(item_id, to_state, performed_by=performed_by)
49
+
50
+
51
+ # -- Validation operations ----------------------------------------------------
52
+
53
+ def validate_schema(dhf_root: Path) -> dict:
54
+ return _adapter(dhf_root).validate_schema()
55
+
56
+
57
+ def validate_traceability(dhf_root: Path) -> dict:
58
+ return _adapter(dhf_root).validate_traceability()
59
+
60
+
61
+ # -- Document operations ------------------------------------------------------
62
+
63
+ def list_doc_types(dhf_root: Path) -> list[str]:
64
+ return _adapter(dhf_root).get_available_doc_types()
65
+
66
+
67
+ def generate_doc(dhf_root: Path, doc_type_code: str) -> dict:
68
+ return _adapter(dhf_root).generate_doc(doc_type_code)
69
+
70
+
71
+ def export_pdf(dhf_root: Path, doc_type_code: str) -> dict:
72
+ return _adapter(dhf_root).export_pdf(doc_type_code)
73
+
74
+
75
+ # -- Test result operations ---------------------------------------------------
76
+
77
+ def get_test_status(dhf_root: Path, tc_id: str) -> Optional[dict]:
78
+ return _adapter(dhf_root).get_test_result(tc_id)
79
+
80
+
81
+ def list_test_results(dhf_root: Path, status_filter: Optional[str] = None) -> dict[str, dict]:
82
+ return _adapter(dhf_root).get_all_test_results(status_filter)
83
+
84
+
85
+ # -- Config operations --------------------------------------------------------
86
+
87
+ def list_doc_type_configs(dhf_root: Path) -> list[dict]:
88
+ return _adapter(dhf_root).list_item_types()