Skip to main content

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.json for clangd/IDE IntelliSense/tooling
  • build/ngksgraph_graph.json as 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> - create ngksgraph.toml from template
  • ngksgraph import --cmake <path> - create ngksgraph.toml from CMakeLists.txt starter mapping
  • ngksgraph configure - scan sources and emit deterministic plan/state
  • ngksgraph build - generate BuildCore plan and execute full compile/link/deploy
  • ngksgraph build --target <name> - build a specific target
  • ngksgraph 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.json by default)
  • ngksgraph buildplan --profile <name> --out <path> - emit NGKsBuildCore plan to a custom path
  • ngksgraph run - generate BuildCore plan and run diagnostics (does not compile; use ngksgraph build for a full build)
  • ngksgraph clean - remove output directory
  • ngksgraph doctor - verify MSVC toolchain availability
  • ngksgraph doctor --binary - verify packaged binary integrity against manifest
  • ngksgraph graph - export structured build graph JSON
  • ngksgraph explain src/main.cpp - explain why/how a source file is compiled
  • ngksgraph explain --link - print exact link command
  • ngksgraph diff - structural diff between two snapshots
  • ngksgraph trace <path> - trace impacted targets/executables for a source
  • ngksgraph trace --timing --profile <name> - print compact timing/cache report
  • ngksgraph freeze - create deterministic reproducibility capsule
  • ngksgraph thaw <capsule.zip> - reconstruct generated outputs from a capsule
  • ngksgraph verify <capsule.zip> - verify capsule hashes
  • ngksgraph why <target> - explain dependency/rebuild attribution for target
  • ngksgraph 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.json with 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.json
  • graph.json
  • compdb.json
  • config.normalized.json
  • hashes.json
  • toolchain.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=, or LIB= environment captures
  • toolchain.json includes 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.sha256 manifest. A missing manifest, a hash mismatch (tampered/corrupted archive), or a truncated/BadZipFile archive aborts the thaw with a structured THAW_FAIL error — no files are extracted.
  • Content verification (graph/compdb/closure/toolchain hashes) runs by default.
  • Each successful thaw writes a thaw_audit.json ledger 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 .sha256 sidecar 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:

  • moc for headers containing Q_OBJECT
  • uic for .ui files
  • rcc for .qrc files

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>.cpp
  • build/qt/ui_<basename>.h
  • build/qt/qrc_<basename>.cpp

Generator fingerprints include:

  • input file hash
  • tool binary hash
  • tool version (-v)
  • generator command arguments
  • for rcc: .qrc referenced-file hashes

Trace and attribution

ngksgraph trace <path> includes Qt generator evidence keys:

  • qt.moc.generated / qt.moc.skipped
  • qt.uic.generated / qt.uic.skipped
  • qt.rcc.generated / qt.rcc.skipped
  • qt.generator.reason
  • qt.generator.tool_hash
  • qt.include.injected
  • qt.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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devfabeco_graph-0.4.0.tar.gz (190.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

devfabeco_graph-0.4.0-py3-none-any.whl (191.1 kB view details)

Uploaded Python 3

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

Hashes for devfabeco_graph-0.4.0.tar.gz
Algorithm Hash digest
SHA256 4ace4d1f78c060803652ad9c003190c5e107bf5402fef81bdc0b08084dec666b
MD5 fbd38dc25e05952ca8c92dddfec8f366
BLAKE2b-256 3212dfed17f15bf6a6a65f70a3cdc5774c78c103c4a51e70d3bc55250e05a0be

See more details on using hashes here.

File details

Details for the file devfabeco_graph-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for devfabeco_graph-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1219483c613fa453b2972cdaf40c0227bb58a71620f6ea115ca4756ff53da603
MD5 6eba6a07bf1c8cf2eb9042ad160b0932
BLAKE2b-256 7f8bc751b6c1d1419223d5e9d5da467c5daa6fdf569d103dcb2d5a96b79dc7c0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page