Skip to content

v18 Continuum opening campaign#91

Open
flyingrobots wants to merge 9 commits into
mainfrom
v18-continuum-opening
Open

v18 Continuum opening campaign#91
flyingrobots wants to merge 9 commits into
mainfrom
v18-continuum-opening

Conversation

@flyingrobots
Copy link
Copy Markdown
Member

@flyingrobots flyingrobots commented May 21, 2026

Summary

  • Harden Continuum artifact ingestion around real Continuum fixture JSON and Wesley realization manifest JSON.
  • Require explicit load context for artifact authority, rejecting self-attested authority fields and local/handwritten mirror authority.
  • Update BEARING and cycle docs for the non-prefixed branch and completed task 5 evidence.

Supersedes #90; this PR replaces the prefixed branch with v18-continuum-opening.

Validation

  • npm run lint
  • npm run typecheck:src
  • npm run typecheck:test
  • npm run typecheck:surface
  • npm run typecheck:policy
  • npm run lint:sludge
  • npm run lint:quarantine-graduate
  • npx --yes markdownlint-cli docs/BEARING.md docs/design/0146-v18-continuum-compatibility-charter/v18-continuum-compatibility-charter.md docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md
  • npx vitest run test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts test/unit/domain/index.exports.test.ts test/unit/domain/errors/index.test.ts
  • npm run test:local (447 files, 6821 tests)
  • npm run test:coverage:ci (92.14% lines; threshold 91.90%)
  • Pre-push IRONCLAD M9 gates passed

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Continuum artifact compatibility: family identifiers, authority model, descriptors, and ingestion policy
    • Added JSON adapter to load, validate and ingest Continuum artifacts and manifests
  • Documentation

    • Completed v17 closeout and retrospectives
    • Added v18 Continuum design charters, contract matrix, ingestion and optic mapping docs
    • Revised vision, backlog and method docs to adopt Continuum/graph-model framing
  • Tests

    • Added extensive unit tests and fixtures covering descriptor, policy and adapter validation

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

This PR adds v18 Continuum compatibility docs, domain types and validators for artifact authority/family/descriptor, a JSON adapter converting Wesley manifests/fixtures into validated ContinuumArtifactDescriptor, an ingestion policy that gates acceptance, public exports, fixtures, and unit tests.

Changes

V18 Continuum Artifact Ingestion

Layer / File(s) Summary
V18 strategy and method docs
docs/BEARING.md, docs/VISION.md, docs/design/0146-0149/*, docs/design/0124-*.md, docs/design/0145-*/push-pr-review-merge.md, docs/design/0147-0148/*, docs/design/continuum-categories.tex, docs/method/backlog/*, docs/method/retro/*
Design charters, backlog/method updates, and release/retro notes framing v18 as Continuum-compatible graph-model convergence and recording v17 closeout.
Domain models & artifact validation
src/domain/continuum/ContinuumFamilyId.ts, src/domain/continuum/ContinuumArtifactAuthority.ts, src/domain/continuum/ContinuumArtifactDescriptor.ts, src/domain/continuum/ContinuumArtifactIngestionPolicy.ts, src/domain/errors/ContinuumArtifactAuthorityError.ts, src/domain/errors/index.ts, test/unit/domain/continuum/*, test/unit/domain/errors/*, test/unit/domain/index.exports.test.ts
Adds carrier classes and validators for family IDs and authority values, descriptor normalization and query methods, an ingestion policy that requires generated authority, a dedicated AuthorityError, and unit tests validating construction, errors, and runtime guards.
JSON File Adapter & parsing, fixtures, tests
src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts, test/fixtures/continuum/*, test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts
Adapter safely parses disk/string JSON, validates Wesley realization manifests and Continuum fixtures (integrity sealing, generated-leg inventories, ops/footprints), converts to ContinuumArtifactDescriptorFields, enforces load-context authority, and runs comprehensive positive/negative tests and fixtures.
Public API exports & integration
index.ts
Exports Continuum artifact modules and related types from the package entrypoint, re-exporting the new error and domain classes/types for external consumption.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • git-stunts/git-warp#41: Updates d.ts declaration parser affecting handling of export type / export declare syntax used by new Continuum type exports.

Poem

🐰 Hopping through schemas with authority-checked grace,

Wesley manifests and fixtures find their place,
Carriers frozen, validators standing guard,
Adapters parse strictly, errors flagged and barred,
V18 ingests what truthfully bears the shard.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'v18 Continuum opening campaign' accurately summarizes the primary change: initiating the v18 phase of Continuum compatibility work, including artifact ingestion hardening and documentation updates.
Description check ✅ Passed The PR description includes a clear summary of changes and a comprehensive validation section. However, it omits the 'ADR checks' section from the required template, which is a non-critical omission for this documentation-heavy PR.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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.

✏️ 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 v18-continuum-opening

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 and usage tips.

@github-actions
Copy link
Copy Markdown

Release Preflight

  • package version: 17.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v17.0.0, release workflow will publish.

@flyingrobots
Copy link
Copy Markdown
Member Author

@codex Self-review pass after clean-worktree check and git fetch origin.

Issue count: Critical 0, Major 3, Minor 2.

Severity File / lines Infraction Evidence Recommended mitigation prompt
Major src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts:166-177, src/domain/continuum/ContinuumArtifactIngestionPolicy.ts:13-15 Shape and authority are not bound together. The adapter always copies context.authority into the descriptor, and the policy accepts either generated-artifact or generated-fixture for every descriptor. A Wesley realization manifest can therefore be admitted as a generated fixture, and a Continuum fixture can be admitted as a generated artifact. That weakens the branch goal of making generated-family authority explicit and non-folkloric. Update ContinuumArtifactJsonFileAdapter so parsed artifact shape determines the allowed authority: Wesley realization manifests must require generated-artifact, Continuum family fixtures must require generated-fixture, and mismatched context authority must throw AdapterValidationError. Add regression tests for both mismatches.
Major src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts:127-135, src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts:158-162 Caller context can override parsed artifact kind. context.artifactKind can replace the canonical parsed kind for both Wesley manifests and Continuum fixtures. This lets an adapter caller emit a descriptor whose artifactKind contradicts the JSON shape the adapter just parsed. Remove artifactKind from ContinuumArtifactJsonLoadContext, or require it to exactly match the parsed shape before descriptor construction. Add tests proving a Wesley manifest cannot be labeled continuum.family.fixture and a Continuum fixture cannot be labeled wesley.realization.manifest.v1.
Major src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts:257-281, src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts:284-302 Wesley generated inventory can be empty or internally inconsistent. readGeneratedLegs accepts {} because it freezes whatever keys exist and never requires at least one leg. readOptionalNumber(leg, artifactCount) validates only numeric shape; it does not require artifactCount === files.length, so a sealed manifest can claim generated artifacts without a matching file inventory. Harden Wesley generatedLegs parsing: require at least one generated leg, require artifactCount to equal the number of file entries when present, and reject positive artifactCount with missing or empty files. Add tests for empty generatedLegs, count mismatch, and positive count without files.
Minor test/fixtures/continuum/receipt-family-wesley-realization-manifest.json:4 Fixture commits a machine-specific absolute path. The fixture stores /Users/james/git/continuum/... in canonicalSchemaPath. This is not used by the adapter, but it bakes a local workstation path into a shared repo fixture and makes the test data look less portable than the parser actually requires. Replace the absolute canonicalSchemaPath fixture value with a repo-neutral path or remove the optional field from the fixture if this test does not exercise it. Keep one parser test that validates canonicalSchemaPath as an optional string without committing a user-local path.
Minor docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md:104-116 Verification prose records a command known to exit nonzero as an observed coverage result. The doc lists npx vitest run --coverage ... and then states that the command exits nonzero because global thresholds apply to the subset. That is accurate but easy to misread as a passing verification command in a completed cycle doc. Move the targeted coverage command under a clearly labeled diagnostic coverage note section, or replace it with a command/configuration that exits zero while reporting only touched-file coverage. Keep the full passing coverage CI command as the authoritative verification line.

@flyingrobots
Copy link
Copy Markdown
Member Author

@coderabbitai review please

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2026

🧩 Analysis chain

I'll gather the relevant files before starting the full review.


🏁 Script executed:

#!/bin/bash
echo "=== ContinuumArtifactJsonFileAdapter.ts ==="
cat src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts

echo ""
echo "=== ContinuumArtifactIngestionPolicy.ts ==="
cat src/domain/continuum/ContinuumArtifactIngestionPolicy.ts

echo ""
echo "=== Wesley realization manifest fixture ==="
cat test/fixtures/continuum/receipt-family-wesley-realization-manifest.json

echo ""
echo "=== Ingestion design doc (lines 90-130) ==="
sed -n '90,130p' docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md

echo ""
echo "=== ContinuumArtifactIngestionPolicy test ==="
cat test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts

echo ""
echo "=== ContinuumArtifactJsonFileAdapter test ==="
cat test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts

echo ""
echo "=== Domain errors index ==="
fd -e ts -e js "index" src/domain/errors/ | head -5
cat src/domain/errors/index.ts 2>/dev/null || fd "index" src/domain/errors | head -3 | xargs cat

echo ""
echo "=== AdapterValidationError ==="
rg -rn "AdapterValidationError" --type ts -C3 | head -60

echo ""
echo "=== ContinuumArtifactJsonLoadContext type ==="
rg -rn "ContinuumArtifactJsonLoadContext" --type ts -C5 | head -80

Length of output: 57081


🏁 Script executed:

#!/bin/bash
echo "=== AdapterValidationError source ==="
fd "AdapterValidationError" src/ | head -5 | xargs cat

echo ""
echo "=== hasGeneratedAuthority definition ==="
rg -n "hasGeneratedAuthority" --type ts -C5

echo ""
echo "=== ContinuumArtifactAuthority allowed values ==="
cat src/domain/continuum/ContinuumArtifactAuthority.ts 2>/dev/null || fd "ContinuumArtifactAuthority.ts" src | xargs cat

echo ""
echo "=== domain/index.exports test ==="
cat test/unit/domain/index.exports.test.ts | grep -i "adapter\|validation" | head -20

echo ""
echo "=== domain errors index.test.ts ==="
cat test/unit/domain/errors/index.test.ts | head -40

Length of output: 7949


@flyingrobots — full review complete. I read all five flagged locations and the supporting types. Findings below.


Review: v18 Continuum Opening Campaign

✅ All five self-review items confirmed


🔴 Major 1 — Shape and authority are not bound together

Confirmed. ContinuumArtifactAuthority.isGeneratedAuthority() returns true for both generated-artifact and generated-fixture:

// ContinuumArtifactAuthority.ts
isGeneratedAuthority(): boolean {
  return (
    this.value === GENERATED_ARTIFACT_AUTHORITY ||  // 'generated-artifact'
    this.value === GENERATED_FIXTURE_AUTHORITY       // 'generated-fixture'
  );
}

ContinuumArtifactIngestionPolicy.assertGeneratedAuthority() calls only descriptor.hasGeneratedAuthority() — it never inspects artifactKind. And descriptorFields() in the adapter copies context.authority unconditionally regardless of which parsing branch executed. Together, these mean:

  • A Wesley manifest loaded with authority: 'generated-fixture'admitted
  • A Continuum family fixture loaded with authority: 'generated-artifact'admitted

The intended invariant — that Wesley manifests carry generated-artifact and fixtures carry generated-fixture — is not enforced anywhere in the current code.


🔴 Major 2 — Caller context can override parsed artifact kind

Confirmed. Both parsing branches delegate artifactKind to the caller:

// wesleyManifestFields()  [~line 131]
artifactKind: context.artifactKind ?? WESLEY_REALIZATION_MANIFEST_KIND,

// parseContinuumFamilyFixture()  [~line 161]
artifactKind: context.artifactKind ?? CONTINUUM_FIXTURE_KIND,

The parsed shape determines which branch runs, but the emitted descriptor's artifactKind can be entirely different from the shape that was parsed. A caller can pass artifactKind: 'continuum.family.fixture' against a Wesley manifest — or vice versa — and the descriptor will silently misrepresent the underlying JSON shape.


🔴 Major 3 — Wesley generated inventory can be empty or internally inconsistent

Confirmed, with a nuance. readGeneratedLegs does not require at least one leg:

// readGeneratedLegs()  [~line 258]
const names = Object.freeze(Object.keys(generatedLegs).sort());  // {} → []
// No minimum-leg check follows

Several existing test fixtures that use "generatedLegs": {} throw AdapterValidationError — but for other reasons (status: "open", malformed targets). A sealed, otherwise-valid manifest with "generatedLegs": {} would currently pass silently.

The artifactCount-vs-files.length cross-check is also absent. Worth noting: the test "accepts Wesley generated legs before the compiler writes file inventory" deliberately allows artifactCount: 0 with no files, which appears to be an intentional design allowance for pre-population manifests. The unguarded cases that remain are:

  • generatedLegs: {} (zero legs entirely)
  • artifactCount > 0 with files absent or with files.length !== artifactCount

🟡 Minor 4 — Machine-specific absolute path in fixture

Confirmed. test/fixtures/continuum/receipt-family-wesley-realization-manifest.json line 4:

"canonicalSchemaPath": "/Users/james/git/continuum/schemas/continuum-receipt-family.graphql"

The field is optional in the adapter (readOptionalString) and is not asserted in any test, so it's purely cosmetic debt — but it does bake a local workstation path into a shared repo fixture.


🟡 Minor 5 — Verification prose documents a known-nonzero exit command

Confirmed. The design doc at lines 109–115 states the targeted npx vitest run --coverage command exits nonzero because the global threshold is applied to the two-suite subset. This is accurate and explained, but a reader skimming the verification record could misread it as a passing CI command. Moving it under a clearly-labeled diagnostic note (separate from the authoritative npm run test:coverage:ci line) would remove the ambiguity.


Additional observation — AdapterValidationError intentionally excluded from domain barrel

AdapterValidationError is imported directly from its file by both the adapter and the tests — it is not in src/domain/errors/index.ts, and this appears to be intentional: test/unit/domain/errors/index.test.ts explicitly locks the exact 18-error export surface and excludes it. No action needed; the boundary is deliberate.


Summary

# Severity Status
1 Major Confirmed — generated-artifact / generated-fixture are both admitted for any shape; policy has no shape-authority coupling
2 Major Confirmed — context.artifactKind can produce a descriptor whose artifactKind contradicts the parsed JSON shape
3 Major Confirmed — empty generatedLegs: {} passes silently; positive artifactCount is never cross-checked against actual files.length
4 Minor Confirmed — absolute workstation path in shared fixture
5 Minor Confirmed — nonzero-exit command in verification prose
✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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: 6

🤖 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/domain/continuum/ContinuumArtifactIngestionPolicy.ts`:
- Around line 13-19: assertGeneratedAuthority currently only checks
descriptor.hasGeneratedAuthority() and therefore allows mismatched
kind/authority pairs; update it to validate that the descriptor's actual
authority exactly matches the expected generated authority for its shape/kind.
In practice, inside assertGeneratedAuthority use ContinuumArtifactDescriptor's
identifying property (e.g., kind or shape) to determine the expected generated
authority (compute or call a helper like
expectedGeneratedAuthorityForKind(kind)) and then check both
descriptor.hasGeneratedAuthority() and
descriptor.authority.equals(expectedAuthority); if either fails throw the
existing ContinuumArtifactAuthorityError with a message that includes
descriptor.familyId, descriptor.kind (or shape) and the actual vs expected
authority so mismatches like Wesley manifest + generated-fixture or fixture +
generated-artifact are rejected. Ensure you reference and update
assertGeneratedAuthority, ContinuumArtifactDescriptor, and the thrown
ContinuumArtifactAuthorityError only.

In `@src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts`:
- Around line 133-135: The parsed JSON must determine artifactKind and authority
rather than letting context override them: in ContinuumArtifactJsonFileAdapter's
JSON parsing logic (the block that sets generatedBy, artifactKind, targets using
readStringArray/readString), read the artifactKind and authority from the source
JSON shape and bind artifactKind to that value (do not default to
context.artifactKind), and validate that context.authority (if provided) matches
the parsed authority; if they mismatch, throw a validation/error. Apply the same
enforcement where similar parsing occurs (the other parsing blocks around the
indicated ranges 158-163 and 166-177).
- Around line 258-303: readGeneratedLegs currently accepts empty generatedLegs
and doesn't validate artifactCount against the actual files, allowing
inconsistent sealed manifests; update readGeneratedLegs (and readGeneratedFiles
usage) so that after calling readOptionalNumber(leg, 'artifactCount') and
collecting files via readGeneratedFiles(leg, name) you validate: if
artifactCount is present and not equal to files.length throw an
AdapterValidationError with a clear message referencing the leg name, and
additionally reject an entirely empty generatedLegs map by throwing an
AdapterValidationError when names.length === 0; use the existing
AdapterValidationError type and the functions readOptionalNumber,
readGeneratedFiles, and rejectUnknownKeys to locate where to insert these checks
in readGeneratedLegs.

In `@test/fixtures/continuum/receipt-family-wesley-realization-manifest.json`:
- Line 4: The fixture contains a machine-specific absolute "canonicalSchemaPath"
value which breaks portability; edit the
receipt-family-wesley-realization-manifest.json fixture to either remove the
optional "canonicalSchemaPath" field entirely or replace its value with a
repo-relative path (e.g., "./schemas/continuum-receipt-family.graphql") so the
fixture is consistent across contributors/CI and no host-specific absolute path
remains.

In `@test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts`:
- Line 14: The test uses an environment-specific fixture value for
sourceSchemaPath ('~/git/continuum/...') which should be replaced with a
repo-neutral constant; update the test ContinuumArtifactIngestionPolicy.test.ts
to import or reference the shared test fixture constant (e.g.,
SCHEMA_FIXTURE_PATH or a suite-level RELATIVE_SCHEMA_PATH) and replace all
occurrences of sourceSchemaPath in the file (including the other instances
noted) with that constant so the path is repo-relative and portable across
environments.

In `@test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts`:
- Around line 276-349: Add three regression tests to the
ContinuumArtifactJsonFileAdapter test suite: (1) create a fixture JSON loaded
via ContinuumArtifactJsonFileAdapter.loadString with authority
'generated-artifact' and attempt to load a Wesley manifest JSON with authority
'generated-fixture' using loadString, asserting it throws AdapterValidationError
(shape-binding/authority mismatch); (2) add a test that constructs a sealed
Wesley manifest where manifest.artifactCount !== manifest.files.length and
assert ContinuumArtifactJsonFileAdapter.loadString throws AdapterValidationError
(ensure explicit artifactCount must match files.length); and (3) add a test that
creates a sealed Wesley manifest with generatedLegs = [] and assert loadString
throws AdapterValidationError (empty generatedLegs rejected for sealed
manifests). Use existing fixture JSON constants and the
ContinuumArtifactJsonFileAdapter class and its loadString/loadFile calls to
locate where to add these tests.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 47103933-1949-48c5-89f1-9178d67e2899

📥 Commits

Reviewing files that changed from the base of the PR and between 5afdd3e and e1b483e.

⛔ Files ignored due to path filters (4)
  • docs/design/0124-v17-release-blocker-dag.dot is excluded by !**/*.dot
  • docs/design/0124-v17-release-blocker-dag.svg is excluded by !**/*.svg
  • docs/design/0124-v17-release-blocker-status.csv is excluded by !**/*.csv
  • docs/design/continuum-categories.pdf is excluded by !**/*.pdf
📒 Files selected for processing (30)
  • docs/BEARING.md
  • docs/VISION.md
  • docs/design/0124-v17-release-blocker-dag.md
  • docs/design/0145-push-pr-review-merge/push-pr-review-merge.md
  • docs/design/0146-v18-continuum-compatibility-charter/v18-continuum-compatibility-charter.md
  • docs/design/0147-v18-continuum-contract-matrix/v18-continuum-contract-matrix.md
  • docs/design/0148-v18-warp-optic-realization-map/v18-warp-optic-realization-map.md
  • docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md
  • docs/design/continuum-categories.tex
  • docs/method/backlog/README.md
  • docs/method/backlog/WORKLOADS.md
  • docs/method/backlog/bad-code/RELEASE_TRIAGE.md
  • docs/method/backlog/v18.0.0/PROTO_echo-shaped-edge-records.md
  • docs/method/backlog/v18.0.0/PROTO_echo-shaped-node-records.md
  • docs/method/backlog/v18.0.0/README.md
  • docs/method/retro/0145-push-pr-review-merge/push-pr-review-merge.md
  • index.ts
  • src/domain/continuum/ContinuumArtifactAuthority.ts
  • src/domain/continuum/ContinuumArtifactDescriptor.ts
  • src/domain/continuum/ContinuumArtifactIngestionPolicy.ts
  • src/domain/continuum/ContinuumFamilyId.ts
  • src/domain/errors/ContinuumArtifactAuthorityError.ts
  • src/domain/errors/index.ts
  • src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts
  • test/fixtures/continuum/receipt-family-generated-artifact.json
  • test/fixtures/continuum/receipt-family-wesley-realization-manifest.json
  • test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts
  • test/unit/domain/errors/index.test.ts
  • test/unit/domain/index.exports.test.ts
  • test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts

Comment on lines +13 to +19
assertGeneratedAuthority(descriptor: ContinuumArtifactDescriptor): void {
if (descriptor.hasGeneratedAuthority()) {
return;
}
throw new ContinuumArtifactAuthorityError(
`Continuum family ${descriptor.familyId.toString()} must be loaded from a generated artifact or fixture, not ${descriptor.authority.toString()}`,
);
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 | 🏗️ Heavy lift

Authority validation is too coarse and permits kind/authority mismatches.

Current policy accepts any “generated” authority and does not enforce the expected authority for each descriptor shape/kind. This can admit contradictory descriptors (e.g., Wesley manifest + generated-fixture, Continuum fixture + generated-artifact).

💡 Proposed tightening
+const EXPECTED_AUTHORITY_BY_KIND = Object.freeze({
+  'wesley.realization.manifest.v1': 'generated-artifact',
+  'continuum.family.fixture': 'generated-fixture',
+} as const);
+
 export default class ContinuumArtifactIngestionPolicy {
   ingest(descriptor: ContinuumArtifactDescriptor): ContinuumArtifactDescriptor {
-    this.assertGeneratedAuthority(descriptor);
+    this.assertGeneratedAuthority(descriptor);
     return descriptor;
   }

   assertGeneratedAuthority(descriptor: ContinuumArtifactDescriptor): void {
-    if (descriptor.hasGeneratedAuthority()) {
-      return;
-    }
-    throw new ContinuumArtifactAuthorityError(
-      `Continuum family ${descriptor.familyId.toString()} must be loaded from a generated artifact or fixture, not ${descriptor.authority.toString()}`,
-    );
+    const expected = EXPECTED_AUTHORITY_BY_KIND[
+      descriptor.artifactKind as keyof typeof EXPECTED_AUTHORITY_BY_KIND
+    ];
+    if (expected === undefined || descriptor.authority.toString() !== expected) {
+      throw new ContinuumArtifactAuthorityError(
+        `Continuum family ${descriptor.familyId.toString()} requires authority ${expected ?? 'known-kind-authority'} for ${descriptor.artifactKind}, not ${descriptor.authority.toString()}`,
+      );
+    }
   }
 }
🤖 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/domain/continuum/ContinuumArtifactIngestionPolicy.ts` around lines 13 -
19, assertGeneratedAuthority currently only checks
descriptor.hasGeneratedAuthority() and therefore allows mismatched
kind/authority pairs; update it to validate that the descriptor's actual
authority exactly matches the expected generated authority for its shape/kind.
In practice, inside assertGeneratedAuthority use ContinuumArtifactDescriptor's
identifying property (e.g., kind or shape) to determine the expected generated
authority (compute or call a helper like
expectedGeneratedAuthorityForKind(kind)) and then check both
descriptor.hasGeneratedAuthority() and
descriptor.authority.equals(expectedAuthority); if either fails throw the
existing ContinuumArtifactAuthorityError with a message that includes
descriptor.familyId, descriptor.kind (or shape) and the actual vs expected
authority so mismatches like Wesley manifest + generated-fixture or fixture +
generated-artifact are rejected. Ensure you reference and update
assertGeneratedAuthority, ContinuumArtifactDescriptor, and the thrown
ContinuumArtifactAuthorityError only.

Comment thread src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts
Comment thread src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts
Comment thread test/fixtures/continuum/receipt-family-wesley-realization-manifest.json Outdated
function makeDescriptor(authority: string): ContinuumArtifactDescriptor {
return new ContinuumArtifactDescriptor({
familyId: 'receipt-family',
sourceSchemaPath: '~/git/continuum/schemas/continuum-receipt-family.graphql',
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

Use a repo-neutral schema path fixture string.

The ~/git/continuum/... path is environment-shaped and makes fixture semantics less portable. Replace with a stable repo-relative token/path constant used across the suite.

🧩 Suggested cleanup
+const RECEIPT_SCHEMA_PATH = 'schemas/continuum/continuum-receipt-family.graphql';
+
 function makeDescriptor(authority: string): ContinuumArtifactDescriptor {
   return new ContinuumArtifactDescriptor({
     familyId: 'receipt-family',
-    sourceSchemaPath: '~/git/continuum/schemas/continuum-receipt-family.graphql',
+    sourceSchemaPath: RECEIPT_SCHEMA_PATH,
@@
-      sourceSchemaPath: '~/git/continuum/schemas/continuum-receipt-family.graphql',
+      sourceSchemaPath: RECEIPT_SCHEMA_PATH,
@@
-      sourceSchemaPath: '~/git/continuum/schemas/continuum-receipt-family.graphql',
+      sourceSchemaPath: RECEIPT_SCHEMA_PATH,

Also applies to: 77-77, 104-104, 113-113, 135-135, 145-145

🤖 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 `@test/unit/domain/continuum/ContinuumArtifactIngestionPolicy.test.ts` at line
14, The test uses an environment-specific fixture value for sourceSchemaPath
('~/git/continuum/...') which should be replaced with a repo-neutral constant;
update the test ContinuumArtifactIngestionPolicy.test.ts to import or reference
the shared test fixture constant (e.g., SCHEMA_FIXTURE_PATH or a suite-level
RELATIVE_SCHEMA_PATH) and replace all occurrences of sourceSchemaPath in the
file (including the other instances noted) with that constant so the path is
repo-relative and portable across environments.

@github-actions
Copy link
Copy Markdown

Release Preflight

  • package version: 17.0.0
  • prerelease: false
  • npm dist-tag on release: latest
  • npm pack dry-run: passed
  • jsr publish dry-run: passed

If you tag this commit as v17.0.0, release workflow will publish.

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.

Caution

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

⚠️ Outside diff range comments (1)
src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts (1)

1-542: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Split this adapter to satisfy source size and cohesion policy.

This module is over the source LOC cap and currently combines multiple peer concerns (context boundary validation, shape parsing, Wesley leg inventory parsing, and descriptor field assembly) in a single file. Please split it into smaller modules before merge.

As per coding guidelines Maximum file size: 500 LOC (source), 800 LOC (test), 300 LOC (scripts) and src/**/*.{ts,tsx}: One file per class, type, or object; split files that accumulate peer concepts.

🤖 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/adapters/ContinuumArtifactJsonFileAdapter.ts` around lines
1 - 542, The file exceeds the LOC/cohesion policy by bundling multiple concerns;
split the adapter into focused modules: keep ContinuumArtifactJsonFileAdapter
and its public methods in one file (ContinuumArtifactJsonFileAdapter with
loadFile/loadString), move parsing entry-points and high-level dispatch
(parseJson, parseDescriptorFields, parseWesleyRealizationManifest,
parseContinuumFamilyFixture, descriptorFields) into a separate parser module,
and extract Wesley-specific inventory logic (readSealedIntegrity,
readGeneratedLegs, readGeneratedLegNames, readGeneratedLegFiles,
validateGeneratedLegEnvelope, readGeneratedFiles) and the various JSON
validation helpers (requireJsonObject, isJsonObject, rejectUnknownKeys,
readRequiredString/readOptionalString/readStringArray/etc.) into their own
validator/inventory modules; ensure exports/imports wire the modules back into
ContinuumArtifactJsonFileAdapter and update references to symbols like
ContinuumArtifactIngestionPolicy, ContinuumArtifactDescriptorFields,
WESLEY_REALIZATION_MANIFEST_KIND, CONTINUUM_FIXTURE_KIND, and LOAD_CONTEXT_KEYS
so tests and policy ingestion behavior remain unchanged.
🤖 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.

Outside diff comments:
In `@src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts`:
- Around line 1-542: The file exceeds the LOC/cohesion policy by bundling
multiple concerns; split the adapter into focused modules: keep
ContinuumArtifactJsonFileAdapter and its public methods in one file
(ContinuumArtifactJsonFileAdapter with loadFile/loadString), move parsing
entry-points and high-level dispatch (parseJson, parseDescriptorFields,
parseWesleyRealizationManifest, parseContinuumFamilyFixture, descriptorFields)
into a separate parser module, and extract Wesley-specific inventory logic
(readSealedIntegrity, readGeneratedLegs, readGeneratedLegNames,
readGeneratedLegFiles, validateGeneratedLegEnvelope, readGeneratedFiles) and the
various JSON validation helpers (requireJsonObject, isJsonObject,
rejectUnknownKeys, readRequiredString/readOptionalString/readStringArray/etc.)
into their own validator/inventory modules; ensure exports/imports wire the
modules back into ContinuumArtifactJsonFileAdapter and update references to
symbols like ContinuumArtifactIngestionPolicy,
ContinuumArtifactDescriptorFields, WESLEY_REALIZATION_MANIFEST_KIND,
CONTINUUM_FIXTURE_KIND, and LOAD_CONTEXT_KEYS so tests and policy ingestion
behavior remain unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b8254e4-902d-4933-b78d-eef97c5f8fb8

📥 Commits

Reviewing files that changed from the base of the PR and between e1b483e and 9b5b6c3.

📒 Files selected for processing (5)
  • docs/BEARING.md
  • docs/design/0149-v18-continuum-artifact-ingestion/v18-continuum-artifact-ingestion.md
  • src/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.ts
  • test/fixtures/continuum/receipt-family-wesley-realization-manifest.json
  • test/unit/infrastructure/adapters/ContinuumArtifactJsonFileAdapter.test.ts
✅ Files skipped from review due to trivial changes (1)
  • test/fixtures/continuum/receipt-family-wesley-realization-manifest.json

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