Skip to content

feat(library): enforce manifest-backed chapter availability - #170

Merged
anantham merged 3 commits into
mainfrom
codex/chapter-publication-client-gate
Sep 6, 2026
Merged

feat(library): enforce manifest-backed chapter availability#170
anantham merged 3 commits into
mainfrom
codex/chapter-publication-client-gate

Conversation

@anantham

@anantham anantham commented Aug 31, 2026

Copy link
Copy Markdown
Owner

Summary

Uses the validated chapter manifest for catalog rows and cache completeness. Missing or invalid declared manifests fail closed; packages without a manifest retain the existing legacy range behavior. The manifest foundation is merged in #169, and this PR now targets main.

Changes

  • Project published chapter identities and completeness from one exact manifest.
  • Normalize relative manifest references and generate matching publication metadata.
  • Preserve the integrated reader's scoped graph and book-selection behavior.

Validation

The combined chapter stack passes 137 focused tests on Node 24.19.0, types, production build and client security checks. Main refresh 07e2123 has the identical Git tree as reviewed head e5e9af0; current-head CI is linked below.

Independent Grok 4.6 source review approved the stack and publisher follow-up (gen-1788706940-9sQzYYjBNNTha8hDheXr). All supplied file bytes were matched to anonymous public GitHub downloads. Codex review was requested but returned no verdict.

Per-chapter output and acquisition are reviewed separately in #171/#172. Companion publication remains separate; no complete novel, semantic scan or physical-device acceptance is claimed.

Context: Metadata ranges could project chapters that had no exact published identity.
Changes: Make validated manifests authoritative for catalog projection, package completeness, and generated publication output.
Impact: Declared invalid manifests fail closed; legacy packages retain prior behavior until migrated.
Tests: 6 focused files, 56 tests; TypeScript; diff check.
Docs: CORE-015 amendment, library guides, WORKLOG.
ADR: CORE-015
@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
lexicon-forge Ready Ready Preview Sep 6, 2026 3:11pm UTC

@anantham

anantham commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5e9af0599

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const manifestContextFor = (novel: NovelEntry, version: NovelVersion) => ({
novelId: novel.id,
versionId: version.versionId,
sessionUrl: version.sessionJsonUrl,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Normalize transport aliases before checking the session URL

For publications built with the default GitHub base URL, the builder records a raw.githubusercontent.com/.../session.json URL in both metadata and the manifest, but RegistryService rewrites only the metadata session URL to media.githubusercontent.com/media/... before this context is constructed. The exact comparison in validateChapterManifest therefore rejects the matching builder-generated manifest, causing both catalog projection and reader import to fail for the default hosted output. Normalize both URLs consistently or compare their canonical artifact identities.

Useful? React with 👍 / 👎.

Comment on lines +204 to +206
const expectedPublication = await resolveExpectedChapterPublication(novel, requestedVersionId);
const expectedChapterCount = expectedPublication.count;
const expectedChapterNumbers = expectedPublication.numbers;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Verify cached tuples rather than chapter numbers alone

When a publisher corrects a session without changing its version ID, an older scoped cache can contain every manifest chapter number while holding different stable IDs/content. Reducing the manifest to numbers here lets that cache satisfy the completeness check, so the session is not replayed and the corrected manifest-backed identities are never acquired. Cache completeness should compare the manifest's stable identity tuple for each chapter, not only membership of its number.

Useful? React with 👍 / 👎.

Comment on lines +172 to +173
cache.set(key, []);
return [];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Do not memoize transient manifest-fetch failures

If the manifest request fails transiently—for example while the client is briefly offline—this stores an empty catalog under the version key. Production has no caller of clearCatalogCache, so subsequent hook reruns continue returning the cached empty array even after connectivity recovers, leaving the dropdown limited to already imported rows for the rest of the page session. Fail closed for the current request, but avoid caching transport failures so a later load can retry.

Useful? React with 👍 / 👎.

@anantham
anantham changed the base branch from codex/chapter-publication-integrity to main September 6, 2026 15:10
@anantham

anantham commented Sep 6, 2026

Copy link
Copy Markdown
Owner Author

Independent source review completed for this stack, including this PR's source at e5e9af059922f0cc96799bc792a140a1a1a5cf85. Grok 4.6 reviewed 29 full application/source/test files, then 13 full cross-repository files after corrections. Every packet file was anonymously matched by SHA-256 to its exact public GitHub commit. The final application subject is 712846d85df329a099aae74aee4abdbc46ceab05.

Final verdict: APPROVE for #169/#170/#171/#172, with no remaining LFS-contract blockers. Review gen-1788706940-9sQzYYjBNNTha8hDheXr closes the raw-vs-media URL finding from gen-1788706056-vu2CR1VUlftNkUr08Xz6. The acquisition boundary and navigation repair source did not change after its approval. This is an external AI source review receipt, not a human or Codex formal GitHub approval. Codex review was requested; no response was returned.

Node 24.19 focused tests, types, production build and client/integrity checks passed on the integrated source. Production Chromium verifies the three late-navigation scope cases and the frozen-graph offline round trip. Real chapter-2 acquisition fetched one 5.34 MB published artifact in 2.61 seconds with zero full-session requests; cached offline navigation took 97 ms (single measurements, not semantic scan latency).

Remaining acceptance limits: actual package main publication, complete novel/index, real semantic scan and physical mobile/Safari. Ordinary backup reopen without a graph loses active selection (CONS-07); readable chapters remain and its assertion is still failing. No full-feature acceptance is claimed.

@anantham
anantham merged commit 6269bf0 into main Sep 6, 2026
8 checks passed
@anantham
anantham deleted the codex/chapter-publication-client-gate branch September 6, 2026 15:30
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