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
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog

## [0.15.8.1] - 2026-04-05 — Community PR Triage + Error Polish

Closed 12 redundant community PRs, merged 2 ready PRs (#798, #776), and expanded the friendly OpenAI error to every design command. If your org isn't verified, you now get a clear message with the right URL instead of a raw JSON dump, no matter which design command you run.

### Fixed

- **Friendly OpenAI org error on all design commands.** Previously only `$D generate` showed a user-friendly message when your org wasn't verified. Now `$D evolve`, `$D iterate`, `$D variants`, and `$D check` all show the same clear message with the verification URL.

### Added

- **>128KB regression test for Codex session discovery.** Documents the current buffer limitation so future Codex versions with larger session_meta will surface cleanly instead of silently breaking.

### For contributors

- Closed 12 redundant community PRs (6 Gonzih security fixes shipped in v0.15.7.0, 6 stedfn duplicates). Kept #752 open (symlink gap in design serve). Thank you @Gonzih, @stedfn, @itstimwhite for the contributions.

## [0.15.8.0] - 2026-04-04 — Smarter Reviews

Code reviews now learn from your decisions. Skip a finding once and it stays quiet until the code changes. Specialists auto-suggest test stubs alongside their findings. And silent specialists that never find anything get auto-gated so reviews stay fast.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.15.8.0
0.15.8.1
4 changes: 4 additions & 0 deletions design/src/check.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ export async function checkMockup(imagePath: string, brief: string): Promise<Che

if (!response.ok) {
const error = await response.text();
if (response.status === 403 && error.includes("organization must be verified")) {
console.error("OpenAI organization verification required. Go to https://platform.openai.com/settings/organization to verify.");
return { pass: true, issues: "OpenAI org not verified — vision check skipped" };
}
// Non-blocking: if vision check fails, default to PASS with warning
console.error(`Vision check API error (${response.status}): ${error}`);
return { pass: true, issues: "Vision check unavailable — skipped" };
Expand Down
7 changes: 7 additions & 0 deletions design/src/evolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ export async function evolve(options: EvolveOptions): Promise<void> {

if (!response.ok) {
const error = await response.text();
if (response.status === 403 && error.includes("organization must be verified")) {
throw new Error(
"OpenAI organization verification required.\n"
+ "Go to https://platform.openai.com/settings/organization to verify.\n"
+ "After verification, wait up to 15 minutes for access to propagate.",
);
}
throw new Error(`API error (${response.status}): ${error.slice(0, 300)}`);
}

Expand Down
14 changes: 14 additions & 0 deletions design/src/iterate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ async function callWithThreading(

if (!response.ok) {
const error = await response.text();
if (response.status === 403 && error.includes("organization must be verified")) {
throw new Error(
"OpenAI organization verification required.\n"
+ "Go to https://platform.openai.com/settings/organization to verify.\n"
+ "After verification, wait up to 15 minutes for access to propagate.",
);
}
throw new Error(`API error (${response.status}): ${error.slice(0, 300)}`);
}

Expand Down Expand Up @@ -142,6 +149,13 @@ async function callFresh(

if (!response.ok) {
const error = await response.text();
if (response.status === 403 && error.includes("organization must be verified")) {
throw new Error(
"OpenAI organization verification required.\n"
+ "Go to https://platform.openai.com/settings/organization to verify.\n"
+ "After verification, wait up to 15 minutes for access to propagate.",
);
}
throw new Error(`API error (${response.status}): ${error.slice(0, 300)}`);
}

Expand Down
3 changes: 3 additions & 0 deletions design/src/variants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ async function generateVariant(

if (!response.ok) {
const error = await response.text();
if (response.status === 403 && error.includes("organization must be verified")) {
return { path: outputPath, success: false, error: "OpenAI organization verification required. Go to https://platform.openai.com/settings/organization to verify." };
}
return { path: outputPath, success: false, error: `API error (${response.status}): ${error.slice(0, 200)}` };
}

Expand Down
38 changes: 38 additions & 0 deletions test/global-discover.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,44 @@ describe("gstack-global-discover", () => {
expect(meta.type).toBe("session_meta");
expect(meta.payload.cwd).toBe("/tmp/test-repo");
});

test("regression: session_meta beyond 128KB still needs streaming parse", () => {
// This test documents the current limitation: 128KB buffer is a heuristic.
// If Codex ever embeds >128KB in session_meta, this test will fail,
// signaling that the buffer needs to increase or be replaced with streaming.
const padding = "x".repeat(140000); // ~140KB payload
const sessionMeta = JSON.stringify({
timestamp: new Date().toISOString(),
type: "session_meta",
payload: {
id: "test-large",
timestamp: new Date().toISOString(),
cwd: "/tmp/large-test",
originator: "codex_exec",
cli_version: "0.200.0",
source: "exec",
model_provider: "openai",
base_instructions: { text: padding },
},
});

expect(sessionMeta.length).toBeGreaterThan(131072);

const filePath = join(codexDir, "large-test.jsonl");
writeFileSync(filePath, sessionMeta + "\n");

// 128KB buffer: JSON.parse FAILS for >128KB lines (current limitation)
const { openSync, readSync, closeSync } = require("fs");
const fd = openSync(filePath, "r");
const buf = Buffer.alloc(131072);
readSync(fd, buf, 0, 131072, 0);
closeSync(fd);
expect(() =>
JSON.parse(buf.toString("utf-8").split("\n")[0])
).toThrow();
// When this test starts passing (e.g., after implementing streaming parse),
// update it to verify correct parsing instead of documenting the limitation.
});
});

describe("discovery output structure", () => {
Expand Down
Loading