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
34 changes: 34 additions & 0 deletions .github/workflows/deploy-cloudflare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Deploy Cloudflare

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: oss-cloudflare-production
cancel-in-progress: false

jobs:
deploy:
runs-on: ubuntu-latest
env:
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run check
- run: npm run build
- run: npm audit --audit-level=low
- name: Upload exact Worker version
run: npx wrangler versions upload --config wrangler.json --tag "$GITHUB_SHA" --message "GitHub $GITHUB_SHA"
- name: Deploy exact Worker version
run: npx wrangler versions deploy --config wrangler.json --version-tag "$GITHUB_SHA" --percentage 100 --yes --message "GitHub $GITHUB_SHA"
39 changes: 39 additions & 0 deletions .github/workflows/refresh-openclaw-ledger.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Refresh OpenClaw ledger

on:
schedule:
- cron: "37 * * * *"
workflow_dispatch:

permissions:
contents: write

concurrency:
group: refresh-openclaw-ledger
cancel-in-progress: false

jobs:
refresh:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run refresh:ledger
- run: npm run check:claims
env:
GH_TOKEN: ${{ github.token }}
- name: Commit changed ledger snapshot
run: |
if git diff --quiet -- public/openclaw-prs.json; then
echo "No OpenClaw ledger changes."
exit 0
fi
git config user.name "Cad from Arca"
git config user.email "cad@arcabot.ai"
git add public/openclaw-prs.json
git commit -m "chore: refresh OpenClaw ledger"
git push
12 changes: 6 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
node_modules
.next
out
.vercel
*.log
node_modules/
dist/
.astro/
.wrangler/
*.tsbuildinfo
.DS_Store
.vercel/
.env*
58 changes: 40 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,63 @@
# Arca OSS

The source for [oss.arcabot.ai](https://oss.arcabot.ai): Arca's public engineering index.
Source for [oss.arcabot.ai](https://oss.arcabot.ai), Arca's public engineering index.

The site distinguishes three different things that are often lazily blended together:
The site distinguishes:

1. **Open-source projects Arca maintains** — public repositories with explicit licenses.
2. **External OSS projects Arca supports** — with precise roles and attribution boundaries.
3. **Upstream work** — open, merged, closed, and superseded pull requests stay distinct.
1. Open-source projects Arca maintains, with explicit licenses.
2. External OSS projects Arca supports, with precise role and attribution boundaries.
3. Upstream work, keeping open, merged, closed, superseded, reviewed, and co-authored records distinct.

## Data sources
## Architecture

- Curated licensed projects: [`lib/data.ts`](lib/data.ts)
- Live OpenClaw PR ledger: [`arcabotai/arca-openclaw-contributions`](https://github.com/arcabotai/arca-openclaw-contributions), refreshed every six hours for `@arcabotai` and Arca-era `@felirami`; the site revalidates it hourly
- Public activity feed: [`public/activity.json`](public/activity.json), regenerated every six hours from scoped upstream PRs, public credits, reviews, and releases
- Curated ClickClack merge-credit receipts: PRs [#91](https://github.com/openclaw/clickclack/pull/91) and [#92](https://github.com/openclaw/clickclack/pull/92), traced to closed origin PR [#78](https://github.com/openclaw/clickclack/pull/78)
- Curated Hermes Agent authorship receipt: maintainer merge [#76400](https://github.com/NousResearch/hermes-agent/pull/76400), traced to Arca origin PR [#74779](https://github.com/NousResearch/hermes-agent/pull/74779) with five Cad-authored commits preserved upstream
- Fallback snapshot: bundled in `lib/data.ts` so a temporary source outage does not erase the public record
- Astro 7 static output
- Existing React page retained as build-time rendering for visual parity
- Cloudflare Workers Static Assets
- HTML-only `Cache-Control: no-transform` prevents Cloudflare from auto-injecting analytics JavaScript
- No application server, database, authentication, or runtime rendering

## Local development
## Evidence refresh

The previous Next.js site fetched the OpenClaw contribution ledger with one-hour ISR. The Astro site uses committed, reviewable snapshots:

- `public/activity.json` refreshes every six hours
- `public/openclaw-prs.json` refreshes hourly
- each workflow validates claims and commits only when public evidence changes
- every committed refresh can trigger a deterministic Cloudflare build after production automation is enabled

A temporary upstream outage cannot erase the public record because `lib/data.ts` retains its curated fallback.

## Development

```bash
npm install
npm run dev
```

Quality gates:
## Verification

```bash
npm run typecheck
npm run lint
npm run check
npm run build
npm run check:claims
npm run cf:dry-run
npm run cf:dev
npm run smoke
npm audit
```

## Evidence policy
## Public data

- `/oss.json`
- `/activity.json`
- `/openclaw-prs.json`
- `/llms.txt`
- `/robots.txt`
- `/sitemap.xml`

## Deployment boundary

Public is not automatically open source. An Arca repository appears as OSS only when it has an explicit license. Authored, open, closed, superseded, merged, and co-authored contributions stay distinct. Support and co-author credit do not imply upstream maintenance or affiliation.
`wrangler.json` defines no custom-domain routes and disables `workers.dev` and preview URLs. Production remains on Vercel until a matched Cloudflare canary is reviewed and approved for cutover.

## License

Expand Down
35 changes: 0 additions & 35 deletions app/layout.tsx

This file was deleted.

3 changes: 0 additions & 3 deletions app/loading.tsx

This file was deleted.

5 changes: 0 additions & 5 deletions app/not-found.tsx

This file was deleted.

4 changes: 0 additions & 4 deletions app/robots.ts

This file was deleted.

4 changes: 0 additions & 4 deletions app/sitemap.ts

This file was deleted.

10 changes: 10 additions & 0 deletions astro.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import { fileURLToPath } from 'node:url';

export default defineConfig({
site: 'https://oss.arcabot.ai',
output: 'static',
integrations: [react()],
vite: { resolve: { alias: { '@': fileURLToPath(new URL('.', import.meta.url)) } } },
});
7 changes: 0 additions & 7 deletions eslint.config.mjs

This file was deleted.

18 changes: 5 additions & 13 deletions lib/data.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import activityJson from "@/public/activity.json";
import openClawLedgerJson from "@/public/openclaw-prs.json";

export type ActivityEventType =
| "upstream_pr_state"
Expand Down Expand Up @@ -522,19 +523,10 @@ const fallbackLedger: OpenClawLedger = {
],
};

const LEDGER_URL =
"https://raw.githubusercontent.com/arcabotai/arca-openclaw-contributions/main/data/openclaw-prs.json";

export async function getOpenClawLedger(): Promise<OpenClawLedger> {
try {
const response = await fetch(LEDGER_URL, { next: { revalidate: 3600 } });
if (!response.ok) return fallbackLedger;
const ledger = (await response.json()) as OpenClawLedger;
if (!Array.isArray(ledger.pullRequests)) return fallbackLedger;
return ledger;
} catch {
return fallbackLedger;
}
export function getOpenClawLedger(): OpenClawLedger {
const ledger = openClawLedgerJson as OpenClawLedger;
if (!Array.isArray(ledger.pullRequests)) return fallbackLedger;
return ledger;
}

const emptyActivityFeed: ActivityFeed = {
Expand Down
7 changes: 0 additions & 7 deletions next-env.d.ts

This file was deleted.

7 changes: 0 additions & 7 deletions next.config.ts

This file was deleted.

Loading