# Contributing

> Fork-only contribution policy, feedback form, design-system token rules (Font.ink*, Color.canvas, ds-allow escape hatch), DESIGN_SYSTEM.md reference, commit-message conventions in AGENTS.md, and CI-enforced checks.

- Repository: cartesia-ai/InkIt
- GitHub: https://github.com/cartesia-ai/InkIt
- Human docs: https://grok-wiki.com/public/docs/cartesia-ai-inkit-18975554254b
- Complete Markdown: https://grok-wiki.com/public/docs/cartesia-ai-inkit-18975554254b/llms-full.txt

## Source Files

- `.github/CONTRIBUTING.md`
- `AGENTS.md`
- `DESIGN_SYSTEM.md`
- `InkIt/InkItApp.swift`
- `tools/check-design-tokens.sh`
- `LICENSE`

---

---
title: "Contributing"
description: "Fork-only contribution policy, feedback form, design-system token rules (Font.ink*, Color.canvas, ds-allow escape hatch), DESIGN_SYSTEM.md reference, commit-message conventions in AGENTS.md, and CI-enforced checks."
---

InkIt is Apache-2.0 open source, but upstream does not accept outside pull requests. You may read, build, learn from, and fork the repository freely; active development stays with the Cartesia team. Fork maintainers and internal contributors follow the design-token rules in `AGENTS.md` and `DESIGN_SYSTEM.md`, with mechanical enforcement via `tools/check-design-tokens.sh` on every CI run.

## Contribution policy

| Path | Status |
|---|---|
| Read, build, and fork under Apache-2.0 | Allowed |
| Submit pull requests to `cartesia-ai/InkIt` | Not accepted |
| Report bugs or share feedback | Use the feedback form (below) |

The repository is public for transparency and learning, not for community-driven merges. Cartesia keeps development in one place to move quickly and keep the codebase coherent. If you want a change upstream does not ship, fork the repo and maintain your own variant — that is what the license is for.

<Warning>
Pull requests to the upstream repository are not reviewed or merged. Do not open PRs expecting integration; fork instead.
</Warning>

## License and forking

InkIt is distributed under the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). You may reproduce, modify, and distribute the work or derivative works in source or object form, provided you include the license, retain attribution notices, and mark modified files. Copyright is held by Cartesia AI (2026).

Forking is the intended path for custom features, experiments, or long-lived private variants. No upstream approval is required beyond complying with the license terms.

## Feedback and bug reports

Upstream does not use GitHub Issues for product feedback. Submit bugs, ideas, and usage notes through the feedback form:

https://forms.gle/jXNtDsTaLt2rKQ8N9

The team reads all submissions. Not every item leads to a change, but feedback informs how InkIt is used and what to prioritize internally.

## Design system — use tokens, never hardcode

InkIt has one source of truth for typography and color: the `Font` and `Color` extensions at the top of `InkIt/InkItApp.swift`, backed by the asset catalog. Full rationale, token tables, and interaction patterns live in `DESIGN_SYSTEM.md`. `AGENTS.md` summarizes the rules for humans and coding agents.

### Typography tokens

Display text must use a named `Font.ink*` token — never a bare `.font(.system(size: N))` at a call site.

| Token family | Examples | Use |
|---|---|---|
| Titles | `inkLargeTitle`, `inkTitle`, `inkBanner`, `inkSheetTitle` | Onboarding hero, pane headers, Home banner |
| Body | `inkBody`, `inkBodyEmphasized`, `inkReading`, `inkReadingEmphasized` | Transcripts, row labels, Try-It practice text |
| UI chrome | `inkHeadline`, `inkCallout`, `inkNav`, `inkSectionHeader`, `inkEyebrow`, `inkCaption` | Cards, nav, grouped headers, metadata |
| Credentials | `inkMono` | API-key fields |
| Notch HUD | `inkNotchBrand`, `inkNotchLabel` | Fixed-size menu-bar strip only |

If a size or weight is missing from the scale, add a new token to the extension block with a doc comment — do not inline the literal.

### Color tokens

Views reference semantic tokens, not raw RGB or hex values.

| Category | Tokens | Notes |
|---|---|---|
| Warm-paper surfaces | `Color.canvas`, `Color.surface`, `Color.lift`, `Color.card`, `Color.paper` | Asset-catalog neutrals for every surface |
| Brand | `Color.accentColor`, `Color.accentSoft`, `Color.recordingAmber`, `Color.diffAdd` | Amber accent; recording signal on the HUD |
| System semantics | `.primary`, `.secondary`, `.tertiary`, `Color(nsColor: .separatorColor)` | Text and hairlines; adapt to appearance |
| Fixed surfaces | `Color.hudPill`, `Color.scrim` | Always-dark HUD pill; modal dimming |

The notch HUD stays dark in all appearances and is exempt from the appearance picker. Only `recordingAmber` adds color to live feedback on that surface.

### Shape, motion, and elevation

Corner radii come from `enum Radius` in `InkItApp.swift`. Drop-shadow inks use `enum Elevation`; modal backdrops use `Color.scrim`. Animation curves use `enum Motion` — not raw `.easeOut(duration:)` at call sites. Hover affordances use `enum Hover` and the `.hoverBackdrop()` modifier.

### Do and don't

**Do**
- Use `.font(.inkBody)` (or another `Font.ink*` token) for every piece of display text.
- Use `Color.canvas`, `.secondary`, and other semantic tokens for UI color.
- Add a new token when the scale lacks the size or weight you need.

**Don't**
- Re-enter `.font(.system(size: N))` for running text or recurring UI.
- Write `Color(red:…)`, hex literals, or other raw color constructors for app chrome.
- Inline corner radii, shadow opacities, or animation durations that belong on the shared scales.

## The `ds-allow` escape hatch

Genuine one-offs may opt out of the lint with a trailing same-line comment that names the reason:

```swift
Image(systemName: "gearshape").font(.system(size: 17, weight: .medium))  // ds-allow: icon
```

Sanctioned one-offs include SF Symbol icon glyphs sized to their container, the always-dark notch HUD micro-type, the dual-appearance `AppearanceThumbnail` preview, and bespoke animations (reveals, repeating pulses). Use sparingly. If a value recurs or is plain running text, it belongs on the token scale — not behind `ds-allow`.

`tools/check-design-tokens.sh` skips lines containing `ds-allow`, token definitions (`static let`), and comment-only lines.

## Local design-token check

Run the guard script before pushing any Swift UI changes:

```sh
./tools/check-design-tokens.sh
```

The script scans `InkIt/*.swift` and fails on unjustified literals:

| Pattern | Label | Fix |
|---|---|---|
| `system(size: N)` | Hardcoded font size | Use a `Font.ink*` token |
| `Color(red:` / `Color(white:` | Raw color literal | Use a `Color` token |
| `easeOut(duration:` | Hardcoded animation | Use a `Motion.*` token |
| `.black.opacity(` | Raw shadow/scrim ink | Use `Elevation.*` or `Color.scrim` |

Success prints `✓ design tokens: no unjustified literals`. Failures list file paths and line numbers; exit code is `1`.

## CI-enforced checks

The `.github/workflows/ci.yml` workflow runs on pushes and pull requests to `main` (macOS 15, Xcode). A PR that breaks mechanical rules will not pass CI.

<Steps>
<Step title="Check design tokens">

```sh
./tools/check-design-tokens.sh
```

First step in CI; fails the job on any unjustified literal.

</Step>
<Step title="Generate Xcode project">

```sh
brew install xcodegen   # CI installs via Homebrew
xcodegen generate
```

`InkIt.xcodeproj` is generated from `project.yml` — edit `project.yml`, not the `.pbxproj`.

</Step>
<Step title="Run unit tests">

```sh
xcodebuild test \
  -project InkIt.xcodeproj \
  -scheme InkIt \
  -configuration Debug \
  -destination 'platform=macOS'
```

</Step>
<Step title="Build Release">

```sh
xcodebuild build \
  -project InkIt.xcodeproj \
  -scheme InkIt \
  -configuration Release \
  -destination 'platform=macOS'
```

Verifies the Release configuration compiles after tests pass.

</Step>
</Steps>

Fork maintainers can mirror this pipeline locally. See [Testing and CI](/testing-and-ci) for test targets and workflow detail.

## Build and test (fork workflow)

For a local fork:

```sh
xcodegen generate
xcodebuild -project InkIt.xcodeproj -scheme InkIt -configuration Debug \
  -destination 'platform=macOS' test
```

Replace `/Applications/InkIt.app` after local builds when testing the installed app. See [Build from source](/build-from-source) for signing, XcodeGen, and install steps.

## Commit message conventions

`AGENTS.md` defines message style for the public repository. Messages stay factual and low-profile.

**Subject line**
- Imperative mood; states what changed mechanically.
- No product framing, editorializing, or intent cues.
- Avoid subjects like "prep for open source", "visual-first landing page", or "leaner repo".

**Body (optional)**
- Technical mechanism only — e.g. why a fix works.
- No narrative about product or business goals.

Coding agents should propose commit messages for approval before committing.

<AccordionGroup>
<Accordion title="Subject examples">

| Avoid | Prefer |
|---|---|
| Add privacy gating for onboarding | Gate Cartesia key field behind onboarding step |
| Visual-first landing page refresh | Replace Home empty state with stats rail |
| Leaner/cleaner repo layout | Move design-token script to tools/ |

</Accordion>
</AccordionGroup>

## Key reference files

| File | Role |
|---|---|
| `.github/CONTRIBUTING.md` | Public contribution policy and feedback link |
| `AGENTS.md` | Agent and maintainer rules: tokens, build, commits |
| `DESIGN_SYSTEM.md` | Full design direction, token tables, interaction patterns |
| `InkIt/InkItApp.swift` | Token definitions: `Color`, `Font`, `Radius`, `Elevation`, `Motion`, `Hover` |
| `tools/check-design-tokens.sh` | Lint script run locally and in CI |
| `.github/workflows/ci.yml` | CI job: tokens → xcodegen → test → Release build |
| `LICENSE` | Apache-2.0 terms |

## Related pages

<CardGroup>
<Card title="Build from source" href="/build-from-source">
Generate the Xcode project, sign Debug/Release builds, and install to `/Applications`.
</Card>
<Card title="Testing and CI" href="/testing-and-ci">
Local `xcodebuild test` commands, CI workflow steps, and test target overview.
</Card>
<Card title="Overview" href="/overview">
What InkIt exposes: dictation pipeline, HUD, history, and runtime requirements.
</Card>
</CardGroup>
