Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
83374ef
feat(dlc10): pure-Rust driver + SPI flash programming
claude May 10, 2026
45be4e5
fix(dlc10): use real 22956-byte Cypress FX2 firmware (was placeholder)
May 12, 2026
5ed3ee5
feat(dlc10): debug subcommand + verbose sram for DONE=LOW diagnosis
claude May 12, 2026
ab68b05
fix(dlc10): RTI parking in Type-1 read + INIT_B poll after JPROGRAM
claude May 12, 2026
45b3edd
fix(dlc10): mirror openFPGALoader dumpRegister — per-word Update-DR
claude May 12, 2026
e3ab436
refactor(tri): centralize FPGA + hooks in Rust, remove Python/shell l…
claude May 12, 2026
fcfcc1f
fix(fpga): SPI flash JEDEC=FF FF FF on QMTech XC7A100T — bit-reverse …
claude May 12, 2026
5513309
feat(fpga): openXC7 build path for QMTech-specific proxy bitstream
claude May 12, 2026
ee13849
fix(tri): nextpnr-himbaechel xilinx uses -o xdc=/-o fasm= not --xdc/-…
gHashTag May 12, 2026
cdcebe8
feat(fpga): openXC7 chipdb setup helper for nextpnr-himbaechel
May 12, 2026
ce0f7ae
feat(fpga): docker vivado build path for QMTech proxy
claude May 12, 2026
572f134
fix(fpga): correct himbaechel device name to xc7a100tfgg676-1
gHashTag May 12, 2026
72fa55d
docs(fpga): openXC7 native FGG676 status — chipdb OK, config-pin rout…
claude May 12, 2026
4f4a0f5
fix(dlc10): SPI capture uses Migen JTAG2SPI framing (marker + BE leng…
claude May 12, 2026
237a6a7
feat(fpga): docker vivado 2025.2 image prep for FGG676 proxy
claude May 12, 2026
916b091
docs(fpga): docker-vivado FGG676 status — image build in progress
claude May 12, 2026
f8ddfde
feat(fpga): deploy CI-built spiOverJtag_xc7a100tfgg676.bit proxy bits…
claude May 12, 2026
cdb820c
feat(dlc10): fix bring-up, read_cfg_reg, and STARTUPCLK — DONE=HIGH a…
claude May 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions .claude/hooks/check-l1-traceability.sh
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
#!/bin/bash
# L1 Traceability Check - Ensures commits reference issues
# L1: "No code merged without `Closes #N`"

#!/usr/bin/env bash
# L1 TRACEABILITY gate — thin forwarder to the Rust implementation.
#
# Real logic lives in `cli/tri` (`tri hooks l1-check`). This file exists
# only so that pre-existing harness wiring that exec's the .sh path keeps
# working. Do not add logic here — edit `cli/tri/src/hooks.rs` instead.
set -euo pipefail

# Get last commit message
COMMIT_MSG=$(git log -1 --pretty=%B HEAD)
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

# Check for issue reference pattern
if ! echo "$COMMIT_MSG" | grep -qE "Closes #|Fixes #|Resolves #|Reference #"; then
for p in \
"$REPO_ROOT/target/release/tri" \
"$REPO_ROOT/target/debug/tri" \
; do
if [[ -x "$p" ]]; then
exec "$p" hooks l1-check
fi
done

# Fallback if the Rust binary is not yet built (e.g. fresh clone).
COMMIT_MSG=$(git log -1 --pretty=%B HEAD)
if ! echo "$COMMIT_MSG" | grep -qE "(Closes|Fixes|Resolves|Reference) #[0-9]+"; then
echo "L1 VIOLATION: Commit missing issue reference"
echo "Commit message: $COMMIT_MSG"
echo "Required pattern: Closes #N, Fixes #N, etc."
echo "Required pattern: Closes #N | Fixes #N | Resolves #N | Reference #N"
exit 1
fi

# Check for issue number after pattern
ISSUE_NUM=$(echo "$COMMIT_MSG" | grep -oE "#[0-9]+" | head -1)
if [ -z "$ISSUE_NUM" ]; then
echo "L1 VIOLATION: No issue number found"
exit 1
fi

echo "L1 PASSED: Issue #$ISSUE_NUM referenced"
exit 0
echo "L1 PASSED: Issue $ISSUE_NUM referenced"
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,8 @@ bootstrap/.trinity/
!.trinity/current_task/notebook_meta.json
.trinity/current_task/session_log.jsonl
.trinity/gate_bypasses.log

# Vivado Docker build secrets (token + installer)
docker/wi_authentication_key
docker/FPGAs_AdaptiveSoCs_Unified_SDI_*.bin
docker/Xilinx_Unified_*.bin
64 changes: 36 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = ["bootstrap", "bindings/javascript", "cli/tri", "cli/trios-bridge", "cli/flash-spi"]
members = ["bootstrap", "bindings/javascript", "cli/tri", "cli/trios-bridge", "cli/flash-spi", "cli/dlc10"]
exclude = ["bindings/python", "tools/converter", "gen"]

[workspace.package]
Expand Down
94 changes: 94 additions & 0 deletions MIGRATION_AUDIT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# MIGRATION_AUDIT.md

Audit of `.py` and `.sh` files in the t27 repository for migration to Rust /
centralization in the `tri` CLI, per issue #592.

**Scope:** every `.py`/`.sh` file outside `target/`, `node_modules/`,
`contrib/solana/node_modules/`, `contrib/portable-claude-setup/`,
`research/trinity-pellis-paper/`, and `.git/`.

**Classes:**

- **A — Infra critical path:** pre-commit / push hooks, CI gates, scripts
invoked from `.githooks/` or `.github/workflows/`. Must be rewritten in
Rust and exposed via `tri hooks <name>`.
- **B — FPGA tooling duplicates:** Python implementations of cable/flash
programming whose behaviour now lives in `cli/dlc10` (Rust, silicon-
verified). Delete.
- **C — Research / examples / contrib backend:** standalone scripts not on
any commit / push / CI critical path. Keep as-is for this migration.
- **D — Bootstrap stubs:** `bootstrap/t27c.py`,
`bootstrap/src/memory/ace_step_wrapper.py`. The real `t27c` is the
Rust binary built from `bootstrap/`. Stubs are unused at the critical
path; keep for this migration, address separately.

## Decisions for this PR (#593, Closes #592)

| Path | Class | Decision | Rationale |
|------|-------|----------|-----------|
| `tools/dlc10_jtag.py` | B | **Delete** | Behaviour reimplemented in `cli/dlc10` lib (silicon-verified: IDCODE `0x13631093`, SRAM blink, SPI flash). |
| `tools/tri_fpga/__init__.py` | B | **Delete** | Same as above; package empty. |
| `tools/tri_fpga/cli.py` | B | **Delete** | Same as above; replaced by `tri fpga ...`. |
| `.claude/hooks/check-l1-traceability.sh` | A | **Rewrite + keep stub** | Wrapped via `tri hooks l1-check`; the `.sh` becomes a one-line forwarder so any existing harness wiring keeps working. |
| `.claude/hooks/session-gate.sh` | A | Keep | Calls into `cargo run`; not on commit/push path, harness-only. Out of scope for this PR. |
| `.claude/hooks/stop-hook-guard.sh` | A | Keep | Session-stop accounting only; not on commit/push gate. |
| `.claude/hooks/inject-notebook-context.sh` | A | Keep | NotebookLM telemetry, not a gate. |
| `.githooks/pre-commit` | A | Keep | Already delegates to `scripts/tri check-now` (Rust `t27c`). Out of scope. |
| `.githooks/pre-push` | A | Keep | NotebookLM gate, no Rust replacement available yet. |
| `.githooks/post-merge` | A | Keep | NotebookLM sync; non-blocking. |
| `scripts/tri` | A | Keep | Already a 17-line forwarder to the Rust `t27c` binary. |
| `scripts/ci/now-sync-gate-diff.sh` | A | Keep | CI-only diff check against GitHub event env; thin glue. |
| `scripts/ci/phi-loop-last-failure.sh` | A | Keep | Diagnostic only, off the merge gate. |
| `scripts/aggregate-experience.sh` | A | Keep | Triggered by `brain-seal-refresh.yml` workflow; not commit-gate. |
| `.claude/skills/tri/scripts/*.sh` | A | Keep | Skill-internal helpers, not invoked from any gate. |
| `scripts/fpga/build.sh`, `scripts/fpga/flash.sh` | C | Keep | Vivado wrappers — orthogonal to the DLC10 USB driver. |
| `examples/fpga/qmtech_minimal/build.sh` | C | Keep | Example; not on critical path. |
| `bootstrap/t27c.py`, `bootstrap/src/memory/ace_step_wrapper.py` | D | Keep | Out of scope; handled separately. |
| `contrib/backend/**/*.py` | C | Keep | NotebookLM / music-generator backends; not on commit gate. |
| `clara-bridge/**/*.py` | C | Keep | Research bridge. |
| `benchmarks/**/*.py`, `research/**/*.py`, `scripts/ultra_engine_v*.py`, `scripts/pysr_*.py`, `scripts/pslq_*.py`, `scripts/trinity-pellis-pipeline/**/*.py`, `external/kaggle/**/*.py`, `docs/clara/examples/*.py` | C | Keep | Research / examples; orthogonal. |
| `bindings/python/**/*.py` | C | Keep | Python bindings to golden-float crate. |
| `conformance/kepler_newton_tests.py` | C | Keep | Conformance helper not on gate. |
| `test_notebooklm.py`, `test_notebooklm_venv.sh` | C | Keep | Manual smoke tests at repo root. |
| `scripts/tri-*.py`, `scripts/audit_discovery.py`, `scripts/check_first_party_doc_language.py`, `scripts/verify_*.py`, `scripts/lee_*.py`, `scripts/compare_*.py`, `scripts/fix_*.py`, `scripts/overnight_research_agent.py`, `scripts/print_pellis_seal_decimal.py`, `scripts/unified_search_all.py`, `scripts/wrapup/*.py` | C | Keep | Standalone helpers; none referenced from `.githooks/` or commit-path workflows. |
| `scripts/install-*.sh`, `scripts/setup-git-hooks.sh`, `scripts/auto-*.sh`, `scripts/check-conflicts.sh`, `scripts/bulk-create-notebooks.sh`, `scripts/generate_episodes.sh`, `scripts/git_commands_tasks_1_4.sh`, `scripts/mcp-wrapper.sh`, `scripts/phi-loop-stack.sh`, `scripts/run_v51_multiple.sh`, `scripts/test-agent-bridge.sh`, `scripts/verify-notebooklm.sh`, `scripts/verify-ssot-integration.sh` | C | Keep | One-shot setup / human-invoked utilities; not gated. |

## New `tri` subcommands added by this PR

| Command | Behaviour |
|---------|-----------|
| `tri fpga idcode` | Read DLC10 JTAG IDCODE (was `tools/dlc10_jtag.py idcode` / `dlc10 idcode`). |
| `tri fpga sram <bit> [--verbose]` | Program FPGA SRAM (volatile). |
| `tri fpga program <bit> [--no-verify]` | Program SPI flash (persistent). |
| `tri fpga flash-id` | Read SPI flash JEDEC ID. |
| `tri fpga status` | Raw CFG_OUT status. |
| `tri fpga debug [--no-jstart]` | Decode 7-series CFG registers. |
| `tri hooks l1-check` | Pure-Rust port of `.claude/hooks/check-l1-traceability.sh` (commit-message issue-reference gate). |
| `tri hooks now-gate` | Verifies `docs/NOW.md` "Last updated" is today's date (UTC). |
| `tri hooks pre-commit` | Runs the migrated gates in sequence (currently `now-gate` + `l1-check`). |

## Crate restructuring

- `cli/dlc10` is now a **lib crate** (`lib.rs` already exposed all primitives;
the `[lib]` target is now consumed by both `cli/flash-spi` and `cli/tri`).
The `dlc10` binary stays as a thin diagnostic wrapper.
- `cli/flash-spi` continues to ship a `flash-spi` binary that re-exports the
same logic; for new work users are pointed at `tri fpga program`.
- `cli/tri` gains a `fpga` subcommand backed by `dlc10::Dlc10` directly
(no shell-out, no Python).

## What was NOT changed and why

- `scripts/tri` (the Bash forwarder to `t27c`): already a 17-line thin
wrapper around a Rust binary. Rewriting it to Rust would be circular
(Rust binary launching a Rust binary). Constitution allows it under
L7-UNITY since it never implements logic.
- `.githooks/pre-commit` and `pre-push`: still call `scripts/tri check-now`
and a NotebookLM ID guard. These remain Bash because they're glue and
the Rust replacement for the NotebookLM client is out of scope.
- `bootstrap/t27c.py`: scaffolding stub; deletion would force a
bootstrap-tooling change that is orthogonal to this issue.

---

**Issue:** #592 — Closes #592 in the corresponding commit.
20 changes: 20 additions & 0 deletions cli/dlc10/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "dlc10"
version.workspace = true
edition.workspace = true
license.workspace = true
description = "Pure-Rust driver for Xilinx Platform Cable USB II (DLC10/DLC9), supports JTAG + SPI flash via 7-series proxy"

[lib]
path = "src/lib.rs"

[[bin]]
name = "dlc10"
path = "src/bin/dlc10.rs"

[dependencies]
rusb = "0.9"
anyhow = "1"
clap = { version = "4", features = ["derive", "env"] }
thiserror = "1"
hex = "0.4"
66 changes: 66 additions & 0 deletions cli/dlc10/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# dlc10 — pure-Rust driver for the Xilinx DLC10/DLC9

Replaces the legacy Python `tools/dlc10_jtag.py` with a Rust crate providing:

- USB enumeration + Cypress FX2 firmware load (Intel-HEX `xusb_xp2.hex`)
- Low-level JTAG primitives (`shift_ir`, `shift_dr`, `cycle_tck`, …)
- `read_idcode`, `read_status`, `program_sram` (correct UG470 §6 sequence)
- `program_flash`: loads a JTAG-to-SPI bridge bitstream into SRAM, then
drives the on-board SPI flash (M25P/N25Q-class) via `USER1`

## Critical fixes vs the prior Python attempt

1. **SRAM `JPROGRAM` was missing.** The old flow `JSHUTDOWN → CFG_IN →
JSTART` left `DONE = LOW`. The correct UG470 §6 sequence is now
implemented:
```
JPROGRAM cycle_tck(64)
JSHUTDOWN cycle_tck(12)
CFG_IN <bitstream> cycle_tck(1)
JSTART cycle_tck(24)
BYPASS → CFG_OUT → STATUS
```
2. **`chunk_bits = 16379`** for `_do_shift` — explicitly **not** a multiple
of 4. The DLC10 firmware silently corrupts payloads with multiple-of-4
bit counts unless padded.
3. **USB endpoints**: `EP_OUT = 0x02`, `EP_IN = 0x86`, vendor-request
`0xB0`, FX2 firmware-load request `0xA0`, FX2 CPUCS register `0xE600`.

## CLI

```text
dlc10 idcode # read and print IDCODE
dlc10 sram <file.bit> # SRAM program (volatile)
dlc10 flash <file.bit> [--verify] # SPI flash program (permanent)
dlc10 flash-id # JEDEC ID via JTAG-to-SPI bridge
dlc10 status # CFG_OUT STATUS register
```

## Embedded blobs

- `fpga/tools/xusb_xp2.hex` — Cypress FX2 firmware for the DLC10 cable.
**The file currently committed is a placeholder EOF record.** Copy the
real 22 956-byte HEX (from a working Vivado / xc3sprog install) onto the
build host before producing a release binary. Build will succeed with
the placeholder, but `Dlc10::open()` will fail to bring up the cable.

- `fpga/tools/bscan_spi_xc7a100t.bit` — JTAG-to-SPI bridge bitstream for
the XC7A100T, **404 986 bytes**, SHA-256
`6e8cef49958fbab96a217c209782be67f4943ff80ae9c81e51425da41fc975e0`.
Sourced from
<https://github.com/quartiq/bscan_spi_bitstreams>, **MIT-licensed**:

> Copyright © Robert Jördens et al.
> Permission is hereby granted, free of charge, to any person obtaining
> a copy of this software and associated documentation files…

See the upstream repo for the full MIT notice; we redistribute the
bitstream unmodified.

## Tests

```sh
cargo test -p dlc10 # unit tests (no hardware needed)
cargo test -p dlc10 -- --ignored # hardware integration (DLC10 + Wukong)
cargo clippy -p dlc10 -- -D warnings
```
Loading
Loading