Skip to content

Add a zero-tolerance TypeDoc documentation gate - #58

Merged
leynos merged 6 commits into
mainfrom
typedoc-rollout
Sep 7, 2026
Merged

Add a zero-tolerance TypeDoc documentation gate#58
leynos merged 6 commits into
mainfrom
typedoc-rollout

Conversation

@leynos

@leynos leynos commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Summary

This branch adds a zero-tolerance TypeDoc documentation gate to make all.
TypeDoc's validation runs over the package entry point (src/index.ts,
resolve strategy) with emit: "none" and validation warnings treated as
errors: every declaration in the public surface must carry a JSDoc comment,
and every {@link} must resolve. The gate reports the qualified name of each
undocumented declaration, writes no documentation artefacts, and fails on a
single omission. CI already runs make all, so it reaches the gate with no
workflow changes.

Base and rebase

Rebased from 11ae114060e07ccdb6132c23b61904e30bacac96 (the pre-rebase head)
onto main, now at e633725, the merge of #74. It was briefly based on that
pull request's branch because main was red; #74 has since landed, so this is
a plain rebase onto main. The author's two commits are preserved, and the
three that follow are new work on top:

  1. Document the public fixture surface to declaration level (author's)
  2. Add a zero-tolerance TypeDoc documentation gate (author's)
  3. Document the shared write surface the gate now reaches
  4. Validate references and contract the documentation gate
  5. Address the July review of the documentation gate

What the rebase exposed

main gained the shared domain-write slice (#18) after this branch was
opened, and its exported object types carry undocumented fields. Commit 3
documents them at their field sites: the domain action arguments and the
built-in updateRepository action, the repository update command, the update
result union, and the REST patch input.

Commit 3 also clears the nine cosmetic "unused @param" warnings in
src/store/keys.ts that the original body noted as accepted. They came from a
real conflict: the Oxlint df12/require-public-jsdoc rule wants one @param
per bound name, while TypeDoc binds a destructured parameter to a single name
and reports the rest as unused. Taking the parameter whole and using nested
@param parts.owner tags satisfies both tools. The parameter types, the call
sites, and the behaviour are unchanged. The gate now finishes with no warnings
at all, not merely with no errors.

Reference validation and the contract

Commit 4 turns on TypeDoc's invalidLink, invalidPath and
unusedMergeModuleWith validation, so an unresolvable reference fails the gate
alongside a missing JSDoc block. That exposed one broken reference:
{@link FoundationSimulator} on simulation names a type from
@simulacrum/foundation-simulator, which cannot resolve into this package's
documentation. It is mapped through externalSymbolLinkMappings to the
upstream package page rather than weakened in the comment.

tests/docs-gate.contract.test.ts asserts the chain that makes this a gate
rather than a script nobody runs:

Link asserted Mutation that turns it red
CI verify job runs make all run: make all replaced with echo skipping
docs-check requires typecheck prerequisite dropped from the recipe line
that step is unconditional continue-on-error: true added to it
make all requires docs-check docs-check removed from the prerequisites
docs-check runs the gate recipe body replaced with @true
docs:check passes typedoc.json --options typedoc.json dropped
notDocumented validation on set to false
link validation on invalidLink set to false
warnings are errors treatValidationWarningsAsErrors set to false

Each assertion matches the command or the option, never a step name or the
comment above it. All nine mutations were run and each failed exactly one
test; the restored tree passes all fourteen.

Pins

typedoc is resolved to exactly 0.28.20 in bun.lock, with its integrity
hash, and CI installs with bun install --frozen-lockfile. There is no TypeDoc
plugin. The package.json range stays a caret, per this repository's stated
dependency policy.

Documentation

docs/development.md gains a "The documentation gate" section covering what
the gate checks, how to run it locally, and the three conventions for
documenting an export that follow from how TypeDoc and the Oxlint JSDoc rules
interact.

The July review

All fourteen threads from the July review are addressed and answered.

The Makefile finding was correct and is fixed at the mechanism: docs-check
now declares typecheck as a prerequisite rather than merely following it in
all, so make -j all cannot start the gate before generation finishes and a
bare make docs-check generates first. The contract test asserts it.

Nine threads pointed at new JSDoc that promised more than the schemas deliver:
ISO 8601 timestamps, a SHA-1 sha, enabled/disabled security statuses,
instance-wide unique issue and pull-request ids, a repository schema that
"fills in" URL fields, a preserved full_name, normalized pull-request refs,
and a user schema that overwrites a supplied name. Each is fixed by correcting
the documentation rather than tightening the validator: adding .datetime(),
z.enum, a hash pattern or a global id allocator would reject or change
fixtures that parse today, which is a fixture-parsing behaviour change and
outside a documentation gate. Every one of those remains a reasonable separate
change and is flagged as such in its thread.

Those nine tightenings are recorded in #77 with each reviewer's rationale, so
they survive this merge. That issue also corrects one claim made in these
threads: measured one at a time against bun test tests, the timestamp and
security-status tightenings break no existing test, and only the 40-hex sha
rule does, failing twenty-two. They remain consumer-visible narrowings of what
initialState accepts, which is why they are versioned work rather than part
of a documentation change, but the suite does not block three of the four.

The remaining four are additions: examples on blobStoreKey and
branchStoreKey, JSDoc on GitHubBlob and GitHubBranch, and a compile-time
test.

tests/documented-surface.test-d.ts answers the request for a type-level test
and guards the part of this branch that a documentation gate cannot see. It
asserts with a strict Equal that interface GitHub* extends z.infer<schema> {} is exactly z.infer<schema>, that each build*Fixture return type is the
named interface rather than a structurally expanded copy, and that the exported
extension hooks keep their shape.

Validation

Every gate below was run on the pushed tree, bare and unfiltered:

Gate Result
make all exit 0; 383 tests pass across 26 files
make docs-check exit 0, no warnings
make markdownlint 18 files, 0 errors
make nixie all diagrams valid
make build build, attw and publint clean
bun audit no vulnerabilities
bun test tests/docs-gate.contract.test.ts 14 pass

Gate mutation checks: removing the JSDoc from UpdateRepositoryCommand.owner
makes make docs-check exit 4 naming the symbol; changing
{@link FoundationSimulator} to an unresolvable name makes it exit 4 reporting
the failed link; restoring each returns the gate to green with no output.

Notes

Summary by Sourcery

Enforce complete, link-valid public API documentation as a required build gate.

New Features:

  • Add a zero-tolerance TypeDoc validation gate covering the public package entry point and resolving documentation links.

Enhancements:

  • Make the documentation gate a required Makefile prerequisite and ensure generated types are available before it runs.
  • Document the exported fixture, entity, action, and API surfaces, including nested object fields and external references.
  • Add compile-time checks that preserve public fixture types, builder signatures, and extension-hook contracts.

Build:

  • Add TypeDoc as a pinned development dependency and configure a no-output documentation check.

Documentation:

  • Document the documentation gate, its local usage, validation scope, and conventions for maintaining public JSDoc.

Tests:

  • Add contract tests verifying CI, Makefile, package scripts, and TypeDoc configuration cannot bypass the documentation gate.
  • Add type-level tests for exported entity aliases, fixture builders, and extension hooks.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Summary

  • Added a zero-tolerance TypeDoc documentation validation gate to make all, executed between typecheck and lint via a new docs-check phase.
  • Introduced a docs:check script and typedoc.json configuration to validate only declarations reachable from src/index.ts, emit no documentation artefacts, and treat TypeDoc validation warnings as errors (with notDocumented enabled).
  • Updated contributor workflow documentation (docs/development.md) to describe the new documentation gate and its rules (including @internal usage to keep Zod schema constants out of the documented surface).
  • Added/expanded JSDoc across the public API:
    • Documented the simulator argument surface and developer workflow.
    • Added JSDoc to fixture builders, schemas, and fields (including internal guidance/normalisation notes where appropriate).
    • Adjusted exported public types for TypeDoc compatibility (notably changing several type exports to interface extensions and adding explicit builder return annotations) without changing runtime behaviour.
  • CI now reaches the gate through its existing make all target.

Validation

  • make all completed successfully with the TypeDoc gate passing.
  • Mutation checks completed successfully.

Walkthrough

Add a TypeDoc documentation check, document exported APIs and fixture schemas, configure warning enforcement without artefacts, and include docs-check in the make all workflow.

Changes

TypeDoc documentation gate

Layer / File(s) Summary
Configure TypeDoc validation
package.json, typedoc.json
Add the docs:check script, TypeDoc development dependency, entry-point configuration, internal/private exclusions, and documentation validation rules.
Document public API and fixture types
src/index.ts, src/store/builders.ts, src/store/entities*
Add JSDoc for exported APIs and fixture schemas, provide explicit builder return types, and represent inferred entity shapes as exported interfaces.
Wire the documentation quality gate
Makefile, docs/development.md
Run docs-check from make all and document the TypeDoc notDocumented gate in the contributor workflow and diagram.

Possibly related PRs

  • leynos/dakar#5: Introduces the same TypeDoc docs:check wiring and configuration pattern.
  • leynos/df12-build#62: Adds the same TypeDoc gate across Makefile, package scripts, and configuration.
  • leynos/simulacat-core#19: Updates the exported simulator API around extendRouter, which is also documented in this change.

Poem

Types bloom where comments gleam,
Docs now guard the buildstream.
Checks march through the Makefile bright,
Warnings turn to errors overnight.
Public shapes stand clear and true.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 3 warnings)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error No new tests guard the new docs-check gate or the seeded user created_at default; existing user tests only assert id/login/name/email. Add focused tests that break if the user created_at default is removed and a command-level check that exercises docs:check/make all behaviour.
Testing (Unit And Behavioural) ⚠️ Warning No test file changed, and nothing exercises bun run docs:check or make all; the new CLI/workflow gate is only configured, not verified. Add an end-to-end regression test that runs the new gate (or make all) and asserts both the success path and a documented failure when a JSDoc is removed.
Testing (Compile-Time / Ui) ⚠️ Warning The PR adds TypeDoc/docs-check and type-shape changes, but I found no trybuild/tsd/type-assertion test or docs:check test; only oxlint and runtime snapshot tests exist. Add a TypeScript compile-time test (tsd/expect-type or equivalent) that fails on the undocumented/public-surface cases this gate is meant to catch.
Domain Architecture ⚠️ Warning FAIL: issue.ts and pull-request.ts still document globally unique IDs, but the transform only computes offset + number, so the model claims an invariant it does not enforce. Either allocate IDs through a repository-aware/global allocator, or rewrite the docs to describe the deterministic per-number fallback.
✅ Passed checks (16 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
User-Facing Documentation ✅ Passed No user-facing behaviour changed; the diff only adds documentation gates and declaration/JSDoc updates, and docs/users-guide.md was untouched.
Developer Documentation ✅ Passed PASS: docs/development.md documents the new docs-check gate, and the repo has no docs/developers-guide.md or relevant roadmap/execplan items to update.
Module-Level Documentation ✅ Passed Every changed source module has a top-level @file doc comment; the lone header-less file is src/generated/resolvers-types.ts, which is excluded from lint/docs.
Testing (Property / Proof) ✅ Passed PASS: the PR only adds docs/type annotations and a docs gate; no new invariant or proof obligation is introduced, and existing fast-check tests already cover the key properties.
Unit Architecture ✅ Passed PASS: The PR only adds docs/build gating and type annotations; it does not add query writes, hidden I/O, ambient context, or new mixed-responsibility units.
Observability ✅ Passed PASS: The diff only adds a TypeDoc docs-check gate, config, and docs; it changes build-time workflow, not runtime operational behaviour, so observability additions are not required.
Security And Privacy ✅ Passed PASS: Added docs-only gates and JSDoc; no secrets, credentials, auth changes, or unsafe sinks appear in the added lines.
Performance And Resource Use ✅ Passed PASS: The diff is doc/type-only plus a bounded build-time TypeDoc gate; no new runtime loops, repeated I/O, unbounded collections, or hot-path cloning appears.
Concurrency And State ✅ Passed Treat this patch as non-stateful; it only adds docs/type annotations and gate wiring, with no new shared mutable state, async tasks, or locks.
Architectural Complexity And Maintainability ✅ Passed PASS: The PR adds an explicit TypeDoc validation gate and documentation-only type/interface tweaks, with no new runtime layer or hidden abstraction; the changes simplify maintenance.
Rust Compiler Lint Integrity ✅ Passed PASS: The diff only touches Makefile, docs, package.json, bun.lock and typedoc.json; no Rust files or lint-suppression/clone changes appear.
Title check ✅ Passed The title clearly identifies the main change: adding a zero-tolerance TypeDoc documentation gate. No roadmap or issue reference is required by the provided context.
Description check ✅ Passed The description directly explains the TypeDoc gate, documentation changes, validation coverage, rebase context, and successful test results. It is fully related to the changeset.
✨ 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 typedoc-rollout
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch typedoc-rollout

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

@sourcery-ai sourcery-ai 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.

Sorry @leynos, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

codescene-access[bot]

This comment was marked as outdated.

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

ℹ️ 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".

Comment thread Makefile Outdated
@buzzybee-df12

Copy link
Copy Markdown
Collaborator

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

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

Caution

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

⚠️ Outside diff range comments (1)
src/store/entities/ref.ts (1)

66-83: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep qualifiedName unqualified during normalization.

When both values are supplied, qualifiedName becomes the full ref such as
refs/heads/main. refStoreKey() and the derived node_id then use that prefixed
value, so equivalent branch fixtures can receive different identities. Normalize the
prefix into ref only and retain main/v1.2.3 as qualifiedName.

Proposed normalization
-    const qualifiedName = ref.ref ?? ref.qualifiedName;
-    const fullRef = qualifiedName.startsWith('refs/')
-      ? qualifiedName
-      : `${defaultRefPrefix(ref.object.type)}${qualifiedName}`;
+    const rawRef = ref.ref ?? ref.qualifiedName;
+    const fullRef = rawRef.startsWith('refs/')
+      ? rawRef
+      : `${defaultRefPrefix(ref.object.type)}${rawRef}`;
+    const qualifiedName = fullRef.replace(/^refs\/(?:heads|tags)\//, '');

Add regression tests covering both branch and tag inputs.

🤖 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/store/entities/ref.ts` around lines 66 - 83, Update the normalization
transform around rawRef, fullRef, and qualifiedName so qualifiedName remains the
unqualified branch or tag name while ref receives the fully prefixed path.
Ensure refStoreKey and derived node_id use the unqualified qualifiedName, and
add regression tests for both branch and tag inputs.
🤖 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 `@docs/development.md`:
- Around line 36-39: Update the documentation-gate description in
docs/development.md to identify src/index.ts as TypeDoc’s package entry point,
while referring to typedoc.json only as the configuration that selects it.
Preserve the existing notDocumented validation, zero-tolerance warning behavior,
and no-artifact details.
- Around line 33-35: Update the contributor workflow guidance in
docs/development.md so the documented manual gate includes bun run docs:check,
or replace it with make all as the sole contributor gate. Keep the documented
command order and existing workflow description consistent with the new TypeDoc
check.

In `@Makefile`:
- Around line 22-34: The Makefile currently documents a serial order that is not
preserved by parallel Make execution. Add an explicit typecheck prerequisite to
docs-check, encode any required downstream ordering such as lint, and update
docs/development.md to describe the guaranteed dependency rather than relying on
prerequisite-list order; apply the Makefile change at Makefile lines 22-34 and
the documentation clarification at docs/development.md lines 33-35.

In `@src/index.ts`:
- Around line 22-41: The exported TypeScript API lacks compile-time coverage.
Add a type-only test covering GitHubSimulatorArgs.extend.extendRouter in
src/index.ts, plus the exported GitHubBranch alias in
src/store/entities/branch.ts, GitHubCommit in src/store/entities/commit.ts, and
GitHubPullRequest in src/store/entities/pull-request.ts; verify these symbols
can be imported and used with their intended types without runtime tests.

In `@src/store/entities.ts`:
- Around line 56-61: Update the documentation comment for the minimal GitHub
user fixture validator to state that name is derived from login only when
missing, then a missing contact email is derived from the normalized name;
clarify that a caller-provided name is preserved.

In `@src/store/entities/blob.ts`:
- Around line 34-41: Add executable JSDoc examples to both exported key helpers:
in src/store/entities/blob.ts lines 34-41, document blob coordinates and the
resulting canonical key; in src/store/entities/branch.ts lines 50-55, document
branch coordinates and the resulting key. Keep the examples consistent with each
helper’s documented input and output format.

In `@src/store/entities/branch.ts`:
- Line 48: Add a concise JSDoc description immediately above the GitHubBranch
interface declaration, documenting its public API purpose while leaving the
interface and githubBranchSchema unchanged.

In `@src/store/entities/issue.ts`:
- Around line 76-81: The timestamp fields in both schemas accept arbitrary
strings despite documenting ISO 8601 values. Update issue.ts fields created_at,
updated_at, and closed_at, and repository.ts fields pushed_at, updated_at, and
created_at to enforce Zod datetime validation while preserving optional/default
and nullable behavior; add malformed-input tests covering these fields in both
schemas.

In `@src/store/entities/repository.ts`:
- Around line 32-39: Update the documentation comment for the repository fixture
normalization schema to accurately state that REST URL fields are accepted when
provided, rather than claiming omitted fields are filled in. Keep the
descriptions of generated id, node_id, and derived full_name unchanged.
- Around line 220-249: Replace the z.string() validators for the four security
status fields in the repository schema with z.enum(['enabled', 'disabled']) so
only documented values are accepted. Update the schema tests to cover both
allowed statuses and rejection of other strings, preserving the existing
defaults of {status: 'enabled'}.

---

Outside diff comments:
In `@src/store/entities/ref.ts`:
- Around line 66-83: Update the normalization transform around rawRef, fullRef,
and qualifiedName so qualifiedName remains the unqualified branch or tag name
while ref receives the fully prefixed path. Ensure refStoreKey and derived
node_id use the unqualified qualifiedName, and add regression tests for both
branch and tag inputs.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5f87d8ba-055b-4843-94c2-faae450af742

📥 Commits

Reviewing files that changed from the base of the PR and between d65cd49 and 11ae114.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • src/__generated__/resolvers-types.ts is excluded by !**/__generated__/**
📒 Files selected for processing (17)
  • Makefile
  • docs/development.md
  • package.json
  • src/index.ts
  • src/store/builders.ts
  • src/store/entities.ts
  • src/store/entities/blob.ts
  • src/store/entities/branch.ts
  • src/store/entities/commit.ts
  • src/store/entities/installation.ts
  • src/store/entities/issue.ts
  • src/store/entities/organization.ts
  • src/store/entities/pull-request.ts
  • src/store/entities/ref.ts
  • src/store/entities/repository.ts
  • src/store/entities/shared.ts
  • typedoc.json

Comment thread docs/development.md Outdated
Comment thread docs/development.md Outdated
Comment thread Makefile
Comment thread src/index.ts
Comment thread src/store/entities.ts
Comment thread src/store/entities/blob.ts
Comment thread src/store/entities/branch.ts
Comment thread src/store/entities/issue.ts Outdated
Comment thread src/store/entities/repository.ts
Comment thread src/store/entities/repository.ts

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

Caution

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

⚠️ Outside diff range comments (1)
docs/development.md (1)

26-31: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Include the TypeDoc gate in the normal contributor gate.

The listed manual gate still runs only formatting, linting, typechecking, and tests. Add bun run docs:check after typechecking, or make make all the sole documented contributor gate.

Triage: [type:docstyle]

🤖 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 `@docs/development.md` around lines 26 - 31, Update the “normal contributor
gate” in the development documentation to include the TypeDoc validation command
`bun run docs:check` immediately after `bun check:types`, while preserving the
existing formatting, linting, typechecking, and test steps.
♻️ Duplicate comments (5)
docs/development.md (1)

35-38: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Name src/index.ts as the package entry point.

typedoc.json configures TypeDoc; it is not the package entry point. Rewrite the sentence to identify src/index.ts as the entry point and retain typedoc.json as its configuration.

Triage: [type:docstyle]

🤖 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 `@docs/development.md` around lines 35 - 38, Update the documentation gate
description to identify src/index.ts as the package entry point, while retaining
typedoc.json solely as the TypeDoc configuration reference. Preserve the
existing explanation of notDocumented validation and public-surface JSDoc
requirements.
src/store/entities/issue.ts (1)

76-81: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Enforce the documented timestamp contract across both schemas.

The fields are documented as ISO 8601 timestamps, but arbitrary strings still pass validation. Apply .datetime() while preserving each field’s existing optional, default, and nullable semantics, then add malformed-input tests.

  • src/store/entities/issue.ts#L76-L81: validate created_at, updated_at, and closed_at.
  • src/store/entities/repository.ts#L57-L71: validate pushed_at, updated_at, and created_at.

As per coding guidelines, validate I/O boundaries with Zod.

🤖 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/store/entities/issue.ts` around lines 76 - 81, Apply Zod .datetime()
validation to created_at, updated_at, and closed_at in
src/store/entities/issue.ts:76-81, preserving their current optional, default,
and nullable behavior. Apply the same validation to pushed_at, updated_at, and
created_at in src/store/entities/repository.ts:57-71, then add tests confirming
malformed timestamps are rejected at both schema boundaries.

Source: Coding guidelines

src/store/entities/repository.ts (2)

220-249: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Enforce the documented security-status values.

Replace all four status: z.string() validators with z.enum(['enabled', 'disabled']), preserve the existing defaults, and add acceptance/rejection tests.

As per coding guidelines, validate I/O boundaries with Zod.

🤖 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/store/entities/repository.ts` around lines 220 - 249, In the repository
schema, update the status validators for advanced_security, secret_scanning,
secret_scanning_push_protection, and secret_scanning_non_provider_patterns from
unrestricted strings to z.enum(['enabled', 'disabled']). Preserve each existing
enabled default and add tests confirming both values are accepted and any other
status is rejected at the Zod I/O boundary.

Source: Coding guidelines


32-39: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Stop claiming that omitted URLs are filled.

Only counters and security settings receive defaults; the URL fields remain optional and absent when omitted. Rewrite this description to state that caller-supplied URLs are accepted, or implement actual URL defaults.

🤖 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/store/entities/repository.ts` around lines 32 - 39, Update the
documentation for the repository fixture normalizer near its exported function
or class to remove the claim that omitted GitHub REST URLs are populated. State
that caller-supplied URL fields are preserved or accepted as optional, while
retaining the documented defaults for counters and security settings.
Makefile (1)

22-34: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Encode the TypeDoc execution dependency.

The documented order is not guaranteed under make -j. Make docs-check depend on typecheck, and make downstream lint ordering explicit if TypeDoc must complete before lint. Update the documentation to describe the guaranteed dependency rather than prerequisite-list order.

  • Makefile#L22-L34: add the required Make dependency chain.
  • docs/development.md#L33-L35: document the enforced dependency, not merely the preferred order.

As per coding guidelines, changes involving ordering or parallelism must make the execution model explicit.

🤖 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 `@Makefile` around lines 22 - 34, Make the Makefile dependency graph explicit:
update docs-check to depend on typecheck, and add any required dependency
ensuring lint runs only after docs-check completes. In docs/development.md,
describe this enforced dependency chain rather than relying on prerequisite-list
order. Apply the Makefile change at Makefile lines 22-34 and update the
corresponding documentation at docs/development.md lines 33-35.

Source: Coding guidelines

🤖 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/store/entities.ts`:
- Around line 93-101: Update the full seeded store description in the
documentation above the validation/normalization implementation to include
issues alongside commits and pull requests, accurately reflecting the schemas
parsed by the full-store flow.

In `@src/store/entities/issue.ts`:
- Around line 56-61: The fallback issue ID generation using
ENTITY_ID_OFFSETS.ISSUE plus issue.number is not instance-wide unique across
repositories. Replace it with a repository-aware or global allocator, or require
callers to supply unique IDs, while preserving the documented uniqueness
contract for id. Add a regression test covering identical issue numbers in
different repositories.

In `@src/store/entities/pull-request.ts`:
- Around line 173-176: Update the JSDoc comments for the base and head fields in
the pull request entity mapping to state that missing owner and repo values
default to the owning repository, rather than claiming normalization to it.
Leave the normalizePullRequestRef calls unchanged.
- Around line 115-116: Update the documentation for the pull-request `id` field
in the entity schema to describe the current deterministic fallback as the
configured pull-request offset plus `number`; do not claim uniqueness across
repositories unless store-wide allocation and duplicate validation are
implemented.

In `@src/store/entities/ref.ts`:
- Around line 60-61: The sha schema in the ref entity must enforce the
documented SHA-1 format rather than accepting arbitrary non-empty strings.
Update the Zod validation for sha to require exactly 40 hexadecimal characters,
and add fixture tests covering valid and invalid hashes at the I/O boundary.

In `@src/store/entities/repository.ts`:
- Around line 52-53: Update the full_name field documentation and normalization
contract in the repository entity schema to accurately reflect that the
transform always derives it from owner and name, or change the transform to
preserve a caller-supplied value. Ensure tests cover the selected behavior and
reference the full_name normalization logic.

---

Outside diff comments:
In `@docs/development.md`:
- Around line 26-31: Update the “normal contributor gate” in the development
documentation to include the TypeDoc validation command `bun run docs:check`
immediately after `bun check:types`, while preserving the existing formatting,
linting, typechecking, and test steps.

---

Duplicate comments:
In `@docs/development.md`:
- Around line 35-38: Update the documentation gate description to identify
src/index.ts as the package entry point, while retaining typedoc.json solely as
the TypeDoc configuration reference. Preserve the existing explanation of
notDocumented validation and public-surface JSDoc requirements.

In `@Makefile`:
- Around line 22-34: Make the Makefile dependency graph explicit: update
docs-check to depend on typecheck, and add any required dependency ensuring lint
runs only after docs-check completes. In docs/development.md, describe this
enforced dependency chain rather than relying on prerequisite-list order. Apply
the Makefile change at Makefile lines 22-34 and update the corresponding
documentation at docs/development.md lines 33-35.

In `@src/store/entities/issue.ts`:
- Around line 76-81: Apply Zod .datetime() validation to created_at, updated_at,
and closed_at in src/store/entities/issue.ts:76-81, preserving their current
optional, default, and nullable behavior. Apply the same validation to
pushed_at, updated_at, and created_at in src/store/entities/repository.ts:57-71,
then add tests confirming malformed timestamps are rejected at both schema
boundaries.

In `@src/store/entities/repository.ts`:
- Around line 220-249: In the repository schema, update the status validators
for advanced_security, secret_scanning, secret_scanning_push_protection, and
secret_scanning_non_provider_patterns from unrestricted strings to
z.enum(['enabled', 'disabled']). Preserve each existing enabled default and add
tests confirming both values are accepted and any other status is rejected at
the Zod I/O boundary.
- Around line 32-39: Update the documentation for the repository fixture
normalizer near its exported function or class to remove the claim that omitted
GitHub REST URLs are populated. State that caller-supplied URL fields are
preserved or accepted as optional, while retaining the documented defaults for
counters and security settings.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5f87d8ba-055b-4843-94c2-faae450af742

📥 Commits

Reviewing files that changed from the base of the PR and between d65cd49 and 11ae114.

⛔ Files ignored due to path filters (2)
  • bun.lock is excluded by !**/*.lock
  • src/__generated__/resolvers-types.ts is excluded by !**/__generated__/**
📒 Files selected for processing (17)
  • Makefile
  • docs/development.md
  • package.json
  • src/index.ts
  • src/store/builders.ts
  • src/store/entities.ts
  • src/store/entities/blob.ts
  • src/store/entities/branch.ts
  • src/store/entities/commit.ts
  • src/store/entities/installation.ts
  • src/store/entities/issue.ts
  • src/store/entities/organization.ts
  • src/store/entities/pull-request.ts
  • src/store/entities/ref.ts
  • src/store/entities/repository.ts
  • src/store/entities/shared.ts
  • typedoc.json

Comment thread src/store/entities.ts
Comment thread src/store/entities/issue.ts Outdated
Comment thread src/store/entities/pull-request.ts Outdated
Comment thread src/store/entities/pull-request.ts Outdated
Comment thread src/store/entities/ref.ts Outdated
Comment thread src/store/entities/repository.ts Outdated
@leynos
leynos changed the base branch from main to tier3/fix-red-main September 6, 2026 23:58
codescene-access[bot]

This comment was marked as outdated.

Base automatically changed from tier3/fix-red-main to main September 7, 2026 00:01
codescene-access[bot]

This comment was marked as outdated.

leynos and others added 5 commits September 7, 2026 01:17
Prepare for a zero-tolerance TypeDoc documentation gate: document every
declaration reachable from the package entry point, including one-line
JSDoc on each zod schema field surfaced through the fixture builders
and the transform-derived fields at their `return { … }` sites.

Tag the zod schema constants with documented `/** … @internal */`
blocks — they are validation seams whose meaning is carried by the
named output types. Convert the `GitHub*` output aliases from
`type … = z.infer<…>` to `interface … extends z.infer<…> {}` so
TypeDoc renders builder return types as references to the documented
interfaces instead of expanding the inferred structural type (the type
is unchanged; TypeDoc cannot preserve `z.infer` alias references), and
give each `build*Fixture` an explicit return-type annotation.
Add `docs-check` to `make all` between `typecheck` and `lint` (after
`typecheck` so the generated GraphQL types exist): TypeDoc's
`notDocumented` validation over the package entry point
(`src/index.ts`, `resolve` strategy, `emit: "none"`, validation
warnings as errors), configured by `typedoc.json` and run through
`bun run docs:check`. The gate requires 100% documentation of the
public surface, reports the qualified name of each undocumented
declaration, and writes no documentation artefacts. CI already runs
`make all`, so the gate needs no workflow changes.
Rebasing the gate onto main brought the shared domain-write slice into
the documented surface, and its exported object types carry undocumented
fields. Document each at its field site, the way the fixture surface
already is: the domain action arguments and the built-in action, the
repository update command, the update result union, and the REST patch
input.

Clear the nine cosmetic "unused @PARAM" warnings in `src/store/keys.ts`
so the gate finishes with none at all. They came from a genuine conflict:
Oxlint's df12/require-public-jsdoc wants one @PARAM per bound name, while
TypeDoc binds a destructured parameter to a single name and reports the
rest as unused. Taking the parameter whole and using nested
`@param parts.owner` tags satisfies both. The parameter type, the call
sites, and the behaviour are unchanged.
Turn on TypeDoc's `invalidLink`, `invalidPath` and `unusedMergeModuleWith`
validation, so an unresolvable `{@link}` fails the gate alongside a missing
JSDoc block. That exposed one broken reference: `{@link FoundationSimulator}`
on `simulation` names a type from `@simulacrum/foundation-simulator`, which
cannot resolve into this package's documentation. Map it through
`externalSymbolLinkMappings` to the upstream package page rather than
weakening the comment.

Add `tests/docs-gate.contract.test.ts`, which asserts the chain that makes
this a gate rather than a script nobody runs: the CI `verify` job runs
`make all` unconditionally and without `continue-on-error`, `make all`
lists `docs-check` among its prerequisites and after `typecheck`, the
`docs-check` recipe runs `bun run docs:check`, that script invokes typedoc
with `typedoc.json`, and `typedoc.json` still validates and still treats
validation warnings as errors. Each assertion matches the command or the
option, never a step name or a comment, so deleting any one link turns the
test red; all eight were mutation-tested.

Document the gate in the developers' guide: what it checks, how to run it
locally, and the three conventions for documenting an export that follow
from how TypeDoc and the Oxlint JSDoc rules interact.
Make `docs-check` depend on `typecheck` rather than merely follow it in
`all`. Ordering inside a prerequisite list is not ordering: `make -j all`
may start the gate before the GraphQL types are generated, and a bare
`make docs-check` after `make clean` skipped generation entirely. Assert
the prerequisite in the contract test.

Correct the new JSDoc where it promised more than the schemas deliver.
The timestamp, `sha` and security-status fields document conventions, not
validators, and now say so; the issue and pull-request `id` fallbacks are
unique within a repository, not across an instance, and now say so; the
user schema preserves a caller-supplied name; the repository schema
accepts REST URL fields rather than filling them in, and always re-derives
`full_name`; the pull-request base and head references default their
missing owner and repo rather than rewriting them; and the full-store
description lists issues. Tightening the validators instead would change
fixture-parsing behaviour, which is outside a documentation change.

Add the missing examples on `blobStoreKey` and `branchStoreKey`, and
JSDoc on `GitHubBlob` and `GitHubBranch`.

Add `tests/documented-surface.test-d.ts`, a compile-time test for the
type-level change this branch makes. The gate is satisfied by comments, so
nothing in it would notice if the `interface … extends z.infer<…> {}`
conversion or the builders' explicit return annotations drifted from the
inferred types. The exported extension hooks are covered too.

Update the developers' guide for the prerequisite and the local command.
codescene-access[bot]

This comment was marked as outdated.

Assert schema parity, builder return type, and builder input type for
`GitHubBranch` and `GitHubRepository` alongside the four already covered.
Neither type is re-exported from the package entry point, but
`buildBranchFixture` and `buildRepositoryFixture` are, so their return
types are public and the interface conversion applies to them too.
Widening `GitHubBranch` by one optional member fails the parity assertion.

Name `src/index.ts` as the package entry point in the guide rather than
letting `typedoc.json` stand in for it, and add the documentation check to
the numbered contributor gate, which otherwise omitted the one gate this
change adds.
@leynos

leynos commented Sep 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai The two documentation findings from the review body are addressed in 8a1cd95.

  • "Name src/index.ts as the package entry point": the gate description now
    reads "runs TypeDoc (bun run docs:check, configured by typedoc.json) over
    the package entry point, src/index.ts".
  • "Include the TypeDoc gate in the normal contributor gate": the numbered list
    now has bun run docs:check after bun check:types, and the paragraph below
    it says make all is the gate CI runs.

The duplicate rows for the Makefile dependency, the repository URL wording, the
timestamp contract and the security-status contract were all answered in their
inline threads on 8761492; the first two are fixed, and the last two are
answered with the reason the documentation moved rather than the validators.

@codescene-access codescene-access 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.

Gates Passed
6 Quality Gates Passed

See analysis details in CodeScene

Absence of Expected Change Pattern

  • simulacat-core/src/index.ts is usually changed with: simulacat-core/src/graphql/converters/repository.ts, simulacat-core/tests/graphql.test.ts, simulacat-core/src/rest/index.ts, simulacat-core/src/rest/utils.ts, simulacat-core/src/store/index.ts

Quality Gate Profile: Pay Down Tech Debt
Install CodeScene MCP: safeguard and uplift AI-generated code. Catch issues early with our IDE extension and CLI tool.

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

git show --stat --oneline --decorate --no-renames 8a1cd95
git show --format=fuller --no-ext-diff --unified=12 8a1cd95 -- docs/development.md

Length of output: 3465


@leynos Verified commit 8a1cd95.

The guide now identifies src/index.ts as the package entry point. The normal contributor gate now includes bun run docs:check. The make all section now states that CI runs this gate.


🧠 Learnings used
Learnt from: leynos
Repo: leynos/simulacat-core

Timestamp: 2026-09-07T00:16:11.572Z
Learning: In `leynos/simulacat-core`, timestamp fields in GitHub fixture schemas can intentionally use `z.string()` while their documentation states that ISO 8601 is a convention and any string is accepted. Replacing these validators with `z.string().datetime()` changes fixture-parsing behaviour and requires a separate compatibility decision and dedicated malformed-input tests.

Learnt from: leynos
Repo: leynos/simulacat-core PR: 58
File: src/store/entities/branch.ts:49-49
Timestamp: 2026-09-07T00:15:54.401Z
Learning: The TypeDoc documentation gate for simulacat-core starts at `src/index.ts`. Types such as `GitHubBranch` and `GitHubBlob` that are not re-exported from `src/index.ts` are not reached by TypeDoc’s `notDocumented` validation, but the project documents them because they are part of the fixture surface that readers encounter.

Learnt from: leynos
Repo: leynos/simulacat-core PR: 58
File: src/store/entities/repository.ts:221-250
Timestamp: 2026-09-07T00:15:53.565Z
Learning: In `src/store/entities/repository.ts`, the four `security_and_analysis` status fields intentionally use `z.string()` rather than `z.enum(['enabled', 'disabled'])`. The documented contract is that `enabled` and `disabled` are typical values, but any string is accepted to preserve compatibility with existing fixtures.

You are interacting with an AI system.

@leynos
leynos merged commit 0396a93 into main Sep 7, 2026
6 checks passed
@leynos
leynos deleted the typedoc-rollout branch September 7, 2026 00:43
@leynos

leynos commented Sep 7, 2026

Copy link
Copy Markdown
Owner Author

The nine validator tightenings from this review are tracked in #77 so they survive the merge.

Each item there carries the reviewer's rationale, the files and fields, and the
resolution #58 took. The issue also corrects a claim I made in these threads.
I said the tightenings would reject fixtures that parse today; measured one at
a time against bun test tests on main at eb906b2, that holds only for the
40-hex sha rule, which fails twenty-two tests. The timestamp and
security-status tightenings break nothing in this repository, so items 1 to 3
of #77 are unblocked. They stayed out of #58 for the narrower reason that they
narrow what simulation({initialState}) accepts for consumers, which is a
versioned behaviour decision that wants its own malformed-input tests.

Also tracked: the remaining threads whose findings were resolved by correcting
the documentation, where the alternative behaviour change is still available
(#77 items 7 to 9).

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.

2 participants