Skip to content

feat(quantum): Q-Share Phase D — P2P sharing notebook + web Results/Backends tabs#25

Merged
febuz merged 1 commit into
mainfrom
feat/quantum-phase-d
Jul 4, 2026
Merged

feat(quantum): Q-Share Phase D — P2P sharing notebook + web Results/Backends tabs#25
febuz merged 1 commit into
mainfrom
feat/quantum-phase-d

Conversation

@febuz

@febuz febuz commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Q-Share Phase D (final phase) — make the three-kind artifact model tangible for users.

Notebook

notebooks/05_p2p_fabric_sharing.ipynb — end-to-end, runnable in Colab:

  1. Load a library circuit → lcid:
  2. Run on Qiskit Aer → QuantumResult (lres:) linking back to the circuit
  3. Describe the backend → BackendDescriptor (lqpu:)
  4. Node A publishes all three by CID (relay-optional)
  5. Node B pulls by CID, verifies bit-identical content across nodes
  6. Cross-kind queries on B
  7. Closes with the true-P2P fabric path via knitweb.quantum (pulse)

Non-Qiskit logic verified against the package end-to-end.

Web

web/index.html gains a Circuits | Results | Backends tab switcher:

  • Results — measurement histograms (bar per bitstring) + provenance CIDs
  • Backends — QPU/simulator capability cards (aer_simulator, ibm_kyiv, ionq_aria, quantinuum_h2) with qubits + native gates, sim/hardware pill
  • Domain chips + search scope to the active tab; a note explains a live node streams real data from the relay. All dynamic values HTML-escaped.

Test plan

  • Notebook JSON valid (15 cells); core artifact flow runs green against knitweb_lens.quantum
  • web/index.html JS syntax-checked (node --check), div/script balanced, all CSS vars defined
  • No Python changes → existing tests/quantum/ unaffected

Completes the Q-Share plan. 🎉

🤖 Generated with Claude Code

Summary by Sourcery

Introduce P2P quantum artifact sharing notebook and extend the web lens UI with circuits/results/backends browsing.

New Features:

  • Add a Colab-ready notebook demonstrating end-to-end P2P sharing of circuits, results, and backend descriptors between nodes using content IDs.
  • Add Results and Backends tabs to the web lens alongside Circuits, with search scoped per tab and example shared artifacts wired into the UI.
  • Display quantum measurement histograms and provenance CIDs for results, and backend capability cards for simulators and hardware QPUs.

Enhancements:

  • Refine web styling with new accent color, histogram, key-value, and simulator/hardware pill components, and contextual tab notes explaining relay-backed data streaming.

…ackends tabs

- notebooks/05_p2p_fabric_sharing.ipynb — end-to-end demo: run a library circuit
  on Qiskit Aer -> QuantumResult (lres:), describe the backend (lqpu:), node A
  publishes all three by CID (relay-optional), node B pulls by CID and verifies
  bit-identical content, then queries across kinds. Closes with the true-P2P
  fabric path via knitweb.quantum. Non-Qiskit logic verified against the package.
- web/index.html — add a Circuits | Results | Backends tab switcher to the circuit
  browser. Results tab shows measurement histograms with provenance CIDs;
  Backends tab shows QPU/simulator capability cards (aer, ibm_kyiv, ionq_aria,
  quantinuum_h2). Domain chips + search scope to the active tab; a note explains
  a live node streams real results/backends from the relay. All values escaped.

Completes the Q-Share plan (P2P sharing of quantum circuits, results & systems).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@sourcery-ai

sourcery-ai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements the final Q-Share Phase D by adding a Colab-ready notebook that demonstrates P2P sharing of circuits, results, and backend descriptors, and by extending the web UI with Circuits/Results/Backends tabs, histogram/result cards, backend capability cards, and tab-aware search/domain chips, all wired through new client-side rendering logic.

Sequence diagram for the P2P sharing notebook circuit/result/backend flow

sequenceDiagram
  actor User
  participant NodeA
  participant StoreA as Store(node_a)
  participant Relay
  participant NodeB
  participant StoreB as Store(node_b)

  User->>NodeA: library()['bell_phi_plus']
  NodeA-->>User: QuantumCircuit(circ) with circ.cid (lcid:)
  User->>NodeA: QuantumResult(circuit_cid=cid, counts, author)
  User->>NodeA: BackendDescriptor(name='aer_simulator', ...)

  User->>StoreA: Store(root, relay)
  User->>StoreA: put(circ)
  StoreA-->>Relay: put(circ) (if relay configured)
  User->>StoreA: put(backend)
  User->>StoreA: put(result)
  StoreA-->>User: list()

  User->>StoreB: Store(root or node_a.root, relay)
  User->>StoreB: get(circ.cid)
  User->>StoreB: get(result.cid)
  User->>StoreB: get(backend.cid)
  StoreB-->>User: QuantumCircuit(got_circuit)
  StoreB-->>User: QuantumResult(got_result)
  StoreB-->>User: BackendDescriptor(got_backend)

  User->>User: assert got_circuit.cid == circ.cid
  User->>User: assert got_result.cid == result.cid
  User->>User: assert got_backend.cid == backend.cid

  User->>StoreB: list(kind='result') / list(kind='backend')
  User->>StoreB: find(query='aer', kind='backend')
Loading

Sequence diagram for the web tab switching and rendering of circuits/results/backends

sequenceDiagram
  actor User
  participant Browser
  participant setTab
  participant renderCircuits
  participant renderResults
  participant renderBackends

  User->>Browser: click Circuits tab
  Browser->>setTab: setTab('circuits', button)
  setTab->>Browser: update domain-row, search placeholder, tab-note
  setTab->>renderCircuits: render()
  renderCircuits-->>Browser: update count, grid with CIRCUITS

  User->>Browser: click Results tab
  Browser->>setTab: setTab('results', button)
  setTab->>Browser: hide domain-row, set placeholder "Search results…", show tab-note
  setTab->>renderResults: render()
  renderResults-->>Browser: update count, grid with RESULTS (histograms)

  User->>Browser: click Backends tab
  Browser->>setTab: setTab('backends', button)
  setTab->>Browser: hide domain-row, set placeholder "Search backends…", show tab-note
  setTab->>renderBackends: render()
  renderBackends-->>Browser: update count, grid with BACKENDS (capability cards)

  User->>Browser: type in search input
  Browser->>renderCircuits: render() [if _tab==='circuits']
  Browser->>renderResults: render() [if _tab==='results']
  Browser->>renderBackends: render() [if _tab==='backends']
Loading

File-Level Changes

Change Details Files
Add tabbed Circuits/Results/Backends UI with tab-aware search and domain chips on the quantum web page.
  • Introduce tab bar markup with three tabs and active-state styling, including a new accent color variable.
  • Wrap domain filter chips in a container that is toggled based on active tab and adjust search placeholder per tab.
  • Add a tab note element that explains relay-backed live data for non-circuit tabs.
  • Implement setTab() to manage active tab state, chip visibility, note text, and trigger re-rendering.
  • Refactor render() into a dispatcher that calls renderCircuits(), renderResults(), or renderBackends() depending on active tab.
web/index.html
Render shared quantum results as histogram cards with provenance CIDs, using example data when not connected to a live node.
  • Define a RESULTS array of example measurement artifacts keyed by circuit, circuit CID, backend, shots, counts, and description.
  • Add CSS for histogram layout and rows, including bitstring labels, bars sized proportionally to shot counts, and count labels.
  • Implement renderResults() to filter results by circuit or backend, update counts, and generate card HTML with histograms and CID tags.
  • Ensure all dynamic strings inserted into the DOM are HTML-escaped via the existing _esc() helper.
web/index.html
Render backend capability cards for simulators and hardware QPUs, including qubit counts, native gates, and simulator/hardware pills.
  • Define a BACKENDS array of example backend descriptors with name, provider, qubit count, native gates, simulator/hardware flag, and description.
  • Add CSS for key-value layout and simulator/hardware pill badges with distinct colors.
  • Implement renderBackends() to filter backends by name, provider, or gate names, update counts, and generate card HTML with capability details and tags.
  • Use the existing _esc() helper when rendering backend-related strings to avoid XSS in dynamic content.
web/index.html
Add a new Colab-ready notebook demonstrating end-to-end P2P sharing of circuits, results, and backend descriptors between two nodes.
  • Create notebook metadata with Python 3 kernelspec and Colab configuration, and add introductory markdown explaining the three artifact kinds and CID namespaces.
  • Install knitweb-lens and Qiskit/Aer, then load a library circuit, printing its name, CID, and QASM representation.
  • Execute the circuit on Qiskit Aer, normalize count keys, and mint a QuantumResult that links back to the circuit and exposes convenience properties.
  • Mint a BackendDescriptor describing an Aer simulator, then re-bind the QuantumResult with backend provenance via backend_cid.
  • Instantiate a Store for node A (optionally bound to KNITWEB_RELAY), publish circuit/result/backend artifacts, and list stored artifacts by kind.
  • Instantiate a Store for node B, fetch artifacts by CID, assert CID equality for bit-identical integrity across nodes, and print summaries of retrieved artifacts.
  • Demonstrate cross-kind queries on node B (listing results/backends and searching backends by query string).
  • Close with markdown describing integration with the Knitweb fabric via knitweb.quantum from the separate pulse package, including example code for publishing circuit records to peers.
notebooks/05_p2p_fabric_sharing.ipynb

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 4 issues, and left some high level feedback:

  • In renderResults, the search filter lowercases q but compares it to r.circuit without lowercasing, which makes circuit-name matching case-sensitive and inconsistent with backend matching; consider normalizing r.circuit as well.
  • Similarly, in renderBackends, the search uses b.gates.join(' ').includes(q) while q is lowercased and gates are not, so gate-name filtering will be case-sensitive; normalizing gate strings (e.g. .toLowerCase()) would make search behavior consistent.
  • The tabs and domain chips rely on inline onclick handlers; moving these to addEventListener-based bindings would keep behavior and presentation separated and make future JS refactoring easier.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `renderResults`, the search filter lowercases `q` but compares it to `r.circuit` without lowercasing, which makes circuit-name matching case-sensitive and inconsistent with backend matching; consider normalizing `r.circuit` as well.
- Similarly, in `renderBackends`, the search uses `b.gates.join(' ').includes(q)` while `q` is lowercased and `gates` are not, so gate-name filtering will be case-sensitive; normalizing gate strings (e.g. `.toLowerCase()`) would make search behavior consistent.
- The tabs and domain chips rely on inline `onclick` handlers; moving these to `addEventListener`-based bindings would keep behavior and presentation separated and make future JS refactoring easier.

## Individual Comments

### Comment 1
<location path="web/index.html" line_range="83" />
<code_context>
+  .tab{background:transparent;border:1px solid var(--border);border-bottom:none;
+    border-radius:8px 8px 0 0;color:var(--muted);cursor:pointer;font:inherit;font-size:12px;padding:8px 16px}
+  .tab:hover{color:var(--text)}
+  .tab.active{color:var(--accent);border-color:var(--accent)55;background:var(--accent)0d}
+  .hist{display:flex;flex-direction:column;gap:3px;margin-top:10px}
+  .hist-row{display:flex;align-items:center;gap:8px;font-size:10px}
</code_context>
<issue_to_address>
**issue (bug_risk):** Alpha suffixes on CSS color variables are invalid and will be ignored by the browser.

Values like `var(--accent)55` and `var(--accent)0d` are not valid CSS colors, so `border-color` and `background` won’t apply. If you need transparency, use `rgba()` or define separate variables (e.g. `--accent-border`, `--accent-bg`) with full color values such as `#58a6ff55`. The same issue applies to the pill styles (`var(--green)18`, `var(--green)44`, `var(--orange)18`, `var(--orange)44`).
</issue_to_address>

### Comment 2
<location path="web/index.html" line_range="383-385" />
<code_context>
   });
 }

+function renderResults() {
+  const q = document.getElementById('search').value.toLowerCase();
+  const rows = RESULTS.filter(r => !q || r.circuit.includes(q) || r.backend.toLowerCase().includes(q));
+  document.getElementById('count').textContent = `${rows.length} result${rows.length===1?'':'s'}`;
+  const grid = document.getElementById('grid');
</code_context>
<issue_to_address>
**issue (bug_risk):** Search in `renderResults` mixes lowercased query with a case-sensitive circuit name comparison.

The query is lower-cased, but only `r.backend` is compared case-insensitively; `r.circuit.includes(q)` stays case-sensitive. For consistent search behavior, also lower-case `r.circuit`, e.g. `r.circuit.toLowerCase().includes(q)`.
</issue_to_address>

### Comment 3
<location path="web/index.html" line_range="409-410" />
<code_context>
+  });
+}
+
+function renderBackends() {
+  const q = document.getElementById('search').value.toLowerCase();
+  const rows = BACKENDS.filter(b => !q || b.name.toLowerCase().includes(q)
+    || b.provider.toLowerCase().includes(q) || b.gates.join(' ').includes(q));
+  document.getElementById('count').textContent = `${rows.length} backend${rows.length===1?'':'s'}`;
</code_context>
<issue_to_address>
**suggestion:** Search in `renderBackends` treats gate names case-sensitively while other fields are case-insensitive.

`b.name` and `b.provider` are compared in lower case, but `b.gates.join(' ').includes(q)` is not, so gate matching is case-sensitive. Consider normalizing the gates string with `.toLowerCase()` before `includes(q)` to keep search behavior consistent.

```suggestion
  const rows = BACKENDS.filter(b => !q || b.name.toLowerCase().includes(q)
    || b.provider.toLowerCase().includes(q) || b.gates.join(' ').toLowerCase().includes(q));
```
</issue_to_address>

### Comment 4
<location path="web/index.html" line_range="91-92" />
<code_context>
+  .hist-row .n{color:var(--muted);width:44px}
+  .kv{display:grid;grid-template-columns:auto 1fr;gap:2px 10px;margin-top:8px;font-size:11px}
+  .kv .k{color:var(--muted)} .kv .v{color:var(--text);word-break:break-all}
+  .pill-sim{font-size:9px;padding:1px 6px;border-radius:3px;background:var(--green)18;border:1px solid var(--green)44;color:var(--green)}
+  .pill-hw{font-size:9px;padding:1px 6px;border-radius:3px;background:var(--orange)18;border:1px solid var(--orange)44;color:var(--orange)}
 </style>
 </head>
</code_context>
<issue_to_address>
**issue (bug_risk):** Pill background/border colors reuse the same invalid color pattern as the active tab styles.

These `background` and `border` values (`var(--green)18`, `var(--green)44`, and the orange equivalents) are not valid CSS colors, so browsers will ignore them and the pills won’t display as intended. Please replace them with valid color tokens (e.g., dedicated `--pill-sim-bg` / `--pill-sim-border` variables using proper hex or rgba values).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread web/index.html
.tab{background:transparent;border:1px solid var(--border);border-bottom:none;
border-radius:8px 8px 0 0;color:var(--muted);cursor:pointer;font:inherit;font-size:12px;padding:8px 16px}
.tab:hover{color:var(--text)}
.tab.active{color:var(--accent);border-color:var(--accent)55;background:var(--accent)0d}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Alpha suffixes on CSS color variables are invalid and will be ignored by the browser.

Values like var(--accent)55 and var(--accent)0d are not valid CSS colors, so border-color and background won’t apply. If you need transparency, use rgba() or define separate variables (e.g. --accent-border, --accent-bg) with full color values such as #58a6ff55. The same issue applies to the pill styles (var(--green)18, var(--green)44, var(--orange)18, var(--orange)44).

Comment thread web/index.html
Comment on lines +383 to +385
function renderResults() {
const q = document.getElementById('search').value.toLowerCase();
const rows = RESULTS.filter(r => !q || r.circuit.includes(q) || r.backend.toLowerCase().includes(q));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Search in renderResults mixes lowercased query with a case-sensitive circuit name comparison.

The query is lower-cased, but only r.backend is compared case-insensitively; r.circuit.includes(q) stays case-sensitive. For consistent search behavior, also lower-case r.circuit, e.g. r.circuit.toLowerCase().includes(q).

Comment thread web/index.html
Comment on lines +409 to +410
const rows = BACKENDS.filter(b => !q || b.name.toLowerCase().includes(q)
|| b.provider.toLowerCase().includes(q) || b.gates.join(' ').includes(q));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Search in renderBackends treats gate names case-sensitively while other fields are case-insensitive.

b.name and b.provider are compared in lower case, but b.gates.join(' ').includes(q) is not, so gate matching is case-sensitive. Consider normalizing the gates string with .toLowerCase() before includes(q) to keep search behavior consistent.

Suggested change
const rows = BACKENDS.filter(b => !q || b.name.toLowerCase().includes(q)
|| b.provider.toLowerCase().includes(q) || b.gates.join(' ').includes(q));
const rows = BACKENDS.filter(b => !q || b.name.toLowerCase().includes(q)
|| b.provider.toLowerCase().includes(q) || b.gates.join(' ').toLowerCase().includes(q));

Comment thread web/index.html
Comment on lines +91 to +92
.pill-sim{font-size:9px;padding:1px 6px;border-radius:3px;background:var(--green)18;border:1px solid var(--green)44;color:var(--green)}
.pill-hw{font-size:9px;padding:1px 6px;border-radius:3px;background:var(--orange)18;border:1px solid var(--orange)44;color:var(--orange)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Pill background/border colors reuse the same invalid color pattern as the active tab styles.

These background and border values (var(--green)18, var(--green)44, and the orange equivalents) are not valid CSS colors, so browsers will ignore them and the pills won’t display as intended. Please replace them with valid color tokens (e.g., dedicated --pill-sim-bg / --pill-sim-border variables using proper hex or rgba values).

@febuz febuz merged commit 3636750 into main Jul 4, 2026
6 checks passed
@febuz febuz deleted the feat/quantum-phase-d branch July 4, 2026 13:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant