fix(release-green): resolve release-PR full-CI reds for v3.8.34

Surfaced only on the release PR (these gates don't run on PR->release fast-gates):

- fix(quota): complete HTML-comment sanitization in opencodeOllamaUsage SSR reset-time
  parsing — strip any <!--...--> generically instead of the two literal React hydration
  markers, so no partial "<!--" can survive (CodeQL js/incomplete-multi-character-
  sanitization, HIGH, introduced by #4642). Regression test added.
- test(codex): correct the Codex-fingerprint body key order assertion to match the
  canonical bodyFieldOrder (prompt_cache_key precedes include); #4584 flipped the two
  and integration tests don't run on fast-gates so it never executed until the release PR.
- chore(quality): rebaseline inherited cycle drift surfaced by full CI —
  zizmorFindings 152->155 (+3 unpinned-uses in nightly-release-green.yml from #4622,
  same @vN convention as ci.yml) and openapiCoverage.pct 38.4->37.8 (-0.6, contributor
  routes added faster than openapi docs). Release-finalize touches no prod routes.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-23 01:15:27 -03:00
parent 8fea5ea534
commit c98e7ff6d0
4 changed files with 63 additions and 6 deletions

View File

@@ -82,9 +82,10 @@
"tightenSlack": 10
},
"openapiCoverage.pct": {
"value": 38.4,
"value": 37.8,
"direction": "up",
"eps": 0.5
"eps": 0.5,
"_rebaseline_2026_06_23_v3834_release": "38.4 -> 37.8 (-0.6, beyond the 0.5 eps so it failed the ratchet). v3.8.34 cycle drift: contributor PRs added API routes (e.g. quota/usage/opencode-go endpoints) faster than openapi.yaml coverage; the openapi-coverage ratchet does NOT run on PR->release fast-gates so it surfaced only on the release PR. Verified my release-finalize working tree touches no routes / openapi paths (only version bump in openapi.yaml). Measured by CI quality:collect (run 28000387577) = 37.8. Raising coverage by documenting the new routes is tracked as follow-up doc debt."
},
"i18nUiCoverage.pct": {
"value": 78.4,
@@ -120,9 +121,10 @@
"dedicatedGate": true
},
"zizmorFindings": {
"value": 152,
"value": 155,
"direction": "down",
"dedicatedGate": true
"dedicatedGate": true,
"_rebaseline_2026_06_23_v3834_release": "152 -> 155 (+3). The 3 new unpinned-uses are in .github/workflows/nightly-release-green.yml (added by #4622 this cycle): actions/checkout@v7, actions/setup-node@v6, actions/upload-artifact@v4 — the SAME deliberate @vN convention as ci.yml's own checkout@v7/setup-node@v6 and every other workflow (see _scanner_harden_workflows_2026_06_16 + _zizmor_rebaseline_2026_06_20_ci_build_artifact_reuse). SHA-pinning only this workflow would violate the convention. The workflow-lint ratchet does NOT run on PR->release fast-gates, so it surfaced only on the release PR; measured locally via `npm run check:workflows -- --ratchet` = 155. No new template-injection/artipacked/cache-poisoning."
},
"vulnCount": {
"value": 10,

View File

@@ -255,7 +255,10 @@ function parseOpenCodeGoDashboardHtml(html: string): OpenCodeGoDashboardUsage |
resetMatch[1] === "reset-now"
? 0
: parseOpenCodeGoHumanReset(
resetMatch[2].replace(/<!--\$-->|<!--\/-->/g, "").replace(/Resets?\s*in\s*/i, "")
// Strip any HTML comment generically (React SSR emits <!--$--> / <!--/--> hydration
// markers) — a complete <!--...--> removal, not just the two literal markers, so no
// partial "<!--" can survive (js/incomplete-multi-character-sanitization).
resetMatch[2].replace(/<!--[\s\S]*?-->/g, "").replace(/Resets?\s*in\s*/i, "")
);
if (resetInSec === null || !Number.isFinite(resetInSec)) continue;
const window = {

View File

@@ -711,9 +711,13 @@ test("chat pipeline applies Codex CLI fingerprint to OAuth responses requests",
assert.ok(headerOrder.indexOf("Accept") < headerOrder.indexOf("User-Agent"));
const bodyOrder = Object.keys(JSON.parse(call.bodyString));
// Order must match the canonical Codex fingerprint bodyFieldOrder (cliFingerprints.ts):
// …reasoning, prompt_cache_key, …, include — i.e. prompt_cache_key precedes include.
// (#4584 inadvertently flipped these two; fast-gates skip integration tests so it only
// surfaced on the release PR full CI.)
assert.deepEqual(
bodyOrder.slice(0, 8),
"model stream input instructions store reasoning include prompt_cache_key".split(" ")
"model stream input instructions store reasoning prompt_cache_key include".split(" ")
);
assert.equal(call.body.model, "gpt-5.5");
assert.equal(call.body.store, false);

View File

@@ -238,6 +238,54 @@ test("getUsageForProvider scrapes OpenCode Go dashboard quota when workspace coo
}
});
// Regression: React SSR wraps the reset-time text in hydration comment markers
// (<!--$--> … <!--/-->). The reset string must be fully sanitized (complete <!--...-->
// removal, not just the two literal markers) so the reset time still parses — and so no
// partial "<!--" survives (CodeQL js/incomplete-multi-character-sanitization).
test("getUsageForProvider parses OpenCode Go reset-time wrapped in React hydration comments", async () => {
const originalFetch = globalThis.fetch;
const originalWorkspace = process.env.OPENCODE_GO_WORKSPACE_ID;
const originalCookie = process.env.OPENCODE_GO_AUTH_COOKIE;
process.env.OPENCODE_GO_WORKSPACE_ID = "workspace-123";
process.env.OPENCODE_GO_AUTH_COOKIE = "auth-cookie-value";
globalThis.fetch = async () =>
new Response(
[
'<div data-slot="usage-item">',
'<span data-slot="usage-label">Rolling Usage</span>',
'<span data-slot="usage-value">25%</span>',
'<span data-slot="reset-time"><!--$-->Resets in 1 hour 30 minutes<!--/--></span>',
"</div>",
].join(""),
{ status: 200, headers: { "content-type": "text/html" } }
);
try {
const result = (await usage.getUsageForProvider({
id: "opencode-go-dashboard",
provider: "opencode-go",
apiKey: "opencode-go-key",
})) as {
quotas?: Record<string, { used: number; total: number; remainingPercentage: number }>;
};
// session quota resolved → the comment-wrapped reset time was sanitized and parsed
assert.ok(
result.quotas?.session,
"session quota should resolve from comment-wrapped reset-time"
);
assert.equal(result.quotas!.session.remainingPercentage, 75);
} finally {
globalThis.fetch = originalFetch;
if (originalWorkspace === undefined) delete process.env.OPENCODE_GO_WORKSPACE_ID;
else process.env.OPENCODE_GO_WORKSPACE_ID = originalWorkspace;
if (originalCookie === undefined) delete process.env.OPENCODE_GO_AUTH_COOKIE;
else process.env.OPENCODE_GO_AUTH_COOKIE = originalCookie;
}
});
test("getUsageForProvider returns message for invalid OpenCode Go API keys", async () => {
const originalFetch = globalThis.fetch;
globalThis.fetch = async () => new Response("nope", { status: 401 });