Skip to content

Implement scoped graph freshness surfaces#478

Merged
mohanagy merged 2 commits into
nextfrom
issue-477-graph-freshness
Jun 2, 2026
Merged

Implement scoped graph freshness surfaces#478
mohanagy merged 2 commits into
nextfrom
issue-477-graph-freshness

Conversation

@mohanagy
Copy link
Copy Markdown
Owner

@mohanagy mohanagy commented Jun 2, 2026

Summary

  • expose overall and selected-context graph freshness across pack, prompt, handoff, doctor/status, and MCP context surfaces
  • add scoped freshness guards (--require-fresh-context / require_fresh_context), keep global strict mode, and reject unsupported review-task usage explicitly
  • preserve scoped freshness on cached MCP explain packs and update docs plus regression coverage for the new contract

Verification

  • npm run typecheck
  • npm run build
  • CI=1 npm run test:run

Closes #477

Summary by CodeRabbit

  • New Features

    • Added strict freshness flags to pack/prompt/handoff requests and enforced selected-context vs. full-graph freshness; JSON responses and CLI output now include a graph freshness receipt with statuses (fresh, partially_stale, possibly_stale, stale, missing) and recommendations
    • Cached explain packs validate/refresh selected-context freshness before returning and may error when strict flags require regeneration
  • Documentation

    • Updated docs and CLI help to describe freshness controls, MCP parameter names, and examples

Expose overall and selected-context freshness across pack, prompt, handoff, doctor/status, and MCP surfaces; add the scoped strict flag; refresh cached context_pack freshness; and document the new contract.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: aa5ed327-81e9-40b4-9b5f-6c09ec8ee8dd

📥 Commits

Reviewing files that changed from the base of the PR and between 7543692 and b9cd20a.

📒 Files selected for processing (7)
  • src/infrastructure/context-pack-command.ts
  • src/infrastructure/context-prompt-command.ts
  • src/infrastructure/handoff-command.ts
  • src/runtime/freshness.ts
  • src/runtime/stdio/tools.ts
  • tests/unit/context-prompt-command.test.ts
  • tests/unit/freshness-surfaces.test.ts
💤 Files with no reviewable changes (1)
  • src/infrastructure/context-pack-command.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/infrastructure/context-prompt-command.ts
  • tests/unit/context-prompt-command.test.ts
  • src/runtime/freshness.ts
  • src/runtime/stdio/tools.ts
  • tests/unit/freshness-surfaces.test.ts

📝 Walkthrough

Walkthrough

This PR implements graph freshness detection and enforcement across Madar's context pack, prompt, handoff, and diagnostic surfaces. It introduces freshness status types, scoped analysis that separates global graph staleness from selected-context staleness, optional enforcement flags, and consistent reporting in human-readable and machine-readable output to help users trust whether the graph is fresh enough for their task.

Changes

Graph Freshness Detection and Enforcement

Layer / File(s) Summary
Freshness type system and analysis engine
src/runtime/freshness.ts
New GraphContextFreshnessStatus and SelectedContextFreshnessStatus types, GraphContextFreshness interface with detailed freshness metadata, analyzeGraphContextFreshness function comparing source file mtimes to graph generation time, requireFreshGraph and requireFreshSelectedContext enforcement helpers, plus status label and selected-context extraction utilities.
Context pack governance freshness contract
src/contracts/context-pack.ts, src/runtime/context-pack-governance.ts
Expand ContextPackGovernanceGraphFreshness from 3 to many fields including freshness status, graph metadata, generation timestamps, source file counts, selected-context status and counts, and recommendation text; update buildContextPackGovernanceReceipt to accept and populate freshness from GraphContextFreshness.
Context pack command: analysis, enforcement, and rendering
src/infrastructure/context-pack-command.ts
Compute initial freshness via analyzeGraphContextFreshness, enforce requireFreshGraph and requireFreshSelectedContext, reject requireFreshContext for task=review, thread freshness into governance, and render freshness summaries in text/markdown/Claude/Copilot formats with status labels and file counts.
CLI flags, parser, and help text
src/cli/parser.ts, src/cli/main.ts
Add --require-fresh-graph and --require-fresh-context boolean options to pack, handoff, and prompt commands via parser interfaces, argument loop recognition, help text, and conditional option output.
Context prompt and stdio integration
src/infrastructure/context-prompt-command.ts, src/runtime/stdio/tools.ts, src/runtime/stdio/definitions.ts
Compute freshness before and after retrieval, conditionally enforce freshness options, include graph_freshness in prompt JSON responses, parse/enforce MCP require_fresh_graph/require_fresh_context, recompute cached explain freshness, and thread governance freshness into MCP responses.
Handoff: propagate freshness flags
src/infrastructure/handoff-command.ts
Thread requireFreshGraph and requireFreshContext from handoff options into the packOptions passed to runContextPackCommand when enabled.
Doctor/status: freshness reporting and health logic
src/infrastructure/doctor.ts
Replace mtime-threshold-based checks with analyzeGraphContextFreshness, update GraphCheck to use new statuses and metadata, broaden remediation triggers, tighten health criteria, and display generated time/version and source change counts.
Test coverage for freshness surfaces
tests/unit/*.test.ts
Add tests verifying analysis outputs, CLI/MCP flag propagation, requireFreshContext rejection for review tasks, prompt/pack/handoff outputs include graph_freshness, cached explain freshness recomputation, scoped/global strictness behavior, and doctor/status consistency.
Documentation and README updates
README.md, docs/concepts/context-packs.md, docs/reference/cli-and-mcp.md
Document freshness states, receipt fields, enforcement flags, MCP equivalents, selected-context behavior, and recovery commands.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CLI_MCP as CLI/MCP
  participant Analyzer as analyzeGraphContextFreshness
  participant Retrieval as retrieveContext
  participant Enforcer as requireFresh*
  participant Governance as BuildGovernance/Render

  Client->>CLI_MCP: call context_pack/context_prompt (require_fresh_*)
  CLI_MCP->>Analyzer: compute initial freshness
  Analyzer-->>CLI_MCP: GraphContextFreshness
  CLI_MCP->>Enforcer: enforce requireFreshGraph (optional)
  Enforcer-->>CLI_MCP: pass or throw
  CLI_MCP->>Retrieval: retrieve selected context
  Retrieval->>Analyzer: recompute freshness with selected files
  Analyzer-->>Enforcer: selected-context status
  Enforcer-->>CLI_MCP: pass or throw
  CLI_MCP->>Governance: build governance receipt with graph_freshness
  Governance-->>Client: response with graph_freshness (JSON + human text)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • mohanagy/madar#448: Expands context pack governance contract with freshness receipt fields overlapping this PR's governance freshness structure and signature changes.
  • mohanagy/madar#348: Modifies MCP tool response construction in src/runtime/stdio/tools.ts; this PR similarly threads freshness through those tool handlers and governance builders.
  • mohanagy/madar#446: Related to handoff/pack plumbing that this PR extends to forward freshness flags.

"I'm a rabbit in the code,
sniffing timestamps in the wood,
fresh leaves mark the chosen path,
stale ones tell me where to stand,
hop, report, and softly guard the pack."

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Implement scoped graph freshness surfaces' directly summarizes the main objective of the PR: exposing graph freshness reporting across multiple command surfaces with scoped enforcement controls.
Description check ✅ Passed The PR description follows the template structure with Summary, Verification (steps listed), and Closes/Related issues. All major changes are summarized concisely.
Linked Issues check ✅ Passed The PR comprehensively implements issue #477 objectives: exposes global and selected-context freshness across pack/prompt/handoff/doctor/status/MCP surfaces, adds scoped freshness guards (--require-fresh-context), detects fresh/partially_stale/possibly_stale/stale states, includes metadata (path/version/generated-at/indexed count), provides recommendations, implements scoped strict mode, documents the model, and includes regression tests covering fresh/modified/deleted/missing scenarios.
Out of Scope Changes check ✅ Passed All changes are directly aligned with issue #477: freshness metadata structures (context-pack.ts, freshness.ts), CLI flags (parser.ts, main.ts), command implementations (pack/prompt/handoff/doctor), MCP tool definitions and handlers, documentation updates (README, concepts, reference), and comprehensive test coverage including a new freshness-surfaces.test.ts suite.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-477-graph-freshness

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/infrastructure/handoff-command.ts (1)

174-181: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Update the runContextPackCommand type signature to include the new optional fields.

The runContextPackCommand signature in HandoffCommandDependencies should include requireFreshGraph?: boolean and requireFreshContext?: boolean to match the PackCliOptions contract. Lines 209-210 now conditionally pass these fields through to packOptions, but the dependency interface type doesn't declare them, creating a gap for test mocks and custom dependency implementations.

📐 Proposed fix to align the type contract
 export interface HandoffCommandDependencies extends Partial<ContextPackCommandDependencies> {
   loadGraph?: (graphPath: string) => KnowledgeGraph
   runContextPackCommand?: (options: {
     prompt: string
     budget: number
     task: HandoffCliOptions['task']
     graphPath: string
     format: 'json'
     verbose: true
+    requireFreshGraph?: boolean
+    requireFreshContext?: boolean
   }) => Promise<string>
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/infrastructure/handoff-command.ts` around lines 174 - 181, The
runContextPackCommand signature on HandoffCommandDependencies is missing the new
optional flags from PackCliOptions; update the type for runContextPackCommand
(the function defined on HandoffCommandDependencies) to accept
requireFreshGraph?: boolean and requireFreshContext?: boolean in its options
object so mocks and implementations can pass them through when building
packOptions (the place that conditionally forwards these fields to packOptions).
Ensure the optional boolean fields are declared alongside prompt, budget, task,
graphPath, format, and verbose in the runContextPackCommand options type.
🧹 Nitpick comments (4)
src/runtime/freshness.ts (1)

351-352: 💤 Low value

generated_ms uses graph file mtime, not actual generation timestamp.

The generated_ms and generated_at fields are derived from graphFreshness.graphModifiedMs (the graph file's mtime), which may differ from the actual generation timestamp if the graph file was touched or copied after generation. If this is intentional (using mtime as a proxy), consider adding a brief comment. If the graph JSON contains a generation timestamp field, that would be more accurate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime/freshness.ts` around lines 351 - 352, The generated_ms and
generated_at fields are currently populated from graphFreshness.graphModifiedMs
(file mtime) which can differ from the actual generation timestamp; update the
code that sets generated_ms/generated_at to use the graph's embedded generation
timestamp if present (e.g., a field like graph.generation_ts or
graph.generatedAt in the parsed graph JSON), falling back to
graphFreshness.graphModifiedMs only when that field is absent, and if you
intentionally keep mtime as the source add a brief comment next to the
generated_ms/generated_at assignment explaining that mtime is used as a proxy.
tests/unit/freshness-surfaces.test.ts (1)

33-36: ⚡ Quick win

writeText helper unused in tests/unit/freshness-surfaces.test.ts (33-36). The fixtures write files via writeFileSync directly, and writeText has no call sites in this file; remove it if it’s unused elsewhere.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/freshness-surfaces.test.ts` around lines 33 - 36, The helper
function writeText is declared but never used in this test; either remove the
writeText function declaration or refactor the test to use writeText instead of
calling writeFileSync directly. Locate the writeText function and any direct
writeFileSync usages in the freshness-surfaces.test module, then either delete
the writeText symbol or replace the raw writeFileSync calls with writeText(path,
content) to consolidate file-writing logic and avoid an unused helper.
src/infrastructure/context-pack-command.ts (1)

537-568: 💤 Low value

Redundant field deletions in cli_pack block.

The fields graph_path, graph_version, generated_ms, generated_at, madar_version, and recommendation are already deleted unconditionally at lines 441-472 before this cli_pack-specific block runs. These deletions will never find the fields present.

Consider consolidating this logic or removing the duplicate checks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/infrastructure/context-pack-command.ts` around lines 537 - 568, The
cli_pack-specific deletion block redundantly re-checks and deletes fields on
graphFreshness that were already unconditionally removed earlier (graph_path,
graph_version, generated_ms, generated_at, madar_version, recommendation),
causing dead checks; inside the same function where graphFreshness is processed
(the cli_pack block that mutates trimmedFields), remove the duplicate
conditional deletes for those already-handled keys or merge the two blocks into
a single responsibility so each field is deleted exactly once—update the
trimmedFields pushes accordingly and keep any unique cli_pack-only deletions
(leave checks for fields not removed earlier).
src/runtime/stdio/tools.ts (1)

1464-1482: 💤 Low value

Consider using graphContextFreshness for impact task governance.

The impact task governance uses initialGraphContextFreshness (Line 1471) but the require_fresh_context enforcement at Lines 1431-1441 uses graphContextFreshness which includes selected source files from retrieval. This creates a slight inconsistency where the enforcement is based on retrieval's selected context, but governance reports freshness without selected context info.

If intentional (impact has different "selected context" semantics), this is fine. Otherwise, consider using graphContextFreshness for consistency.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/runtime/stdio/tools.ts` around lines 1464 - 1482, The governance payload
for the impact task is using initialGraphContextFreshness but enforcement
earlier uses graphContextFreshness; update the call that builds the impact task
governance (the withContextPackGovernance invocation inside the helpers.ok(...)
return) to pass graphContextFreshness instead of initialGraphContextFreshness so
reported freshness matches the enforcement context (replace
initialGraphContextFreshness with graphContextFreshness in the governance
metadata for the impact task).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/infrastructure/context-prompt-command.ts`:
- Around line 85-87: The requireFreshGraph check currently runs after retrieval
completes; move the early-fail check so it runs immediately after computing
initialGraphFreshness (i.e., right after the initialGraphFreshness is set) to
mirror runContextPackCommand and avoid doing retrieval work when
options.requireFreshGraph is true; specifically relocate the
options.requireFreshGraph / requireFreshGraph(initialGraphFreshness) invocation
to just after initialGraphFreshness is calculated and before any retrieval or
network calls in the same function.

In `@src/runtime/freshness.ts`:
- Around line 179-184: The loop over (fallbackNodes.length > 0 ? fallbackNodes :
result.matched_nodes) directly calls node.source_file.trim(), which can throw if
source_file is null/undefined; change the access to mirror earlier usage by
normalizing with optional chaining and a fallback string (e.g., use
node?.source_file?.trim() ?? '') before checking length and adding to
sourceFiles so fallbackNodes/result.matched_nodes entries are handled safely;
update the loop body that references sourceFile, keeping the same variable names
(sourceFile, sourceFiles, node) for clarity.

In `@tests/unit/context-prompt-command.test.ts`:
- Around line 6-15: The status regex in expectGraphFreshnessContract currently
omits the valid "partially_stale" enum value causing legitimate outputs to fail;
update the matcher inside expectGraphFreshnessContract so the status regex
includes "partially_stale" (e.g., change the pattern to
/^(fresh|partially_stale|possibly_stale|stale|missing)$/) so the contract
accepts the full set of allowed statuses.

---

Outside diff comments:
In `@src/infrastructure/handoff-command.ts`:
- Around line 174-181: The runContextPackCommand signature on
HandoffCommandDependencies is missing the new optional flags from
PackCliOptions; update the type for runContextPackCommand (the function defined
on HandoffCommandDependencies) to accept requireFreshGraph?: boolean and
requireFreshContext?: boolean in its options object so mocks and implementations
can pass them through when building packOptions (the place that conditionally
forwards these fields to packOptions). Ensure the optional boolean fields are
declared alongside prompt, budget, task, graphPath, format, and verbose in the
runContextPackCommand options type.

---

Nitpick comments:
In `@src/infrastructure/context-pack-command.ts`:
- Around line 537-568: The cli_pack-specific deletion block redundantly
re-checks and deletes fields on graphFreshness that were already unconditionally
removed earlier (graph_path, graph_version, generated_ms, generated_at,
madar_version, recommendation), causing dead checks; inside the same function
where graphFreshness is processed (the cli_pack block that mutates
trimmedFields), remove the duplicate conditional deletes for those
already-handled keys or merge the two blocks into a single responsibility so
each field is deleted exactly once—update the trimmedFields pushes accordingly
and keep any unique cli_pack-only deletions (leave checks for fields not removed
earlier).

In `@src/runtime/freshness.ts`:
- Around line 351-352: The generated_ms and generated_at fields are currently
populated from graphFreshness.graphModifiedMs (file mtime) which can differ from
the actual generation timestamp; update the code that sets
generated_ms/generated_at to use the graph's embedded generation timestamp if
present (e.g., a field like graph.generation_ts or graph.generatedAt in the
parsed graph JSON), falling back to graphFreshness.graphModifiedMs only when
that field is absent, and if you intentionally keep mtime as the source add a
brief comment next to the generated_ms/generated_at assignment explaining that
mtime is used as a proxy.

In `@src/runtime/stdio/tools.ts`:
- Around line 1464-1482: The governance payload for the impact task is using
initialGraphContextFreshness but enforcement earlier uses graphContextFreshness;
update the call that builds the impact task governance (the
withContextPackGovernance invocation inside the helpers.ok(...) return) to pass
graphContextFreshness instead of initialGraphContextFreshness so reported
freshness matches the enforcement context (replace initialGraphContextFreshness
with graphContextFreshness in the governance metadata for the impact task).

In `@tests/unit/freshness-surfaces.test.ts`:
- Around line 33-36: The helper function writeText is declared but never used in
this test; either remove the writeText function declaration or refactor the test
to use writeText instead of calling writeFileSync directly. Locate the writeText
function and any direct writeFileSync usages in the freshness-surfaces.test
module, then either delete the writeText symbol or replace the raw writeFileSync
calls with writeText(path, content) to consolidate file-writing logic and avoid
an unused helper.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 448454ff-672e-4169-b83c-2bef346a1afb

📥 Commits

Reviewing files that changed from the base of the PR and between 192c259 and 7543692.

📒 Files selected for processing (23)
  • README.md
  • docs/concepts/context-packs.md
  • docs/reference/cli-and-mcp.md
  • src/cli/main.ts
  • src/cli/parser.ts
  • src/contracts/context-pack.ts
  • src/infrastructure/context-pack-command.ts
  • src/infrastructure/context-prompt-command.ts
  • src/infrastructure/doctor.ts
  • src/infrastructure/handoff-command.ts
  • src/runtime/context-pack-governance.ts
  • src/runtime/freshness.ts
  • src/runtime/stdio/definitions.ts
  • src/runtime/stdio/tools.ts
  • tests/unit/answer-ready-explain-pack.test.ts
  • tests/unit/cli.test.ts
  • tests/unit/context-pack-command.test.ts
  • tests/unit/context-prompt-command.test.ts
  • tests/unit/freshness-surfaces.test.ts
  • tests/unit/handoff-command.test.ts
  • tests/unit/stdio-server.test.ts
  • tests/unit/stdio-tool-profile.test.ts
  • tests/unit/why-madar-doc.test.ts

Comment thread src/infrastructure/context-prompt-command.ts Outdated
Comment thread src/runtime/freshness.ts
Comment thread tests/unit/context-prompt-command.test.ts
Address the current PR blockers by making prompt graph strictness fail fast, aligning handoff types, hardening freshness selection, making freshness assertions Windows-safe, and applying the small CodeRabbit cleanup fixes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mohanagy
Copy link
Copy Markdown
Owner Author

mohanagy commented Jun 2, 2026

Applied the remaining still-valid CodeRabbit follow-ups in b9cd20a.

Included in the same fix set:

  • fail-fast requireFreshGraph in context-prompt-command
  • nullable source_file handling in freshness fallback selection
  • partially_stale added to the shared context-prompt freshness matcher
  • handoff dependency type updated for the new freshness flags
  • Windows-safe freshness path assertions
  • small cleanup items: removed the unused helper, dropped redundant governance deletions, kept the mtime-as-proxy note next to generated_*, and aligned impact governance freshness with the scoped enforcement context

@mohanagy
Copy link
Copy Markdown
Owner Author

mohanagy commented Jun 2, 2026

I would hold this PR before merge.

The feature is directionally useful, but I don't think this should merge yet. It adds a broad freshness surface, but the core freshness model still needs to be tightened so we do not ship a noisy contract that has to be unwound later.

  1. Freshness should be based on graph build revision + current diff, not graph/source mtimes.

The issue is about turning staleness into a scoped diff. Current implementation compares every indexed source file mtime to the graph file mtime (src/runtime/freshness.ts), with the graph file mtime as generated_at. That means touch, checkout tools, filesystem clock behavior, or preserved mtimes can produce false positives/negatives, and every pack/prompt call does a sync stat over all indexed files. Please rework the source of truth to store the graph build git SHA/dirty state and compute changed files from current HEAD plus staged/unstaged/untracked/deleted working-tree diff. Keep mtime/file-hash as a fallback for non-git repos only.

  1. The governance privacy contract contradicts the new freshness payload.

ContextPackGovernancePrivacyBoundary says includes_file_paths: false, but graph_freshness.graph_path is part of the governance receipt and text output prints Graph source: .... Either remove/redact/hash graph paths from governance freshness, or change the privacy contract so it does not claim no file paths. This matters especially for MCP/handoff/share-safe consumers.

  1. The shared/reachable-file acceptance case is not actually covered.

The test named "modified shared files on the selected route" changes auth.ts, not routes.ts, so it only proves direct selected-file drift. Please add a real shared/reachable-file case: modify a route/config/middleware/schema file that affects the selected auth context without being the primary auth file, and prove the selected-context status behaves correctly. Otherwise the PR can still pass while missing the main product edge case.

Until these are resolved, this looks like a large additive surface around a freshness model that is still too easy to misclassify. I would prefer this PR first consolidate the freshness source-of-truth and contract shape, then layer CLI/MCP/docs on top.

@mohanagy mohanagy merged commit 813f8d7 into next Jun 2, 2026
7 checks passed
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