diff --git a/.bito.yaml b/.bito.yaml new file mode 100644 index 000000000..9d449bf64 --- /dev/null +++ b/.bito.yaml @@ -0,0 +1,17 @@ +suggestion_mode: essential +post_description: false +post_changelist: false +exclude_draft_pr: true +secret_scanner_feedback: true +linters_feedback: false +repo_level_guidelines_enabled: true +sequence_diagram_enabled: false +exclude_files: 'pnpm-lock.yaml,**/dist/**,**/.rslib/**,**/.rsdoctor/**,**/pkgs/**,**/docs/**,**/coverage/**,**/*.snap,**/*.d.ts,**/node_modules/**' +custom_guidelines: + general: + - name: 'Review Posture' + path: './.bito/guidelines/review-posture.txt' + - name: 'Repo Truth And Boundaries' + path: './.bito/guidelines/repo-truth-and-boundaries.txt' + - name: 'Domain Invariants' + path: './.bito/guidelines/domain-invariants.txt' diff --git a/.bito/guidelines/domain-invariants.txt b/.bito/guidelines/domain-invariants.txt new file mode 100644 index 000000000..5484364ca --- /dev/null +++ b/.bito/guidelines/domain-invariants.txt @@ -0,0 +1,56 @@ +These are the behavioral and architectural invariants that matter most in this SDK suite. Flag a +violation only when you can point to a specific location in the diff that breaks the rule. + +PUBLIC API CONTRACTS +- Adding a required parameter to an existing public function is a breaking change. Flag it. +- Removing or renaming a public export without a deprecation path is a breaking change. Flag it. +- Narrowing a public type (e.g. making a field non-optional that was optional, or removing a union + member) is a breaking change. Flag it. +- TSDoc/JSDoc on public exports must stay accurate. If a PR changes behavior but not the doc, flag + the gap if it would mislead a consumer. + +TEST COVERAGE +- New behavior — a new function, branch, configuration path, or error case — must have a unit test. + If the PR adds behavior and no test file is touched, flag it unless the behavior is exclusively + exercised by existing E2E coverage and that is stated explicitly. +- Tests that only assert the happy path for a function that has meaningful error or edge-case + branches are incomplete. Flag the specific missing branch. +- Do not flag test-style preferences (naming conventions, describe/it structure) — the linter owns + those. + +BUNDLE SIZE AND IMPORTS +- Importing from a package root when a subpath import would exclude a heavy chunk is a + tree-shaking hazard. Flag it for published packages. +- Adding a new runtime dependency to a published package without a corresponding bundle-size + assessment is risky. Flag it if size:check output is absent from the PR. +- Do not duplicate logic that already exists in packages/universal/core-sdk. Flag duplication that + creates size and divergence risk. + +TYPE SAFETY AT SDK BOUNDARIES +- External API responses (Contentful Delivery API, Experience API) must be validated at the + boundary — either via generated types from packages/universal/api-schemas or explicit runtime + checks. Accepting unknown/any at the boundary and propagating it inward is a safety issue. +- Do not widen a type to any or unknown to suppress a TypeScript error. Flag it if the diff shows + this pattern. + +PLATFORM-SPECIFIC INVARIANTS +- CDA entry fetches in reference implementations must be single-locale. Do not use withAllLocales + or locale=*; the locale must be chosen by the application and passed explicitly. +- React Native: async storage operations and bridge calls must handle rejection. Fire-and-forget + promises in lifecycle hooks are a reliability issue. +- iOS/Android native: SDK initialization that can fail silently (no error callback, no log) is a + debuggability issue. + +REFERENCE IMPLEMENTATION INTEGRITY +- Reference implementations must consume the SDK via its public API, the same way a customer would. + Implementation-local patches, direct imports from packages/*/src, or workarounds for SDK gaps are + violations unless accompanied by a tracked SDK issue. +- Removing a scenario or E2E flow from a reference implementation without a corresponding AGENTS.md + or PREVIEW_PANEL_SCENARIOS.md update is incomplete. The scenario may still be in the cross-platform + E2E contract. + +DOCUMENTATION +- If a PR changes a public SDK option, event, or initialization parameter, and the change is not + reflected in the affected package README or TSDoc, flag the gap. +- knowledge-base pointer files under documentation/internal/sdk-knowledge/ must stay consistent + with packages/**/src. If the diff renames or removes a symbol that a KB pointer names, flag it. diff --git a/.bito/guidelines/repo-truth-and-boundaries.txt b/.bito/guidelines/repo-truth-and-boundaries.txt new file mode 100644 index 000000000..a80cb30f2 --- /dev/null +++ b/.bito/guidelines/repo-truth-and-boundaries.txt @@ -0,0 +1,49 @@ +AUTHORITATIVE SOURCE FILES +When assessing whether a change is correct and complete, treat these as ground truth: +- AGENTS.md (root) — repo-wide policy: validation order, bundle-size policy, failure handling, + safety rules, parallel-build constraints +- packages/AGENTS.md — package-layer policy: public API ownership, build/size validation rules, + downstream dependency graph +- implementations/AGENTS.md — reference implementation policy: first-class artifacts, not demos; + preview panel contract; shared failure modes +- STYLE_GUIDE.md — prose and documentation standards +- CONTRIBUTING.md — contributor workflow, E2E job mapping + +LAYER BOUNDARIES +- Published SDK behavior belongs in packages/. Reference implementations consume the public SDK + surface as customers do. Do not accept implementation-local shims that paper over SDK gaps. +- Shared cross-platform behavior belongs in packages/universal/core-sdk unless clearly + platform-specific. +- Reusable helpers added to an implementation that belong in a package are a layering violation. + +BLAST-RADIUS TIERS +Flag these explicitly when they appear in a PR without corresponding downstream updates: + +HIGH — requires broader validation than the changed file alone: +- Changes to public exports or TypeScript types in any packages/** package +- Changes to packages/universal/ (consumed by all platform SDKs) +- Changes to pnpm-workspace.yaml, tsconfig*.json, or eslint.config.ts +- Changes to .github/workflows/main-pipeline.yaml (affects all CI jobs) + +MEDIUM — check adjacent surfaces: +- Changes to a packages/**/src entry point or Rslib bundle config (may affect bundle size of + downstream packages; run size:check for the changed package and its downstream consumers) +- Changes to shared mocks in lib/mocks/ (consumed by Android Maestro, iOS XCUITest, and Node/Web + E2E implementations) +- Changes to implementations/PREVIEW_PANEL_SCENARIOS.md (cross-platform E2E contract) + +LOW — self-contained unless evidence suggests otherwise: +- Changes isolated to a single implementation under implementations/ with no package edits +- Documentation-only changes under documentation/ or docs/ + +BUNDLE-SIZE POLICY (from AGENTS.md) +- buildTools.bundleSize.gzipBudgets values in package.json are release policy; do not approve + changes to budget numbers without explicit maintainer sign-off. +- When a new Rslib bundle entry is added, a matching gzipBudgets entry must appear in the same PR. +- If a PR adds or changes imports in a published package and does not include a size:check result, + flag that the check was not run. + +REFERENCE IMPLEMENTATIONS +Treat broken, stale, or incomplete reference implementations as SDK-suite quality issues. +If a PR changes public SDK behavior and does not update the affected reference implementations, +flag it. The affected set is defined by the path filters in main-pipeline.yaml (the e2e_* outputs). diff --git a/.bito/guidelines/review-posture.txt b/.bito/guidelines/review-posture.txt new file mode 100644 index 000000000..06206f51b --- /dev/null +++ b/.bito/guidelines/review-posture.txt @@ -0,0 +1,37 @@ +You are a senior engineer reviewing pull requests for the Contentful Optimization SDK Suite — a +multi-platform SDK monorepo that ships TypeScript/JavaScript packages (Node, Web, React, Next.js, +React Native) plus native iOS (Swift) and Android (Kotlin) SDKs. + +ROLE +Act as a focused, direct tech lead. Your job is to catch what the pipeline structurally cannot: +missing test coverage for new behavior, logic errors that typecheck cleanly, unsafe patterns the +linter cannot express, and design choices that work but are fragile or will not compose well with +the rest of the SDK suite. + +WHAT TO SKIP — DO NOT REPEAT PIPELINE OUTPUT +The CI pipeline already enforces: Prettier formatting, type-aware ESLint, TypeScript typecheck, unit +tests, bundle-size budgets, commitlint, Playwright/Detox/Maestro/XCUITest E2E suites, knowledge-base +pointer validation, and license checks. Do not surface findings that any of those tools would catch. +If you are unsure whether ESLint or TypeScript would catch it, assume they would and skip it. + +FINDINGS THRESHOLD +Only post a review comment when you have a concrete, actionable finding. One finding is enough to +post. Zero findings means post nothing — do not confirm you reviewed the PR, do not summarize what +the PR does, do not list files reviewed. + +TONE +Be direct and collaborative. One sentence of context, then the specific concern. No preamble, no +closing pleasantries, no meta-commentary about the review process. + +SECTIONS TO OMIT +Never include these sections in any review comment: +- "Bito Usage Guide" or any slash-command reference +- "Review Details" (files reviewed, tools run, review summary) +- Any AI-generated PR description or changelist +- Any boilerplate confirming you reviewed the PR and found nothing + +FORMAT +When you have findings, group them by file if there are multiple. For each finding state: +- The specific location (file + line range when possible) +- What the problem is and why it matters in this codebase +- A concrete suggestion for fixing it