Skip to content

CLI graph --html and --output renderer work (3.4.5)#312

Draft
leynos wants to merge 13 commits into
mainfrom
3-4-5-extend-graph-subcommand-with-an-html-renderer
Draft

CLI graph --html and --output renderer work (3.4.5)#312
leynos wants to merge 13 commits into
mainfrom
3-4-5-extend-graph-subcommand-with-an-html-renderer

Conversation

@leynos
Copy link
Copy Markdown
Owner

@leynos leynos commented May 22, 2026

Summary

This branch carries the pre-implementation ExecPlan for roadmap item
3.4.5: extending netsuke graph with an --html renderer and a shared
--output <FILE> flag. No code lands in this branch — the plan must be
approved before implementation begins.

The plan introduces a GraphView domain projection consumed by a
GraphRenderer port, with separate adapters for DOT and HTML output, and
migrates the no-flag DOT path away from ninja -t graph to an in-process
renderer so a single pipeline owns ordering and escaping. The HTML
artefact is a single self-contained file with server-rendered SVG plus a
text outline, so it remains usable with JavaScript disabled. Renderer
technology selection happens at a Stage C prototyping gate: a pure-Rust
graph layout crate is the preferred path, with a vendored viz-js +
WebAssembly bundle documented as the fallback if the license,
determinism, binary-size, or artefact-size criteria fail. Structured
graph inspection (--json) is deferred to a follow-up roadmap item, but
the projection shape is designed to accommodate it.

Roadmap task: (3.4.5).

ExecPlan:
docs/execplans/3-4-5-extend-graph-subcommand-with-an-html-renderer.md.

Review walkthrough

  • Start with the Purpose / big picture section
    for the user-visible contract and the twelve observable-success
    criteria.
  • Then review Constraints
    and Tolerances
    for the hard invariants and the explicit escalation triggers — in
    particular the decision to remove ninja -t graph from the dispatch,
    and the binary-size and HTML-artefact ceilings.
  • Read Decision log
    for the captured choices from the planning consultation, including
    the rationale for rendering from the in-memory IR rather than the
    Ninja round-trip.
  • Step through the Plan of work
    stages: A (domain projection), B (CLI surface and DOT migration), C
    (HTML renderer behind a go/no-go gate), D (documentation, BDD, and
    accessibility polish).
  • The Interfaces and dependencies
    section names the exact types and signatures expected at each stage
    boundary; this is the contract a future implementing agent commits to.
  • The Referenced documents and skills
    block signposts every document and skill the implementing agent
    should load.

Validation

  • make markdownlint: 0 errors (55 files linted).

The plan does not introduce code, so no make check-fmt, make lint,
or make test change is in scope on this branch. Those gates will run
against the implementation pull request.

Notes

  • This pull request is pre-implementation. Future work is gated on
    explicit user approval of the plan.
  • Renderer technology selection deliberately escalates at Stage C if the
    pure-Rust path fails the documented acceptance gate. The vendored
    viz-js fallback is described but not adopted by default.
  • The plan removes the existing ninja -t graph dispatch for the
    graph subcommand and rewrites the associated tool-subcommand tests.
    This is allowed by ADR-003 (no compatibility aliases pre-0.1.0) and is
    recorded in the plan's Decision log.

References

Summary by Sourcery

Documentation:

  • Add a detailed ExecPlan describing the staged implementation, constraints, risks, and acceptance criteria for adding an HTML renderer and --output support to the graph subcommand.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 22, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6f62eb0a-f8ad-424c-b83e-5f4ff8b9adfb

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 3-4-5-extend-graph-subcommand-with-an-html-renderer

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai
Copy link
Copy Markdown
Contributor

sourcery-ai Bot commented May 22, 2026

Reviewer's Guide

Adds a detailed execution plan document for extending the netsuke graph subcommand with an --html renderer and shared --output flag, defining architecture, constraints, staged implementation steps, and testing/documentation requirements but no code changes yet.

File-Level Changes

Change Details Files
Introduce a comprehensive ExecPlan markdown document describing how to extend the graph subcommand with HTML rendering and an --output flag, migrate DOT generation in-process, and structure the work into staged milestones with constraints, risks, and validation steps.
  • Document user-facing goals and observable success criteria for the new graph behaviours, including DOT and HTML outputs and --output semantics.
  • Define architectural approach with a GraphView projection and GraphRenderer port, plus DOT and HTML adapters, and removal of ninja -t graph from the graph path.
  • Specify hard constraints, tolerances, and risks around determinism, binary and artefact size, licensing, localization, and configuration layering.
  • Lay out a four-stage plan (projection, CLI + DOT, HTML renderer with go/no-go gate, documentation/BDD/polish) including concrete steps and acceptance criteria for each stage.
  • Detail expected interfaces and type signatures for new modules (graph_view, renderers, CLI args, file I/O helpers) and enumerate required tests, docs updates, and external references/skills.
docs/execplans/3-4-5-extend-graph-subcommand-with-an-html-renderer.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos leynos changed the title Plan graph --html and --output renderer work (3.4.5) CLI graph --html and --output renderer work (3.4.5) May 26, 2026
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 26, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

tests/bdd/steps/cli.rs

Comment on lines +279 to +294

fn verify_graph_output_path(world: &TestWorld, path: &PathString) -> Result<()> {
    let command = get_command(world)?;
    match command {
        Commands::Graph(args) => {
            let actual = args.output;
            ensure!(
                actual.as_deref() == Some(path.as_path()),
                "expected graph output path {}, got {:?}",
                path,
                actual
            );
            Ok(())
        }
        other => bail!("expected graph command, got {other:?}"),
    }
}

❌ New issue: Code Duplication
The module contains 5 functions with similar structure: verify_graph_output_path,verify_job_count,verify_manifest_command_path,verify_manifest_path and 1 more functions

@coderabbitai

This comment was marked as resolved.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

leynos and others added 6 commits May 29, 2026 19:51
Draft an ExecPlan for roadmap item 3.4.5 covering the new `--html` and
`--output` flags on `netsuke graph`. The plan introduces a `GraphView`
domain projection (sorted, deterministic) consumed by a `GraphRenderer`
port, with separate adapters for DOT and HTML output. The HTML adapter
produces a single self-contained file with server-rendered SVG plus a
text outline so the artefact remains usable without JavaScript.

The plan migrates the no-flag DOT path away from `ninja -t graph` to the
same in-process renderer so a single pipeline owns ordering and
escaping. Tests previously asserting Ninja-tool dispatch for `graph`
are updated rather than retained.

Renderer technology selection happens at a Stage C prototyping gate: a
pure-Rust layout crate is the preferred path, with a vendored viz-js
WebAssembly bundle documented as the fallback if license, determinism,
binary-size, or output-size criteria fail.

Structured graph inspection (`--json`) is deferred to a follow-up
roadmap item but the projection shape is designed to accommodate it.
`.claude/` holds local session state written by the Claude Code / lody
agent harness (for example `scheduled_tasks.lock`, which records the
session ID, process ID, and a wakeup timestamp). The contents are
specific to the developer running the harness and have no place in the
repository.

Ignore the directory so that contributors using the agent harness do not
accidentally stage its lock files alongside real changes, and so that
the harness's "uncommitted changes" check stops flagging it.
Introduce src/graph_view/ with the deterministic GraphView projection of
BuildGraph plus the GraphRenderer port trait. The projection sorts every
collection (nodes by path, edges by from/to/class, defaults
lexicographically) so renderer adapters never observe HashMap iteration
order. Covered by rstest parametric cases and a 256-case proptest
asserting equivalence under reversed insertion order across freshly
seeded HashMaps. No user-visible behaviour changes yet — Stage A is
scaffolding for the Stage B in-process DOT renderer and the Stage C HTML
renderer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds `Commands::Graph(GraphArgs)` with `--html` and `--output <FILE>`,
introduces a deterministic in-process `DotRenderer` that consumes
`GraphView`, and rewires the graph dispatch to skip Ninja entirely. The
`--html` flag parses but still falls through to DOT in this stage; the
`HtmlRenderer` lands in Stage C.

File-IO helpers gain `write_text_file{,_utf8}` and `write_text_stdout`;
`write_ninja_file`/`write_ninja_stdout` are thin `NinjaContent`-typed
wrappers around them.

Adds new graph integration tests, BDD scenarios for `--output` and
`--html`, and rewrites the runner-tool-subcommands and
features_unix/graph.feature suites to reflect the new behaviour.
Localizes the new flag help strings and the
`status.tool.graph_html` status key in en-US and es-ES.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Implements `HtmlRenderer` producing a self-contained offline-safe HTML
document with a server-rendered SVG, accessible textual outline, and
`<noscript>` fallback containing the verbatim DOT source. Layout uses
a hand-rolled topological-depth layered placement; no third-party
layout crate is added (see Stage C go/no-go decision in the execplan).

`netsuke graph --html` now produces the HTML page; `--html --output
graph.html` writes it to disk. Both share the existing `write_text_*`
sink helpers. All new strings are localized in en-US and es-ES.

Adds `tests/runner_graph_tests.rs::graph_html_writes_self_contained_document`
and a unit-test suite under `src/graph_view/render_html_tests.rs`
covering structural integrity, accessibility metadata, determinism,
locale plumbing, and HTML escaping.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Update users-guide section 12.2 to describe in-process rendering,
  `--output`, `--html`, the `-` sentinel, and the `-C/--directory`
  interaction; the top-level subcommand summary follows suit.
- Replace the "planned for a later milestone" caveat in
  netsuke-design.md §8.3 with the actual in-process design referencing
  GraphView and the GraphRenderer port.
- Mark `--html` as shipped in the CLI design document and note that
  `--json` remains the open follow-up (roadmap 3.15.6).
- Add a developer-guide section documenting the graph view domain
  projection, the renderer port, and where new renderers should be
  added.
- Add ADR-004 recording the migration off `ninja -t graph` for the
  graph subcommand and the rationale for the in-process port/adapter
  shape.
- Tick roadmap item 3.4.5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lodyai lodyai Bot force-pushed the 3-4-5-extend-graph-subcommand-with-an-html-renderer branch from b0d9372 to 934ac4a Compare May 29, 2026 17:53
All four stages cleared `coderabbit review --agent` with zero findings.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lodyai lodyai Bot force-pushed the 3-4-5-extend-graph-subcommand-with-an-html-renderer branch from 934ac4a to c941846 Compare May 29, 2026 17:54
codescene-delta-analysis[bot]

This comment was marked as outdated.

codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 29, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response.

Bumpy Road Ahead

src/graph_view/render_html.rs: write_outline

What lead to degradation?

write_outline has 2 blocks with nested conditional logic. Any nesting of 2 or deeper is considered. Threshold is 2 blocks per function

Why does this problem occur?

A Bumpy Road is a function that contains multiple chunks of nested conditional logic inside the same function. The deeper the nesting and the more bumps, the lower the code health.
A bumpy code road represents a lack of encapsulation which becomes an obstacle to comprehension. In imperative languages there’s also an increased risk for feature entanglement, which leads to complex state management. CodeScene considers the following rules for the code health impact: 1) The deeper the nested conditional logic of each bump, the higher the tax on our working memory. 2) The more bumps inside a function, the more expensive it is to refactor as each bump represents a missing abstraction. 3) The larger each bump – that is, the more lines of code it spans – the harder it is to build up a mental model of the function. The nesting depth for what is considered a bump is levels of conditionals.

How to fix it?

Bumpy Road implementations indicate a lack of encapsulation. Check out the detailed description of the Bumpy Road code health issue.
A Bumpy Road often suggests that the function/method does too many things. The first refactoring step is to identify the different possible responsibilities of the function. Consider extracting those responsibilities into smaller, cohesive, and well-named functions. The EXTRACT FUNCTION refactoring is the primary response.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 29, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

Code Duplication

tests/bdd/steps/cli.rs:

What lead to degradation?

The module contains 5 functions with similar structure: verify_graph_output_path,verify_job_count,verify_manifest_command_path,verify_manifest_path and 1 more functions

Why does this problem occur?

Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health.

How to fix it?

A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More
Once you have identified the similarities across functions, look to extract and encapsulate the concept that varies into its own function(s). These shared abstractions can then be re-used, which minimizes the amount of duplication and simplifies change.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 29, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

Code Duplication

src/graph_view/render_html.rs:

What lead to degradation?

The module contains 4 functions with similar structure: collect_inputs_by_target,collect_predecessors,escape_attr,escape_text

Why does this problem occur?

Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health.

How to fix it?

A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More
Once you have identified the similarities across functions, look to extract and encapsulate the concept that varies into its own function(s). These shared abstractions can then be re-used, which minimizes the amount of duplication and simplifies change.

@coderabbitai

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 29, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

Code Duplication

src/graph_view/render_html.rs:

What lead to degradation?

The module contains 4 functions with similar structure: collect_inputs_by_target,collect_predecessors,escape_attr,escape_text

Why does this problem occur?

Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health.

How to fix it?

A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More
Once you have identified the similarities across functions, look to extract and encapsulate the concept that varies into its own function(s). These shared abstractions can then be re-used, which minimizes the amount of duplication and simplifies change.

@coderabbitai

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented May 31, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

Code Duplication

src/graph_view/tests.rs:

What lead to degradation?

The module contains 2 functions with similar structure: implicit_output_yields_implicit_edge_class,order_only_dep_yields_order_only_edge

Why does this problem occur?

Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health.

How to fix it?

A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More
Once you have identified the similarities across functions, look to extract and encapsulate the concept that varies into its own function(s). These shared abstractions can then be re-used, which minimizes the amount of duplication and simplifies change.

@coderabbitai

This comment was marked as resolved.

leynos and others added 5 commits May 31, 2026 19:05
Eliminates the nested match/for bumpy road in write_outline by splitting
the per-node rendering logic into two focused helpers.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Centralize graph and manifest command extraction in the BDD CLI step
helpers so verification functions only assert their expected fields.
Remove the local empty slice binding from `write_outline` while keeping the
outline rendering refactor flat and lint-compliant.
Reuse `collect_predecessors` for outline input grouping and centralize XML
escaping behind `escape_xml_chars` so text and attribute escaping share one
character loop.
Restore `collect_inputs_by_target` as a delegate to `collect_predecessors`
and expose the shared escaping loop as `escape_html` so the duplicated
helpers keep the requested shape.
codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jun 1, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

tests/bdd/steps/cli.rs

Comment on lines +295 to +304

fn verify_graph_output_path(world: &TestWorld, path: &PathString) -> Result<()> {
    let actual = extract_graph_args(world)?.output;
    ensure!(
        actual.as_deref() == Some(path.as_path()),
        "expected graph output path {}, got {:?}",
        path,
        actual
    );
    Ok(())
}

❌ New issue: Code Duplication
The module contains 5 functions with similar structure: verify_emit_path,verify_graph_output_path,verify_job_count,verify_manifest_path and 1 more functions

@coderabbitai

This comment was marked as resolved.

Centralize optional path comparison in the BDD CLI step helpers so emit,
graph output, and working directory checks share the same assertion path.
codescene-delta-analysis[bot]

This comment was marked as outdated.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jun 2, 2026

@coderabbitai Please suggest a fix for this issue and supply a prompt for an AI coding agent to enable it to apply the fix. Include the file and symbol names indicated in the issue at the head of your response. Ensure that this is validated against the current version of the codegraph.

If further refinement to address this finding would be deleterious, please supply a clear explanatory one to two paragraph markdown message I can paste into the CodeScene web ui's diagnostic suppression function so this diagnostic can be silenced.

Code Duplication

src/graph_view/tests.rs:

What lead to degradation?

The module contains 2 functions with similar structure: implicit_output_yields_implicit_edge_class,order_only_dep_yields_order_only_edge

Why does this problem occur?

Duplicated code often leads to code that's harder to change since the same logical change has to be done in multiple functions. More duplication gives lower code health.

How to fix it?

A certain degree of duplicated code might be acceptable. The problems start when it is the same behavior that is duplicated across the functions in the module, ie. a violation of the Don't Repeat Yourself (DRY) principle. DRY violations lead to code that is changed together in predictable patterns, which is both expensive and risky. DRY violations can be identified using CodeScene's X-Ray analysis to detect clusters of change coupled functions with high code similarity. Read More
Once you have identified the similarities across functions, look to extract and encapsulate the concept that varies into its own function(s). These shared abstractions can then be re-used, which minimizes the amount of duplication and simplifies change.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jun 2, 2026

@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix:

error[E0063]: missing field `implicit_deps` in initializer of `ir::graph::BuildEdge`
Error:   --> src/graph_view/tests.rs:39:16
   |
39 |     let edge = BuildEdge {
   |                ^^^^^^^^^ missing `implicit_deps`

For more information about this error, try `rustc --explain E0063`.
error: could not compile `netsuke` (lib test) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
make: *** [Makefile:32: lint] Error 101

@coderabbitai

This comment was marked as resolved.

@coderabbitai

This comment was marked as resolved.

@leynos
Copy link
Copy Markdown
Owner Author

leynos commented Jun 2, 2026

@coderabbitai Please investigate the cause of the following issue using codegraph exploration and research, identify a fix and provide an AI coding agent prompt for the fix:

error[E0063]: missing field `implicit_deps` in initializer of `ir::graph::BuildEdge`
Error:   --> src/graph_view/tests.rs:39:16
   |
39 |     let edge = BuildEdge {
   |                ^^^^^^^^^ missing `implicit_deps`

For more information about this error, try `rustc --explain E0063`.
error: could not compile `netsuke` (lib test) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
make: *** [Makefile:32: lint] Error 101

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 2, 2026

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Show BuildEdge struct in full
rg -n 'struct BuildEdge' --type rust -A 20

# Show the failing region of tests.rs (add_edge helper + EdgeFixture)
sed -n '1,90p' src/graph_view/tests.rs

# Show EdgeSpec and arb_edge_spec and build_graph_from_edge_specs
sed -n '200,280p' src/graph_view/tests.rs

Length of output: 7024



File: src/ir/graph.rsBuildEdge
File: src/graph_view/tests.rsEdgeFixture, add_edge, EdgeSpec, arb_edge_spec, build_graph_from_edge_specs


Root cause

The pushed branch snapshot shows BuildEdge without implicit_deps. Your local commit has added implicit_deps: Vec<Utf8PathBuf> to BuildEdge, but the five construction sites in src/graph_view/tests.rs have not been updated to match — hence E0063.


Fix

src/ir/graph.rs — add the field to BuildEdge after inputs:

/// Explicit inputs that trigger a rebuild when changed.
pub inputs: Vec<Utf8PathBuf>,
/// Implicit inputs that trigger a rebuild when changed but do not
/// appear in `$in` (Ninja `|`).
pub implicit_deps: Vec<Utf8PathBuf>,
/// Outputs explicitly generated by the command.
pub explicit_outputs: Vec<Utf8PathBuf>,

src/graph_view/tests.rs — add the field to EdgeFixture:

#[derive(Default, Clone, Copy)]
struct EdgeFixture<'a> {
    action_id: &'a str,
    inputs: &'a [&'a str],
    implicit_deps: &'a [&'a str],   // new
    explicit_outputs: &'a [&'a str],
    implicit_outputs: &'a [&'a str],
    order_only_deps: &'a [&'a str],
}

All existing call sites that use ..EdgeFixture::default() require no change because &'static [T] defaults to &[].

Update add_edge:

fn add_edge(graph: &mut BuildGraph, fixture: EdgeFixture<'_>) {
    let edge = BuildEdge {
        action_id: fixture.action_id.into(),
        inputs: fixture.inputs.iter().map(|s| p(s)).collect(),
        implicit_deps: fixture.implicit_deps.iter().map(|s| p(s)).collect(), // new
        explicit_outputs: fixture.explicit_outputs.iter().map(|s| p(s)).collect(),
        implicit_outputs: fixture.implicit_outputs.iter().map(|s| p(s)).collect(),
        order_only_deps: fixture.order_only_deps.iter().map(|s| p(s)).collect(),
        phony: false,
        always: false,
    };
    // remainder unchanged

Update EdgeSpec:

#[derive(Debug, Clone)]
struct EdgeSpec {
    action_id: String,
    inputs: Vec<String>,
    implicit_deps: Vec<String>,   // new
    explicit_outputs: Vec<String>,
    implicit_outputs: Vec<String>,
    order_only_deps: Vec<String>,
}

Update arb_edge_spec:

fn arb_edge_spec(action_id: String) -> impl Strategy<Value = EdgeSpec> {
    (
        prop::collection::vec(arb_path(), 0..3),  // inputs
        prop::collection::vec(arb_path(), 0..2),  // implicit_deps  new
        prop::collection::vec(arb_path(), 1..3),  // explicit_outputs
        prop::collection::vec(arb_path(), 0..2),  // implicit_outputs
        prop::collection::vec(arb_path(), 0..2),  // order_only_deps
    )
        .prop_map(
            move |(inputs, implicit_deps, explicit_outputs, implicit_outputs, order_only_deps)| {
                EdgeSpec {
                    action_id: action_id.clone(),
                    inputs,
                    implicit_deps,   // new
                    explicit_outputs,
                    implicit_outputs,
                    order_only_deps,
                }
            },
        )
}

Update build_graph_from_edge_specs:

for spec in edge_specs {
    let inputs: Vec<&str> = spec.inputs.iter().map(String::as_str).collect();
    let implicit_deps: Vec<&str> =
        spec.implicit_deps.iter().map(String::as_str).collect(); // new
    let explicit_outputs: Vec<&str> =
        spec.explicit_outputs.iter().map(String::as_str).collect();
    let implicit_outputs: Vec<&str> =
        spec.implicit_outputs.iter().map(String::as_str).collect();
    let order_only_deps: Vec<&str> =
        spec.order_only_deps.iter().map(String::as_str).collect();
    add_edge(
        &mut graph,
        EdgeFixture {
            action_id: &spec.action_id,
            inputs: &inputs,
            implicit_deps: &implicit_deps,   // new
            explicit_outputs: &explicit_outputs,
            implicit_outputs: &implicit_outputs,
            order_only_deps: &order_only_deps,
        },
    );
}

AI Coding Agent Prompt

## Task: Add `implicit_deps` to `BuildEdge` and update all construction sites

### Context
A new field `implicit_deps: Vec<Utf8PathBuf>` (Ninja implicit inputs, preceded by `|`) is being
added to the `BuildEdge` struct in `src/ir/graph.rs`. Five construction sites in
`src/graph_view/tests.rs` must be updated to include the field.

### Step 1 — `src/ir/graph.rs`

Confirm or add the field to `BuildEdge`, immediately after `inputs`:

```rust
/// Explicit inputs that trigger a rebuild when changed.
pub inputs: Vec<Utf8PathBuf>,
/// Implicit inputs that trigger a rebuild when changed but do not appear
/// in `$in` (Ninja `|`).
pub implicit_deps: Vec<Utf8PathBuf>,
/// Outputs explicitly generated by the command.
pub explicit_outputs: Vec<Utf8PathBuf>,
```

### Step 2 — `src/graph_view/tests.rs`: update `EdgeFixture`

Add `implicit_deps: &'a [&'a str]` after `inputs`:

```rust
#[derive(Default, Clone, Copy)]
struct EdgeFixture<'a> {
    action_id: &'a str,
    inputs: &'a [&'a str],
    implicit_deps: &'a [&'a str],
    explicit_outputs: &'a [&'a str],
    implicit_outputs: &'a [&'a str],
    order_only_deps: &'a [&'a str],
}
```

All call sites that use `..EdgeFixture::default()` need no further change.

### Step 3 — Update `add_edge`

Add the mapping line for `implicit_deps` to the `BuildEdge` literal:

```rust
let edge = BuildEdge {
    action_id: fixture.action_id.into(),
    inputs: fixture.inputs.iter().map(|s| p(s)).collect(),
    implicit_deps: fixture.implicit_deps.iter().map(|s| p(s)).collect(),
    explicit_outputs: fixture.explicit_outputs.iter().map(|s| p(s)).collect(),
    implicit_outputs: fixture.implicit_outputs.iter().map(|s| p(s)).collect(),
    order_only_deps: fixture.order_only_deps.iter().map(|s| p(s)).collect(),
    phony: false,
    always: false,
};
```

### Step 4 — Update `EdgeSpec`

Add `implicit_deps: Vec<String>` after `inputs`:

```rust
#[derive(Debug, Clone)]
struct EdgeSpec {
    action_id: String,
    inputs: Vec<String>,
    implicit_deps: Vec<String>,
    explicit_outputs: Vec<String>,
    implicit_outputs: Vec<String>,
    order_only_deps: Vec<String>,
}
```

### Step 5 — Update `arb_edge_spec`

Add an `implicit_deps` generator as the second tuple element and wire it through:

```rust
fn arb_edge_spec(action_id: String) -> impl Strategy<Value = EdgeSpec> {
    (
        prop::collection::vec(arb_path(), 0..3),  // inputs
        prop::collection::vec(arb_path(), 0..2),  // implicit_deps
        prop::collection::vec(arb_path(), 1..3),  // explicit_outputs
        prop::collection::vec(arb_path(), 0..2),  // implicit_outputs
        prop::collection::vec(arb_path(), 0..2),  // order_only_deps
    )
        .prop_map(
            move |(inputs, implicit_deps, explicit_outputs, implicit_outputs, order_only_deps)| {
                EdgeSpec {
                    action_id: action_id.clone(),
                    inputs,
                    implicit_deps,
                    explicit_outputs,
                    implicit_outputs,
                    order_only_deps,
                }
            },
        )
}
```

### Step 6 — Update `build_graph_from_edge_specs`

Collect `implicit_deps` and pass it to `EdgeFixture`:

```rust
for spec in edge_specs {
    let inputs: Vec<&str> = spec.inputs.iter().map(String::as_str).collect();
    let implicit_deps: Vec<&str> =
        spec.implicit_deps.iter().map(String::as_str).collect();
    let explicit_outputs: Vec<&str> =
        spec.explicit_outputs.iter().map(String::as_str).collect();
    let implicit_outputs: Vec<&str> =
        spec.implicit_outputs.iter().map(String::as_str).collect();
    let order_only_deps: Vec<&str> =
        spec.order_only_deps.iter().map(String::as_str).collect();
    add_edge(
        &mut graph,
        EdgeFixture {
            action_id: &spec.action_id,
            inputs: &inputs,
            implicit_deps: &implicit_deps,
            explicit_outputs: &explicit_outputs,
            implicit_outputs: &implicit_outputs,
            order_only_deps: &order_only_deps,
        },
    );
}
```

### Step 7 — Verify

1. Run `cargo check --tests` — zero E0063 errors must remain.
2. Run `make check-fmt` and `make lint`.
3. Run the full test suite (unit + BDD + proptest). All tests must pass without modification.

### Acceptance criteria
- `BuildEdge` has `implicit_deps: Vec<Utf8PathBuf>` after `inputs`.
- `EdgeFixture` has `implicit_deps: &'a [&'a str]`.
- `add_edge` maps `fixture.implicit_deps` into the `BuildEdge` literal.
- `EdgeSpec` has `implicit_deps: Vec<String>` and `arb_edge_spec` generates it.
- `build_graph_from_edge_specs` passes `implicit_deps` to `EdgeFixture`.
- No existing test is deleted or semantically altered.
- No new Clippy warnings are introduced.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant