Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .docs/TSK-4-public-trust-desktop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .docs/TSK-4-public-trust-mobile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions .tasks/2026-07-18-TSK-4-public-repository-trust-TASKS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# TSK-4 — Public Repository Trust

**Overall status:** DONE

## TG-001 — Public narrative and boundaries

- **Owner:** Main agent
- **Status:** DONE
- **Acceptance:** README and root guidance explain the problem, evidence, limitations, contribution, security, and source terms.
- **Evidence:** Product-first README, real website screenshot, explicit available/unavailable table, `CONTRIBUTING.md`, `SECURITY.md`, and source-available `LICENSE` are present.

## TG-002 — GitHub presentation

- **Owner:** Main agent
- **Status:** DONE
- **Acceptance:** Description, homepage, topics, and landing-page repository language are accurate.
- **Evidence:** GitHub description, preview homepage, ten relevant topics, private vulnerability reporting, and protected `main` are configured. Landing copy now says design-partner research, price hypothesis, proposed workflow, and public build.

## TG-003 — Validation

- **Owner:** Main agent
- **Status:** DONE
- **Acceptance:** Links, checks, public rendering, and independent truthfulness review pass.
- **Evidence:** Full `bun run check` passes, Impeccable detector returns zero findings, desktop/mobile screenshots are inspected, and two isolated public-credibility reviews confirm the implemented boundary language.
15 changes: 15 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Contributing

OpenAPI Studio is an evidence-gated founding build. Discuss substantial product work in an issue before implementation; unsolicited feature expansion may be declined when it is not supported by pilot evidence.

## Before opening a pull request

1. Read `AGENTS.md`, `PRODUCT.md`, `DESIGN.md`, and `specs/roadmap.md`.
2. Keep changes inside one small vertical slice.
3. Preserve truthful product boundaries—do not imply unfinished capabilities exist.
4. Do not include real API contracts, customer information, credentials, or generated secrets.
5. Run `bun run check`.

Pull requests should explain the user problem, scope, validation evidence, and any security or privacy impact. Include screenshots for visual changes and link the relevant issue or feature specification.

By submitting a contribution, you agree that the project owner may use, modify, and redistribute it as part of OpenAPI Studio. Opening a pull request does not change the repository’s source-available license.
9 changes: 9 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Copyright (c) 2026 Milon Biswas. All rights reserved.

This repository is made publicly available for transparency and technical evaluation only.

No permission is granted to copy, modify, distribute, sublicense, sell, host, or create derivative works from this software or its design assets without prior written permission from the copyright holder.

Viewing or forking the repository through functionality provided by GitHub does not grant additional rights. Third-party dependencies and bundled font assets remain subject to their respective licenses.

For licensing enquiries, contact pitechae@gmail.com.
58 changes: 46 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,66 @@
# OpenAPI Studio

Single-package modular monolith built with TanStack Start Solid for Cloudflare Workers.
Review consequential OpenAPI contract changes before they reach users.

> **Founding build:** OpenAPI Studio is not a finished editor or self-serve product. The public repository currently proves the delivery foundation, demand test, and proposed review workflow. Product capabilities are built only after design-partner evidence.

[![Quality](https://github.com/bymilon/openapi-studio-tanstack/actions/workflows/quality.yml/badge.svg)](https://github.com/bymilon/openapi-studio-tanstack/actions/workflows/quality.yml)

![OpenAPI Studio demand-validation website](.docs/TSK-4-public-trust-desktop.png)

_Website preview—not product UI._

[View the live preview](https://openapi-studio-tanstack-preview.pibin.workers.dev) · [Join design-partner research](mailto:pitechae@gmail.com?subject=OpenAPI%20Studio%20design-partner%20research) · [Read the product roadmap](specs/roadmap.md)

## The problem

Raw OpenAPI diffs show which lines moved, but teams still have to determine what may break, who is affected, and whether the new contract should be published. OpenAPI Studio is testing a focused workflow that keeps the change, consequence, and team decision connected.

## What exists today

| Area | Current evidence |
| ----------------------- | ---------------------------------------------------------------------------------------- |
| Design-partner research | Responsive landing page, qualified email path, explicit `$29/workspace/month` hypothesis |
| Delivery | Cloudflare Workers preview, locked Bun install, GitHub Actions validation |
| Quality | TypeScript, Oxlint, Oxfmt, Vitest, Playwright, axe accessibility checks |
| Data foundation | Drizzle schema, committed migration, local migration and database smoke checks |
| Operations | Request observability and identifier-free first-party conversion events |
| Product design | Labelled OpenAPI review prototype and evidence-gated roadmap |

## What does not exist yet

- No production OpenAPI editor or account access
- No contract import, validation, diff engine, revision history, or publishing workflow
- No customers, usage claims, testimonials, checkout, or billing
- No production deployment or custom domain

The next product phase is intentionally gated on qualified conversations and pilot commitment. See [PRODUCT.md](PRODUCT.md), [DESIGN.md](DESIGN.md), and the [roadmap](specs/roadmap.md) for the decisions behind that boundary.

## Architecture

This is a single-package modular monolith using TanStack Start with Solid, TypeScript, Cloudflare Workers, Bun, Turso/libSQL, Drizzle ORM, Valibot, Tailwind CSS, Oxlint, Oxfmt, Vitest, and Playwright. Feature code lives under `src/features`; platform boundaries live under `src/platform`; migrations live under `drizzle`; browser and unit tests live under `tests` and adjacent feature files.

## Local development

Prerequisite: Bun 1.3.14 or a newer 1.x release.
Requires Bun 1.3.14 or a newer 1.x release.

```bash
bun install --frozen-lockfile
bun run dev
```

## Validation
Run the same validation used by CI:

```bash
bun run check
```

Validate committed database migrations without cloud credentials:
Database access expects `TURSO_DATABASE_URL` and `TURSO_AUTH_TOKEN`. Copy `.env.example` to an ignored local environment file. Local development and CI do not require production credentials. `bun run deploy:preview` is human-gated; no production deployment command exists.

```bash
bun run db:check
bun run db:smoke
```
## Contributing and security

Runtime database access expects `TURSO_DATABASE_URL` and `TURSO_AUTH_TOKEN`. Copy `.env.example` to an ignored local environment file; never commit real credentials.
`bun run db:integration` is reserved for an approved disposable Turso database.
Read [CONTRIBUTING.md](CONTRIBUTING.md) before proposing a change. Do not report vulnerabilities in public issues; follow [SECURITY.md](SECURITY.md). Never submit real API contracts, customer data, credentials, or confidential material.

`bun run deploy:preview` is intentionally human-gated and targets only the named Cloudflare preview environment. Local development and CI require no production credentials. No production deploy command exists in this phase.
## Source terms

Pull requests and pushes to `main` run the same locked install, application checks, and local migration smoke test in GitHub Actions. Remote Turso credentials are not available to untrusted pull-request jobs.
The repository is public for transparency and technical evaluation, but it is not currently open source. No reuse rights are granted. See [LICENSE](LICENSE).
17 changes: 17 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Security Policy

## Reporting a vulnerability

Do not open a public issue for suspected vulnerabilities. Email `pitechae@gmail.com` with the subject `OpenAPI Studio security report` and include:

- The affected route, component, or commit
- Reproduction steps and expected impact
- Any suggested mitigation

Do not access data that is not yours, degrade the service, or include credentials, customer data, or confidential API contracts in the report. Receipt will be acknowledged within three business days. No bug-bounty program is currently offered.

Good-faith research that follows these boundaries will not be pursued or referred for legal action by the project owner.

## Supported surface

Only the latest commit on `main` and the named Cloudflare preview are in scope. OpenAPI Studio is a founding build without production accounts, editor access, or billing. Security claims beyond the implemented public surface are not implied.
23 changes: 23 additions & 0 deletions specs/features/2026-07-18-public-repository-trust/spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Public Repository Trust

| Field | Value |
| ---------- | ---------------------------------------------------------------- |
| Feature ID | TSK-4 |
| Status | SPEC_APPROVED |
| Outcome | Make the public repository credible and truthful before outreach |

## Requirements

- **REQ-001:** Lead with the buyer problem and founding-build status, not the stack.
- **REQ-002:** Show current evidence and unavailable product capabilities separately.
- **REQ-003:** Link the live preview, pilot contact, roadmap, validation, and screenshot.
- **REQ-004:** State contribution, security-reporting, privacy, and source-use boundaries.
- **REQ-005:** Curate GitHub description, homepage, and topics.
- **REQ-006:** Landing-page repository links describe public build transparency, not finished-product proof.

## Validation

- README links and image resolve on GitHub.
- Repository metadata is populated and accurate.
- `bun run check` passes after copy and test changes.
- No product capability absent from the repository is presented as available.
44 changes: 22 additions & 22 deletions src/features/marketing/marketing-home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Would we pay $29/workspace/month if this worked? Why or why not?
Best,
`.replaceAll('\n', '\r\n')

const applicationHref = `mailto:pitechae@gmail.com?subject=${encodeURIComponent('OpenAPI Studio founding pilot')}&body=${encodeURIComponent(applicationBody)}`
const applicationHref = `mailto:pitechae@gmail.com?subject=${encodeURIComponent('OpenAPI Studio design-partner research')}&body=${encodeURIComponent(applicationBody)}`
const repositoryHref = 'https://github.com/bymilon/openapi-studio-tanstack'

function Mark() {
Expand Down Expand Up @@ -47,44 +47,43 @@ export function MarketingHome() {
href={applicationHref}
onClick={() => recordConversion('design_partner_clicked')}
>
Join pilot
Join research
</a>
</nav>
</header>

<section class="hero shell">
<div class="hero-copy">
<p class="eyebrow">
<span>Founding pilot</span> Five teams
<span>Design-partner research</span> Five teams
</p>
<h1>Catch the breaking change before your users do.</h1>
<p class="hero-lead">
We are testing a workflow that turns an OpenAPI diff into a clear review of what
changed, what may break, and what the team should publish next.
We are testing whether small API teams need a clearer way to review OpenAPI contract
changes before we build the product workflow.
</p>
<div class="hero-actions">
<a
class="button button-dark"
href={applicationHref}
onClick={() => recordConversion('design_partner_clicked')}
>
Email the founder about the pilot <span aria-hidden="true">↗</span>
Email the founder about the research <span aria-hidden="true">↗</span>
</a>
<a class="text-link" href="#workflow">
See the workflow <span aria-hidden="true">↓</span>
</a>
</div>
<p class="availability">
Free pilot now. $29/workspace/month only if it earns its place.
Interviews are free. A product pilot and $29/workspace/month price are hypotheses—not
available yet.
</p>
</div>

<figure class="contract-artifact" aria-labelledby="artifact-title">
<div class="artifact-top">
<div>
<p class="artifact-kicker">
Illustrative founding-pilot prototype · not a live editor
</p>
<p class="artifact-kicker">Illustrative product concept · not a live editor</p>
<p id="artifact-title" class="artifact-title">
billing-api.yaml <span>PR #184</span>
</p>
Expand Down Expand Up @@ -139,8 +138,8 @@ export function MarketingHome() {
<section id="workflow" class="workflow-section">
<div class="shell">
<div class="section-intro">
<p class="section-label">The workflow</p>
<h2>From changed line to team decision.</h2>
<p class="section-label">Proposed workflow</p>
<h2>The workflow we want to validate.</h2>
</div>
<ol class="workflow-list">
<li>
Expand Down Expand Up @@ -171,18 +170,19 @@ export function MarketingHome() {
<section id="evidence" class="evidence-section">
<div class="shell evidence-grid">
<div>
<p class="section-label">Evidence, not theatre</p>
<h2>Inspect the work before you trust the promise.</h2>
<p class="section-label">Current build status</p>
<h2>See what exists today—and what comes next.</h2>
</div>
<div class="evidence-copy">
<p>
OpenAPI Studio is an early founding pilot, not a finished self-serve product. The
public build targets OpenAPI 3.0/3.1, deploys to a Cloudflare preview, and records
identifier-free conversion events. No invented customers. No fake screenshots. No
checkout.
OpenAPI Studio is in demand validation, not a working editor. Today’s repository
contains this website, delivery checks, preview infrastructure, and identifier-free
conversion measurement. OpenAPI 3.0/3.1 import, validation, diff review, and
publishing are roadmap work—not implemented yet. No invented customers. No fake
screenshots. No checkout.
</p>
<a href={repositoryHref} onClick={() => recordConversion('repository_clicked')}>
Inspect public source <span>↗</span>
Follow the public build <span>↗</span>
</a>
<a
href={`${repositoryHref}/actions`}
Expand All @@ -197,16 +197,16 @@ export function MarketingHome() {
<section class="offer-section">
<div class="shell offer-grid">
<div>
<p class="section-label">Five-team founding offer</p>
<p class="section-label">Five-team research cohort</p>
<h2>Bring the contract change your team keeps paying for.</h2>
</div>
<div class="price">
<span>$</span>
<strong>29</strong>
<p>
per workspace / month
price hypothesis
<br />
after a free pilot
product not available yet
</p>
</div>
<div class="offer-action">
Expand Down
19 changes: 10 additions & 9 deletions tests/browser/marketing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ test('presents a truthful design-partner conversion path', async ({ page }) => {
}),
).toBeVisible()

const application = page.getByRole('link', { name: 'Email the founder about the pilot' })
const application = page.getByRole('link', { name: 'Email the founder about the research' })
const applicationUrl = new URL((await application.getAttribute('href')) ?? '')
expect(applicationUrl.protocol).toBe('mailto:')
expect(applicationUrl.pathname).toBe('pitechae@gmail.com')
expect(applicationUrl.searchParams.get('subject')).toBe('OpenAPI Studio founding pilot')
expect(applicationUrl.searchParams.get('subject')).toBe('OpenAPI Studio design-partner research')
expect(applicationUrl.searchParams.get('body')).toContain('Team and product:')
expect(applicationUrl.searchParams.get('body')).toContain('Current OpenAPI workflow:')
expect(applicationUrl.searchParams.get('body')).toContain(
Expand All @@ -31,12 +31,11 @@ test('presents a truthful design-partner conversion path', async ({ page }) => {
expect(applicationUrl.searchParams.get('body')).toContain(
'Would we pay $29/workspace/month if this worked? Why or why not?',
)
await expect(
page.getByText('No invented customers. No fake screenshots. No checkout.'),
).toBeVisible()
await expect(page.getByText('not a working editor')).toBeVisible()
await expect(page.getByText('roadmap work—not implemented yet')).toBeVisible()
await expect(page.getByText('Illustrative prototype—not a screenshot')).toBeVisible()
await expect(page.getByText('no contract upload or confidential material')).toBeVisible()
await expect(page.getByRole('link', { name: 'Inspect public source' })).toHaveAttribute(
await expect(page.getByRole('link', { name: 'Follow the public build' })).toHaveAttribute(
'href',
'https://github.com/bymilon/openapi-studio-tanstack',
)
Expand All @@ -54,7 +53,7 @@ test('has no detectable accessibility violations and a usable tab order', async
await page.keyboard.press('Tab')
await expect(page.getByRole('link', { name: 'Evidence' })).toBeFocused()
await page.keyboard.press('Tab')
await expect(page.getByRole('link', { name: 'Join pilot' })).toBeFocused()
await expect(page.getByRole('link', { name: 'Join research' })).toBeFocused()
})

test('keeps the offer usable on a narrow screen without JavaScript', async ({ browser }) => {
Expand All @@ -67,8 +66,10 @@ test('keeps the offer usable on a narrow screen without JavaScript', async ({ br
await page.goto('/')

await expect(page.getByRole('main')).toBeVisible()
await expect(page.getByRole('link', { name: 'Email the founder about the pilot' })).toBeVisible()
await expect(page.getByText('per workspace / month')).toBeVisible()
await expect(
page.getByRole('link', { name: 'Email the founder about the research' }),
).toBeVisible()
await expect(page.getByText('price hypothesis')).toBeVisible()
expect((await page.locator('body').evaluate((body) => body.scrollWidth)) <= 360).toBe(true)

await context.close()
Expand Down