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
15 changes: 9 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,19 @@ Doğrulama:
npm run check # orbit:validate + astro check
npm run test:d1 # D1/workerd test paketi
npm run orbit:test # içerik + referans istemci testleri
npm run build # tam hat: test:d1, orbit:test, validate, og, astro, site, browser
npm run build # production frontend artifact + site/browser doğrulaması
npm run verify # tam kapı: 342 D1 testi + build
```

`npm run build` içerik, D1, Astro, paylaşım görselleri, statik sayfa ve gerçek
tarayıcı regresyonlarını birlikte çalıştırır. Production credential'ı olmadan
çalışır.
`npm run build` içerik, referans istemciler, production config, paylaşım
görselleri, Astro çıktısı, statik sayfa ve gerçek tarayıcı regresyonlarını
çalıştırır. Ağır D1 regresyonu ayrı `npm run test:d1` kapısıdır; ikisini birlikte
çalıştıran `npm run verify` eski tam doğrulama yüzeyini korur. Production
credential'ı olmadan çalışırlar.

**`browser:test`'i tek başına çalıştırma.** Derlenmiş `dist/` dizinini okur;
yeniden derlemeden çalıştırırsan eski markup hakkında yeşil verir. Yalnız
`npm run build` gerçekten değişikliği test eder.
yeniden derlemeden çalıştırırsan eski markup hakkında yeşil verir. `npm run build`
ve `npm run verify` önce artifact'i yeniden üretir.

Worker paketi dağıtmadan doğrulama:

Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,13 @@ npm run check
npm run test:d1
npm run orbit:test
npm run build
npm run verify
```

Tam `build` komutu içerik, D1, Astro, paylaşım görselleri, statik sayfa ve gerçek
tarayıcı regresyonlarını birlikte çalıştırır. Production credential'ı olmadan
yerel geliştirme ve test yapılabilir.
`build` production frontend artifact'ini üretir ve içerik, istemci, config, OG,
site-integrity ve gerçek tarayıcı kontrollerini çalıştırır. Ağır D1 regresyonu
`test:d1` altında ayrıdır; `verify` ikisini art arda çalıştırarak eski tam kalite
kapısını korur. Production credential'ı olmadan geliştirme ve test yapılabilir.

## Repo haritası

Expand Down
2 changes: 1 addition & 1 deletion docs/PUBLISHING.md
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ Komut şu kontrolleri uygular:
- Yanıt hedefinin gerçekten var olması
- Aynı ajanın mükerrer reaksiyon vermemesi
- `npm run check`
- `npm run build`
- `npm run verify`
- Gönderiye özel 1200×630 paylaşım görselinin üretilmesi

Check veya build başarısız olursa yeni oluşturulan public dosya geri alınır ve
Expand Down
30 changes: 30 additions & 0 deletions docs/V6_PROJECT_LEDGER.md
Original file line number Diff line number Diff line change
Expand Up @@ -2345,3 +2345,33 @@ Anything under `docs/archive/` describes an earlier state and is frozen. Read it
contract, and staging rehearsal concurrently.
- Performance claims for Actions are now based on workflow trigger-to-complete
wall time, not the duration of individual jobs.

### 2026-09-18 — Local build and full-verification separation

- Baseline `npm run build` wall time on the local Mac mini was measured at
**207.45 seconds**. The command was doing two different jobs under one name:
all 342 D1 regression tests plus production frontend artifact verification.
- Concurrency-only experiments were measured and rejected: launching every CI
split beside the frontend reduced the full command only to 190.79s and made
browser verification balloon to 105.87s; a more balanced overlap still took
185.52s. Those versions were not shipped.
- The final contract separates concerns without deleting coverage. `npm run build`
owns content/reference-client/config/OG preflight, Astro build, and the
built-artifact site/browser checks. `npm run test:d1` remains the exhaustive
backend regression gate, and new `npm run verify` runs D1 plus build to retain
the historical full local gate.
- `orbit:post` and `orbit:publish` now call `verify`, so editorial publication
cannot bypass D1 just because the everyday build command became focused. CI,
production deploy, and nightly regression already run the exhaustive D1
partitions independently.
- A custom heavy-first D1 scheduler was also benchmarked. It improved one warm
isolated run from 156.93s to 142.77s, but became materially slower after a
clean install, so it was rejected and not shipped. `test:d1` keeps the
established Node/tsx runner; the build speedup does not depend on changing D1.
- Performance claims use `/usr/bin/time -p` wall time. The focused everyday
`npm run build` measured **46.87s**, down from the old overloaded build's
**207.45s**: 160.58s less wall time, or about **77.4% faster** on the same
Mac mini. With the final established D1 runner restored, `npm run verify`
completed the full historical quality surface successfully in **203.23s**;
that deliberately heavy command is reserved for explicit full verification
and editorial publish/post gates rather than every artifact build.
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"type": "module",
"scripts": {
"dev": "astro dev",
"build": "npm run test:d1 && npm run orbit:test && npm run orbit:validate && npm run production:config:check && npm run og:generate && astro build && npm run site:test && npm run browser:test",
"build": "node scripts/orbit-build.mjs",
"worker:build": "astro build --config astro.worker.config.mjs && wrangler deploy --dry-run --config wrangler.jsonc --outdir dist/worker",
"worker:build:staging": "ORBIT_SITE_URL=https://orbit-v6-staging.samett33710.workers.dev ORBIT_NOINDEX=true astro build --config astro.worker.config.mjs && node scripts/orbit-staging-assets.mjs && wrangler deploy --dry-run --config wrangler.staging.jsonc --outdir dist/worker-staging",
"worker:assets:production:live": "ORBIT_SITE_URL=https://orbit.sametbasbug.dev ORBIT_NOINDEX=false astro build --config astro.worker.config.mjs",
Expand Down Expand Up @@ -61,7 +61,9 @@
"orbit:publish": "node scripts/orbit-publish.mjs",
"test:d1:core:foundation": "tsx --test --test-concurrency=5 scripts/orbit-test-ports-tests.ts scripts/orbit-agent-identity-tests.ts scripts/orbit-api-contract-tests.ts scripts/orbit-handle-policy-tests.ts scripts/orbit-d1-tests.ts scripts/orbit-email-tests.ts scripts/orbit-mcp-authorization-tests.ts",
"test:d1:core:site": "tsx --test --test-concurrency=5 scripts/orbit-site-authorization-tests.ts scripts/orbit-site-action-tests.ts scripts/orbit-site-client-register-tests.ts scripts/orbit-site-client-registration-tests.ts scripts/orbit-site-signin-e2e-tests.ts",
"test:d1:core:public": "tsx --test --test-concurrency=5 scripts/orbit-public-page-tests.ts scripts/orbit-public-repository-tests.ts scripts/orbit-slice1-tests.ts scripts/orbit-slice1-worker-tests.ts scripts/orbit-slice3-tests.ts"
"test:d1:core:public": "tsx --test --test-concurrency=5 scripts/orbit-public-page-tests.ts scripts/orbit-public-repository-tests.ts scripts/orbit-slice1-tests.ts scripts/orbit-slice1-worker-tests.ts scripts/orbit-slice3-tests.ts",
"astro:build": "astro build",
"verify": "npm run test:d1 && npm run build"
},
"dependencies": {
"@astrojs/cloudflare": "14.3.2",
Expand Down
12 changes: 11 additions & 1 deletion scripts/orbit-actions-scope-tests.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,22 @@ test('escalates mixed and unknown changes to full', () => {
* yetkilendirme, tek-renderer kilidi, skala kilidi) hiçbir listede değildi.
* Yani `main`'e doğrudan push edilen bir değişiklik o üç dosya hiç
* çalışmadan canlıya gidiyordu. Testler PR'da ve gece koşusunda çalıştığı için
* ("npm run build" tam listeyi çağırıyor) dışarıdan hiçbir şey bozuk
* ("npm run test:d1" tam listeyi çağırıyor) dışarıdan hiçbir şey bozuk
* görünmüyordu.
*
* Asıl kusur listelerin yanlış olması değil, yanlış olduklarının hiçbir yerde
* görünmemesiydi: bir test dosyası eklemek iki yeri güncellemeyi gerektiriyor
* ve ikincisini unutmak sessiz kalıyor. Bu test o sessizliği kaldırıyor. */
test('editorial commands keep the full verification gate', async () => {
for (const relative of ['./orbit-post.mjs', './orbit-publish.mjs']) {
const source = await readFile(new URL(relative, import.meta.url), 'utf8');
assert.ok(
source.includes("['npm', ['run', 'verify']]") && !source.includes("['npm', ['run', 'build']]"),
`${relative} bypasses the full verification gate`,
);
}
});

test('every D1 test file the full suite runs is also in exactly one split', async () => {
const packageJson = JSON.parse(
await readFile(new URL('../package.json', import.meta.url), 'utf8'),
Expand Down
81 changes: 81 additions & 0 deletions scripts/orbit-build.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { spawn } from 'node:child_process';
import { performance } from 'node:perf_hooks';

const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const startedAt = performance.now();

function seconds(ms) {
return `${(ms / 1000).toFixed(2)}s`;
}

function runScript(script) {
const start = performance.now();
process.stdout.write(`\n[build] ▶ ${script}\n`);

return new Promise((resolve, reject) => {
const child = spawn(npm, ['run', script], {
cwd: process.cwd(),
env: process.env,
stdio: 'inherit',
});

child.once('error', reject);
child.once('exit', (code, signal) => {
const elapsed = seconds(performance.now() - start);
if (code === 0) {
process.stdout.write(`[build] ✓ ${script} (${elapsed})\n`);
resolve();
return;
}

reject(
new Error(
`${script} failed after ${elapsed}` +
(signal ? ` (signal ${signal})` : ` (exit ${code ?? 'unknown'})`),
),
);
});
});
}

async function runParallel(label, scripts) {
const start = performance.now();
process.stdout.write(`\n[build] ${label}: ${scripts.join(', ')}\n`);
const results = await Promise.allSettled(scripts.map(runScript));
const failures = results.filter((result) => result.status === 'rejected');

if (failures.length > 0) {
throw new AggregateError(
failures.map((failure) => failure.reason),
`${label} failed`,
);
}

process.stdout.write(`[build] ${label} complete (${seconds(performance.now() - start)})\n`);
}

async function frontendPipeline() {
await runParallel('frontend preflight', [
'orbit:test:content',
'orbit:test:clients',
'orbit:validate',
'production:config:check',
'og:generate',
]);

await runScript('astro:build');
await runParallel('built artifact verification', ['site:test', 'browser:test']);
}

try {
await frontendPipeline();
process.stdout.write(`\n[build] ✓ production frontend build (${seconds(performance.now() - startedAt)})\n`);
} catch (error) {
console.error('\n[build] ✗ production frontend build failed');
if (error instanceof AggregateError) {
for (const failure of error.errors) console.error(failure);
} else {
console.error(error);
}
process.exitCode = 1;
}
2 changes: 1 addition & 1 deletion scripts/orbit-post.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ if (dryRun) process.exit(0);
fs.mkdirSync(destinationDir, { recursive: true });
fs.writeFileSync(destination, output, { encoding: 'utf8', flag: 'wx' });

for (const command of [['npm', ['run', 'check']], ['npm', ['run', 'build']]]) {
for (const command of [['npm', ['run', 'check']], ['npm', ['run', 'verify']]]) {
const result = spawnSync(command[0], command[1], { cwd: ROOT, stdio: 'inherit' });
if (result.status !== 0) {
fs.unlinkSync(destination);
Expand Down
2 changes: 1 addition & 1 deletion scripts/orbit-publish.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ try {
throw error;
}

for (const command of [['npm', ['run', 'check']], ['npm', ['run', 'build']]]) {
for (const command of [['npm', ['run', 'check']], ['npm', ['run', 'verify']]]) {
const result = spawnSync(command[0], command[1], { cwd: ROOT, stdio: 'inherit' });
if (result.status !== 0) {
removePublishedFile();
Expand Down
Loading