From 790131b5dd415bf788e8ae7bb681e0ecd001ec9b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 00:54:55 +0000 Subject: [PATCH 1/4] Initial plan From f247f057e6f79e5600a3666161d6c79cb812c00c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 00:57:37 +0000 Subject: [PATCH 2/4] Fix critical import and function name mismatches Co-authored-by: toolate28 <105518313+toolate28@users.noreply.github.com> --- agent_skills.py | 2 +- .../src/__tests__/vortex-wavespec.test.ts | 35 +++++++++---------- 2 files changed, 17 insertions(+), 20 deletions(-) diff --git a/agent_skills.py b/agent_skills.py index a46811c..f559a5c 100644 --- a/agent_skills.py +++ b/agent_skills.py @@ -23,7 +23,7 @@ import sys from datetime import datetime from pathlib import Path -from typing import Optional, Tuple +from typing import Optional, Tuple, Union # Default simulated coherence aligned with the '>60%' workflow threshold # In production, this would be measured via state tomography instead of a fixed stub value diff --git a/packages/quantum-ethics/src/__tests__/vortex-wavespec.test.ts b/packages/quantum-ethics/src/__tests__/vortex-wavespec.test.ts index ea1081c..9cfa4ff 100644 --- a/packages/quantum-ethics/src/__tests__/vortex-wavespec.test.ts +++ b/packages/quantum-ethics/src/__tests__/vortex-wavespec.test.ts @@ -9,7 +9,7 @@ import { runVortexCheck, createVortexPayload, formatVortexReport, - fibonacciCoherenceBoost, + applyFibonacciWeightedBoost, type VortexNode, type VortexConfig, type VortexResult, @@ -473,10 +473,10 @@ describe('formatVortexReport', () => { }); }); -describe('fibonacciCoherenceBoost', () => { +describe('applyFibonacciWeightedBoost', () => { test('should boost coherence at iteration 0', () => { const baseCoherence = 0.5; - const boosted = fibonacciCoherenceBoost(baseCoherence, 0); + const boosted = applyFibonacciWeightedBoost(baseCoherence, 0); expect(boosted).toBeGreaterThanOrEqual(baseCoherence); expect(boosted).toBeLessThanOrEqual(1); @@ -484,9 +484,9 @@ describe('fibonacciCoherenceBoost', () => { test('should boost coherence at higher iterations', () => { const baseCoherence = 0.6; - const boost1 = fibonacciCoherenceBoost(baseCoherence, 1); - const boost2 = fibonacciCoherenceBoost(baseCoherence, 2); - const boost3 = fibonacciCoherenceBoost(baseCoherence, 5); + const boost1 = applyFibonacciWeightedBoost(baseCoherence, 1); + const boost2 = applyFibonacciWeightedBoost(baseCoherence, 2); + const boost3 = applyFibonacciWeightedBoost(baseCoherence, 5); expect(boost1).toBeGreaterThanOrEqual(baseCoherence); expect(boost2).toBeGreaterThanOrEqual(baseCoherence); @@ -500,14 +500,14 @@ describe('fibonacciCoherenceBoost', () => { test('should cap boost at 1.0', () => { const baseCoherence = 0.95; - const boosted = fibonacciCoherenceBoost(baseCoherence, 10); + const boosted = applyFibonacciWeightedBoost(baseCoherence, 10); expect(boosted).toBe(1); }); test('should handle low base coherence', () => { const baseCoherence = 0.1; - const boosted = fibonacciCoherenceBoost(baseCoherence, 3); + const boosted = applyFibonacciWeightedBoost(baseCoherence, 3); expect(boosted).toBeGreaterThan(baseCoherence); expect(boosted).toBeLessThanOrEqual(1); @@ -515,7 +515,7 @@ describe('fibonacciCoherenceBoost', () => { test('should handle high iteration counts', () => { const baseCoherence = 0.5; - const boosted = fibonacciCoherenceBoost(baseCoherence, 100); + const boosted = applyFibonacciWeightedBoost(baseCoherence, 100); // Should be capped even with very high iterations expect(boosted).toBeGreaterThanOrEqual(baseCoherence); @@ -526,8 +526,8 @@ describe('fibonacciCoherenceBoost', () => { const baseCoherence = 0.7; const iteration = 5; - const result1 = fibonacciCoherenceBoost(baseCoherence, iteration); - const result2 = fibonacciCoherenceBoost(baseCoherence, iteration); + const result1 = applyFibonacciWeightedBoost(baseCoherence, iteration); + const result2 = applyFibonacciWeightedBoost(baseCoherence, iteration); expect(result1).toBe(result2); }); @@ -535,9 +535,9 @@ describe('fibonacciCoherenceBoost', () => { test('should increase boost with higher iterations', () => { const baseCoherence = 0.5; - const boost1 = fibonacciCoherenceBoost(baseCoherence, 1); - const boost5 = fibonacciCoherenceBoost(baseCoherence, 5); - const boost10 = fibonacciCoherenceBoost(baseCoherence, 10); + const boost1 = applyFibonacciWeightedBoost(baseCoherence, 1); + const boost5 = applyFibonacciWeightedBoost(baseCoherence, 5); + const boost10 = applyFibonacciWeightedBoost(baseCoherence, 10); // Later iterations should generally give higher boosts (until cap) expect(boost5).toBeGreaterThanOrEqual(boost1); @@ -546,7 +546,7 @@ describe('fibonacciCoherenceBoost', () => { test('should handle zero base coherence', () => { const baseCoherence = 0; - const boosted = fibonacciCoherenceBoost(baseCoherence, 5); + const boosted = applyFibonacciWeightedBoost(baseCoherence, 5); expect(boosted).toBeGreaterThanOrEqual(0); expect(boosted).toBeLessThanOrEqual(1); @@ -554,10 +554,7 @@ describe('fibonacciCoherenceBoost', () => { test('should handle perfect base coherence', () => { const baseCoherence = 1.0; - if (typeof fibonacciCoherenceBoost !== 'function') { - throw new Error('fibonacciCoherenceBoost is not a function'); - } - const boosted = fibonacciCoherenceBoost(baseCoherence, 5); + const boosted = applyFibonacciWeightedBoost(baseCoherence, 5); // Should remain at 1.0 expect(boosted).toBe(1); From 1a6b8077ca1fced1fe1a51921298f87f0d2fad70 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 00:59:36 +0000 Subject: [PATCH 3/4] Remove unused imports, dead code, and fix formatting issues Co-authored-by: toolate28 <105518313+toolate28@users.noreply.github.com> --- .github/workflows/coding-agent.yml | 34 ++++-------------------------- README.md | 14 ++++++------ agent_skills.py | 2 +- pytest.ini | 3 --- tests/test_agent_skills.py | 1 - 5 files changed, 12 insertions(+), 42 deletions(-) diff --git a/.github/workflows/coding-agent.yml b/.github/workflows/coding-agent.yml index 0ff3a5d..445d6e5 100644 --- a/.github/workflows/coding-agent.yml +++ b/.github/workflows/coding-agent.yml @@ -48,41 +48,15 @@ jobs: uses: actions/github-script@v7 with: script: | - // Security: Sanitize user-controlled input to prevent - // injection attacks. This function escapes special - // characters that could be used for injection - const sanitizeInput = (input) => { - if (typeof input !== 'string') return ''; - // Escape markdown special characters and HTML tags - return input - .replace(/[<>&"']/g, (char) => { - const entities = { - '<': '<', - '>': '>', - '&': '&', - '"': '"', - "'": ''' - }; - return entities[char]; - }) - .trim(); - }; + // NOTE: If user-controlled data (e.g., PR titles or bodies) + // is added to this message in the future, be sure to sanitize + // it before including it in the comment to avoid injection + // attacks. // Use hardcoded safe message (current implementation) const message = '🌀 **Agent Review**: Coherence >60%. ' + 'Ethical quantum sims validated. Ready for merge.'; - // Example of safely using user-controlled data - // (for future extensions): - // const prTitle = sanitizeInput( - // context.payload.pull_request?.title || '' - // ); - // const prBody = sanitizeInput( - // context.payload.pull_request?.body || '' - // ); - // const customMessage = `🌀 **Agent Review**: ` + - // `Analyzing PR "${prTitle}"\n\n${message}`; - github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, diff --git a/README.md b/README.md index db77c32..c93fb82 100644 --- a/README.md +++ b/README.md @@ -188,15 +188,15 @@ qdi/ ## 🤝 Contributing **Requirements:** - - Tests pass (`bun test`) - - No lint errors (`bun run lint`) - - PR description coherence ≥60% +- Tests pass (`bun test`) +- No lint errors (`bun run lint`) +- PR description coherence ≥60% **Tips for high coherence:** - - Avoid circular reasoning - - Conclude expansions clearly - - Use connectives: therefore, moreover, consequently - - Increase vocabulary diversity +- Avoid circular reasoning +- Conclude expansions clearly +- Use connectives: therefore, moreover, consequently +- Increase vocabulary diversity ## Coding Agent diff --git a/agent_skills.py b/agent_skills.py index f559a5c..6967233 100644 --- a/agent_skills.py +++ b/agent_skills.py @@ -19,7 +19,6 @@ import argparse import json -import os import sys from datetime import datetime from pathlib import Path @@ -175,6 +174,7 @@ def _extract_qubit_indices(gate_str: str) -> Optional[Union[Tuple[int], Tuple[in if len(params) == 2: return (int(params[0].strip()), int(params[1].strip())) except (ValueError, IndexError): + # Parsing failed (e.g., invalid integer or malformed indices); treat as no qubit indices. pass return None diff --git a/pytest.ini b/pytest.ini index 09f7130..7d68688 100644 --- a/pytest.ini +++ b/pytest.ini @@ -7,6 +7,3 @@ addopts = -v --strict-markers --tb=short -markers = - slow: marks tests as slow (deselect with '-m "not slow"') - integration: marks tests as integration tests diff --git a/tests/test_agent_skills.py b/tests/test_agent_skills.py index ae5ed02..c3051b7 100644 --- a/tests/test_agent_skills.py +++ b/tests/test_agent_skills.py @@ -6,7 +6,6 @@ """ import pytest -import json import sys from pathlib import Path From d2c47381f5c98aa13aebaf2d29931ef41d4f4721 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 18 Jan 2026 01:02:08 +0000 Subject: [PATCH 4/4] Add comprehensive tests for qubit range validation and ATOM decision functionality Co-authored-by: toolate28 <105518313+toolate28@users.noreply.github.com> --- tests/test_agent_skills.py | 232 +++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) diff --git a/tests/test_agent_skills.py b/tests/test_agent_skills.py index c3051b7..536ddb8 100644 --- a/tests/test_agent_skills.py +++ b/tests/test_agent_skills.py @@ -495,5 +495,237 @@ def test_functions_never_raise_exceptions(self): assert isinstance(result, dict) +class TestQubitRangeValidation: + """Test qubit index validation to prevent resource exhaustion""" + + def test_valid_single_qubit_gate(self): + """Test that valid single-qubit gate indices are accepted""" + result = agent_skills.simulate_circuit("h(0)") + assert result['status'] == 'simulated' + + result = agent_skills.simulate_circuit("h(50)") + assert result['status'] == 'simulated' + + result = agent_skills.simulate_circuit("h(100)") + assert result['status'] == 'simulated' + + def test_valid_two_qubit_gate(self): + """Test that valid two-qubit gate indices are accepted""" + result = agent_skills.simulate_circuit("cx(0,1)") + assert result['status'] == 'simulated' + + result = agent_skills.simulate_circuit("cx(50,51)") + assert result['status'] == 'simulated' + + result = agent_skills.simulate_circuit("cx(99,100)") + assert result['status'] == 'simulated' + + def test_single_qubit_below_range(self): + """Test that qubit index below 0 is rejected""" + result = agent_skills.simulate_circuit("h(-1)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + assert '-1' in result['error'] + assert 'Must be between 0 and 100' in result['error'] + + def test_single_qubit_above_range(self): + """Test that qubit index above MAX_QUBIT_INDEX is rejected""" + result = agent_skills.simulate_circuit("h(101)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + assert '101' in result['error'] + assert 'Must be between 0 and 100' in result['error'] + + def test_two_qubit_control_below_range(self): + """Test that control qubit below 0 is rejected""" + result = agent_skills.simulate_circuit("cx(-1,0)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + assert 'Control qubit' in result['error'] + assert '-1' in result['error'] + + def test_two_qubit_control_above_range(self): + """Test that control qubit above MAX_QUBIT_INDEX is rejected""" + result = agent_skills.simulate_circuit("cx(101,0)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + assert 'Control qubit' in result['error'] + assert '101' in result['error'] + + def test_two_qubit_target_below_range(self): + """Test that target qubit below 0 is rejected""" + result = agent_skills.simulate_circuit("cx(0,-1)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + assert 'Target qubit' in result['error'] + assert '-1' in result['error'] + + def test_two_qubit_target_above_range(self): + """Test that target qubit above MAX_QUBIT_INDEX is rejected""" + result = agent_skills.simulate_circuit("cx(0,101)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + assert 'Target qubit' in result['error'] + assert '101' in result['error'] + + def test_very_large_qubit_index(self): + """Test that extremely large qubit indices are rejected""" + result = agent_skills.simulate_circuit("h(10000)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + assert '10000' in result['error'] + + def test_multiple_gates_with_invalid_qubit(self): + """Test that circuit with one invalid qubit is rejected""" + result = agent_skills.simulate_circuit("h(0); h(101); x(1)") + assert result['status'] == 'error' + assert 'out of range' in result['error'] + + def test_boundary_values(self): + """Test boundary values for qubit indices""" + # Test exact boundaries + result = agent_skills.simulate_circuit("h(0)") + assert result['status'] == 'simulated' + + result = agent_skills.simulate_circuit("h(100)") + assert result['status'] == 'simulated' + + # Test just outside boundaries + result = agent_skills.simulate_circuit("h(-1)") + assert result['status'] == 'error' + + result = agent_skills.simulate_circuit("h(101)") + assert result['status'] == 'error' + + +class TestATOMDecisionFunctionality: + """Test ATOM trail provenance tracking functionality""" + + def test_cascade_integration_creates_atom_decision(self): + """Test that cascade_integration creates ATOM decision""" + result = agent_skills.cascade_integration("provenance quantum ethical") + + # Check that ATOM decision fields are present + assert 'atom_decision' in result + assert 'atom_tag' in result + + # Verify ATOM decision structure + decision = result['atom_decision'] + assert 'atom_tag' in decision + assert 'type' in decision + assert 'description' in decision + assert 'timestamp' in decision + assert 'files' in decision + assert 'tags' in decision + assert 'freshness' in decision + assert 'verified' in decision + + def test_atom_decision_type_is_verify(self): + """Test that cascade ATOM decisions have type VERIFY""" + result = agent_skills.cascade_integration("test") + decision = result['atom_decision'] + assert decision['type'] == 'VERIFY' + + def test_atom_decision_includes_keyword_count(self): + """Test that ATOM decision description includes keyword count""" + result = agent_skills.cascade_integration("provenance quantum ethical") + decision = result['atom_decision'] + assert '3 ethical keywords' in decision['description'] + + result = agent_skills.cascade_integration("no keywords here") + decision = result['atom_decision'] + assert '0 ethical keywords' in decision['description'] + + def test_atom_decision_tags_include_found_keywords(self): + """Test that ATOM decision tags include found keywords""" + result = agent_skills.cascade_integration("provenance quantum") + decision = result['atom_decision'] + + # Should include base tags plus found keywords + assert 'cascade' in decision['tags'] + assert 'provenance' in decision['tags'] + assert 'ethical-review' in decision['tags'] + assert 'quantum' in decision['tags'] + + def test_atom_tag_format(self): + """Test that ATOM tag follows correct format: ATOM-TYPE-YYYYMMDD-NNN-description""" + result = agent_skills.cascade_integration("test") + atom_tag = result['atom_tag'] + + # Check format + parts = atom_tag.split('-') + assert parts[0] == 'ATOM' + assert parts[1] == 'VERIFY' + # parts[2] should be YYYYMMDD + assert len(parts[2]) == 8 + assert parts[2].isdigit() + # parts[3] should be NNN (counter) + assert len(parts[3]) == 3 + assert parts[3].isdigit() + # parts[4+] should be slugified description + assert len(parts) >= 5 + + def test_atom_decision_timestamp_format(self): + """Test that ATOM decision timestamp is ISO format""" + result = agent_skills.cascade_integration("test") + decision = result['atom_decision'] + + # Check ISO format timestamp + timestamp = decision['timestamp'] + assert 'T' in timestamp + # Should be parseable as ISO format + from datetime import datetime + datetime.fromisoformat(timestamp) + + def test_atom_decision_freshness_and_verified(self): + """Test that new ATOM decisions are marked fresh and unverified""" + result = agent_skills.cascade_integration("test") + decision = result['atom_decision'] + + assert decision['freshness'] == 'fresh' + assert decision['verified'] == False + + def test_atom_decision_files_field(self): + """Test that ATOM decision includes files field""" + result = agent_skills.cascade_integration("test") + decision = result['atom_decision'] + + assert isinstance(decision['files'], list) + assert 'pr_body' in decision['files'] + + def test_atom_trail_directory_created(self): + """Test that ATOM trail directories are created""" + from pathlib import Path + + # Trigger ATOM decision creation + agent_skills.cascade_integration("test") + + # Check directories exist + assert Path(".atom-trail").exists() + assert Path(".atom-trail/counters").exists() + assert Path(".atom-trail/decisions").exists() + + def test_atom_decision_persisted_to_file(self): + """Test that ATOM decision is persisted to JSON file""" + import json + from pathlib import Path + + result = agent_skills.cascade_integration("test") + atom_tag = result['atom_tag'] + + # Check that decision file exists + decision_file = Path(".atom-trail/decisions") / f"{atom_tag}.json" + assert decision_file.exists() + + # Verify file content matches decision + with open(decision_file, 'r') as f: + persisted = json.load(f) + + assert persisted['atom_tag'] == atom_tag + assert persisted['type'] == 'VERIFY' + assert 'description' in persisted + assert 'timestamp' in persisted + + if __name__ == '__main__': pytest.main([__file__, '-v'])