Skip to content

Commit 2ad3dfc

Browse files
Merge pull request #28 from quantumdynamics927-dotcom/copilot/add-help-menu-dropdown
Clarify DNA responsible-use guidance and scope the security policy to project reality
2 parents 27477be + 3ed8763 commit 2ad3dfc

File tree

3 files changed

+173
-77
lines changed

3 files changed

+173
-77
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,22 @@ print([record.record_id for record in get_available_dna_sequences()])
247247
This feature imports curated OpenQASM assets and exposes them as circuit-exploration data. It does not claim biological simulation fidelity.
248248
OpenQASM 3 assets require the optional dependency `qiskit_qasm3_import`.
249249

250+
#### Responsible Use Notice
251+
252+
The DNA-related features in QPyth are provided for educational, computational, and circuit-exploration purposes only.
253+
254+
- They do not constitute biological modeling, clinical analysis, or validated genetic interpretation.
255+
- They do not provide medical, diagnostic, therapeutic, or laboratory guidance.
256+
- They are not intended for pathogen design, wet-lab experimentation, synthesis planning, or any harmful biological application.
257+
- They should not be relied upon as evidence of biological function, safety, or real-world DNA behavior.
258+
259+
Any DNA-inspired or sequence-related assets in this repository are presented as computational abstractions or curated examples unless explicitly documented otherwise.
260+
261+
#### Data Provenance
262+
263+
Where bundled DNA or sequence-like assets are included, the repository should identify whether they are synthetic/demo-only, derived from public reference material, or transformed for educational use.
264+
Unless explicitly stated otherwise, treat such assets as illustrative and non-authoritative.
265+
250266
**Available Hardware Profiles:**
251267

252268
| Backend | Qubits | Avg T1 (μs) | Avg T2 (μs) | Avg Readout Error |

SECURITY.md

Lines changed: 52 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,87 @@
11
# 🔒 Security Policy
22

3-
## Supported Versions
4-
5-
| Version | Supported |
6-
|---------|--------------------|
7-
| 0.2.x | ✅ Active support |
8-
| 0.1.x | ❌ End of life |
9-
10-
Security updates are provided for the **latest stable release** on the `main` branch only.
11-
Users are encouraged to upgrade to the latest version to receive all security fixes.
12-
13-
---
3+
## Scope
144

15-
## 🛡️ Security Best Practices
5+
QPyth is an open-source quantum software toolkit. Some repository features use DNA-inspired or sequence-themed representations for computational exploration. These features are not biological simulation tools and are not intended for laboratory, medical, diagnostic, therapeutic, or bioengineering use.
166

17-
### What We Do
18-
19-
- **Dependency scanning**: Automated checks for vulnerable dependencies
20-
- **Code review**: All PRs reviewed for security issues
21-
- **Input validation**: Sanitization of user-provided values
22-
- **Secure defaults**: Safe configurations out of the box
7+
## Supported Versions
238

24-
### Security Testing
9+
Security updates are provided for the latest stable release and the `main` branch.
2510

26-
```bash
27-
# Check for known vulnerabilities
28-
pip-audit -r <(pip freeze)
11+
| Version | Supported |
12+
|---------|-----------|
13+
| Latest stable release ||
14+
| `main` branch ||
15+
| Older releases ||
2916

30-
# Type checking for type-related issues
31-
mypy quantumpytho/
32-
33-
# Static analysis
34-
ruff check .
35-
```
17+
Users should upgrade to the latest release to receive security fixes and dependency updates.
3618

3719
---
3820

39-
## 📬 Reporting a Vulnerability
21+
## Security Boundaries
4022

41-
### Responsible Disclosure
23+
QPyth should be treated as developer and research software, not as a safety-certified system. In particular:
4224

43-
We take security seriously and appreciate your help in keeping QPyth safe.
25+
- outputs are not guaranteed to be biologically valid, clinically meaningful, or safe for real-world use
26+
- DNA-related features must not be used for synthesis, pathogen engineering, wet-lab experimentation, or operational biological decision-making
27+
- optional integrations and external services may introduce network, API, credential, or third-party dependency risk
4428

45-
**If you find a security issue:**
29+
---
4630

47-
1. **Do not** create a public GitHub issue
48-
2. Use GitHub Security Advisories:
49-
- Go to the repository **Security** tab
50-
- Click **Report a vulnerability**
51-
3. Alternatively, open a private issue with "SECURITY" in the title
31+
## What We Review
5232

53-
### What to Include
33+
We aim to reduce risk through:
5434

55-
- Description of the vulnerability
56-
- Steps to reproduce
57-
- Potential impact
58-
- Suggested fix (if any)
35+
- dependency monitoring
36+
- static analysis and linting
37+
- code review
38+
- input validation for user-facing interfaces
39+
- secure handling of optional integrations where applicable
5940

60-
### Response Timeline
41+
Repository CI currently runs:
6142

62-
| Stage | Expected Time |
63-
|-------|---------------|
64-
| Acknowledgment | 48 hours |
65-
| Triage | 7 days |
66-
| Fix | Priority-based |
67-
| Public disclosure | Coordinated |
43+
```bash
44+
ruff check .
45+
ruff format --check .
46+
pytest -v --tb=short
47+
pytest --cov=quantumpytho --cov-report=xml
48+
```
6849

6950
---
7051

71-
## 🔐 Security Features
52+
## Reporting a Vulnerability
7253

73-
### Dependency Security
54+
Please do not open a public issue for suspected vulnerabilities.
7455

75-
```toml
76-
# pyproject.toml
77-
dependencies = [
78-
"qiskit>=1.1.0", # Version-pinned major releases
79-
"qiskit-aer>=0.15.0", # Latest stable with security fixes
80-
"numpy>=2.0.0", # Modern, maintained version
81-
]
82-
```
83-
84-
### Input Validation
56+
Instead:
8557

86-
All user inputs are validated:
58+
1. Use GitHub Security Advisories or private vulnerability reporting if it is enabled for the repository.
59+
2. If private reporting is unavailable, contact the maintainers privately and include `SECURITY` in the subject line.
8760

88-
```python
89-
def read_float(prompt: str, min_val: float, max_val: float) -> float:
90-
"""Validates user input against bounds."""
91-
# Raises ValueError if out of range
92-
```
61+
Please include:
9362

94-
### Secure Defaults
63+
- affected component
64+
- reproduction steps
65+
- impact assessment
66+
- suggested mitigation, if available
9567

96-
- QuantumSimulator (Aer) as default - no external connections
97-
- Local execution only - no remote API calls
98-
- Minimal permissions - no filesystem/network access
68+
We ask reporters to avoid public disclosure until the issue has been reviewed and a fix or mitigation is available.
9969

10070
---
10171

102-
## 📚 Security Resources
72+
## Domain-Specific Responsible Use
73+
74+
If you identify a risk involving:
75+
76+
- misuse of DNA-related functionality
77+
- unsafe interpretation of sequence-like assets
78+
- misleading biological claims
79+
- dual-use or biosecurity concerns
10380

104-
- [Qiskit Security](https://qiskit.org/security)
105-
- [PyPI Security](https://pypi.org/security/)
106-
- [OWASP Quantum Computing](https://owasp.org/www-project-quantum-computing/)
81+
please report it as a security concern even if it is not a traditional software exploit.
10782

10883
---
10984

110-
## 🙏 Thank You
85+
## Disclaimer
11186

112-
Your security reporting helps protect the entire quantum computing community.
87+
QPyth is provided for research, education, and software experimentation. It is not intended for clinical, medical, diagnostic, therapeutic, biosurveillance, synthesis, or wet-lab decision support.

tests/test_dna_circuits.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55

66
import pytest
77

8+
import quantumpytho.modules.dna_circuits as dna_circuits
89
from quantumpytho.modules.dna_circuits import (
910
get_available_dna_circuit_ids,
1011
get_available_dna_circuits,
1112
get_available_dna_sequences,
1213
get_dna_circuit_preview,
1314
get_dna_sequence,
1415
load_dna_circuit,
16+
load_dna_circuit_metadata,
1517
load_qasm_circuit_file,
18+
run_dna_circuit_explorer,
1619
summarize_dna_circuit,
1720
validate_qasm_file,
1821
)
@@ -43,6 +46,14 @@ def test_load_dna_circuit_parses_qasm():
4346
assert circuit.num_clbits == 21
4447

4548

49+
def test_load_dna_circuit_metadata_reads_bundled_json():
50+
"""Bundled metadata should be readable without summary normalization."""
51+
metadata = load_dna_circuit_metadata("dna_helix_10bp")
52+
53+
assert metadata["qubits"] == 21
54+
assert metadata["config"]["base_pairs"] == 10
55+
56+
4657
def test_load_stealth_dna_circuit_parses_qasm():
4758
"""Bundled 34bp stealth QASM should parse into a large Qiskit circuit."""
4859
circuit = load_dna_circuit("stealth_dna_34bp")
@@ -64,6 +75,16 @@ def test_summarize_dna_circuit_normalizes_metadata():
6475
assert summary.sequences["strand1"] == "GTAGGTAAGC"
6576

6677

78+
def test_dna_summary_to_dict_is_json_safe():
79+
"""Normalized summaries should serialize into simple Python data."""
80+
summary = summarize_dna_circuit("dna_helix_10bp")
81+
payload = summary.to_dict()
82+
83+
assert payload["circuit_id"] == "dna_helix_10bp"
84+
assert payload["sequences"] == summary.sequences
85+
assert payload["geometry"] == summary.geometry
86+
87+
6788
def test_summarize_stealth_dna_circuit_preserves_large_asset_metadata():
6889
"""Large stealth asset should preserve curated metadata and parsed metrics."""
6990
summary = summarize_dna_circuit("stealth_dna_34bp")
@@ -95,6 +116,21 @@ def test_stealth_circuit_preview_contains_named_registers():
95116
assert "qreg bridge[34];" in preview
96117

97118

119+
def test_validate_qasm_file_rejects_missing_file(tmp_path: Path):
120+
"""Missing QASM files should raise a helpful error."""
121+
with pytest.raises(FileNotFoundError, match="not found"):
122+
validate_qasm_file(tmp_path / "missing.qasm")
123+
124+
125+
def test_validate_qasm_file_rejects_invalid_header(tmp_path: Path):
126+
"""Non-OpenQASM files should be rejected before parsing."""
127+
invalid_qasm = tmp_path / "invalid.qasm"
128+
invalid_qasm.write_text("qreg q[1];", encoding="utf-8")
129+
130+
with pytest.raises(ValueError, match="not valid OpenQASM"):
131+
validate_qasm_file(invalid_qasm)
132+
133+
98134
def test_validate_qasm_file_rejects_empty_file(tmp_path: Path):
99135
"""Empty QASM placeholders should be rejected clearly."""
100136
empty_qasm = tmp_path / "empty.qasm"
@@ -113,6 +149,12 @@ def test_available_dna_sequences_contains_blueprint_and_library_entries():
113149
assert "lib_acgt" in record_ids
114150

115151

152+
def test_get_dna_sequence_unknown_record_raises_keyerror():
153+
"""Sequence lookup should fail clearly for unknown ids."""
154+
with pytest.raises(KeyError, match="Unknown DNA sequence record"):
155+
get_dna_sequence("missing-record")
156+
157+
116158
def test_get_dna_sequence_blueprint_is_normalized():
117159
"""Blueprint sequence should be normalized by stripping separators."""
118160
record = get_dna_sequence("seq_3")
@@ -122,6 +164,41 @@ def test_get_dna_sequence_blueprint_is_normalized():
122164
assert record.phi_scaling == pytest.approx(0.7232610426788172)
123165

124166

167+
def test_dna_sequence_to_dict_is_json_safe():
168+
"""Sequence records should serialize into simple Python data."""
169+
record = get_dna_sequence("seq_3")
170+
payload = record.to_dict()
171+
172+
assert payload["record_id"] == "seq_3"
173+
assert payload["sequence"] == record.sequence
174+
assert payload["metadata"] == record.metadata
175+
176+
177+
def test_load_dna_circuit_metadata_raises_for_missing_bundled_file(
178+
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
179+
):
180+
"""Missing bundled metadata files should raise a clear error."""
181+
monkeypatch.setattr(dna_circuits, "_data_dir", lambda: tmp_path)
182+
183+
with pytest.raises(FileNotFoundError, match="DNA metadata file not found"):
184+
load_dna_circuit_metadata("dna_helix_10bp")
185+
186+
187+
def test_load_dna_circuit_rejects_unknown_asset():
188+
"""Unknown bundled circuit ids should fail clearly."""
189+
with pytest.raises(KeyError, match="Unknown DNA circuit asset"):
190+
load_dna_circuit("missing-circuit")
191+
192+
193+
def test_load_qasm_circuit_file_rejects_unsupported_openqasm_version(tmp_path: Path):
194+
"""Unknown OpenQASM versions should fail before import."""
195+
qasm_path = tmp_path / "sample.qasm"
196+
qasm_path.write_text("OPENQASM 4.0;\nqubit q;\n", encoding="utf-8")
197+
198+
with pytest.raises(ValueError, match="Unsupported OpenQASM version"):
199+
load_qasm_circuit_file(qasm_path)
200+
201+
125202
def test_load_qasm_circuit_file_handles_openqasm3_optional_dependency(tmp_path: Path):
126203
"""OpenQASM 3 loading should either parse or fail with an install hint."""
127204
qasm3_path = tmp_path / "sample.qasm"
@@ -136,3 +213,31 @@ def test_load_qasm_circuit_file_handles_openqasm3_optional_dependency(tmp_path:
136213
else:
137214
circuit = load_qasm_circuit_file(qasm3_path)
138215
assert circuit.num_qubits == 1
216+
217+
218+
def test_run_dna_circuit_explorer_allows_quit(
219+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
220+
):
221+
"""CLI explorer should return cleanly when the user quits."""
222+
monkeypatch.setattr("builtins.input", lambda _: "q")
223+
224+
run_dna_circuit_explorer()
225+
226+
output = capsys.readouterr().out
227+
assert "[DNA-Inspired Circuit Explorer]" in output
228+
assert "Returning to main menu..." in output
229+
230+
231+
def test_run_dna_circuit_explorer_uses_default_selection(
232+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
233+
):
234+
"""Blank input should select the first bundled DNA circuit."""
235+
monkeypatch.setattr("builtins.input", lambda _: "")
236+
monkeypatch.setattr(dna_circuits.importlib.util, "find_spec", lambda _: None)
237+
238+
run_dna_circuit_explorer()
239+
240+
output = capsys.readouterr().out
241+
assert "OpenQASM 3 import support: install qiskit_qasm3_import" in output
242+
assert "Name: DNA Helix 10bp" in output
243+
assert "QASM preview:" in output

0 commit comments

Comments
 (0)