Dev - #1
Open
pro-utkarshM wants to merge 25 commits into
Open
Conversation
- Added tree-sitter runtime deps then pulled them after install failures on Node 25.2.1 (native binding ABI mismatch with Node 25's cppgc internals). M1 falls back to a regex-based SV scanner for the AST layer; tree-sitter promoted to the M2 upgrade path (already noted in the plan's risks section). - Added vitest, tsx, typescript devDeps. - Pre-emptively gitignore .hermes/ (local scratch) and bench/ output tmpfiles.
…ter) - Pure-TS scanner handles modules (parameter lists, port lists, package-import-then-ports), module instantiations (param + named ports), and a stable sha-256 source digest. - Tree-sitter stays in the M2 upgrade path after Node ABI stabilises.
Pipeline: contracts → ast_slice → decisions → constraints → agent_exemplars. - Each layer is a pure function of inputs. - content_hash is sha-256 over the rendered layers (length-prefixed). - Test suite asserts identical content_hash over 10 reruns and full byte-equality of every layer (determinism invariant #2).
End-to-end: profile + contracts + repo rtl/ + entities.json → 5-layer deterministic context package → JSON output file + optional append to events.log.
- rtl/uart_tx.sv: real synthesizable 8N1 FSM (replaces T6 placeholder). - rtl/uart_rx.sv: minimal RX stub (loopback fixture only). - rtl/uart_top.sv: top-level wrapper exercising both TX and RX as instantiations, used to validate queryInstantiations() on real code. - tb/tb_uart_tx.sv: self-checking testbench, prints PASS/FAIL. - entities.json: real engineering graph — 2 requirements, 3 modules, 2 decisions, 4 constraints, 10 relations. - TASK.md / EXPECTED_DIFF.md: the bench prompt + reference solution. - Makefile: lint + simulate, gracefully skips if no Verilator/Icarus.
Honest about what's in M1 and what's deliberately deferred to M2+. The try-it block works against the bench fixture.
10 reruns against the bench fixture. Unique content_hashes: 1 Variance: 0.00% (PASS criterion: ≤ 2%) Verdict: PASS ✅ M1 has converged. No determinism leak in compiler.ts.
Canonical signal shape used by entity, contract, and (M2) AST layers. Includes isSignalRef type-guard and renderSignalRef with a fixed, hash-stable output format. Replaces ad-hoc per-layer signal typings.
Net -20 LOC. parseContract delegates signal validation to isSignalRef. Re-exports renderSignalRef as renderContractSignal for unified signal rendering. Behaviour on shipped contracts: zero (no shipped contract has description on signals).
Entity is now { kind, id, fields, extensions? }. First-class kinds (11)
ship with isX narrowing helpers (isModule, isConstraint, ...). Plugins
can register new kinds without modifying core/src/.
Breaking change for any caller of addEntity that constructs entities
in the old inline shape. Test files updated; bench fixture migration
to the new shape lands in the entities.json task.
Register/has/kinds/validate. First-class kinds (11, in entities.ts) are reserved names. validate is pass-through for first-class kinds; the runtime's narrowing helpers carry that responsibility. v1.0.1 ships the framework. No plugin kinds in this release; that's M2 work.
input_hash previously dropped description, exemplars_per_agent, and soft_token_margin from the digest input. As soon as a renderer reads any of those, the cache silently returns stale output. The full profile object is now canonicalised into the hash. Five regression tests verify that mutating any profile field changes the input_hash. Note: bench fixture entities.json is still in the v0.1 shape; this breaks the bench ablation until T11 migrates the fixture. Verified by unit tests, not the bench gate.
Replaces the unicode-arrow hand-roll. Signal rendering is now exactly one place (types.ts#renderSignalRef), text-safe, hash-stable across reruns for any transformer that touches the output.
…olarity
R-2 / SCHEMA-F (partial). SvScan extends from { modules, instantiations }
to also include ports, parameters, clock_signals, reset_signals,
reset_polarity, and parameter_overrides. Width parsing handles
literal '[msb:lsb]', '[msb-1]', and symbolic widths (resolution
deferred to M2). Reset polarity inferred from always_ff sensitivity
lists and if-conditions (active_{low,high}_{sync,async}, or 'none').
…s, reset The renderer now produces a structured per-module section with port list, parameters, clock signals, reset signals, and reset polarity. Also removes the redundant source_sha duplication (it lived in both the layer content and the input_hash; the second is enough).
Layout: <root>/<sha[:2]>/<sha[2:4]>/<sha>.bin + <root>/manifests/<sha>.json. Identical bytes produce identical sha → no duplicate writes. Producers (compile-context, EDA adapters, verifiers) attach metadata via put(). Consumers query by sha, type, producer, or entity_refs. M2+ lands producers. v1.0.1 has the surface + tests, no producer wired.
ARCHITECTURE (overrides prior plan line):
compile() computes. ← pure, sync, deterministic, zero I/O
ArtefactStore persists. ← async, content-addressed, generic
CLI composes both.
Rationale (per architecture review):
Async compile() optimised for filesystem writes, but filesystem is
one of many possible persistence backends (memory, S3, OCI, ...).
Pushing I/O into compile() would force every remote-store plugin to
replay the same machinery, leak timeout/retry semantics, and make
'compute only' impossible without writing a null store.
Option B keeps compile() pure. The CLI composes compile() →
compileOutputToArtefact() → store.record(). The same store carries
context packages, AST snapshots, synthesis reports, timing reports,
waveforms, benchmarks — because the store does not interpret bytes.
Substrate changes:
- compile() is sync, no artefact_store on CompileInputs, no
artefact_sha on CompileOutput.
- Artefact redesigned around opaque body + ref envelope (no
compiler-specific knowledge in the store).
- New: core/src/cli/artefact-bridge.ts owns the
CompileOutput → Artefact serialisation. Lives in CLI layer because
'what does a context package look like on disk' is an
orchestration concern.
- CLI now: sync compile → writeFileSync(--out) → async
store.record(artefact). The compile step stays synchronous.
Architectural invariants verified:
- compile() function body has zero I/O calls (verified via source
analysis).
- 106 tests pass, including 9 artefact-store tests with non-JSON
bytes (raw waveform payloads) verifying the store is opaque.
- The compile-step can run entirely in memory; only persistence is
async.
Plan file gets an erratum: T10 was mis-stated as 'compile() takes
optional artefact_store'. The correct form is the optional layer
above compile().
T11 — bench fixture migration:
bench/uart/entities.json rewritten in {kind, id, fields} open
shape. addEntity's strict validation already enforces the shape
(landed in T3); this commit migrates the fixture to match.
T12 — dual-gate ablation:
Question 1 — compile() determinism (variance ≤ 2% across 10
reruns). Pillar of M1, unchanged in spirit.
Question 2 — ArtefactStore content-addressing (one manifest after
N reruns of the same body). NEW. The bridge ensures bodies are
keyed on content_hash, not on task_id, so the invariant holds.
Also: compileOutputToArtefact() drops task_id from the body.
Different task_ids that produce the same compile result now hash
to the same artefact — the store dedupes them on disk.
Verification:
106 unit tests pass.
Ablation: variance 0.00%, manifest count 1, verdict PASS.
README documents Option B (compile() pure), the AST layer's new fields, the open-shape entities, the cache-key fix, the artefact-store + content-addressing invariant, and the six architectural invariants the substrate carries forward.
Documents the Option B correction, the four MUST fixes, the verification gauntlet (8/8 gates, 106 unit tests, ablation PASS), remaining debt (six SHOULD/CAN items from the architecture review; deliberately parked), and the six invariants the substrate carries forward to v2.0. Verdict: substrate ready to freeze.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Why
Testing
Checklist
Breaking Changes
None