Deterministic build graph planner and DAG plan generator for MSVC/Qt C++ projects
Project description
NGKsGraph
NGKsGraph is a deterministic Python CLI for Windows C++ build intelligence with MSVC-aware graph analysis.
It scans sources, generates deterministic build plans, and executes full compile/link/deploy builds via
ngksgraph build. It can also iteratively apply deterministic repair actions for common MSVC linker/compiler failures.
At configure time it also exports:
build/compile_commands.jsonfor clangd/IDE IntelliSense/toolingbuild/ngksgraph_graph.jsonas a structured target graph snapshot
Requirements
- Python 3.11+
- MSVC tools available (
cl,link) - MSVC developer environment (run inside x64 Native Tools Command Prompt)
Quickstart
cd examples/hello_msvc
python -m ngksgraph configure
python -m ngksgraph build
python -m ngksgraph run
or after install:
ngksgraph configure
ngksgraph build
ngksgraph run
Building without opening VS Developer Prompt
From a normal PowerShell session, NGKsGraph can bootstrap MSVC for the build process:
python -m ngksgraph configure
python -m ngksgraph build --msvc-auto
python -m ngksgraph run
With --msvc-auto, NGKsGraph discovers Visual Studio via vswhere, captures an
MSVC build environment using VsDevCmd.bat, and uses that environment only for
toolchain-aware planning/analysis subprocesses. Your current shell environment is not modified.
Repository CI includes a Windows smoke gate (.github/workflows/ngksgraph-windows-smoke.yml)
that validates --msvc-auto and targeted regression tests for bootstrap/buildplan behavior.
Commands
ngksgraph init --template <default|basic|qt-app|multi-target>- createngksgraph.tomlfrom templatengksgraph import --cmake <path>- createngksgraph.tomlfromCMakeLists.txtstarter mappingngksgraph configure- scan sources and emit deterministic plan/statengksgraph build- generate BuildCore plan and execute full compile/link/deployngksgraph build --target <name>- build a specific targetngksgraph plan --profile <name>- emit graph-native planning artifact (build_graph/<profile>/ngksgraph_plan.json)ngksgraph buildplan --profile <name>- emit NGKsBuildCore-consumable plan (build_graph/<profile>/ngksbuildcore_plan.jsonby default)ngksgraph buildplan --profile <name> --out <path>- emit NGKsBuildCore plan to a custom pathngksgraph run- generate BuildCore plan and run diagnostics (does not compile; usengksgraph buildfor a full build)ngksgraph clean- remove output directoryngksgraph doctor- verify MSVC toolchain availabilityngksgraph doctor --binary- verify packaged binary integrity against manifestngksgraph graph- export structured build graph JSONngksgraph explain src/main.cpp- explain why/how a source file is compiledngksgraph explain --link- print exact link commandngksgraph diff- structural diff between two snapshotsngksgraph trace <path>- trace impacted targets/executables for a sourcengksgraph trace --timing --profile <name>- print compact timing/cache reportngksgraph freeze- create deterministic reproducibility capsulengksgraph thaw <capsule.zip>- reconstruct generated outputs from a capsulengksgraph verify <capsule.zip>- verify capsule hashesngksgraph why <target>- explain dependency/rebuild attribution for targetngksgraph rebuild-cause <target>- classify structural vs command rebuild causes
Standalone Windows Build
Build a standalone Windows distribution (no pip/venv required for end users):
powershell -NoProfile -ExecutionPolicy Bypass -File tools/package_windows.ps1
Smoke test packaged executable:
powershell -NoProfile -ExecutionPolicy Bypass -File tools/smoke_standalone.ps1
Package output is written to:
artifacts/package/phase10/<timestamp>/
Integrity checks from packaged binary:
.\ngksgraph.exe --version
.\ngksgraph.exe doctor --binary
Multi-target config schema
Use [[targets]] to define multiple build targets (for example static libraries and executables):
out_dir = "build"
[build]
default_target = "app"
[[targets]]
name = "core"
type = "staticlib"
src_glob = ["src/core/**/*.cpp"]
include_dirs = ["src/core"]
links = []
[[targets]]
name = "app"
type = "exe"
src_glob = ["src/app/**/*.cpp"]
include_dirs = ["src/core"]
links = ["core"]
libs = ["user32"]
Single-target legacy top-level config remains supported and is upgraded internally.
Multi-target example
cd examples/multi_target_msvc
python -m ngksgraph configure
python -m ngksgraph build --target app --msvc-auto
python -m ngksgraph explain src/core/core.cpp
python -m ngksgraph explain --link --target app
Determinism
- Sorted source list and config collections (
include_dirs,defines,libs,lib_dirs) - Stable planning and action ordering
- Forward-slash normalized paths
Temporal + Graph Intelligence (Phase 5)
NGKsGraph now writes deterministic snapshots under build/.ngksgraph_snapshots/<timestamp>/.
Each snapshot stores:
graph.json(always)compdb.json(optional via[snapshots].write_compdb)ngksgraph.toml(optional via[snapshots].write_config)meta.jsonwith stable hashes (graph_hash,compdb_hash,config_hash,closure_hashes)
Snapshot retention is controlled by [snapshots].keep and oldest snapshots are pruned automatically.
Diff snapshots
ngksgraph diff
ngksgraph diff --json
ngksgraph diff --a 2026-02-26T06-39-21-082Z --b 2026-02-26T06-40-44-645Z
The diff includes:
- added/removed/changed targets
- added/removed graph edges
- hash changes
- compile command deltas and reason tokens
Trace source impact
ngksgraph trace src/core/core.cpp
ngksgraph trace src/core/core.cpp --json
Trace reports:
- owning target(s) for the source
- reverse-dependency impacted targets
- impacted executable closure
Reproducibility Capsules (Phase 6B)
Capsules are deterministic portable build-state artifacts:
- default path:
build/ngksgraph_capsules/<timestamp>_<project>_<target>.ngkcapsule.zip - deterministic ZIP ordering and fixed archive timestamps
- stable JSON newline normalization (
\n) - a freeze-time archive-hash manifest sidecar,
<capsule>.ngkcapsule.zip.sha256, recording the SHA-256 of the archive itself
Capsule content:
capsule_meta.jsongraph.jsoncompdb.jsonconfig.normalized.jsonhashes.jsontoolchain.json(sanitized summary only)snapshot_ref.json(only when freezing from snapshot)
Security/privacy:
- No API keys, tokens, or raw env dumps
- No
PATH=,INCLUDE=, orLIB=environment captures toolchain.jsonincludes only version/path summary fields
Freeze
ngksgraph freeze
ngksgraph freeze --target app
ngksgraph freeze --from-snapshot 2026-02-26T06-40-44-645Z
ngksgraph freeze --out build/ngksgraph_capsules/custom.ngkcapsule.zip
Verify
ngksgraph verify build/ngksgraph_capsules/<capsule>.ngkcapsule.zip
Thaw (fail-closed)
ngksgraph thaw build/ngksgraph_capsules/<capsule>.ngkcapsule.zip
ngksgraph thaw build/ngksgraph_capsules/<capsule>.ngkcapsule.zip --out-dir thawed_build --force
Thaw is fail-closed:
- Archive integrity is always verified, regardless of any flag. The archive's
SHA-256 is recomputed and compared to the freeze-time
<capsule>.zip.sha256manifest. A missing manifest, a hash mismatch (tampered/corrupted archive), or a truncated/BadZipFilearchive aborts the thaw with a structuredTHAW_FAILerror — no files are extracted. - Content verification (graph/compdb/closure/toolchain hashes) runs by default.
- Each successful thaw writes a
thaw_audit.jsonledger into the output directory recording the verified archive hash and whether verification was bypassed.
Skipping content verification is intentionally hard:
# Refused: --no-verify alone is not enough
ngksgraph thaw <capsule>.ngkcapsule.zip --no-verify
# -> THAW_FAIL (reason: verify_bypass_requires_acceptance)
# Allowed only with an explicit risk acceptance (archive integrity still enforced):
ngksgraph thaw <capsule>.ngkcapsule.zip --no-verify --i-accept-risks
# -> proceeds, prints a DANGER warning, and records the bypass in thaw_audit.json
Typical usage: freeze a known-good build state before refactors, then verify/thaw later to reproduce generated graph/compdb/config outputs.
Migration note: capsules frozen before this release have no
.sha256sidecar manifest and will fail closed on thaw (missing_archive_manifest). Re-freeze them, or restore the sidecar from a trusted record of the archive's SHA-256.
Build Forensics (Phase 6A)
Forensics mode explains why targets rebuild and where dependency/link behavior comes from.
Why attribution
ngksgraph why app
ngksgraph why app --json
ngksgraph why app --from-snapshot 2026-02-26T06-40-44-645Z
ngksgraph why app --from-capsule build/ngksgraph_capsules/<capsule>.ngkcapsule.zip
why output includes:
- target overview (type, direct links, closure, closure hash)
- direct edge attribution with origin metadata (
config_field,field,target_index) - closure path chains (direct vs indirect vs duplicate-path attribution)
- rebuild reasoning from latest snapshot comparison when baseline exists
Rebuild cause
ngksgraph rebuild-cause app
ngksgraph rebuild-cause app --json
rebuild-cause separates:
- STRUCTURAL CHANGE (closure hash, field-level root cause)
- COMMAND CHANGE (compdb deltas + mapped command tokens)
- NO CHANGE (likely timestamp-only or non-structural trigger)
Symbol-level heuristic
When logs contain unresolved-symbol errors (LNK2019, undefined reference), forensics performs a lightweight symbol search across sources and suggests missing link edges when symbol ownership appears outside the current closure.
Capsule forensic mode
why --from-capsule verifies capsule hashes first, then analyzes in-memory payloads (no extraction required).
Qt Toolchain Integration (Phase 6D)
NGKsGraph supports explicit deterministic Qt generation with:
mocfor headers containingQ_OBJECTuicfor.uifilesrccfor.qrcfiles
No implicit CMake-like behavior is used. Qt paths must be explicit.
Config
[qt]
enabled = true
moc_path = "C:/Qt/6.6.0/msvc2019_64/bin/moc.exe"
uic_path = "C:/Qt/6.6.0/msvc2019_64/bin/uic.exe"
rcc_path = "C:/Qt/6.6.0/msvc2019_64/bin/rcc.exe"
include_dirs = ["C:/Qt/6.6.0/msvc2019_64/include", "C:/Qt/6.6.0/msvc2019_64/include/QtCore", "C:/Qt/6.6.0/msvc2019_64/include/QtWidgets"]
lib_dirs = ["C:/Qt/6.6.0/msvc2019_64/lib"]
libs = ["Qt6Core.lib", "Qt6Widgets.lib"]
If qt.enabled = true and a required tool path is missing or invalid, configure fails hard.
Generated outputs
build/qt/moc_<basename>.cppbuild/qt/ui_<basename>.hbuild/qt/qrc_<basename>.cpp
Generator fingerprints include:
- input file hash
- tool binary hash
- tool version (
-v) - generator command arguments
- for
rcc:.qrcreferenced-file hashes
Trace and attribution
ngksgraph trace <path> includes Qt generator evidence keys:
qt.moc.generated/qt.moc.skippedqt.uic.generated/qt.uic.skippedqt.rcc.generated/qt.rcc.skippedqt.generator.reasonqt.generator.tool_hashqt.include.injectedqt.lib.injected
Capsule integration
freeze includes generated Qt artifacts and Qt tool provenance (path/hash/version). verify fails if Qt tool hash/version mismatches capsule metadata or generated Qt payload hashes differ.
End-to-end commands
ngksgraph configure
ngksgraph build
ngksgraph trace src/main.cpp
ngksgraph freeze
ngksgraph verify build/ngksgraph_capsules/<capsule>.ngkcapsule.zip
AI Repair Plugin Model
AI support is optional and plugin-based.
- AI never edits files directly or runs shell commands.
- AI can only suggest structured config actions such as:
- add include directory
- add library
- add library directory
- add define
If AI is enabled, deterministic repair is always attempted first.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file devfabeco_graph-0.4.0.tar.gz.
File metadata
- Download URL: devfabeco_graph-0.4.0.tar.gz
- Upload date:
- Size: 190.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ace4d1f78c060803652ad9c003190c5e107bf5402fef81bdc0b08084dec666b
|
|
| MD5 |
fbd38dc25e05952ca8c92dddfec8f366
|
|
| BLAKE2b-256 |
3212dfed17f15bf6a6a65f70a3cdc5774c78c103c4a51e70d3bc55250e05a0be
|
File details
Details for the file devfabeco_graph-0.4.0-py3-none-any.whl.
File metadata
- Download URL: devfabeco_graph-0.4.0-py3-none-any.whl
- Upload date:
- Size: 191.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1219483c613fa453b2972cdaf40c0227bb58a71620f6ea115ca4756ff53da603
|
|
| MD5 |
6eba6a07bf1c8cf2eb9042ad160b0932
|
|
| BLAKE2b-256 |
7f8bc751b6c1d1419223d5e9d5da467c5daa6fdf569d103dcb2d5a96b79dc7c0
|