A deterministic dependency manager for physical hardware manufacturing.
In circuit design, a "Star Ground" is the single reference point where all signal paths converge to eliminate noise.
In manufacturing, this application serves the same function: it is the Single Source of Truth for your inventory, eliminating the "noise" of disorganized BOMs and supply chain drift.
In software, dependency resolution is deterministic: uv sync guarantees the exact same environment every time. In hardware, procurement is currently stochastic: manual aggregation introduces human error, where a single forgotten $0.01 resistor causes a blocking failure weeks later.
Star Ground forces hardware logistics to behave like software. It rejects ambiguous inputs and treats physical inventory as a strict dependency tree. By enforcing a validated schema on unstructured data, it transforms procurement from fragile manual aggregation into a deterministic data pipeline.
π Try the Live App
Case Study: This engine was utilized as the logistics backbone for Systems Audio Lab, a project demonstrating the recursive engineering of physical instrumentation.
This system is designed to bridge the gap between Software Precision and Hardware Chaos. The architectural choices prioritize data integrity and human ergonomics over simple automation.
Supply chains have zero tolerance for hallucination. A 10k resistor cannot be "inferred" as 1k.
- The Decision: Instead of using an LLM to parse PDFs, I implemented a Hybrid Spatial Parser (
src/bom_lib/parser.py). It usespdfplumberto extract table vectors (spatial analysis) and falls back to rigorous Regex pattern matching. - The Result: 100% reproducible ingestion. The system fails loudly on ambiguity rather than guessing silently.
Most BOM tools sort lists alphabetically. Star Ground sorts by Physical Z-Height.
- The Insight: Efficient PCB assembly requires soldering low-profile components (Resistors, Diodes) before bulky ones (Electrolytic Capacitors, Switches) to keep the board flat on the workbench.
- The Implementation: The PDF generation engine enforces a topological sort order on the output artifacts, optimizing the human operator's runtime performance.
-
The Problem: The cost of a "Stockout" (halting work) is infinite relative to the cost of inventory.
-
The Algorithm: The sourcing engine applies a category-specific risk profile. It automatically buffers cheap components (resistors rounded to nearest 10) while strictly calculating expensive ones (ICs), transforming purchasing logic from simple arithmetic into a risk-management strategy.
-
The Problem: Most web apps swallow errors to "look clean," leaving users stranded when edge cases occur. In hardware, a silent failure (e.g., a parser dropping a line) results in a missing component and a failed build.
-
The Solution: I implemented a User-Facing Debug Console and Log Artifact Generation.
- The system strictly separates "Residuals" (noise) from "Exceptions" (logic failures).
- Critical errors are never suppressed; they are surfaced in the UI with full stack traces.
- Users can download a
debug.logsnapshot to attach to GitHub Issues, creating a deterministic feedback loop for bug reporting.
Beyond parsing, the engine functions as a domain expert system. It utilizes a lookup table of heuristic substitutions to suggest component upgrades based on audio engineering best practices.
-
Op-Amps: Detects generic chips and suggests Hi-Fi alternatives (e.g.,
TL072βOPA2134for lower noise floor). - Fuzz Logic: Automatically detects "Fuzz" topologies and injects Germanium transistors with specific "Positive Ground" warnings.
-
Texture Generation: Maps clipping diodes to their sonic equivalents based on Forward Voltage (
$V_f$ ) and Reverse Recovery Time ($t_{rr}$ ).
Ordering parts for multiple analog circuits is error-prone.
- Format Inconsistency: Every BOM uses different spacing, tabs, and naming conventions.
- Inventory Risk: Buying parts you already own (waste) or forgetting a $0.01 resistor (shipping delay).
- Assembly Chaos: Mixing up parts between three different projects on the same workbench.
This tool treats BOM parsing as a data reduction problem. It doesn't just read lines; it verifies them against a stateful inventory model.
- Multi-Format Ingestion:
- PDF Parsing: Extracts tables from PedalPCB build docs using visual layout analysis (hybrid grid/text strategy).
- Smart Presets: A hierarchical browser allowing filtering by Source (e.g., PedalPCB) and Category to load standard circuit definitions.
- URL Ingestion: Fetch BOMs directly from websites like PedalPCB.
- Inventory Logistics (Net Needs):
- Upload your current stock CSV.
- The engine calculates
Net Need = max(0, BOM_Qty - Stock_Qty). - Safety buffers are only applied to the deficit, preventing over-ordering.
- Manufacturing Outputs:
- Field Manuals: Generates Z-height sorted printable PDF checklists (Resistors β Sockets β Caps) for streamlined assembly.
- Sticker Sheets: Generates Avery 5160 labels with condensed references (e.g.,
R1-R4) for part binning. - Master Bundle: Downloads a single ZIP containing all source docs, shopping lists, and manual PDFs.
- Smart Normalization:
- Expands ranges automatically (
R1-R5βR1, R2, R3, R4, R5). - Detects potentiometers by value (
B100k) even if labeled non-standardly.
- Expands ranges automatically (
- Observability & Debugging:
- In-App Console: Real-time visibility into the parsing kernel via a
st.session_statelog buffer. - Error Taxonomy: Visual distinction between "Partial Success" (warnings) and "Critical Failure" (errors), ensuring the user always knows the integrity of their data.
- In-App Console: Real-time visibility into the parsing kernel via a
This system is designed to bridge the gap between Software Precision and Hardware Chaos. The architectural choices prioritize data integrity and human ergonomics over simple automation.
Most BOM tools sort lists alphabetically or by Reference ID (C1, C2, R1...). Star Ground sorts by Physical Z-Height.
- The Insight: Efficient PCB assembly requires soldering low-profile components (Resistors/Diodes) before high-profile ones (Electrolytic Capacitors/Switches) to keep the board flat on the workbench.
- The Implementation: The PDF generation engine (
src/pdf_generator.py) enforces a strict topological sort order on the output artifacts. The software explicitly optimizes the human operator's runtime performance, reducing context switching and physical instability during assembly.
PDFs are visual documents, not data structures. A standard text scraper loses the row/column relationships defined by the grid lines.
- The Strategy: I implemented a Hybrid Parser that utilizes
pdfplumberto extract table vectors (spatial analysis) first. - The Fallback: If the spatial grid is ambiguous, the system gracefully degrades to a deterministic Regex scanner. This "Defense in Depth" strategy allows the engine to digest everything from pristine digital exports to legacy documents without hallucinating data.
In small-batch manufacturing, the cost of a "Stockout" (halting work for a $0.05 part) is effectively infinite relative to the cost of inventory.
- The Algorithm: The sourcing engine applies a category-specific risk profile to the "Net Needs" calculation:
- Resistors: Round up to nearest 10 (Economy of scale; cheaper to buy 10 than 1).
- Discrete Silicon: +1 Safety Buffer for Transistors/Oscillators (high risk of heat damage during soldering).
- ICs: Exact Count (Protected by sockets, reducing risk of installation failure).
- This transforms the purchasing logic from simple arithmetic into a risk-management strategy.
Electronic component values are notoriously inconsistent (4k7, 4.7k, 4700, 4,700R). String matching fails here.
-
The Mechanism: The ingestion layer (
src/bom_lib/utils.py) acts as a recursive parser for SI prefixes (p,n,u,k,M). It normalizes all inputs to floating-point primitives ($4.7 \times 10^3$ ) before any aggregation occurs. -
The Result:
4k7and4700are correctly aggregated as the exact same SKU, preventing duplicate orders that string-based parsers would miss.
The reliability of the physical build depends entirely on the determinism of the data pipeline. To mitigate the "Logistical Entropy" of changing PDF formats, the system employs a multi-layered testing strategy:
PDF parsing is inherently fragile. To ensure that updates to the parser do not silently break support for legacy formats, we utilize Snapshot Testing.
- Methodology: The test suite parses a library of "Golden Master" PDFs (real-world build docs).
- Verification: The resulting object model is serialized to JSON and diffed against a stored "Truth" file.
- Outcome: Any deviation in the parsing logicβeven a single changed resistor valueβtriggers a CI failure, guaranteeing 100% backward compatibility.
Standard unit tests only check the "happy path." We use the Hypothesis library to perform property-based testing.
- Fuzzing: The test runner generates thousands of semi-random inputs (malformed text, edge-case floats, Unicode injection) to "attack" the parser.
- Invariant Checking: Ensures that
calculate_net_needs()remains mathematically sound (e.g.,Net_Need >= 0) regardless of input chaos.
We utilize Streamlit.AppTest to run headless simulations of the user interface during CI.
- Simulation: The test runner instantiates the app kernel, mimics user clicks/uploads, and asserts the state of the dataframes.
- Scope: Verifies the full "Paste β Parse β Download" lifecycle without requiring a browser driver.
- Python 3.13 - Core language (Strictly typed & pinned)
- uv - Ultra-fast dependency management and locking
- Streamlit - Interactive web interface and state management
- pdfplumber - PDF table extraction and layout analysis
- fpdf2 - Programmatic PDF generation
- Docker - Containerized runtime environment
- GitHub Actions - Continuous Integration enforcing strict quality gates:
- Linting: Ruff
- Type Safety: Mypy
- Snapshot Regression Testing: PDF "Golden Master" verification (ensures parser stability across legacy build docs)
- Property-Based Testing: Hypothesis (Fuzzing component values to ensure mathematical invariants)
- Integration Testing: Streamlit AppTest (Headless simulation of the full "Paste-to-PDF" user lifecycle)
- Delivery: Auto-publishes Docker images to GHCR on release
- Environment: Ubuntu Latest
.
βββ app.py <-- Interface: Streamlit Web App
βββ assets/ <-- Static assets (images, demos)
βββ Dockerfile <-- Container configuration
βββ examples/ <-- Output: Sample generated artifacts
β βββ Star_Ground_Artifacts/
β βββ Field Manuals/
β βββ Sticker Sheets/
β βββ Source Documents/
β βββ Shopping List.csv
β βββ My Inventory Updated.csv
βββ raw_boms/ <-- Input: Source files for the Presets Library
β βββ pedalpcb/
β βββ tayda/
βββ src/ <-- Application Core
β βββ bom_lib/ <-- Domain Logic Package
β β βββ __init__.py <-- Public API exposure
β β βββ classifier.py <-- Logic: Component identification heuristics
β β βββ constants.py <-- Data: Static lookups and regex patterns
β β βββ manager.py <-- Logic: Inventory mutation & net needs calculation
β β βββ parser.py <-- Logic: PDF/CSV ingestion engines
β β βββ presets.py <-- Data: Library of known pedal circuits
β β βββ sourcing.py <-- Logic: Purchasing rules & hardware injection
β β βββ types.py <-- Data: Type definitions (TypedDicts)
β β βββ utils.py <-- Logic: String parsing & normalization
β βββ exporters.py <-- Logic: CSV/Excel generation
β βββ feedback.py <-- Logic: Google Sheets API integration
β βββ pdf_generator.py <-- Output: Field Manuals & Sticker Sheets
βββ tests/ <-- QA Suite
β βββ samples/ <-- Real-world PDF/Text inputs for regression
β βββ snapshots/ <-- Golden Master JSONs for PDF testing
βββ tools/ <-- Developer Utilities
β βββ generate_presets.py
βββ CONTRIBUTING.md <-- Dev guide
βββ ROADMAP.md <-- Technical architectural plans
βββ pyproject.toml <-- Project metadata & tool config (Ruff/Mypy/Pytest)
βββ uv.lock <-- Exact dependency tree (Deterministic builds)
βββ requirements.txt <-- Deployment: Generated via uv for Streamlit Cloud
You can pull the pre-built image directly from the GitHub Container Registry without building it yourself.
# Run latest stable release
docker run -p 8501:8501 ghcr.io/jacksonfergusondev/star-ground:latestOr build from source:
docker build -t star-ground .
docker run -p 8501:8501 star-groundThis project uses uv for dependency management.
# 1. Clone & Enter
git clone https://github.com/JacksonFergusonDev/star-ground.git
cd star-ground
# 2. Install Dependencies (Creates virtualenv automatically)
uv sync
# 3. Run App
uv run streamlit run app.pyWe are aggressively moving from a simple regex script to a context-aware physics engine.
Key Upcoming Initiatives:
- Architecture: Migrating to a Strategy Pattern and Context-Free Grammars for parsing.
- Intelligence: Topology inference (detecting "Fuzz" vs "Delay" circuits based on component clusters).
- Finance: Real-time pricing integration (Octopart/DigiKey) and volume arbitrage.
For the detailed technical breakdown and milestones, see ROADMAP.md.
We welcome contributions! Please see CONTRIBUTING.md for details on how to set up the dev environment, run the snapshot tests, and submit PRs.
- GitHub: @JacksonFergusonDev
- LinkedIn: Jackson Ferguson
- Email: jackson.ferguson0@gmail.com
This project is licensed under the MIT License - see the LICENSE file for details.
