π release: sync dev/v1.6 β main for v1.6.0 GA - #697
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
π WalkthroughWalkthroughPromoted repository release references from Possibly related PRs
π₯ Pre-merge checks | β 2β Passed checks (2 passed)
β¨ Finishing Touchesπ Generate docstrings
π§ͺ Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
e0a427d to
9ef7427
Compare
biggest-littlest
left a comment
There was a problem hiding this comment.
Tree-replacement sync: single commit off main whose tree matches dev/v1.6 exactly. Verified both resolve to 356691b6.
ALARGECOMPANY
left a comment
There was a problem hiding this comment.
Second approval for the v1.6.0 GA sync.
0c0deff
9ef7427 to
0c0deff
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
π§Ή Nitpick comments (1)
SECURITY-ASSURANCE.md (1)
96-101: π Security & Privacy | π΅ Trivial | β‘ Quick winAdd
.github/workflows/e2e-playwright.ymlto the evidence links. The browser-test claim is implemented by its requiredplaywrightjob, not by the currently linked workflows.π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@SECURITY-ASSURANCE.md` around lines 96 - 101, Add .github/workflows/e2e-playwright.yml to the evidence links supporting the browser-test claim, specifically referencing its required playwright job while preserving the existing CI coverage and security evidence.
π€ Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@content/docs/current/updates/index.mdx`:
- Around line 8-18: Keep the release identity at 1.6.0-rc.13 until the GA
release-cut change: update content/docs/current/updates/index.mdx lines 8-18 to
retain the rc.13 heading and changelog link; retain 1.6.0-rc.13 in
apps/demo/src/mocks/data/server.ts line 2, both version sites in
apps/demo/src/mocks/handlers/app.ts lines 7 and 19,
apps/web/src/lib/site-content.ts line 284, content/docs/current/api/agent.mdx
lines 26 and 156, content/docs/current/api/app.mdx line 15,
content/docs/current/api/portwing.mdx lines 200 and 223, and
content/docs/current/quickstart/index.mdx line 111.
In `@GOVERNANCE.md`:
- Around line 51-56: Update the release-continuity statement in GOVERNANCE.md to
qualify the one-week timeline: state that the remaining organization owner can
continue the release process within one week subject to pending discussion
replies, RC soak completion, and required release gates. Do not present the
--force option from scripts/release-precut-check.mjs as normal continuity
behavior.
In `@SECURITY-ASSURANCE.md`:
- Around line 60-64: Update the authentication description in
SECURITY-ASSURANCE.md to state that missing configuration or
DD_ANONYMOUS_AUTH_CONFIRM=true causes the service to refuse to serve: the
process remains running, protected requests return 401, and /health returns 503.
Replace the claim that authentication configuration fails closed or prevents
startup, while preserving the surrounding middleware and regression-test
statements.
---
Nitpick comments:
In `@SECURITY-ASSURANCE.md`:
- Around line 96-101: Add .github/workflows/e2e-playwright.yml to the evidence
links supporting the browser-test claim, specifically referencing its required
playwright job while preserving the existing CI coverage and security evidence.
πͺ Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
βΉοΈ Review info
βοΈ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 9a1c9c55-5cd1-4434-b7db-5c37b4b37b33
β Files ignored due to path filters (1)
CHANGELOG.mdis excluded by!CHANGELOG.md
π Files selected for processing (18)
GOVERNANCE.mdREADME.mdSECURITY-ASSURANCE.mdapps/demo/src/mocks/data/agents.tsapps/demo/src/mocks/data/audit.tsapps/demo/src/mocks/data/containers.tsapps/demo/src/mocks/data/server.tsapps/demo/src/mocks/handlers/app.tsapps/web/src/lib/site-config.tsapps/web/src/lib/site-content.tscontent/docs/current/api/agent.mdxcontent/docs/current/api/app.mdxcontent/docs/current/api/portwing.mdxcontent/docs/current/quickstart/index.mdxcontent/docs/current/updates/index.mdxscripts/changelog-links.test.mjsscripts/release-docs-identity.test.mjsscripts/release-identity.test.mjs
| ## v1.6.0 Highlights β August 11, 2026 | ||
|
|
||
| Consolidates the `1.6.0-rc.1` β¦ `1.6.0-rc.13` prereleases into one GA release. The | ||
| biggest themes: Portwing edge/agent transport maturing into a first-class citizen, | ||
| a declarative three-tier update policy with a maturity stabilization gate, | ||
| per-rule notification templates and a new health-status event, every major list | ||
| view going responsive with a consistent table/card toggle, `/api/v1` parity with | ||
| the unversioned `/api/*` alias removed, and fail-closed security hardening | ||
| throughout. See [CHANGELOG.md](https://github.com/CodesWhat/drydock/blob/main/CHANGELOG.md#160--2026-08-11) | ||
| for the full release notes. | ||
|
|
There was a problem hiding this comment.
ποΈ Data Integrity & Integration | π Major | ποΈ Heavy lift
Keep the release identity on 1.6.0-rc.13 until the GA cut.
The changed surfaces now identify 1.6.0, but the PR objective says the rc.13 soak ends on August 16, 2026, the GA cut is still pending, and the GA changelog rollup has not been completed. Update all affected surfaces together in the release-cut change. Partial promotion makes the demo, public API documentation, roadmap, quickstart, release notes, and validation contract identify an unreleased version.
content/docs/current/updates/index.mdx#L8-L18: retain the rc.13 heading and changelog link until the GA rollup exists.apps/demo/src/mocks/data/server.ts#L2-L2: retainserverInfo.versionas1.6.0-rc.13.apps/demo/src/mocks/handlers/app.ts#L7-L7: retain the/api/v1/appmock version as1.6.0-rc.13.apps/demo/src/mocks/handlers/app.ts#L19-L19: retain the debug dump server version as1.6.0-rc.13.apps/web/src/lib/site-content.ts#L284-L284: retain the roadmap milestone label asv1.6.0-rc.13.content/docs/current/api/agent.mdx#L26-L26: retain the agent list example version as1.6.0-rc.13.content/docs/current/api/agent.mdx#L156-L156: retain thedd:ackexample version as1.6.0-rc.13.content/docs/current/api/app.mdx#L15-L15: retain the/api/v1/appexample version as1.6.0-rc.13.content/docs/current/api/portwing.mdx#L200-L200: retain the hello-frame version as1.6.0-rc.13.content/docs/current/api/portwing.mdx#L223-L223: retain the welcome-frame version as1.6.0-rc.13.content/docs/current/quickstart/index.mdx#L111-L111: retain the immutable image tag as1.6.0-rc.13.
π Affects 8 files
content/docs/current/updates/index.mdx#L8-L18(this comment)apps/demo/src/mocks/data/server.ts#L2-L2apps/demo/src/mocks/handlers/app.ts#L7-L7apps/demo/src/mocks/handlers/app.ts#L19-L19apps/web/src/lib/site-content.ts#L284-L284content/docs/current/api/agent.mdx#L26-L26content/docs/current/api/agent.mdx#L156-L156content/docs/current/api/app.mdx#L15-L15content/docs/current/api/portwing.mdx#L200-L200content/docs/current/api/portwing.mdx#L223-L223content/docs/current/quickstart/index.mdx#L111-L111
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@content/docs/current/updates/index.mdx` around lines 8 - 18, Keep the release
identity at 1.6.0-rc.13 until the GA release-cut change: update
content/docs/current/updates/index.mdx lines 8-18 to retain the rc.13 heading
and changelog link; retain 1.6.0-rc.13 in apps/demo/src/mocks/data/server.ts
line 2, both version sites in apps/demo/src/mocks/handlers/app.ts lines 7 and
19, apps/web/src/lib/site-content.ts line 284,
content/docs/current/api/agent.mdx lines 26 and 156,
content/docs/current/api/app.mdx line 15, content/docs/current/api/portwing.mdx
lines 200 and 223, and content/docs/current/quickstart/index.mdx line 111.
Sources: Path instructions, Learnings
| Canonical source, issues, CI, release workflows, container images, and release | ||
| artifacts are kept in GitHub and GHCR. Releases use GitHub Actions OIDC for | ||
| keyless signing and attestations, so continuity does not depend on a private | ||
| signing key held on one maintainer's workstation. If one maintainer becomes | ||
| unavailable, the remaining organization owner can revoke stale access, update | ||
| role assignments, merge approved work, and publish a release within one week. |
There was a problem hiding this comment.
π Security & Privacy | π Major | β‘ Quick win
Qualify the one-week release promise.
If discussion replies remain pending, scripts/release-precut-check.mjs fails a stable release unless --force is used. This PR still lists 13 discussion replies as a GA runbook item, and the RC soak ends on August 16, 2026 at 04:17:32 UTC. State that the remaining owner can continue the release process within one week, subject to discussion replies, soak completion, and release gates. Do not imply that --force is normal continuity behavior.
Evidence: scripts/release-precut-check.mjs:131-174 and the PR objectives.
Proposed wording
-If one maintainer becomes unavailable, the remaining organization owner can revoke stale access, update
-role assignments, merge approved work, and publish a release within one week.
+If one maintainer becomes unavailable, the remaining organization owner can revoke stale access, update
+role assignments, merge approved work, and continue the release process within one week, subject to
+the discussion-reply, soak, and release-gate requirements.π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Canonical source, issues, CI, release workflows, container images, and release | |
| artifacts are kept in GitHub and GHCR. Releases use GitHub Actions OIDC for | |
| keyless signing and attestations, so continuity does not depend on a private | |
| signing key held on one maintainer's workstation. If one maintainer becomes | |
| unavailable, the remaining organization owner can revoke stale access, update | |
| role assignments, merge approved work, and publish a release within one week. | |
| Canonical source, issues, CI, release workflows, container images, and release | |
| artifacts are kept in GitHub and GHCR. Releases use GitHub Actions OIDC for | |
| keyless signing and attestations, so continuity does not depend on a private | |
| signing key held on one maintainer's workstation. If one maintainer becomes | |
| unavailable, the remaining organization owner can revoke stale access, update | |
| role assignments, merge approved work, and continue the release process within one week, subject to | |
| the discussion-reply, soak, and release-gate requirements. |
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@GOVERNANCE.md` around lines 51 - 56, Update the release-continuity statement
in GOVERNANCE.md to qualify the one-week timeline: state that the remaining
organization owner can continue the release process within one week subject to
pending discussion replies, RC soak completion, and required release gates. Do
not present the --force option from scripts/release-precut-check.mjs as normal
continuity behavior.
| Authentication configuration fails closed. Anonymous mode must be explicitly | ||
| confirmed, and protected routes share the authentication middleware rather than | ||
| opting in route by route. Docker updates flow through the same policy and | ||
| operation tracking used by the API and UI. Regression tests cover authentication | ||
| failure, authorization, rate limiting, update admission, and agent boundaries. |
There was a problem hiding this comment.
π Security & Privacy | π Major | β‘ Quick win
Describe the authentication failure mode accurately.
Missing authentication configuration or missing DD_ANONYMOUS_AUTH_CONFIRM=true does not stop the process. The process remains running, protected requests return 401, and /health returns 503. Replace βAuthentication configuration fails closedβ with wording that states the service refuses to serve, not that it refuses to start.
Based on learnings: βDescribe this as refusing to serve, not refusing to start.β
Proposed wording
-Authentication configuration fails closed. Anonymous mode must be explicitly
-confirmed, and protected routes share the authentication middleware rather than
-opting in route by route.
+When authentication configuration is missing, or anonymous mode lacks
+`DD_ANONYMOUS_AUTH_CONFIRM=true`, the process remains running, protected
+requests return `401`, and `/health` returns `503`. Protected routes share the
+authentication middleware rather than opting in route by route.π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Authentication configuration fails closed. Anonymous mode must be explicitly | |
| confirmed, and protected routes share the authentication middleware rather than | |
| opting in route by route. Docker updates flow through the same policy and | |
| operation tracking used by the API and UI. Regression tests cover authentication | |
| failure, authorization, rate limiting, update admission, and agent boundaries. | |
| When authentication configuration is missing, or anonymous mode lacks | |
| `DD_ANONYMOUS_AUTH_CONFIRM=true`, the process remains running, protected | |
| requests return `401`, and `/health` returns `503`. Protected routes share the | |
| authentication middleware rather than opting in route by route. Docker updates | |
| flow through the same policy and operation tracking used by the API and UI. Regression tests cover authentication failure, authorization, rate limiting, update admission, and agent boundaries. |
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@SECURITY-ASSURANCE.md` around lines 60 - 64, Update the authentication
description in SECURITY-ASSURANCE.md to state that missing configuration or
DD_ANONYMOUS_AUTH_CONFIRM=true causes the service to refuse to serve: the
process remains running, protected requests return 401, and /health returns 503.
Replace the claim that authentication configuration fails closed or prevents
startup, while preserving the surrounding middleware and regression-test
statements.
Source: Learnings
Replaces main's tree with dev/v1.6 wholesale so the two branches are byte identical before the GA tag is cut. Carries the auditable soak override, the star-history GraphQL fix, and the OpenSSF assurance evidence.
0c0deff to
d4be7b1
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
π§Ή Nitpick comments (2)
.github/tests/release-cut-soak-override.test.ts (1)
203-311: π Maintainability & Code Quality | π΅ Trivial | β‘ Quick winAdd a case for a reason supplied on an already-soaked candidate.
Line 287 covers an aged candidate with an empty reason. No case covers an aged candidate with a non-empty reason. That is the path where the workflow silently discards the justification (see the comment on
.github/workflows/release-cut.ymlLines 294-331).π§ͺ Proposed test
+test('a soak_override_reason on an already-soaked candidate is not silently discarded', () => { + const result = runSourceStep({ + isPrerelease: false, + ageSeconds: SEVEN_DAYS + 3600, + soakOverrideReason: 'unnecessary justification that is well over twenty characters', + }); + + expect(result.status).not.toBe(0); + expect(result.stdout).toContain('already cleared the seven-day soak'); +});π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/tests/release-cut-soak-override.test.ts around lines 203 - 311, Add a test alongside βa candidate that already cleared seven days needs no reason at allβ covering an aged GA candidate with a non-empty soak_override_reason. Assert the workflow succeeds without using the override, does not emit the override warning or summary entry, and does not record override outputs or the reason file, matching the existing behavior for already-soaked candidates..github/tests/release-cut-retry-workflow.test.ts (1)
227-240: π Security & Privacy | π΅ Trivial | β‘ Quick winThe injection guard misses
with.commandscript bodies.This workflow runs shell through
nick-fields/retrywithwith.command:in at least nine steps (Lines 479, 493, 507, 596, 869, 996, 1166, 1220, 1279 of.github/workflows/release-cut.yml). Those bodies are executed the same wayrun:is, butstep.runisundefinedfor them, sostep.run ?? ''passes without checking anything. A future step that interpolates the raw input intowith.commandwould slip past this test.Check both script surfaces.
β»οΈ Proposed refactor
for (const step of stepsReferencingReason) { // The raw input must only ever appear on the right-hand side of an `env:` // mapping (e.g. `SOAK_OVERRIDE_REASON: ${{ inputs.soak_override_reason }}`), // never templated straight into `run:`, which is how a candidate_tag-style // template-injection finding would happen. - expect(step.run ?? '').not.toContain('inputs.soak_override_reason'); + const scriptBodies = [step.run ?? '', String(step.with?.command ?? '')]; + for (const body of scriptBodies) { + expect(body).not.toContain('inputs.soak_override_reason'); + } }Confirm
WorkflowStepin.github/tests/workflow-test-utils.tsdeclareswith; add it if not.π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In @.github/tests/release-cut-retry-workflow.test.ts around lines 227 - 240, Update the injection guard in the release-cut test to inspect both step.run and the with.command field for direct inputs.soak_override_reason interpolation. Ensure WorkflowStep in workflow-test-utils.ts declares with if needed, and retain the existing requirement that referenced input values are passed through an env mapping rather than embedded in either script surface.
π€ Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/release-cut.yml:
- Around line 1136-1151: Update the release-note generation block guarded by
SOAK_OVERRIDE_USED in release-cut.yml so multiline SOAK_OVERRIDE_REASON_PATH
content cannot break the Markdown bullet list. Format the reason as a fenced
block or prefix/indent every continuation line, while preserving the existing
reason text and surrounding soak-override note.
- Around line 294-331: Add an else branch to the age_seconds check in
.github/workflows/release-cut.yml (lines 294-331) that trims
SOAK_OVERRIDE_REASON and exits non-zero with an error when a non-empty reason is
supplied for an already-soaked candidate. Add a corresponding test case in
.github/tests/release-cut-soak-override.test.ts (lines 203-311) using
ageSeconds: SEVEN_DAYS + 3600 and a non-empty reason, asserting a non-zero
status.
In `@apps/web/src/app/api/star-history/route.ts`:
- Around line 113-117: Update the continuation handling around
pageInfo.endCursor to return undefined when the cursor is empty or equals the
current after value, while preserving the existing non-string rejection and
assignment for valid advancing cursors. Add matching test coverage in the
marketing performance test for both empty and repeated cursors.
---
Nitpick comments:
In @.github/tests/release-cut-retry-workflow.test.ts:
- Around line 227-240: Update the injection guard in the release-cut test to
inspect both step.run and the with.command field for direct
inputs.soak_override_reason interpolation. Ensure WorkflowStep in
workflow-test-utils.ts declares with if needed, and retain the existing
requirement that referenced input values are passed through an env mapping
rather than embedded in either script surface.
In @.github/tests/release-cut-soak-override.test.ts:
- Around line 203-311: Add a test alongside βa candidate that already cleared
seven days needs no reason at allβ covering an aged GA candidate with a
non-empty soak_override_reason. Assert the workflow succeeds without using the
override, does not emit the override warning or summary entry, and does not
record override outputs or the reason file, matching the existing behavior for
already-soaked candidates.
πͺ Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
βΉοΈ Review info
βοΈ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: a1b6989c-fa98-4aa6-a91c-fa998e9ec012
π Files selected for processing (5)
.github/tests/release-cut-retry-workflow.test.ts.github/tests/release-cut-soak-override.test.ts.github/workflows/release-cut.ymlapps/web/scripts/marketing-performance.test.mjsapps/web/src/app/api/star-history/route.ts
| if [ "${age_seconds}" -lt 604800 ]; then | ||
| echo "::error::Candidate ${CANDIDATE_TAG} is only ${age_seconds}s old; GA promotion requires seven full days (604800s)." | ||
| exit 1 | ||
| # Trim leading/trailing whitespace so a lone space (or a string | ||
| # that is only whitespace) cannot pass as a reason. | ||
| trimmed_reason="$(printf '%s' "${SOAK_OVERRIDE_REASON}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" | ||
| if [ -z "${trimmed_reason}" ]; then | ||
| echo "::error::Candidate ${CANDIDATE_TAG} is only ${age_seconds}s old; GA promotion requires seven full days (604800s)." | ||
| exit 1 | ||
| fi | ||
| if [ "${#trimmed_reason}" -lt 20 ]; then | ||
| echo "::error::soak_override_reason must be at least 20 characters of real justification to bypass the seven-day soak; got ${#trimmed_reason} after trimming whitespace." | ||
| exit 1 | ||
| fi | ||
|
|
||
| age_days="$(awk -v s="${age_seconds}" 'BEGIN { printf "%.1f", s / 86400 }')" | ||
| # The reason is free text and may be multiline, so it never goes | ||
| # into a workflow command: a line starting with :: would be parsed | ||
| # as a second command. The job summary and release notes carry it. | ||
| echo "::warning::Candidate ${CANDIDATE_TAG} is only ${age_seconds}s (${age_days} days) old, short of the seven-day (604800s) soak requirement. Soak overridden; the justification is in the job summary and release notes." | ||
|
|
||
| { | ||
| echo "### :warning: Seven-day soak overridden for GA promotion" | ||
| echo "- Candidate: \`${CANDIDATE_TAG}\`" | ||
| echo "- Age at promotion: ${age_seconds}s (~${age_days} days) β short of the 604800s (7-day) requirement" | ||
| echo "- Reason: ${trimmed_reason}" | ||
| } >> "${GITHUB_STEP_SUMMARY}" | ||
|
|
||
| # The reason is free text from a workflow_dispatch input (any repo | ||
| # collaborator can supply it), so it is carried to later steps as | ||
| # a file path rather than inlined into GITHUB_OUTPUT: appending | ||
| # arbitrary multi-line content directly as `key=value` risks | ||
| # output injection if it ever contains its own newlines or an | ||
| # `EOF`-style delimiter. | ||
| soak_override_used="true" | ||
| soak_override_age_seconds="${age_seconds}" | ||
| soak_override_age_days="${age_days}" | ||
| soak_override_reason_path="${RUNNER_TEMP}/soak-override-reason.txt" | ||
| printf '%s' "${trimmed_reason}" > "${soak_override_reason_path}" | ||
| fi |
There was a problem hiding this comment.
π― Functional Correctness | π‘ Minor | β‘ Quick win
An unnecessary soak_override_reason is neither rejected nor recorded, and nothing tests it. The override block only runs when age_seconds is under 604800, so a reason passed on an already-soaked candidate is dropped without a warning, a summary line, or an output. The input description at Line 35 states that any non-empty value is recorded permanently.
.github/workflows/release-cut.yml#L294-L331: add anelsebranch on theage_secondscheck that fails whenSOAK_OVERRIDE_REASONis non-empty after whitespace stripping..github/tests/release-cut-soak-override.test.ts#L203-L311: add a case withageSeconds: SEVEN_DAYS + 3600and a non-empty reason that asserts a non-zero status.
π Affects 2 files
.github/workflows/release-cut.yml#L294-L331(this comment).github/tests/release-cut-soak-override.test.ts#L203-L311
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release-cut.yml around lines 294 - 331, Add an else branch
to the age_seconds check in .github/workflows/release-cut.yml (lines 294-331)
that trims SOAK_OVERRIDE_REASON and exits non-zero with an error when a
non-empty reason is supplied for an already-soaked candidate. Add a
corresponding test case in .github/tests/release-cut-soak-override.test.ts
(lines 203-311) using ageSeconds: SEVEN_DAYS + 3600 and a non-empty reason,
asserting a non-zero status.
| # GA-only: the seven-day soak was shortened via soak_override_reason | ||
| # on the "Resolve release source" step. Record it in the published | ||
| # release body too, not just the run summary, so anyone reading the | ||
| # release later can see the soak was cut short and why. | ||
| if [ "${SOAK_OVERRIDE_USED:-false}" = "true" ]; then | ||
| override_reason="$(cat "${SOAK_OVERRIDE_REASON_PATH}")" | ||
| { | ||
| echo "" | ||
| echo "---" | ||
| echo "" | ||
| echo "**Note:** the standard seven-day release-candidate soak was shortened for this release." | ||
| echo "- Candidate age at promotion: ${SOAK_OVERRIDE_AGE_SECONDS}s (~${SOAK_OVERRIDE_AGE_DAYS} days), short of the usual 7 days (604800s)." | ||
| echo "- Reason: ${override_reason}" | ||
| } >> "${notes_path}" | ||
| fi | ||
|
|
There was a problem hiding this comment.
π― Functional Correctness | π‘ Minor | β‘ Quick win
A multiline reason breaks the release-note bullet list.
echo "- Reason: ${override_reason}" emits every line of the reason unprefixed. Markdown then renders lines 2..n as continuation text or, if a line starts with - or #, as new list items and headings. The soak-override test at Line 263 explicitly exercises a multiline reason, so this path is reachable.
Emit the reason as a fenced block or indent the continuation lines.
π οΈ Proposed fix
- echo "- Reason: ${override_reason}"
+ echo "- Reason:"
+ echo ""
+ echo '```text'
+ printf '%s\n' "${override_reason}"
+ echo '```'π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| # GA-only: the seven-day soak was shortened via soak_override_reason | |
| # on the "Resolve release source" step. Record it in the published | |
| # release body too, not just the run summary, so anyone reading the | |
| # release later can see the soak was cut short and why. | |
| if [ "${SOAK_OVERRIDE_USED:-false}" = "true" ]; then | |
| override_reason="$(cat "${SOAK_OVERRIDE_REASON_PATH}")" | |
| { | |
| echo "" | |
| echo "---" | |
| echo "" | |
| echo "**Note:** the standard seven-day release-candidate soak was shortened for this release." | |
| echo "- Candidate age at promotion: ${SOAK_OVERRIDE_AGE_SECONDS}s (~${SOAK_OVERRIDE_AGE_DAYS} days), short of the usual 7 days (604800s)." | |
| echo "- Reason: ${override_reason}" | |
| } >> "${notes_path}" | |
| fi | |
| # GA-only: the seven-day soak was shortened via soak_override_reason | |
| # on the "Resolve release source" step. Record it in the published | |
| # release body too, not just the run summary, so anyone reading the | |
| # release later can see the soak was cut short and why. | |
| if [ "${SOAK_OVERRIDE_USED:-false}" = "true" ]; then | |
| override_reason="$(cat "${SOAK_OVERRIDE_REASON_PATH}")" | |
| { | |
| echo "" | |
| echo "---" | |
| echo "" | |
| echo "**Note:** the standard seven-day release-candidate soak was shortened for this release." | |
| echo "- Candidate age at promotion: ${SOAK_OVERRIDE_AGE_SECONDS}s (~${SOAK_OVERRIDE_AGE_DAYS} days), short of the usual 7 days (604800s)." | |
| echo "- Reason:" | |
| echo "" | |
| echo ' |
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.github/workflows/release-cut.yml around lines 1136 - 1151, Update the
release-note generation block guarded by SOAK_OVERRIDE_USED in release-cut.yml
so multiline SOAK_OVERRIDE_REASON_PATH content cannot break the Markdown bullet
list. Format the reason as a fenced block or prefix/indent every continuation
line, while preserving the existing reason text and surrounding soak-override
note.
| const cursor = pageInfo.endCursor; | ||
| if (typeof cursor !== "string") { | ||
| return undefined; | ||
| } | ||
| after = cursor; |
There was a problem hiding this comment.
π©Ί Stability & Availability | π‘ Minor | β‘ Quick win
Reject empty and repeated continuation cursors.
If endCursor is empty or equals after, the loop does not advance. It can consume the request budget before fallback. Reject both values. Add matching coverage in apps/web/scripts/marketing-performance.test.mjs.
Proposed fix
const cursor = pageInfo.endCursor;
- if (typeof cursor !== "string") {
+ if (typeof cursor !== "string" || cursor.length === 0 || cursor === after) {
return undefined;
}
after = cursor;π Committable suggestion
βΌοΈ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const cursor = pageInfo.endCursor; | |
| if (typeof cursor !== "string") { | |
| return undefined; | |
| } | |
| after = cursor; | |
| const cursor = pageInfo.endCursor; | |
| if (typeof cursor !== "string" || cursor.length === 0 || cursor === after) { | |
| return undefined; | |
| } | |
| after = cursor; |
π€ Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/web/src/app/api/star-history/route.ts` around lines 113 - 117, Update
the continuation handling around pageInfo.endCursor to return undefined when the
cursor is empty or equals the current after value, while preserving the existing
non-string rejection and assignment for valid advancing cursors. Add matching
test coverage in the marketing performance test for both empty and repeated
cursors.
biggest-littlest
left a comment
There was a problem hiding this comment.
Tree-identical to dev/v1.6. Ready for the GA cut.
Tree-replacement sync bringing main level with dev/v1.6 ahead of the v1.6.0 GA promotion (rc.13 digest, soak clock expires 2026-08-16T04:17:32Z).
Delta since the rc.13 sync (#685) is a single commit: e0a427d (#689), the refreshed demo favicon set, plus its CHANGELOG bullet.
Verified before opening:
git diff origin/main origin/dev/v1.6shows only that delta; squash-merging this branch (exact dev/v1.6 tree) restoresgit diff --quiet origin/main origin/dev/v1.6.GA runbook status:
## [1.6.0]heading; forward-ported to dev/v1.6)release:precheck v1.6.0Changelog
β¨ Added
soak_override_reasonvalidation and audit handling to the release workflow.π§ Changed
dev/v1.6intomainfor v1.6.0 GA promotion.1.6.0-rc.13to1.6.0.?v=2."any maskable".ποΈ Removed
Removed the SVG favicon reference.
Removed REST-specific star-history pagination and headers.
Merge the sync.
Create the GA CHANGELOG rollup PR.
Complete 13 discussion replies.
Dispatch the release cut with the rc.13 candidate tag and digest.
Confirm the rc.13 soak period ends on 2026-08-16 at 04:17:32 UTC.