Skip to content

feat: programmatic validateMesh v1 with structured findings - #25

Merged
djradon merged 6 commits into
mainfrom
lane/validate-mesh-api
Jul 31, 2026
Merged

feat: programmatic validateMesh v1 with structured findings#25
djradon merged 6 commits into
mainfrom
lane/validate-mesh-api

Conversation

@djradon

@djradon djradon commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

Delivers the v0.6.0 headline: validateMesh in src/api / @semantic-flow/weave-lib, returning structured findings with a stable 14-code registry instead of formatted CLI text — the adoption-deciding ask from the Stagecraft consumer reviews (wd.consumer-feedback-0.5.1 §8, re-raised 2026-07-29 §1).

Built against the ratified contract note documentation/notes/wd.programmatic-validate-api.md (spec review r1 rulings + build receipts live in the weave-dev-archive task note wa.task.2026.2026-07-29_1219-programmatic-validate-mesh-api).

  • 295c530 feat(validate): classify runtime findings with stable codes — finding-code slots on WeaveInputError/WeaveRuntimeError tagged at family emission sites; InventoryResolutionError replaces plain inventory Errors; previously-escaping config/policy error families are caught and classified. CLI text/exit behavior unchanged; strict mode (API) rethrows untagged domain refusals raw.
  • 4d89b5a feat(api): add validateMesh with structured findings — exact-shape admission, 14-code registry, planner-coverage counts, optional meshBase, additive read-failure code on the shared WeaveApiErrorCode union, pre-resolution unsupported-source refusal for floating repository sources (threaded mesh-local-only capability; the git seam is never reached), raw propagation of unclassified errors. Includes a feature-tolerant lookup for Deno.errors.NotADirectory/IsADirectory, which the dnt Node shim omits.
  • 310bc40 feat(lib): package validateMesh in weave-lib — npm description/README + settled and seeded-defect validateMesh legs in the off-tree Node smoke.
  • fe3a0d7 docs — the normative contract note, wu.api-reference validateMesh section + weave/weave-lib consumption-model ruling, CLI validate pointer, wd.todo swap.
  • 8f9d742 docsrelease-notes.v0.6.0 DRAFT boarding stub.

Behavioral change (named per the changelog rule)

CLI weave validate now reports findings for malformed inventory Turtle and config-resolution failures (exit 1 with a message, like other findings) instead of letting them escape as uncaught crashes. All other CLI output and exit semantics are byte-covered unchanged.

Test evidence

  • Full deno task ci: 733 passed / 0 failed (independently re-earned by the reviewing seat).
  • deno task build:npm-lib + off-tree Node smoke green: "2 payloads versioned and validateMesh returned settled/defect contract results under Node".
  • src/api/fs_purity_test.ts green over the enlarged API graph; admission/parity/repository-refusal suites added.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a programmatic validateMesh API with structured findings, stable error codes, target filtering, and coverage metrics.
    • Added machine-readable diagnostics with affected paths and designators.
    • Added reporting for unreadable sources, malformed inventory, unsupported sources, and publication-readiness issues.
    • Restricted validation to mesh-local sources where required and documented CLI/library usage.
  • Documentation

    • Expanded API references, CLI guidance, npm package documentation, and draft v0.6.0 release notes.
  • Tests

    • Added unit, integration, smoke, and package-consumption coverage for validation behavior and error reporting.

djradon and others added 5 commits July 30, 2026 13:48
Tag refusal emission sites with MeshValidationFindingCode, replace the
plain inventory errors with InventoryResolutionError, and catch the
config/policy error families that previously escaped executeValidate
uncaught. CLI validate output and exit behavior are unchanged; strict
mode (API) rethrows untagged domain refusals raw.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
v1 per wd.programmatic-validate-api: exact-shape admission, the
14-code finding registry, coverage counts, optional meshBase, additive
read-failure WeaveApiErrorCode, pre-resolution unsupported-source
refusal for floating repository sources, raw propagation of
unclassified errors. Deno.errors.NotADirectory/IsADirectory are looked
up feature-tolerantly because the dnt Node shim omits them.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
npm description/README gain the validateMesh example with the
source-capability and planner-coverage caveats; the off-tree Node
smoke gains settled and seeded-defect validateMesh legs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
wd.programmatic-validate-api carries the ratified v1 contract (14-code
finding registry, family mapping, thrown taxonomy, coverage and
fail-fast semantics). wu.api-reference gains the validateMesh section
and the weave vs weave-lib consumption-model ruling; the CLI validate
reference points at the programmatic surface; the wd.todo backlog line
now tracks landing the built slice.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Boarding stub only — unreleased; finalize artifacts and wording at
release time. Names the CLI strict improvement (malformed inventory/
config now findings, not crashes) per the behavioral-changelog rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

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: f7159512-3228-45f2-af1a-80b780759df3

📥 Commits

Reviewing files that changed from the base of the PR and between 8f9d742 and 8402727.

📒 Files selected for processing (3)
  • src/api/validate_mesh.ts
  • src/api/validate_mesh_test.ts
  • src/core/weave/rdf_helpers.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/api/validate_mesh_test.ts
  • src/api/validate_mesh.ts

📝 Walkthrough

Walkthrough

This PR adds a public validateMesh API that returns structured findings and coverage metadata. It classifies validation errors across core and runtime paths, enforces mesh-local source rules, and updates tests, documentation, and npm smoke checks.

Changes

validateMesh feature

Layer / File(s) Summary
Validation contract and public error taxonomy
documentation/notes/*, src/core/weave/errors.ts, src/api/*, src/mod.ts
Defines request, target, result, finding, and finding-code contracts. Adds read-failure and public exports.
Structured error propagation and source restrictions
src/core/weave/*, src/runtime/mesh/*, src/runtime/publication/*, src/runtime/weave/*
Adds finding codes, attribution metadata, inventory and publication classifications, source-capability enforcement, and coverage propagation through planning.
validateMesh implementation and verification
src/api/validate_mesh.ts, tests/*, scripts/*
Implements admission, preflight, target validation, execution, and error mapping. Adds integration tests, fixtures, README generation, and Node package smoke checks.

Estimated code review effort: 4 (Complex) | ~75 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant validateMesh
  participant executeValidate
  participant prepareVersionExecution
  participant loadMeshState
  Client->>validateMesh: ValidateMeshRequest
  validateMesh->>validateMesh: Admit request and preflight mesh root
  validateMesh->>executeValidate: Targets and mesh-local source capability
  executeValidate->>prepareVersionExecution: Prepare validation execution
  prepareVersionExecution->>loadMeshState: Load mesh state and inventory
  loadMeshState-->>prepareVersionExecution: Mesh metadata and designator paths
  prepareVersionExecution-->>executeValidate: Coverage and classified findings
  executeValidate-->>validateMesh: Validation result
  validateMesh-->>Client: ValidateMeshResult
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.28% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding the v1 programmatic validateMesh API with structured findings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch lane/validate-mesh-api

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (3)
src/runtime/weave/artifact_loaders.ts (3)

418-437: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Missing designatorPath attribution on mesh-path boundary errors.

requireObservedMeshPath throws WeaveRuntimeError with the "unresolvable-extraction-source" code but no attribution object. Its only caller, resolveSelectedExtractionSource, already has designatorPath in scope when it builds errorMessage. Other unresolvable-extraction-source sites in this file (lines 267-271, 288-299, 391-392, 408-412) all attach designatorPath. Pass it here too, so structured findings consistently carry attribution instead of only embedding it in the free-text message.

🔧 Proposed fix to attach designatorPath
 function requireObservedMeshPath(
   meshBase: string,
   iri: string,
   errorMessage: string,
+  designatorPath?: string,
 ): string {
   if (!iri.startsWith(meshBase)) {
-    throw new WeaveRuntimeError(
-      errorMessage,
-      "unresolvable-extraction-source",
-    );
+    throw new WeaveRuntimeError(
+      errorMessage,
+      "unresolvable-extraction-source",
+      designatorPath === undefined ? {} : { designatorPath },
+    );
   }
   const meshPath = iri.slice(meshBase.length);
   if (meshPath.includes("#") || meshPath.includes("?")) {
-    throw new WeaveRuntimeError(
-      errorMessage,
-      "unresolvable-extraction-source",
-    );
+    throw new WeaveRuntimeError(
+      errorMessage,
+      "unresolvable-extraction-source",
+      designatorPath === undefined ? {} : { designatorPath },
+    );
   }
   return meshPath;
 }
🤖 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/weave/artifact_loaders.ts` around lines 418 - 437, Update
requireObservedMeshPath and its call from resolveSelectedExtractionSource to
accept and pass through designatorPath, then include that attribution object in
both WeaveRuntimeError constructions for mesh-base and fragment/query boundary
failures. Preserve the existing error message and
"unresolvable-extraction-source" code.

212-284: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Thread sourceCapability through the extraction-source payload loader. Under sourceCapability: "mesh-local-only", loadReferenceTargetSourcePayloadArtifact bypasses the repository/floating source rejection because it does not pass this option into loadPayloadWorkingArtifact. Add the option to this loader and pass options?.sourceCapability from the candidate loader.

🤖 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/weave/artifact_loaders.ts` around lines 212 - 284, The
extraction-source payload path must preserve sourceCapability enforcement. In
src/runtime/weave/artifact_loaders.ts lines 212-284, add an options parameter to
loadReferenceTargetSourcePayloadArtifact and pass options?.sourceCapability into
loadPayloadWorkingArtifact; in src/runtime/weave/candidate_loader.ts lines
284-298, pass the candidate loader’s sourceCapability option into
loadReferenceTargetSourcePayloadArtifact.

212-219: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Thread sourceCapability through extraction-source payload loading.

loadPayloadWorkingArtifact rejects repositorySourceFloatingLocator under sourceCapability: "mesh-local-only", but loadReferenceTargetSourcePayloadArtifact always defaults the nested loadPayloadWorkingArtifact call to "all". Since firstExtractedKnopWeave candidates use this path directly with options?.sourceCapability, pass sourceCapability into loadReferenceTargetSourcePayloadArtifact and forward it to loadPayloadWorkingArtifact at lines 277-284.

🤖 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/weave/artifact_loaders.ts` around lines 212 - 219, Add a
sourceCapability parameter to loadReferenceTargetSourcePayloadArtifact, pass
options?.sourceCapability from firstExtractedKnopWeave, and forward it to the
nested loadPayloadWorkingArtifact call instead of defaulting to "all". Preserve
existing behavior when no capability is provided.
🧹 Nitpick comments (1)
src/api/validate_mesh.ts (1)

264-298: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Unclassified errors escape the structured WeaveApiError contract.

mapCannotValidateError returns unrecognized errors unchanged at line 297. Every other branch normalizes failures into a WeaveApiError with a stable code/stage. A consumer catching only WeaveApiError (the documented public error type) can still receive an arbitrary internal error type for any failure not covered by the listed classes. Wrap unrecognized errors in a fallback WeaveApiError (e.g., a generic "internal-error" code) so every rejection from validateMesh carries the structured shape the rest of the API promises.

♻️ Proposed fallback wrapping
   return error;
+  // Consider instead:
+  // return new WeaveApiError(
+  //   error instanceof Error ? error.message : "Could not validate the mesh.",
+  //   { code: "internal-error", stage: "load", cause: error },
+  // );
 }
🤖 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/api/validate_mesh.ts` around lines 264 - 298, Update
mapCannotValidateError so unrecognized errors are wrapped in a fallback
WeaveApiError instead of returned unchanged, using a stable generic code such as
"internal-error", stage "load", and the original error as cause. Preserve the
existing mappings for all recognized error types.
🤖 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/api/validate_mesh.ts`:
- Around line 117-129: In admitValidateMeshRequest, validate that
request.targets is an array whenever it is provided before calling map. Reject
truthy non-array values with the admission path’s existing clear validation
error mechanism, while preserving the optional behavior for omitted targets and
the existing normalization flow for valid arrays.

In `@src/api/version_payloads.ts`:
- Line 87: Update the filesystem error handling in the target inventory read,
working-file Deno.readFile, and current-file stat paths in version_payloads.ts
to construct the new "read-failure" code for newly thrown read errors. Preserve
existing WeaveApiError codes, including "malformed-mesh", and replace only
UnknownTargetError or unsupported-source fallbacks used for these filesystem
failures.

In `@src/core/weave/shape_assertions.ts`:
- Around line 45-58: Update the progression parsing flow in
progression_resolvers.ts to import and call the classified parseWeaveShapeQuads
wrapper from shape_assertions.ts instead of the raw rdf_helpers.ts parser.
Preserve the existing progression shape finding-code handling so malformed
inventory Turtle is surfaced as WeaveInputError.

In `@src/runtime/mesh/inventory.ts`:
- Around line 1690-1707: In the path validation logic within
normalizeWorkingLocalRelativePath, add a check after the normalized path is
computed to reject any path that starts with "../". This check should be placed
alongside the existing check for exact "." and ".." values to prevent directory
traversal paths like `a/../../secret` (which normalize to `../secret`) from
passing validation when they should be rejected as pointing outside the allowed
directory.

---

Outside diff comments:
In `@src/runtime/weave/artifact_loaders.ts`:
- Around line 418-437: Update requireObservedMeshPath and its call from
resolveSelectedExtractionSource to accept and pass through designatorPath, then
include that attribution object in both WeaveRuntimeError constructions for
mesh-base and fragment/query boundary failures. Preserve the existing error
message and "unresolvable-extraction-source" code.
- Around line 212-284: The extraction-source payload path must preserve
sourceCapability enforcement. In src/runtime/weave/artifact_loaders.ts lines
212-284, add an options parameter to loadReferenceTargetSourcePayloadArtifact
and pass options?.sourceCapability into loadPayloadWorkingArtifact; in
src/runtime/weave/candidate_loader.ts lines 284-298, pass the candidate loader’s
sourceCapability option into loadReferenceTargetSourcePayloadArtifact.
- Around line 212-219: Add a sourceCapability parameter to
loadReferenceTargetSourcePayloadArtifact, pass options?.sourceCapability from
firstExtractedKnopWeave, and forward it to the nested loadPayloadWorkingArtifact
call instead of defaulting to "all". Preserve existing behavior when no
capability is provided.

---

Nitpick comments:
In `@src/api/validate_mesh.ts`:
- Around line 264-298: Update mapCannotValidateError so unrecognized errors are
wrapped in a fallback WeaveApiError instead of returned unchanged, using a
stable generic code such as "internal-error", stage "load", and the original
error as cause. Preserve the existing mappings for all recognized error types.
🪄 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: ba515434-20fc-41ef-93a5-306aee90eaa3

📥 Commits

Reviewing files that changed from the base of the PR and between c962ab2 and 8f9d742.

📒 Files selected for processing (31)
  • documentation/notes/release-notes.v0.6.0.md
  • documentation/notes/wd.programmatic-validate-api.md
  • documentation/notes/wd.todo.md
  • documentation/notes/wu.api-reference.md
  • documentation/notes/wu.cli-reference.validate.md
  • scripts/build-npm-lib.ts
  • scripts/smoke-npm-lib.ts
  • src/api/mod.ts
  • src/api/validate_mesh.ts
  • src/api/validate_mesh_test.ts
  • src/api/version_payloads.ts
  • src/core/weave/errors.ts
  • src/core/weave/mesh_support_pages.ts
  • src/core/weave/payload_version_layout.ts
  • src/core/weave/payload_weave_read_model.ts
  • src/core/weave/progression_resolvers.ts
  • src/core/weave/shape_assertions.ts
  • src/core/weave/weave.ts
  • src/mod.ts
  • src/runtime/mesh/inventory.ts
  • src/runtime/publication/presets.ts
  • src/runtime/weave/artifact_loaders.ts
  • src/runtime/weave/candidate_loader.ts
  • src/runtime/weave/errors.ts
  • src/runtime/weave/mesh_state.ts
  • src/runtime/weave/version_execution.ts
  • src/runtime/weave/weave.ts
  • tests/integration/validate_mesh_test.ts
  • tests/integration/validate_version_generate_test.ts
  • tests/integration/version_payloads_test.ts
  • tests/support/payload_mesh_fixture.ts

Comment thread src/api/validate_mesh.ts
Comment thread src/api/version_payloads.ts
Comment thread src/core/weave/shape_assertions.ts
Comment thread src/runtime/mesh/inventory.ts
Non-array request.targets now refuses with a clear invalid-request
message instead of surfacing a TypeError text, and shape-parse
failures in rdf_helpers carry the unsupported-mesh-shape finding code
so raw-importing callers (progression resolvers, read models) classify
identically in strict mode.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@djradon
djradon merged commit f9b64ce into main Jul 31, 2026
6 of 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