diff --git a/devlog/_fin/260908_c248_individual_fixes/000_plan.md b/devlog/_fin/260908_c248_individual_fixes/000_plan.md new file mode 100644 index 0000000000..3dca83c8cb --- /dev/null +++ b/devlog/_fin/260908_c248_individual_fixes/000_plan.md @@ -0,0 +1,33 @@ +# Lane C: independently reviewable 2.48 preparation fixes + +Scope: satisfy-spec HOTL requested by the owner on 2026-09-08. Goal: independently land #3953, #3899 and the timezone-only part of #3950 into dev, retaining original authors. This returned/stored roadmap is the memory artifact. Baseline dev: `514350e6f79ed4539378388bc39d3fc79ff2c70c`. No resource budget was specified; native host limits apply. Tool scope: local Git/source/artifact checks, GitHub repository/Actions, and explicitly authorized A/B coordination; astra high read-only auditors. No local product tests, typechecks, builds or dependency installation, including incidental Git-hook execution. Use per-command `git -c core.hooksPath=/dev/null` for mutating Git operations, and `push --no-verify`; do not modify shared Git configuration. + +## Work phases and ownership + +`roadmap` (this docs-only full PABCD) precedes three independent delivery cycles: `privacy`, `release_notes`, `timezone`. `reconcile` depends on those deliveries and lane B's JWT evidence. The processing order is scheduling, not a code dependency: each delivery remains a separate dev-targeted PR. Reuse original #3953 if unchanged and reviewable; carry #3899 onto current dev if needed; timezone gets a new PR sourced from only commit 1d8f6ff7e8d48f33c3ce7a1b7118068754bbbe83. Never create a combined code-delivery PR or squash different bugs together. Local roadmap/outcome commits stay on this coordination branch until a separate documentation-only closeout is appropriate. A separately audited evidence-only workflow branch may add supplemental hosted platform proof without entering any delivery PR or changing its required CI. + +## Boundaries + +No JWT changes, provider/routing work, main/preview promotions, version changes, deployments, release execution, live-account/service probes, history rewriting or public reproduction of removed material. Confidential investigation stays in ignored `.tmp/c248/`. The public docs describe only approved correction scope, not sensitive values. No new runtime type/enum/field is added, so creation/serialization/deserialization/consumer field-chain work is N/A. + +## Verification contract + +The roadmap uses actual file and source-object inspection plus `git diff --check` (run in this checkout before the roadmap close). Delivery uses the repository's existing hosted CI on each PR's current head; source-sensitive suites and the actual workflow scope must be checked. Local product commands are explicitly NOT RUN. No blind retries, cancelled/skipped/pending-as-pass, broad test weakening or artificial screenshots. A docs-only scope check is not a product-suite pass. Head rewrites require fresh current-head evidence. If dev moves, classify the actual delta and do not claim an unexecuted integration tree was tested. Before merge, validate required gates and exact head; preserve unrelated destination changes and prove the landed source diff. + +## Integration coordination + +The active A and B workstreams agreed on `/ocx-248-dev-merge.lock`: atomic mkdir, owner.json with sessionId/pid/hostname/PR/SHA/acquiredAt, owned only from final refresh through landed verification. Never hold it while waiting for CI or delete another owner's lock. This is a cooperative serialization convention, not a security boundary; an uncooperative actor can bypass it. The main thread resolves collisions, missing permissions or contradictory evidence without expanding worker scope; a new worker slice requires a plan amendment, and two distinct failed workers return the slice to main. + +Use the repository PR template and MAINTAINERS.md. Explicit maintainer integration is allowed only after checking live identity/role, outstanding objections, required CI, and required security review. Existing PR head authors remain attributed; carried commits use cherry-pick provenance and a Co-authored-by trailer surviving squash. After landing, verify merge SHA ancestry, actual file delta, destination preservation, and authors. Close original carry PRs only then. #3950 stays open until both timezone and B JWT fixes are proven on dev; C owns final closure. A/B status contributes to a readiness report, not release authority. + +## Stop and outcomes + +DONE requires all three delivered/proven already present and #3950 reconciled; final report lists source PR, delivery PR, landed SHA, actual CI results, authors and residuals. A blocked item does not stop independent work. Missing authority or unsafe evidence is unresolved, not a successful criterion. Read goalplan/ledger after each D and continue remaining cycles. Scope does not include a fixed cost/time budget or new paid service purchases. + +## Roadmap audit and completion + +Independent astra high roadmap audit: PASS, no blocking findings. The timeout prose was aligned with the dedicated child marker used in the exact patch. The roadmap-only check is Git diff whitespace plus independent source/semantic audit; no product suite was run. Next cycle: adopt and validate the unchanged #3953 correction. + +## Final reconciliation + +Privacy and release-note cycles completed before the timezone cycle. All delivery evidence and residuals are in050_outcome.md. Original3950 closed after both BJWT and Ctimezone landing proof. This unit archives to_fin through a separate docs-only PR; no product commit is combined with this record. diff --git a/devlog/_fin/260908_c248_individual_fixes/010_privacy.md b/devlog/_fin/260908_c248_individual_fixes/010_privacy.md new file mode 100644 index 0000000000..6e22b7a5f2 --- /dev/null +++ b/devlog/_fin/260908_c248_individual_fixes/010_privacy.md @@ -0,0 +1,19 @@ +# Phase privacy: adopt the exact #3953 correction + +Source SHA: 05fd82807b4a0014f84b9d74d05b70a3591cb574. Source URL: https://github.com/lidge-jun/opencodex/pull/3953 + +MODIFY the two existing records under devlog/_plan/260904_provider_quota_refresh/: 030_wp3_live_verification_and_pr.md and 031_live_verification_record.md. DELETE assets/030_accounts_refresh_button.png and assets/040_accounts_refresh_result.png. The exact after-content is the existing source SHA's Git blobs, retrieved by `git show :`; do not copy removed values into this plan. The two deletions and two post-image blobs define the complete executable patch; no other path changes. Reuse the unchanged existing PR if its head still matches; otherwise refresh and re-audit instead of force-pushing the contributor branch. + +Acceptance: both asset paths are absent in the candidate tree; no retained Markdown literal reference points to them; the isolated-instance and real forced-read evidence remains; the cleanup statement still says moved to Trash, never permanent destruction. Do not open/display either removed PNG. Independent privacy/semantic review checks this exact source. Current-head hosted PR scope check and aggregate must complete, with all skipped jobs described as skipped. Inspect full candidate delta and workflow equality before approving a fork run. No public operating values are recorded in new artifacts. Public documentation is the SoT target; history cleanup is out of scope. + +Rollback: retain source/landed SHAs, but do not automatically reintroduce removed captures; any rollback needs explicit privacy assessment. Completion uses actual merged PR state/merge SHA, touched-path equality, unchanged destination paths and author attribution. + +Execution decision: use a maintainer-owned carry PR with the identical source commit. The contributor checklist asks for local-CI attestation that this run cannot truthfully supply under the no-local-product-check instruction; no source rewrite or new behavior is needed. Original #3953 remains open until the carry lands, and its author is preserved in the squash trailer. + +C review repair: CodeRabbit requested American-English afterward at the existing isolation sentence. Accepted one-word correction in 0ed232d5c, with surrounding historical facts unchanged. Previous CI 34166442230 passed 3 scope/aggregate jobs and skipped 10 product jobs; it does not certify the new head. The new head must be checked before landing. + +Source refresh correction: original #3953 advanced to ca21efd29730086ede902c4701124893ce58b404 before closure. It remains OPEN; any earlier closure claim in the operational task log was premature and has been corrected. The initial carry is already landed and must not be rewritten. Audit and carry the incremental 05fd828..ca21efd2 delta as a separate privacy follow-up: MODIFY 000_plan.md, 030_wp3_live_verification_and_pr.md, 031_live_verification_record.md under the source unit; DELETE assets/010_meta_usage_quota.png and assets/020_usage_refresh_result.png. Exact post-images are sourceca21efd2 blobs, retaining the landed afterward spelling. The complete delta is retrieved with git diff05fd828..ca21efd2 scoped to those five paths. Acceptance: one retention rule covers both Accounts/Usage, textual behavior and Trash historical outcomes remain, no PNG inspected, all four capture assets and all scoped old references absent, current-head hosted scope checks and fresh source/author/landing proof. + +Review synthesis: #3959 exposed two issues. Accepted the source plan/actual isolation mismatch and corrected both old restart sites so completed scratch evidence supersedes the working-service restart plan (fc6b07eaf). Declined history purge as explicitly outside owner scope; the historical reachability residual is preserved, not claimed fixed. Both review threads have documented dispositions. No runtime operation was performed. Latest head needs fresh hosted scope CI. + +DONE: initial carry#3955 landed9c54000c9 and follow-up#3959 landed01c23aedc. Current-head hosted scope CI34167651789 success3/skipped10, independent final privacy audit PASS, all known review findings dispositioned; automatic rereview was pending at merge and not counted as successful. Both landed trees, parents, dev ancestry and actual author trailers verified. Original#3953 closed at refreshedca21efd2. History purge remains explicitly outside scope. diff --git a/devlog/_fin/260908_c248_individual_fixes/020_release_notes.md b/devlog/_fin/260908_c248_individual_fixes/020_release_notes.md new file mode 100644 index 0000000000..de8b38e701 --- /dev/null +++ b/devlog/_fin/260908_c248_individual_fixes/020_release_notes.md @@ -0,0 +1,144 @@ +# Phase release_notes: exact leading enforcement marker normalization + +Source PR #3899, source SHA 4d6896cd0bd62434b4703a1956fe57a99cd4959a. MODIFY the three files below. Preserve/reuse the source PR's related numbered implementation record if carrying its whole commit; it is documentation for this same bug, not another feature. Security review covers title text handling only: no workflow, command dispatch, credentials, publishing or release execution change. SoT: structure/06_docs-and-release.md. + +Activation/acceptance: prefixed generated and carried notes lose only the exact leading marker in summaries and full changelog; conventional scope grouping and attribution remain; unrelated bracketed/nonleading/near-match markers remain. Hosted CI must execute tests/ci-workflows/release-notes.test.ts (via the existing shard manifest) plus required gates. Explicit security review is recorded before maintainer sponsorship/integration. No local tests or typecheck are run. Rebase/carry applies only to our branch, uses original author and -x/Co-authored-by, and exact current-head checks. Issue #3895 closes only after verified dev landing. One independent revert restores only this bug's diff. + +Exact source patch follows; refresh against latest dev at its P phase: + +```diff +diff --git a/scripts/release-notes.ts b/scripts/release-notes.ts +index 16627f5f9..d0a58a043 100644 +--- a/scripts/release-notes.ts ++++ b/scripts/release-notes.ts +@@ -546,8 +546,14 @@ export function parseGeneratedNotes(body: string): ReleaseNoteCategory[] { + const CONVENTIONAL_COMMIT_PREFIX = + /^(?:feat|fix|docs|chore|refactor|perf|test|build|ci|style|revert|merge|release)(?:\(([^)]+)\))?:\s*(.+)$/i; + ++function stripPrEnforcementPrefix(title: string): string { ++ const text = title.trim(); ++ const prefix = "[WRONG BRANCH] "; ++ return text.startsWith(prefix) ? text.slice(prefix.length).trim() : text; ++} ++ + export function cleanPrTitle(title: string, prNumber: number | null = null): { scope: string | null; text: string } { +- let text = title.trim(); ++ let text = stripPrEnforcementPrefix(title); + let scope: string | null = null; + const prefix = CONVENTIONAL_COMMIT_PREFIX.exec(text); + if (prefix) { +@@ -689,7 +695,7 @@ export function renderReleaseNotes(input: { + changelog.push(`Full Changelog: https://github.com/${repo}/compare/${from}...${to}`, ""); + } + for (const pr of allPrs) { +- changelog.push(`- #${pr.number} ${pr.title.trim()} @${pr.author}`); ++ changelog.push(`- #${pr.number} ${stripPrEnforcementPrefix(pr.title)} @${pr.author}`); + } + parts.push(changelog.join("\n")); + } +diff --git a/structure/06_docs-and-release.md b/structure/06_docs-and-release.md +index 8c6149802..886c8fc04 100644 +--- a/structure/06_docs-and-release.md ++++ b/structure/06_docs-and-release.md +@@ -227,6 +227,11 @@ so stable notes are the aggregate of their preview train. The raw commit dump is + intentionally gone — non-PR commits stay reachable via the Full Changelog compare link when + that link is available. + ++Both summary bullets and full-changelog titles strip the exact leading `[WRONG BRANCH] ` ++enforcement marker. Other bracketed text is preserved. Summary bullets still remove conventional ++commit prefixes and group by scope; full-changelog entries keep those conventional prefixes, ++PR numbers, and author attribution. This normalization does not change PR-target enforcement. ++ + The deterministic renderer produces the structure but not curated prose. Maintainers who want + the OpenAI-style grouped summaries can run the optional local polish step against the rendered + body (needs an OpenAI-compatible API key): +diff --git a/tests/ci-workflows/release-notes.test.ts b/tests/ci-workflows/release-notes.test.ts +index 11196108d..d27036008 100644 +--- a/tests/ci-workflows/release-notes.test.ts ++++ b/tests/ci-workflows/release-notes.test.ts +@@ -455,6 +455,20 @@ describe("rewriteTakeoverCredits", () => { + }); + + describe("cleanPrTitle", () => { ++ test("removes the enforcement marker before extracting scope and sentence casing", () => { ++ expect(cleanPrTitle(" [WRONG BRANCH] chore(release): promote validated 2.45.0 to main (#3813) ", 3813)).toEqual({ ++ scope: "release", ++ text: "Promote validated 2.45.0 to main", ++ }); ++ }); ++ ++ test.each([ ++ ["[Preview] chore(release): keep this marker", "[Preview] chore(release): keep this marker"], ++ ["fix: document [WRONG BRANCH] markers", "Document [WRONG BRANCH] markers"], ++ ["[WRONG BRANCH]ish: keep this title", "[WRONG BRANCH]ish: keep this title"], ++ ])("preserves meaningful title text: %s", (title, text) => { ++ expect(cleanPrTitle(title).text).toBe(text); ++ }); + test("strips conventional prefix, keeps scope, and sentence-cases the title", () => { + expect(cleanPrTitle("feat(providers): add Baseten Model APIs preset", 653)).toEqual({ + scope: "providers", +@@ -488,6 +502,55 @@ describe("cleanPrTitle", () => { + }); + + describe("renderReleaseNotes", () => { ++ test.each(["delta", "carried"])("removes the bot marker from summaries and full changelogs (%s)", source => { ++ const body = [ ++ "## What's Changed", ++ "### Chores", ++ "* [WRONG BRANCH] chore(release): promote validated 2.45.0 to main by @lidge-jun in https://github.com/lidge-jun/opencodex/pull/3813", ++ ].join("\n"); ++ const notes = renderReleaseNotes({ ++ npmMetadata: "", ++ ...(source === "delta" ? { deltaPrNotes: body } : { carriedPreviewNotes: [ ++ "## Chores", "", ++ "- [WRONG BRANCH] chore(release): promote validated 2.45.0 to main (#3813)", "", ++ "## Changelog", "", ++ "- #3813 [WRONG BRANCH] chore(release): promote validated 2.45.0 to main @lidge-jun", ++ ].join("\n") }), ++ }); ++ expect(notes).toBe([ ++ "## Chores", "", ++ "- Promote validated 2.45.0 to main (#3813)", "", ++ "## Changelog", "", ++ "- #3813 chore(release): promote validated 2.45.0 to main @lidge-jun", "", ++ ].join("\n")); ++ }); ++ ++ test("groups a bot-prefixed title with ordinary titles of the same scope", () => { ++ const notes = renderReleaseNotes({ ++ npmMetadata: "", ++ deltaPrNotes: [ ++ "## What's Changed", "### Chores", ++ "* [WRONG BRANCH] chore(release): promote verified version by @maintainer in https://github.com/lidge-jun/opencodex/pull/10", ++ "* chore(release): update notes by @contributor in https://github.com/lidge-jun/opencodex/pull/11", ++ ].join("\n"), ++ }); ++ expect(notes).toContain("- Release: Promote verified version; Update notes (#10, #11)"); ++ expect(notes).toContain("- #10 chore(release): promote verified version @maintainer"); ++ expect(notes).toContain("- #11 chore(release): update notes @contributor"); ++ expect(notes).not.toContain("[WRONG BRANCH]"); ++ }); ++ ++ test.each([ ++ "[Preview] chore(release): retain the preview marker", ++ "fix: document [WRONG BRANCH] markers (#99)", ++ "[WRONG BRANCH]ish: retain this title", ++ ])("preserves meaningful full-changelog title text: %s", title => { ++ const notes = renderReleaseNotes({ ++ npmMetadata: "", ++ deltaPrNotes: `## What's Changed\n### Chores\n* ${title} by @contributor in https://github.com/lidge-jun/opencodex/pull/12`, ++ }); ++ expect(notes).toContain(`- #12 ${title} @contributor`); ++ }); + const carried = [ + "", + "", +``` + +## C-stage correction: active release builder + +Accepted Codex review: actual release.yml invokes scripts/build-release-changelog.ts, whose changelog still used pr.title.trim(). The original tests certified a renderer but not this active entry. Extend the same bug fix: export stripPrEnforcementPrefix from scripts/release-notes.ts, import/use it for PR changelog titles in scripts/build-release-changelog.ts; add public buildReleaseNotes regressions in existing tests/ci-workflows/build-release-changelog.test.ts for generated-note enrichment and associated-PR fallback, asserting cleaned summary, preserved conventional changelog title/author/ID, and unrelated/embedded/near-match preservation. Keep category policy, direct-commit policy, network/dispatch and release coverage rules unchanged. The two new paths are part of this one bug, not a new delivery. Hosted current-head CI must execute both renderer test files. No local product test. Re-audit active caller and pure-string security boundary before accepting the repair. + +Repair source audit PASS at ef15842fc: actual builder emission and generated/associated regression paths verified. Source-of-truth paragraph corrected in be1f60f28 to distinguish active builder from standalone renderer; category selection/direct-commit policy unchanged. Final proof compares landed blobs to final reviewed candidate, not the original incomplete source. Prior run34167832861 passed16/skipped3 and showed original renderer cases onLinux/macOS; final newhead must be certified separately. + +DONE: PR3960 landed9c8f66b9d, finalheadbe1f60f28; CI34168481093 success16/skipped3. Both renderer files and new5 active-builder cases were observed in Linux logs; macOS lanespassed. Independent final source/security auditPASS. Exact destination60bcb9050 plus reviewed patch tree verified; coauthor present; source3899 and issue3895 closed. The combined destination tree was verified structurally, not claimed executed as the PR test tree. Local productcommandsNOTRUN. diff --git a/devlog/_fin/260908_c248_individual_fixes/030_timezone.md b/devlog/_fin/260908_c248_individual_fixes/030_timezone.md new file mode 100644 index 0000000000..479027db3f --- /dev/null +++ b/devlog/_fin/260908_c248_individual_fixes/030_timezone.md @@ -0,0 +1,157 @@ +# Phase timezone: extract only the Santiago fixture + +Source PR #3950. Carry ONLY commit 1d8f6ff7e8d48f33c3ce7a1b7118068754bbbe83 onto current dev, retaining luvs01's author and adding a surviving Co-authored-by. MODIFY only gui/tests/usage-custom-range.test.tsx. No JWT, product UI, dependency or workflow change. No UI screenshot is fabricated: describe the test-only scope truthfully in the PR. No new SoT contract beyond fixture isolation; production date interpretation is unchanged. + +Activation/acceptance: parent TZ absent and set cases retain exact presence/value and local Date epoch; a child Bun process is created with TZ=America/Santiago and an exact anchored test-name filter, preventing recursion by that timezone value. Child asserts skipped midnight, final-day activity and tooltip as before. Process deadline 12s, child test timeout 10s, parent test timeout 15s; timeout, signal and nonzero exit surface captured diagnostics. Reviewer must check config/preload behavior under direct child invocation and Windows Bun 1.4.0 compatibility. Hosted dashboard test gate explicitly executes this test file; inspect result and logs, not only a generic check badge. Additional fault-path testing is required only if audit reveals a reachable unprotected failure; amend this doc before any code change. Local product tests/build/typecheck/install NOT RUN. + +#3950 original stays open until B's separate JWT fix is independently confirmed on dev. No assumption that the original mixed PR's CI certifies this split head. One independent revert covers the timezone test only. + +Exact source patch follows: + +```diff +diff --git a/gui/tests/usage-custom-range.test.tsx b/gui/tests/usage-custom-range.test.tsx +index 887c31134..02df29f3d 100644 +--- a/gui/tests/usage-custom-range.test.tsx ++++ b/gui/tests/usage-custom-range.test.tsx +@@ -154,31 +154,45 @@ for (const connected of [false, true]) { + } + + test("America/Santiago midnight DST retains final-day activity and tooltip", async () => { +- const previous = process.env.TZ; +- process.env.TZ = "America/Santiago"; +- try { +- expect(new Date(2026, 8, 6, 0).getHours()).toBe(1); +- await mount(); +- await respond(0, "preset-marker"); +- await enter("2026-09-05T00:00", "2026-09-07T23:59"); +- await apply(); +- const gate = requests.at(-1)!; +- const data = report(gate, "santiago-marker", "2026-09-07"); +- data.days = ["2026-09-05", "2026-09-06", "2026-09-07"].map(date => ({ +- date, requests: date === "2026-09-07" ? 7 : 0, measuredRequests: 0, reportedRequests: 0, +- totalTokens: date === "2026-09-07" ? 700 : 0, models: [], +- })); +- await act(async () => gate.resolve(Response.json(data))); +- const active = container.querySelector('.heatmap-grid .heatmap-cell:not(.heatmap-cell-0)'); +- expect(active).not.toBeNull(); +- await act(async () => active!.dispatchEvent(new testWindow.MouseEvent("mouseover", { bubbles: true }))); +- expect(container.querySelector(".heatmap-tip-date")?.textContent).toBe("2026-09-07"); +- expect(container.querySelector(".heatmap-tip")?.textContent).toContain("700"); +- } finally { +- if (previous === undefined) delete process.env.TZ; +- else process.env.TZ = previous; ++ if (process.env.TZ !== "America/Santiago") { ++ // Restoring an absent TZ can change Bun's effective timezone on Windows. ++ // Start the DST case in its timezone without mutating this suite's clock. ++ const timezone = { present: Object.hasOwn(process.env, "TZ"), value: process.env.TZ }; ++ const localTime = new Date(2020, 8, 15, 10, 20).getTime(); ++ const child = Bun.spawnSync([ ++ process.execPath, "test", import.meta.path, ++ "-t", "^America/Santiago midnight DST retains final-day activity and tooltip$", ++ "--timeout", "10000", ++ ], { ++ env: { ...process.env, TZ: "America/Santiago" }, ++ stdout: "pipe", stderr: "pipe", timeout: 12000, killSignal: "SIGKILL", ++ }); ++ const diagnostics = `${child.stdout.toString()}\n${child.stderr.toString()}`; ++ expect(child.exitedDueToTimeout, diagnostics).not.toBe(true); ++ expect(child.signalCode, diagnostics).toBeUndefined(); ++ expect(child.exitCode, diagnostics).toBe(0); ++ expect({ present: Object.hasOwn(process.env, "TZ"), value: process.env.TZ }).toEqual(timezone); ++ expect(new Date(2020, 8, 15, 10, 20).getTime()).toBe(localTime); ++ return; + } +-}); ++ expect(new Date(2026, 8, 6, 0).getHours()).toBe(1); ++ await mount(); ++ await respond(0, "preset-marker"); ++ await enter("2026-09-05T00:00", "2026-09-07T23:59"); ++ await apply(); ++ const gate = requests.at(-1)!; ++ const data = report(gate, "santiago-marker", "2026-09-07"); ++ data.days = ["2026-09-05", "2026-09-06", "2026-09-07"].map(date => ({ ++ date, requests: date === "2026-09-07" ? 7 : 0, measuredRequests: 0, reportedRequests: 0, ++ totalTokens: date === "2026-09-07" ? 700 : 0, models: [], ++ })); ++ await act(async () => gate.resolve(Response.json(data))); ++ const active = container.querySelector('.heatmap-grid .heatmap-cell:not(.heatmap-cell-0)'); ++ expect(active).not.toBeNull(); ++ await act(async () => active!.dispatchEvent(new testWindow.MouseEvent("mouseover", { bubbles: true }))); ++ expect(container.querySelector(".heatmap-tip-date")?.textContent).toBe("2026-09-07"); ++ expect(container.querySelector(".heatmap-tip")?.textContent).toContain("700"); ++}, 15000); + + test("Apply submits inclusive bounds once; Clear restores the held preset without custom cache entries", async () => { + await mount(); +``` + +## Audit-driven amendment before implementation + +The source patch's explicit 15-second per-test timeout overrides its child CLI 10-second timeout. Change the final test timeout to `process.env.OCX_USAGE_SANTIAGO_CHILD === "1" ? 10000 : 15000`. Add a unique completion marker printed only after the child's last UI assertion; require the marker in the parent as well as exit/signal/timeout checks. Set the child's cwd explicitly to the dashboard root resolved from import.meta.dir. These are same-bug test integrity changes; no production code changes. Preserve the original assertions and parameterized test cases. + +Existing hosted Windows/macOS jobs do not run gui/tests. A supplemental verification-only branch will use the already-registered ci.yml workflow_dispatch path, with a separately reviewed minimal workflow that checks out an immutable candidate SHA and executes only focused timezone proof on GitHub-hosted ubuntu/windows/macos. This branch/workflow is excluded from delivery and never merged. Candidate PR CI remains unchanged and required; the supplemental run is independently labeled, not passed off as normal candidate workflow CI. Actions use existing pinned SHAs, contents:read only, no secrets, checkout persist-credentials:false, Bun1.4.0, frozen root and dashboard installs on the hosted machines, and bounded jobs/processes. Never run any of these commands locally. Negative controls must restore candidate bytes before the final positive run and record source identity. + +The proposed hosted verification starts in gui/: `bun test --isolate ./tests/usage-custom-range.test.tsx`, with TZ absent, Etc/UTC, Asia/Seoul and America/Santiago in distinct subprocess environments. Verify parent environment and next tests, child success marker, nonzero-exit/absent-marker propagation and process deadline; no fixture/process may survive teardown. Exact workflow YAML, pinned commit and control script are reviewed before dispatch. The repository's Windows product runtime suite is distinct from this Windows dashboard proof. + +### Exact test-integrity follow-up diff atop the original source commit + +```diff +--- a/gui/tests/usage-custom-range.test.tsx ++++ b/gui/tests/usage-custom-range.test.tsx +@@ -1,5 +1,6 @@ + import { afterEach, beforeEach, expect, test } from "bun:test"; + import { Window } from "happy-dom"; ++import { resolve } from "node:path"; + import { act } from "react"; + import type { Root } from "react-dom/client"; + import { LanguageProvider } from "../src/i18n/provider"; +@@ -154,7 +155,7 @@ + } + + test("America/Santiago midnight DST retains final-day activity and tooltip", async () => { +- if (process.env.TZ !== "America/Santiago") { ++ if (process.env.OCX_USAGE_SANTIAGO_CHILD !== "1" && process.env.TZ !== "America/Santiago") { + // Restoring an absent TZ can change Bun's effective timezone on Windows. + // Start the DST case in its timezone without mutating this suite's clock. + const timezone = { present: Object.hasOwn(process.env, "TZ"), value: process.env.TZ }; +@@ -164,17 +165,20 @@ + "-t", "^America/Santiago midnight DST retains final-day activity and tooltip$", + "--timeout", "10000", + ], { +- env: { ...process.env, TZ: "America/Santiago" }, ++ cwd: resolve(import.meta.dir, ".."), ++ env: { ...process.env, TZ: "America/Santiago", OCX_USAGE_SANTIAGO_CHILD: "1" }, + stdout: "pipe", stderr: "pipe", timeout: 12000, killSignal: "SIGKILL", + }); + const diagnostics = `${child.stdout.toString()}\n${child.stderr.toString()}`; + expect(child.exitedDueToTimeout, diagnostics).not.toBe(true); + expect(child.signalCode, diagnostics).toBeUndefined(); + expect(child.exitCode, diagnostics).toBe(0); ++ expect(child.stdout.toString().split(/\r?\n/), diagnostics).toContain("OCX_SANTIAGO_CASE_COMPLETED"); + expect({ present: Object.hasOwn(process.env, "TZ"), value: process.env.TZ }).toEqual(timezone); + expect(new Date(2020, 8, 15, 10, 20).getTime()).toBe(localTime); + return; + } ++ expect(process.env.TZ).toBe("America/Santiago"); + expect(new Date(2026, 8, 6, 0).getHours()).toBe(1); + await mount(); + await respond(0, "preset-marker"); +@@ -192,7 +196,8 @@ + await act(async () => active!.dispatchEvent(new testWindow.MouseEvent("mouseover", { bubbles: true }))); + expect(container.querySelector(".heatmap-tip-date")?.textContent).toBe("2026-09-07"); + expect(container.querySelector(".heatmap-tip")?.textContent).toContain("700"); +-}, 15000); ++ if (process.env.OCX_USAGE_SANTIAGO_CHILD === "1") console.log("OCX_SANTIAGO_CASE_COMPLETED"); ++}, process.env.OCX_USAGE_SANTIAGO_CHILD === "1" ? 10000 : 15000); + + test("Apply submits inclusive bounds once; Clear restores the held preset without custom cache entries", async () => { + await mount(); +``` + +C review amendment: use the dedicated child marker as the sole recursion guard, even when the parent already starts in Santiago. This preserves all original DST assertions and makes completion/state checks run for every parent TZ. Accepted CodeRabbit finding; final source/evidence checkout SHA will be repinned and hosted proof rerun. Prior Linux/Windows proof8223788bd remains historical, not finalhead evidence. + +Final candidate ce71d9171 passed independent marker-guard source re-audit. Evidence workflow7d5f1097e/run34170111719 checks out exactcandidatece71d9171; Linux/Windows/macOS each completed10scenarios, fivepositive/fiveexpectednegative, with exactfailure attribution, timeoutPIDabsence and candidatebytesrestored. Actual evidence JSON logs checked. Normal PR3967CI34170093095 pending; no completion/landing claim yet. Existing maintainer gui-screenshot-waived exception applied for test-only change after workflow/label policy inspection. No UI screenshot fabricated, no product gate waived. + +NormalCI attempt1 of34170093095 was cancelled at macos1 job20-minute deadline. Last emitted test was the unchanged client-connect CLI rejection case, followed by dangling-process cleanup and no completion. This root macOS lane does not include gui/tests; exact cause remains under investigation. Preserve cancellation as an unsuccessful/incomplete attempt. One same-head failed-job recheck was requested for diagnosis; a green recheck alone does not establish the unrelated runner stall is fixed. Supplemental3OS timezoneproof remains separately valid. + +DONE: PR3967 landedc46c22f3e with luvs01 trailer and exactcandidate file. Final candidatece71d9171 supplemental3OS run34170111719 passed all30expected scenarios. StandardCI34170093095 attempt2 passed19jobs/skipped2; attempt1 macos1 stalled/cancelled20min at unchangedclientconnect boundary remains unresolved reliability residual, not a fixedflake claim. Exact destinationbbea77a48+candidatepatch tree and devancestry verified. BJWT3962/eb4188a9 confirmed ondev; source3950 closure follows reconciliation. diff --git a/devlog/_fin/260908_c248_individual_fixes/040_reconcile.md b/devlog/_fin/260908_c248_individual_fixes/040_reconcile.md new file mode 100644 index 0000000000..753a2fa2ee --- /dev/null +++ b/devlog/_fin/260908_c248_individual_fixes/040_reconcile.md @@ -0,0 +1,3 @@ +# Phase reconcile: independent delivery and release readiness + +No product delta. MODIFY this unit's outcome record (050_outcome.md) with each original PR, actual delivery PR, reviewed head, CI run/check counts, landed SHA, author trailer and issue state. Query B for the JWT-only landing and independently verify it in dev together with C's timezone commit before closing #3950. Inspect A/B status and record readiness without doing their work or publishing a release. Move this unit from devlog/_plan to devlog/_fin only after all scoped tasks are complete; publish a separate docs-only closeout PR if needed, keeping it out of all three bug commits. Verify that closeout's scope check and diff preserve product files. No version change or promotion. Outcomes must distinguish true merged source PRs from closed carry sources. diff --git a/devlog/_fin/260908_c248_individual_fixes/050_outcome.md b/devlog/_fin/260908_c248_individual_fixes/050_outcome.md new file mode 100644 index 0000000000..aa085d5840 --- /dev/null +++ b/devlog/_fin/260908_c248_individual_fixes/050_outcome.md @@ -0,0 +1,35 @@ +# Lane C outcome + +All three scoped corrections landed into dev through independent bug PRs. The capture correction needed a separate follow-up after its author advanced the source PR during CI. No already-landed commit was rewritten. This record is documentation only and is not another product fix. + +| Source | Delivery PR | Landed SHA | Current-head CI | Scope | +|---|---|---|---|---| +| #3953 initial | [3955](https://github.com/lidge-jun/opencodex/pull/3955) | `9c54000c937276ba8d93ce63a922b3fe6797cbde` | [34166758020](https://github.com/lidge-jun/opencodex/actions/runs/34166758020) (3 success / 10 skipped) | Current-tree Accounts capture cleanup | +| #3953 follow-up | [3959](https://github.com/lidge-jun/opencodex/pull/3959) | `01c23aedcdfcb913151a2ac8f7acebda58d91eee` | [34167651789](https://github.com/lidge-jun/opencodex/actions/runs/34167651789) (3 success / 10 skipped) | Consistent capture retention and isolation guidance | +| #3899 / #3895 | [3960](https://github.com/lidge-jun/opencodex/pull/3960) | `9c8f66b9df4cdf133a16c95a95ee07ff5171a46d` | [34168481093](https://github.com/lidge-jun/opencodex/actions/runs/34168481093) (16 success / 3 skipped) | Release-note marker in both actual and standalone builders | +| #3950 timezone only | [3967](https://github.com/lidge-jun/opencodex/pull/3967) | `c46c22f3e4d00ff31a0e6bb10f74505577806776` | [34170093095](https://github.com/lidge-jun/opencodex/actions/runs/34170093095) (19 success / 2 skipped) | Santiago subprocess isolation and oracle integrity | + +## Proof and attribution + +Each landing was serialized through the shared merge lock and checked against the then-current destination: actual merge parent, computed combined tree, dev ancestry and surviving Co-authored-by trailer. luvs01 is credited in both capture carries and the timezone carry; Joonsuh Park is credited in the release-note correction. The original source PRs were closed as carried, not described as directly merged. + +#3953 was closed only after its refreshed ca21efd2 follow-up was included. #3899 and issue #3895 closed after the active release builder was corrected and verified. #3950 was closed only after B's independent JWT delivery #3962 (eb4188a9f2e127f5ee2980b62d6e5bb213c43c70) and C's timezone delivery #3967 were both confirmed on dev. Product commits remain independently revertible. + +The release-note original patch missed scripts/build-release-changelog.ts, the actual release workflow entry. Review led to a shared normalizer and five public-builder cases covering generated and associated PR sources and negative marker preservation. Those cases and the original renderer cases were observed passing in the final Linux CI logs; the final macOS lanes also passed. The structure guide now accurately distinguishes the active and standalone renderers. + +Timezone final candidate ce71d917143ddcbd5675b6ba92d8b1053971cd25 was separately exercised by evidence workflow7d5f1097ec587a0ced441f475eb02d750e06b9ac in [run34170111719](https://github.com/lidge-jun/opencodex/actions/runs/34170111719). The workflow checked out that immutable candidate separately. Linux, Windows and macOS each completed ten scenarios: five positive/restored runs and five deliberately failing controls. Controls require the intended test failure and specific diagnostics, not any nonzero exit. All platforms verified the final candidate file hash recorded below. Child timeout termination and restored candidate bytes/HEAD were verified. The evidence branch is not in any delivery PR and is never merged. + +## Limits and remaining work + +- All local product tests, test:changed, typechecks, builds and dependency installs were NOT RUN. Mutating Git operations disabled hooks per command, and pushes used --no-verify. Git/diff/source and operational evidence checks are distinct from product tests. +- Skipped jobs are not counted as passing tests. Normal PR workflows skip the full Windows runtime suite and macOS whole-pool control; the supplementary timezone run explicitly supplies Windows/macOS focused dashboard evidence, not a full runtime-suite result. +- Timezone normal CI34170093095 attempt1 timed out after20minutes in the unchanged root macOS client-connect test. The next helper contains an unbounded synchronous child wait, but the actual stopping mechanism is unproven. Attempt2 succeeded on the same candidate without a source change. The cancelled attempt remains unsuccessful evidence and the unrelated CI reliability defect is not claimed fixed. +- Privacy cleanup affects the current tree only. Historical blobs/links were not purged, and no claim of historical erasure is made. The working proxy was not restarted or reconfigured by this task. +- Concurrent dev changes were preserved through actual-tree comparison. That structural proof does not imply every merged integration tree was separately executed by the candidate CI. +- A and B were still active at reconciliation. B's JWT slice is verified; no assertion is made that their remaining changes or the overall2.48 release are complete. main/preview promotion, version changes and npm publication were outside C's authority and were not performed. + +## Final supplemental evidence + +- win32: Bun1.4.0, candidate file SHA-256 `6cbb58c96643f500cf2541ef3b7707aed072c1f981b16b49f97949536fe30f50`, ten scenarios, restored=True. +- linux: Bun1.4.0, candidate file SHA-256 `6cbb58c96643f500cf2541ef3b7707aed072c1f981b16b49f97949536fe30f50`, ten scenarios, restored=True. +- darwin: Bun1.4.0, candidate file SHA-256 `6cbb58c96643f500cf2541ef3b7707aed072c1f981b16b49f97949536fe30f50`, ten scenarios, restored=True.