AI Agent Instructions — HDL IP Packager¶
Read this first. This file is your briefing. Everything critical fits below; references lead you to detail when needed. If you are a human contributor, this is also the fastest onboarding path.
Project in one paragraph¶
The HDL IP Packager is a Python 3.11+ tool that brings package-manager
ergonomics (think pip/npm/cargo/docker pull) to HDL IP cores
(Verilog/VHDL/SystemVerilog). Each core carries an ip.toml manifest declaring a
VLNV identity (vendor:library:name:version), metadata, source filesets,
dependencies (as SemVer constraints), and build targets. The library
(hdlpkg) and CLI (hdlpkg) provide the manifest → resolve → lock →
fetch → generate pipeline. The foundation (versioning, identity, manifest) is
implemented and tested; resolution, registries, packaging, and tool-flow
generation are designed and stubbed. Design rationale lives in
research/state_of_the_art.md.
Status & what to work on next¶
No blocking issues. The project is at the foundation stage. The ordered roadmap (Resolver → Lockfile → Cache/Registry → Pack/Publish → Generate → IP-XACT export → Supply-chain) is in progress_tracker.md. Always read the progress tracker before starting — it is the single source of truth for what is done versus planned.
Build & run¶
- Requirements: Python 3.11+ (uses stdlib
tomllib). No runtime deps yet. - Set up the dev environment (editable install + test/lint/type tools):
python -m pip install -e ".[dev]" - Run the tool:
hdlpkg --help, orpython -m hdlpkg --help(works even if the script dir is not on PATH). - Quality gates (all must pass before merge):
Optionally
pytest # tests + coverage gate (fail_under in pyproject) ruff check . # lint ruff format --check . # formatting mypy # strict typing on src/pre-commit installto run ruff + mypy automatically on each commit (config in.pre-commit-config.yaml).
Branch & merge workflow¶
Day-to-day work lands on develop, the working branch — commit directly (or via
a short-lived feature branch you merge into it); no PR for normal work. main is
the protected release line (ruleset "main": no direct commits/pushes, no force-push,
no deletion, merge-commit-only), updated only through the release flow:
- Do the work on
develop; make the quality gates green and commit. No PR — the accumulateddevelopdiff is reviewed at the next release. - At release time, cut
release/X.Y.Zoffdevelop, bump the version, push, and open a PR intomain(gh pr create). CI runs on the PR. - Once CI is green, review the PR with
/code-reviewand resolve every finding — fix it, or, if it's out of this release's scope, file it indocs/progress_tracker.mdOpen Non-Blocking Issues. Never merge with an open, unaddressed finding. - Confirm every PR check is green (hard gate) with
gh pr checks <branch> --watch(must exit 0 — the whole CI matrix, not one workflow; never pipe totail, which hides the exit code). A flaky infra failure is re-run to green (gh run rerun <id> --failed), never bypassed. - Merge with a merge commit —
gh pr merge --merge --admin(squash and rebase are disabled,allowed_merge_methods: ["merge"]; GitHub forbids approving your own PR, so--admincovers only the required-review / last-push approval — never use it to merge past a red or pending check) — then tag the mergedmainand fast-forwarddevelopto it.
Defer to a human gate only when the agent cannot safely decide on its own — the
1.0.0 stability sign-off, a security-sensitive or hard-to-reverse change, or
anything the user has explicitly reserved; there, prepare the branch + PR and stop.
The /tackle-issue and /release commands encode this flow (see
README -> Releasing).
File map — where to find what¶
| What you need | Where |
|---|---|
| CLI entry point | src/hdlpkg/cli.py (main) |
| Public API exports | src/hdlpkg/init.py |
| SemVer + constraints | src/hdlpkg/version.py |
| VLNV identity | src/hdlpkg/vlnv.py |
ip.toml parsing/validation |
src/hdlpkg/manifest.py |
| Exception hierarchy | src/hdlpkg/exceptions.py |
| Resolver | src/hdlpkg/resolver.py |
Lockfile (ip.lock) |
src/hdlpkg/lockfile.py |
| Content-addressed cache | src/hdlpkg/cache.py |
| Registry (local/HTTP/writable) | src/hdlpkg/registry.py |
Packaging (.ipkg) |
src/hdlpkg/packaging.py |
Tool-flow backends (gen) |
src/hdlpkg/backends/ |
| IP-XACT / SBOM / tree view | ipxact.py, sbom.py, treeview.py |
| Per-module reference (manual) | docs/modules/ |
| Tests | tests/ — see tests/README.md |
| Test summary renderer | scripts/render_test_summary.py |
| Project + tool config | pyproject.toml (single source of truth) |
| CI pipeline | .github/workflows/ci.yml |
Documentation map¶
| Document | Purpose |
|---|---|
README.md |
Project overview, install, usage, workflow (root) |
docs/ai_agent_instructions.md |
This briefing |
docs/architecture.md |
Module map, data model, subsystem designs, data flow |
docs/progress_tracker.md |
Done / in-progress / planned — read before working |
docs/research/state_of_the_art.md |
Research survey backing every design choice |
docs/INDEX.md |
Quick-find: every file, concept, topic |
docs/README.md |
docs/ folder navigation |
tests/README.md |
How the test suite is organized and how to extend it |
Coding conventions (Python) — follow these for all new code¶
The implemented modules are the reference; match their style.
- Language & style: Python 3.11+, PEP 8 via
ruff format(line length 100). English for all identifiers, comments, docstrings, and log/error messages. - Naming:
snake_casefor functions/variables/modules,PascalCasefor classes,UPPER_SNAKE_CASEfor module constants,_leading_underscorefor internal helpers. Boolean helpers read asis_/has_/can_. - Types are mandatory on every function signature in
src/.mypy --strictmust pass. Prefer precise types (tuple[str, ...],dict[str, object]) overAny. - Purity by default: keep parsing/logic free of I/O and global state (see
version/vlnv/manifest). Do filesystem/network only in the CLI and the registry layer. This is the single most important rule for testability. - Immutable value types: model data as
@dataclass(frozen=True). Parse with a@classmethodparse/from_*; render with__str__. - Errors: raise a subclass of
HdlPackagerError(add one inexceptions.pyif needed) with a message that names the offending input. Neverprintfor errors in library code; never silently swallow. - Docstrings: a module docstring stating purpose + key design notes, and a one-line docstring on every public function/class stating its contract (what it returns, what counts as failure). Comment the why, not the what; keep inline comments to one or two lines.
- Dependencies: keep runtime deps minimal — justify every new one in the PR
and the progress tracker. Dev-only tools go in
[project.optional-dependencies].dev. - CLI: keep it thin — parse args, delegate to library functions, return an
exit code. No business logic in
cli.py.
Implement for testability — hard rule¶
- Every new behaviour ships with tests in the same change. No exceptions.
- Write the logic as a pure function you can call with plain values; if you
find yourself needing the filesystem/network to test something, extract the
pure decision into its own function and test that (this is exactly how
manifeststays testable despite reading files). - Put fast, isolated tests under
tests/unit/(markerunit); multi-module or filesystem tests undertests/integration/(markerintegration). - Cover the error paths, not just the happy path — every
raiseshould have a test. - Keep coverage at or above the
fail_undergate inpyproject.toml; raise the gate as the implemented surface grows. See tests/README.md.
Agent obligations — after every change¶
- Update progress_tracker.md — move the item, add a dated entry at the top of the relevant section. Never delete history; archive it.
- Update architecture.md when a module, the data model, or the data flow changed (flip a (planned) to (implemented)).
- Update INDEX.md when files, concepts, or commands were added.
- Update
README.mdwhen user-visible behaviour, install, or the CLI changed. - Run the quality gates (pytest + ruff + mypy) and make them green.
- No duplication — if the same explanation exists in two docs, consolidate and link. Long-form goes in docs; code carries a one-line pointer.
- English only. No emojis in doc/heading text (the test-report status icons
in
scripts/are the one intentional exception). - Consider the
/coding-guidelinesand/update-docsskills in .claude/commands/ — read the full skill file when relevant.
Document size guidance¶
| File | Soft limit | When exceeded |
|---|---|---|
docs/ai_agent_instructions.md |
150 lines | Move detail to architecture.md |
docs/architecture.md |
400 lines | Split a subsystem into docs/modules/<name>.md |
docs/progress_tracker.md |
250 lines | Move old milestones to Archive |
docs/INDEX.md |
200 lines | Split by domain |