Skip to content

Next/v0.1.3 - #17

Merged
djradon merged 27 commits into
mainfrom
next/v0.1.3
May 23, 2026
Merged

Next/v0.1.3#17
djradon merged 27 commits into
mainfrom
next/v0.1.3

Conversation

@djradon

@djradon djradon commented May 23, 2026

Copy link
Copy Markdown
Contributor

weave refactors

Summary by CodeRabbit

  • Documentation

    • Rewrote and expanded install/upgrade instructions; added codebase overview, performance guidance, roadmap updates, and detailed docs for weaving and page generation workflows
  • New Features

    • Improved weave/version targeting, resource-page generation, and history/progression handling; enhanced payload/version planning and page rendering behavior
  • Tests

    • New and expanded unit, integration, and e2e tests covering weave flows and timing instrumentation
  • Chores

    • Project version bumped to v0.1.3

Review Change Stack

djradon added 24 commits May 21, 2026 10:09
- move prepared weave target derivation and requested-target coverage policy into core targeting
- route executeWeave through PreparedWeaveExecution and prepared generate targets
- add exact-versus-recursive target coverage tests
- update codebase overview for the new shared/runtime split
- add nested WEAVE_TIMING phases for candidate loading and ResourcePage collection
- assert timing detail and cache counters in the CLI timing e2e test
- extract runtime errors, mesh-state loading, planning overlay/cache, artifact loaders, candidate loading, request normalization, and timing helpers from the weave façade
- keep public weave runtime exports stable
- update the runtime codebase overview
- move prepared weave execution and version planning/write helpers out of the runtime weave façade
- add shared execution config, workspace path, and progress helper modules
- keep public runtime weave exports stable while reducing weave.ts to the command façade plus page generation
- update runtime codebase overview
- move ResourcePage model types into core/weave/resource_page_models.ts
- move pure ResourcePage history grouping helpers into core/weave/resource_page_history_groups.ts
- keep core/weave/weave.ts as the stable re-export surface
- wire runtime page generation to the shared model and history modules
- preserve runtime WeaveRuntimeError wrapping for history parse failures
- update the codebase overview for the new module boundaries
- move GenerateDesignatorContext and designator context loading into runtime/weave/page_contexts.ts
- move child identifier, RDF type hint, Knop owner title, artifact link, and context history helpers with that context boundary
- keep weave.ts focused on generate/page assembly orchestration
- update codebase overview for the new runtime page-context module
- verify with check, lint, focused integration tests, e2e weave CLI tests, and import graph cycle scan
Move generated page orchestration and generated-page upsert behavior out of the
runtime weave facade into page_generation.ts. Move the remaining ResourcePage
model assembly helpers into page_model_assembly.ts, keeping timing phase names
stable and preserving executeGenerate/executeWeave behavior.

Update the runtime codebase overview with the new module layout.
- add --include defaults to deno compile arguments for release binaries
- factor compile args into a tested helper
- cover the defaults embedding flag in release script tests
- move core weave request contracts into requests.ts while preserving weave.ts type re-exports
- move reusable source locator, candidate, planning, and slice-name types into focused core weave modules
- update runtime weave type imports to use the focused model modules directly
- keep planner functions and generated RDF/Page behavior unchanged
- verify with fmt, lint, check, core weave tests, integration weave tests, and import-cycle audit
- move core weave RDF parser/query/resolution helpers into rdf_helpers.ts
- move Turtle subject-block editing helpers into turtle_blocks.ts
- keep source-locator helpers, SFLO semantic shorthands, shape assertions, slice classification, and renderer behavior in weave.ts
- update the codebase overview with the extracted helper modules
- move pending weave slice detection into slice_classification.ts
- move shared artifact-history query helpers into artifact_history_queries.ts
- preserve detectPendingWeaveSlice through the weave.ts compatibility façade
- update the codebase overview with the extracted helper modules
- verify with fmt, lint, check, core weave tests, integration weave tests, and import-cycle audit
- move payload history/state/manifestation layout resolution into payload_version_layout.ts
- move guarded overwriteExistingState validation and planning into payload_overwrite.ts
- move shared artifact manifestation path construction into artifact_manifestation_paths.ts
- keep payload renderers, ResourcePage builders, shape assertions, and planner façade behavior in weave.ts
- verify with fmt, lint, check, core weave tests, integration weave tests, and import-cycle audit
- move current ReferenceCatalog link parsing into reference_catalog_links.ts
- keep role-label derivation private to the parser module
- preserve planner dispatch, generated RDF/Page output, and public weave façade exports
- move current working-file and repository floating-locator render helpers into source_locator_renderers.ts
- keep source locator assertions, path normalization, planner dispatch, and generated RDF/Page output unchanged
- update the codebase overview for the new module boundary
- move first and second payload KnopInventory Turtle renderers into payload_renderers.ts
- keep multi-history payload rendering private to the payload renderer module
- move shared support-history omission postprocessors into support_history_renderers.ts
- keep mesh-inventory renderers, planner dispatch, and generated RDF/Page output unchanged
- move carried KnopSourceRegistry and ReferenceCatalog preservation helpers into knop_support_renderers
- keep weave.ts as the planner dispatcher and public façade
- preserve generated Turtle behavior while reducing weave.ts size
- update core weave module overview
- move mesh-inventory Turtle renderers into mesh_inventory_renderers
- keep weave.ts as the planner dispatcher and public facade
- preserve fixture-sensitive legacy renderer output
- defer shared LocatedFile/ResourcePage block helper cleanup
Move page-definition, KnopInventory, and MeshInventory progression resolution
out of weave.ts into progression_resolvers.ts while preserving planner behavior
and public façade imports.
@coderabbitai

coderabbitai Bot commented May 23, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 581461db-b8e4-4469-87b2-0b48decef0a2

📥 Commits

Reviewing files that changed from the base of the PR and between 017bc15 and ac1c8a7.

📒 Files selected for processing (11)
  • deno.json
  • documentation/notes/release-notes.v0.1.3.md
  • src/core/weave/payload_renderers.ts
  • src/core/weave/reference_catalog_links.ts
  • src/core/weave/reference_catalog_links_test.ts
  • src/core/weave/source_locator_renderers.ts
  • src/core/weave/turtle_blocks.ts
  • src/core/weave/turtle_blocks_test.ts
  • src/runtime/weave/artifact_loaders.ts
  • src/runtime/weave/page_generation.ts
  • tests/scripts/fixture_ladder_test.ts
✅ Files skipped from review due to trivial changes (3)
  • documentation/notes/release-notes.v0.1.3.md
  • src/core/weave/reference_catalog_links_test.ts
  • deno.json

📝 Walkthrough

Walkthrough

Adds target normalization, numerous core weave renderers/assertions/utilities, runtime loaders/execution/page generation, request normalization and timing helpers, extensive documentation updates, and new/updated tests.

Changes

End-to-end weave targeting, planning, execution, and pages

Layer / File(s) Summary
Target normalization & request shapes
src/core/targeting.ts, src/runtime/weave/request_normalization.ts, src/core/weave/requests.ts
Prepare and normalize version/targets, compute shared targets, and expose normalized request shapes for weave/version flows.
Core weave renderers & assertions
src/core/weave/*
Adds many new modules (renderers, manifest/path helpers, RDF query/assertion utilities, history/progression resolvers, payload/knop/mesh inventory renderers, resource-page models/builders, and turtle block helpers) implementing weave transformation and validation logic.
Runtime loaders, planning, execution
src/runtime/weave/*, scripts/build-binaries.ts
Adds artifact loaders, candidate loading, TextFileOverlay, prepare/execute version flows, page model assembly, page generation/upsert logic, timing helpers, and a deno compile-args helper.
Documentation & release
documentation/notes/*, README.md, documentation/notes/release-notes.v0.1.3.md
Rewrites/extends codebase overview, adds performance/testing notes, updates README install instructions, and adds release notes for v0.1.3.
Tests & fixtures
tests/*, src/core/weave/*_test.ts, tests/scripts/*
Adds/updates unit, integration, and e2e tests validating targeting, reference catalog extraction, turtle block rendering, artifact planning, timing output, and fixture context updates.

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant Runtime
  participant Core
  participant FS
  CLI->>Runtime: prepareWeaveExecution(request)
  Runtime->>Core: prepareWeaveTargets / normalize request
  Runtime->>FS: read mesh state (meta/inventory)
  Runtime->>Core: load candidates, classify slices
  Runtime->>Core: planVersion (renderers/assertions)
  Core-->>Runtime: VersionPlan (PlannedFiles, pages)
  Runtime->>FS: write created/updated files (upsert)
  CLI->>Runtime: generatePreparedPages(targets)
  Runtime->>Core: collectResourcePageModels, render pages
  Runtime->>FS: upsert generated pages
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Poem

A rabbit nibbled Turtle lines by moonlight,
Split targets, stitched pages, kept RDF tight.
It hummed through quads and danced on mesh roots,
Sniffed tests and docs, left tiny foot-loots.
Hop—deploy! The weave wakes, soft and bright.

✨ 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 next/v0.1.3

@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: 11

🧹 Nitpick comments (2)
src/core/weave/source_locator_renderers.ts (1)

34-44: 💤 Low value

Inconsistent indentation in template literal.

The blank node template has inconsistent indentation between lines. Lines 40-42 break the indentation pattern established by the rest of the literal.

♻️ Suggested formatting fix
 export function renderRepositorySourceFloatingLocatorBlankNode(
   locator: RepositorySourceFloatingLocator,
 ): string {
   return `[
     a sflo:RepositorySourceFloatingLocator ;
     sflo:sourceRepositoryUrl ${JSON.stringify(locator.repositoryUrl)} ;
-    sflo:sourceRepositoryPathFromRoot ${
-    JSON.stringify(locator.repositoryPathFromRoot)
-  }
+    sflo:sourceRepositoryPathFromRoot ${JSON.stringify(locator.repositoryPathFromRoot)}
   ]`;
 }
🤖 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/core/weave/source_locator_renderers.ts` around lines 34 - 44, The
template literal in renderRepositorySourceFloatingLocatorBlankNode has
inconsistent indentation for the lines inserting locator.repositoryPathFromRoot
(the lines around the sflo:sourceRepositoryPathFromRoot interpolation break the
established indentation). Fix by normalizing spacing inside the template so each
predicate line aligns (ensure the sflo:sourceRepositoryPathFromRoot line is
indented the same as sflo:sourceRepositoryUrl), keeping
JSON.stringify(locator.repositoryUrl) and
JSON.stringify(locator.repositoryPathFromRoot) unchanged while adjusting
surrounding whitespace to maintain consistent formatting for the blank node
string.
src/core/weave/working_file_paths.ts (1)

38-43: ⚡ Quick win

Clarify validation contract and avoid redundant normalization.

The usesMeshLocalWorkingLocatedFile function name suggests a simple boolean predicate, but it throws when given an invalid path and re-validates on every call. Consider one of these approaches:

  1. Accept pre-normalized paths: Add a parameter accepting an already-normalized path to avoid re-validation
  2. Make the contract explicit: Rename to requireMeshLocalWorkingLocatedFile or similar to indicate it validates
  3. Return false on invalid input: Catch validation errors and return false instead of throwing

The current design may surprise callers expecting a simple boolean check.

♻️ Option 1: Accept pre-normalized path
 export function usesMeshLocalWorkingLocatedFile(
-  workingLocalRelativePath: string,
+  normalizedPath: string,
 ): boolean {
-  return !normalizeWorkingLocalRelativePathLiteral(workingLocalRelativePath)
-    .startsWith("../");
+  return !normalizedPath.startsWith("../");
 }

Callers would normalize once and pass the result to this function.

🤖 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/core/weave/working_file_paths.ts` around lines 38 - 43, The function
usesMeshLocalWorkingLocatedFile currently throws if
normalizeWorkingLocalRelativePathLiteral fails and re-validates every call;
change it to a safe predicate by wrapping the call to
normalizeWorkingLocalRelativePathLiteral(workingLocalRelativePath) in a
try/catch, return false on any validation error, and otherwise return
!normalized.startsWith("../"); this keeps the name as a boolean check and avoids
surprising exceptions and redundant callers-side normalization.
🤖 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/core/weave/knop_inventory_renderers.ts`:
- Around line 466-510: The blocks referenceCatalogArtifactBlock,
referenceCatalogHistoryBlocks, referenceCatalogLocatedFileBlock,
referenceCatalogHistoricalLocatedFileBlock and
referenceCatalogResourcePageBlocks are hard-coding "references.ttl" which
overwrites non-default workingLocalRelativePath; update them to use the original
reference catalog's workingLocalRelativePath variable (e.g.,
referenceCatalogWorkingPath or the existing workingLocalRelativePath passed into
the renderer) when building <.../locatedFile> and manifestation/resource page
URIs (including the historical manifestation and located file entries under
<${knopPath}/_references/...> and <${referenceCatalogPath}/>), so all
occurrences of "references.ttl" are replaced with the dynamic
workingLocalRelativePath value to preserve the original file layout.

In `@src/core/weave/mesh_inventory_renderers.ts`:
- Around line 738-747: The legacy fallback currently injects hardcoded Alice
fixture RDF (<alice>, <alice/_knop>, inventory/page entries) unconditionally;
update the builder that emits that template so it only appends the
Alice-specific fragment when the current designatorPath equals (or matches)
'alice' (use the existing designatorPath variable) or otherwise skip adding the
<alice> / <alice/_knop> block; look for the template/variable emitting the
"<alice>" fragment and references to knopPath and ensure the same conditional
removal is applied to the other duplicated block later in the file (the second
legacy payload at the noted range).
- Around line 933-957: renderMeshInventoryHistoryBlock currently omits the mesh
history metadata fields latestHistoricalState and nextStateOrdinal, causing
callers to lose state-progression info; update renderMeshInventoryHistoryBlock
to emit RDF triples for sflo:latestHistoricalState with the IRI of the latest
state (use the latestStatePath parameter) and sflo:nextStateOrdinal with the
next ordinal (latestStateOrdinal + 1 as an xsd:nonNegativeInteger literal), in
addition to the existing sflo:hasHistoricalState entries so history blocks
preserve both the list of states and the progression metadata.
- Around line 926-931: The shared artifact block returned by
renderMeshInventoryArtifactBlock is missing the progression triples
sflo:currentArtifactHistory and sflo:nextHistoryOrdinal; update
renderMeshInventoryArtifactBlock to include sflo:currentArtifactHistory pointing
to the same historyPath argument and add sflo:nextHistoryOrdinal as an
xsd:integer literal (e.g., 0) so downstream planning can identify the current
mesh history and compute the next ordinal.

In `@src/core/weave/payload_renderers.ts`:
- Around line 428-442: The artifact block currently only writes
sflo:hasArtifactHistory for the single current history (using
knopInventoryHistory and knopInventoryCurrentHistoryPath), causing older
histories to be dropped; update the multi-history renderer in
payload_renderers.ts to iterate over all entries in knopInventoryHistory (emit
one `sflo:hasArtifactHistory <...> ;` line per history.path) while still
emitting `sflo:currentArtifactHistory <${knopInventoryCurrentHistoryPath}> ;`
and preserving sflo:nextHistoryOrdinal, sflo:hasWorkingLocatedFile and
sflo:hasResourcePage; ensure you handle the undefined case (no histories) the
same way it currently does.
- Around line 514-533: The current branch sends any artifact with
countArtifactHistoryPaths(...) === 1 into the single-history fallback which
wrongly rewrites named histories (e.g. "releases/v0.0.1") into the hard-coded
ordinal shape; change the condition that chooses the multi-history renderer so
it also routes single-path but non-ordinal (named) histories to
renderMultiHistoryPayloadWovenKnopInventoryTurtle: specifically, in the if that
currently checks payloadLayout.isNewHistory || countArtifactHistoryPaths(...) >
1, update it to also check whether the sole history path is non-ordinal (e.g.
add a predicate that inspects the single history name and returns true when it
does not match the ordinal pattern used by the single-history branch), so
applySupportHistoryPolicies(renderMultiHistoryPayloadWovenKnopInventoryTurtle(...))
is used for new histories, multiple histories, or a single named (non-ordinal)
history, while leaving the ordinal single-history fallback unchanged.

In `@src/core/weave/reference_catalog_links.ts`:
- Around line 36-45: The current linkSubjects discovery (using quads.flatMap and
linkSubjectPrefix) only matches by prefix and can include unrelated fragments;
update the filter that builds linkSubjects to only include subjects that not
only startWith(linkSubjectPrefix) but also have an associated rdf:type of
sflo:ReferenceLink or appear as object of sflo:hasReferenceLink in the quads
set. Concretely, when iterating quads to collect quad.subject.value for
linkSubjects, add a check against the quads collection (e.g., quads.some) to
ensure there exists a triple with subject equal to that NamedNode and predicate
rdf:type with object sflo:ReferenceLink, or a triple where predicate is
sflo:hasReferenceLink and object equals that NamedNode, so only true
ReferenceLink candidates are returned.

In `@src/core/weave/resource_page_history_groups.ts`:
- Around line 129-151: mergeHistoryGroupsByResourcePath currently dedupes by
group.path but leaves the merged arrays in append order, which can surface older
histories before newer ones; after deduping each resource's array (the local
variable existing) re-sort it into recency order using the
ResourcePageHistoryGroupModel's recency field (e.g., a timestamp like
group.timestamp or group.updatedAt) before calling merged.set(resourcePath,
existing), so that combined results from multiple inputs are ordered by
most-recent first; keep references to mergeHistoryGroupsByResourcePath,
existing, existingPaths and group.path when locating the code to change.

In `@src/core/weave/turtle_blocks.ts`:
- Around line 104-111: renderSubjectPredicateBlock emits an extra trailing
semicolon when predicates is empty; update the function
(renderSubjectPredicateBlock) to check predicates.length (or predicates.length
=== 0) and, if empty, return a single-triple line like `<${subjectPath}> a
${typeList} .` (no semicolon and with final dot), otherwise keep the current
output that joins predicates with " ;\n  " and appends " ."; ensure
spacing/indentation matches existing formatting.

In `@src/runtime/weave/artifact_loaders.ts`:
- Around line 67-69: The code constructs local snapshot paths by joining
workspaceRoot with user-supplied snapshot paths (e.g.,
latestHistoricalSnapshotLocalPath built from latestHistoricalSnapshotPath),
which bypasses path validation; replace direct join(...) uses with calls to
resolveAllowedLocalPath(workspaceRoot, <snapshotPath>) to enforce the local-path
policy and return undefined or throw if the path is outside the allowed
workspace. Update all occurrences in this file that build local snapshot paths
(including where latestHistoricalSnapshotLocalPath is set and the similar
constructions in the 103-116 and 233-245 regions) so they call
resolveAllowedLocalPath and use its result for downstream reads instead of raw
join() results; ensure callers handle undefined/failed resolutions
appropriately.

In `@src/runtime/weave/page_generation.ts`:
- Around line 178-184: In resolveGeneratedAt, validate the parsed env value
before returning: after creating const generatedAt =
Deno.env.get("WEAVE_GENERATED_AT") and new Date(generatedAt), check
Number.isNaN(date.getTime()) and handle invalid values; either fall back to new
Date() or throw a clear WeaveInputError (e.g., `throw new
WeaveInputError("Invalid WEAVE_GENERATED_AT value: ...")`) so callers of
resolveGeneratedAt won't receive an Invalid Date; update the function to
import/reference WeaveInputError and use the now() path unchanged.

---

Nitpick comments:
In `@src/core/weave/source_locator_renderers.ts`:
- Around line 34-44: The template literal in
renderRepositorySourceFloatingLocatorBlankNode has inconsistent indentation for
the lines inserting locator.repositoryPathFromRoot (the lines around the
sflo:sourceRepositoryPathFromRoot interpolation break the established
indentation). Fix by normalizing spacing inside the template so each predicate
line aligns (ensure the sflo:sourceRepositoryPathFromRoot line is indented the
same as sflo:sourceRepositoryUrl), keeping JSON.stringify(locator.repositoryUrl)
and JSON.stringify(locator.repositoryPathFromRoot) unchanged while adjusting
surrounding whitespace to maintain consistent formatting for the blank node
string.

In `@src/core/weave/working_file_paths.ts`:
- Around line 38-43: The function usesMeshLocalWorkingLocatedFile currently
throws if normalizeWorkingLocalRelativePathLiteral fails and re-validates every
call; change it to a safe predicate by wrapping the call to
normalizeWorkingLocalRelativePathLiteral(workingLocalRelativePath) in a
try/catch, return false on any validation error, and otherwise return
!normalized.startsWith("../"); this keeps the name as a boolean check and avoids
surprising exceptions and redundant callers-side normalization.
🪄 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

Run ID: 93675940-0fc2-4e56-8219-9399f1318d79

📥 Commits

Reviewing files that changed from the base of the PR and between 0354fad and 017bc15.

📒 Files selected for processing (62)
  • README.md
  • documentation/notes/roadmap.md
  • documentation/notes/wd.codebase-overview.md
  • documentation/notes/wd.performance.md
  • documentation/notes/wd.todo.md
  • scripts/build-binaries.ts
  • src/core/targeting.ts
  • src/core/targeting_test.ts
  • src/core/weave/artifact_history_queries.ts
  • src/core/weave/artifact_manifestation_paths.ts
  • src/core/weave/candidates.ts
  • src/core/weave/extraction_source_blocks.ts
  • src/core/weave/knop_inventory_renderers.ts
  • src/core/weave/knop_support_renderers.ts
  • src/core/weave/legacy_page_renderers.ts
  • src/core/weave/mesh_inventory_renderers.ts
  • src/core/weave/payload_overwrite.ts
  • src/core/weave/payload_renderers.ts
  • src/core/weave/payload_version_layout.ts
  • src/core/weave/planning_models.ts
  • src/core/weave/progression_models.ts
  • src/core/weave/progression_resolvers.ts
  • src/core/weave/rdf_helpers.ts
  • src/core/weave/reference_catalog_links.ts
  • src/core/weave/requests.ts
  • src/core/weave/resource_page_builders.ts
  • src/core/weave/resource_page_history_groups.ts
  • src/core/weave/resource_page_models.ts
  • src/core/weave/resource_page_reference_links.ts
  • src/core/weave/resource_page_reference_links_test.ts
  • src/core/weave/shape_assertions.ts
  • src/core/weave/slice_classification.ts
  • src/core/weave/slices.ts
  • src/core/weave/source_locator_assertions.ts
  • src/core/weave/source_locator_renderers.ts
  • src/core/weave/source_models.ts
  • src/core/weave/support_history_renderers.ts
  • src/core/weave/turtle_blocks.ts
  • src/core/weave/weave.ts
  • src/core/weave/working_file_paths.ts
  • src/runtime/weave/artifact_loaders.ts
  • src/runtime/weave/candidate_loader.ts
  • src/runtime/weave/errors.ts
  • src/runtime/weave/execution_config.ts
  • src/runtime/weave/mesh_state.ts
  • src/runtime/weave/page_contexts.ts
  • src/runtime/weave/page_definition.ts
  • src/runtime/weave/page_generation.ts
  • src/runtime/weave/page_model_assembly.ts
  • src/runtime/weave/pages.ts
  • src/runtime/weave/planning_context.ts
  • src/runtime/weave/prepared_execution.ts
  • src/runtime/weave/progress.ts
  • src/runtime/weave/raw_source_panels.ts
  • src/runtime/weave/request_normalization.ts
  • src/runtime/weave/timing_helpers.ts
  • src/runtime/weave/version_execution.ts
  • src/runtime/weave/weave.ts
  • src/runtime/weave/workspace_paths.ts
  • tests/e2e/weave_cli_test.ts
  • tests/integration/weave_test.ts
  • tests/scripts/release_metadata_test.ts

Comment on lines +466 to +510
const referenceCatalogArtifactBlock = hasReferenceCatalog
? `

<${referenceCatalogPath}> a sflo:ReferenceCatalog, sflo:DigitalArtifact, sflo:RdfDocument ;
sflo:hasArtifactHistory <${referenceCatalogPath}/_history001> ;
sflo:currentArtifactHistory <${referenceCatalogPath}/_history001> ;
sflo:nextHistoryOrdinal "2"^^xsd:nonNegativeInteger ;
sflo:hasWorkingLocatedFile <${referenceCatalogPath}/references.ttl> ;
sflo:hasResourcePage <${referenceCatalogPath}/index.html> .`
: "";
const referenceCatalogHistoryBlocks = hasReferenceCatalog
? `

<${knopPath}/_references/_history001> a sflo:ArtifactHistory ;
sflo:historyOrdinal "1"^^xsd:nonNegativeInteger ;
sflo:hasHistoricalState <${knopPath}/_references/_history001/_s0001> ;
sflo:latestHistoricalState <${knopPath}/_references/_history001/_s0001> ;
sflo:nextStateOrdinal "2"^^xsd:nonNegativeInteger ;
sflo:hasResourcePage <${knopPath}/_references/_history001/index.html> .

<${knopPath}/_references/_history001/_s0001> a sflo:HistoricalState ;
sflo:stateOrdinal "1"^^xsd:nonNegativeInteger ;
sflo:hasManifestation <${knopPath}/_references/_history001/_s0001/ttl> ;
sflo:locatedFileForState <${knopPath}/_references/_history001/_s0001/ttl/references.ttl> ;
sflo:hasResourcePage <${knopPath}/_references/_history001/_s0001/index.html> .

<${knopPath}/_references/_history001/_s0001/ttl> a sflo:ArtifactManifestation, sflo:RdfDocument ;
sflo:locatedFileForManifestation <${knopPath}/_references/_history001/_s0001/ttl/references.ttl> ;
sflo:hasResourcePage <${knopPath}/_references/_history001/_s0001/ttl/index.html> .`
: "";
const referenceCatalogLocatedFileBlock = hasReferenceCatalog
? `\n\n<${referenceCatalogPath}/references.ttl> a sflo:LocatedFile, sflo:RdfDocument .`
: "";
const referenceCatalogHistoricalLocatedFileBlock = hasReferenceCatalog
? `\n\n<${knopPath}/_references/_history001/_s0001/ttl/references.ttl> a sflo:LocatedFile, sflo:RdfDocument .`
: "";
const referenceCatalogResourcePageBlocks = hasReferenceCatalog
? `\n\n<${referenceCatalogPath}/index.html> a sflo:ResourcePage, sflo:LocatedFile .

<${referenceCatalogPath}/_history001/index.html> a sflo:ResourcePage, sflo:LocatedFile .

<${referenceCatalogPath}/_history001/_s0001/index.html> a sflo:ResourcePage, sflo:LocatedFile .

<${knopPath}/_references/_history001/_s0001/ttl/index.html> a sflo:ResourcePage, sflo:LocatedFile .`
: "";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the existing reference-catalog file layout instead of hard-coding references.ttl.

These blocks always recreate the carried reference catalog as _references/.../ttl/references.ttl, but the initial reference-catalog renderer already supports arbitrary workingLocalRelativePath. A non-default reference catalog will be rewritten to the wrong working locator and manifestation path on the next page-definition weave.

🤖 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/core/weave/knop_inventory_renderers.ts` around lines 466 - 510, The
blocks referenceCatalogArtifactBlock, referenceCatalogHistoryBlocks,
referenceCatalogLocatedFileBlock, referenceCatalogHistoricalLocatedFileBlock and
referenceCatalogResourcePageBlocks are hard-coding "references.ttl" which
overwrites non-default workingLocalRelativePath; update them to use the original
reference catalog's workingLocalRelativePath variable (e.g.,
referenceCatalogWorkingPath or the existing workingLocalRelativePath passed into
the renderer) when building <.../locatedFile> and manifestation/resource page
URIs (including the historical manifestation and located file entries under
<${knopPath}/_references/...> and <${referenceCatalogPath}/>), so all
occurrences of "references.ttl" are replaced with the dynamic
workingLocalRelativePath value to preserve the original file layout.

Comment on lines +738 to +747
sflo:hasKnop <alice/_knop> ;
sflo:hasKnop <${knopPath}> ;
sflo:hasResourcePage <_mesh/index.html> .

<alice>
sflo:hasResourcePage <alice/index.html> .

<alice/_knop> a sflo:Knop ;
sflo:hasWorkingKnopInventoryFile <alice/_knop/_inventory/inventory.ttl> ;
sflo:hasResourcePage <alice/_knop/index.html> .

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Remove the Alice-specific fixture data from the legacy payload fallback.

This fallback unconditionally injects <alice>, <alice/_knop>, and their file/page entries regardless of designatorPath. Any non-Alice mesh that hits the legacy path will write foreign resources into _mesh/_inventory.

Also applies to: 841-855

🤖 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/core/weave/mesh_inventory_renderers.ts` around lines 738 - 747, The
legacy fallback currently injects hardcoded Alice fixture RDF (<alice>,
<alice/_knop>, inventory/page entries) unconditionally; update the builder that
emits that template so it only appends the Alice-specific fragment when the
current designatorPath equals (or matches) 'alice' (use the existing
designatorPath variable) or otherwise skip adding the <alice> / <alice/_knop>
block; look for the template/variable emitting the "<alice>" fragment and
references to knopPath and ensure the same conditional removal is applied to the
other duplicated block later in the file (the second legacy payload at the noted
range).

Comment on lines +926 to +931
function renderMeshInventoryArtifactBlock(historyPath: string): string {
return `<_mesh/_inventory> a sflo:MeshInventory, sflo:DigitalArtifact, sflo:RdfDocument ;
sflo:hasArtifactHistory <${historyPath}> ;
sflo:hasWorkingLocatedFile <_mesh/_inventory/inventory.ttl> ;
sflo:hasResourcePage <_mesh/_inventory/index.html> .`;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Restore _mesh/_inventory progression fields in the shared artifact block.

This helper drops both sflo:currentArtifactHistory and sflo:nextHistoryOrdinal. After callers replace _mesh/_inventory with this block, later planning no longer has the metadata needed to identify the current mesh history or advance to the next one.

🤖 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/core/weave/mesh_inventory_renderers.ts` around lines 926 - 931, The
shared artifact block returned by renderMeshInventoryArtifactBlock is missing
the progression triples sflo:currentArtifactHistory and sflo:nextHistoryOrdinal;
update renderMeshInventoryArtifactBlock to include sflo:currentArtifactHistory
pointing to the same historyPath argument and add sflo:nextHistoryOrdinal as an
xsd:integer literal (e.g., 0) so downstream planning can identify the current
mesh history and compute the next ordinal.

Comment on lines +933 to +957
function renderMeshInventoryHistoryBlock(
historyPath: string,
latestStateOrdinal: number,
latestStatePath = `${historyPath}/${toStateSegment(latestStateOrdinal)}`,
): string {
const ordinalStatePaths = latestStatePath ===
`${historyPath}/${toStateSegment(latestStateOrdinal)}`
? Array.from(
{ length: latestStateOrdinal },
(_, index) => `${historyPath}/${toStateSegment(index + 1)}`,
)
: [
...Array.from(
{ length: latestStateOrdinal - 1 },
(_, index) => `${historyPath}/${toStateSegment(index + 1)}`,
),
latestStatePath,
];
const stateFacts = ordinalStatePaths.map((statePath) =>
` sflo:hasHistoricalState <${statePath}> ;`
).join("\n");
return `<${historyPath}> a sflo:ArtifactHistory ;
sflo:historyOrdinal "1"^^xsd:nonNegativeInteger ;
${stateFacts}
sflo:hasResourcePage <${historyPath}/index.html> .`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Do not strip latestHistoricalState and nextStateOrdinal from mesh history blocks.

renderMeshInventoryHistoryBlock() never emits either field, so every caller that replaces a mesh history block removes the state-progression metadata required to resolve the current state and continue the history on the next weave.

🤖 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/core/weave/mesh_inventory_renderers.ts` around lines 933 - 957,
renderMeshInventoryHistoryBlock currently omits the mesh history metadata fields
latestHistoricalState and nextStateOrdinal, causing callers to lose
state-progression info; update renderMeshInventoryHistoryBlock to emit RDF
triples for sflo:latestHistoricalState with the IRI of the latest state (use the
latestStatePath parameter) and sflo:nextStateOrdinal with the next ordinal
(latestStateOrdinal + 1 as an xsd:nonNegativeInteger literal), in addition to
the existing sflo:hasHistoricalState entries so history blocks preserve both the
list of states and the progression metadata.

Comment thread src/core/weave/payload_renderers.ts
Comment thread src/core/weave/reference_catalog_links.ts
Comment on lines +129 to +151
export function mergeHistoryGroupsByResourcePath(
...maps: readonly ReadonlyMap<
string,
readonly ResourcePageHistoryGroupModel[]
>[]
): ReadonlyMap<string, readonly ResourcePageHistoryGroupModel[]> {
const merged = new Map<string, ResourcePageHistoryGroupModel[]>();

for (const map of maps) {
for (const [resourcePath, groups] of map) {
const existing = merged.get(resourcePath) ?? [];
const existingPaths = new Set(existing.map((group) => group.path));
for (const group of groups) {
if (!existingPaths.has(group.path)) {
existing.push(group);
existingPaths.add(group.path);
}
}
merged.set(resourcePath, existing);
}
}

return merged;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Re-sort merged history groups after deduping.

collectHistoryGroupsByResourcePath() returns each resource's histories in recency order, but this merge helper just appends unseen groups. If two inputs contribute different histories for the same resource, the merged list can surface an older history before a newer one.

🤖 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/core/weave/resource_page_history_groups.ts` around lines 129 - 151,
mergeHistoryGroupsByResourcePath currently dedupes by group.path but leaves the
merged arrays in append order, which can surface older histories before newer
ones; after deduping each resource's array (the local variable existing) re-sort
it into recency order using the ResourcePageHistoryGroupModel's recency field
(e.g., a timestamp like group.timestamp or group.updatedAt) before calling
merged.set(resourcePath, existing), so that combined results from multiple
inputs are ordered by most-recent first; keep references to
mergeHistoryGroupsByResourcePath, existing, existingPaths and group.path when
locating the code to change.

Comment thread src/core/weave/turtle_blocks.ts
Comment thread src/runtime/weave/artifact_loaders.ts Outdated
Comment thread src/runtime/weave/page_generation.ts
djradon added 2 commits May 22, 2026 23:30
- fill v0.1.3 release notes
- document native binary defaults embedding
- record source quality gate validation
- preserve KnopInventory history links in multi-history payload rendering
- filter ReferenceCatalog current-link discovery to true ReferenceLink nodes
- validate historical snapshot paths and generated timestamp input
- handle type-only Turtle subject rendering
- add focused regression tests
@djradon
djradon merged commit 4b5e6e1 into main May 23, 2026
6 checks passed
@djradon
djradon deleted the next/v0.1.3 branch May 23, 2026 07:29
@coderabbitai coderabbitai Bot mentioned this pull request May 26, 2026
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