v1.57.5.0 feat: cross-session decision memory + gbrain dream-stage call graph #388
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: PR Title Sync | |
| # WHY pull_request_target (not pull_request): the default GITHUB_TOKEN is | |
| # READ-ONLY on fork PRs under `pull_request`, so the title-sync backstop could | |
| # never `gh pr edit` a fork/agent PR. `pull_request_target` runs in the base-repo | |
| # context with a write token, which fixes fork coverage. | |
| # | |
| # WHY this is SAFE (pull_request_target is the most dangerous trigger): | |
| # - We check out the BASE repo (no `ref:`), so the only code we execute is | |
| # trusted base-repo infra (bin/gstack-pr-title-rewrite.sh). We NEVER check | |
| # out or run PR-head/fork code. | |
| # - Every attacker-controlled PR field (title, head repo, head sha) arrives via | |
| # `env:` and is referenced as a shell-quoted "$VAR". We NEVER inline a | |
| # `${{ github.event.pull_request.* }}` expression inside the run: script | |
| # (that would execute a crafted title as shell). | |
| # - The PR-head VERSION is read as DATA via the API (raw media type), from the | |
| # head repo at the head sha — never by checking out the head. | |
| # test/pr-title-sync-workflow-safety.test.ts is the static tripwire for all of | |
| # the above and fails CI if any of it regresses. | |
| on: | |
| pull_request_target: | |
| types: [opened, synchronize, edited] | |
| paths: | |
| - 'VERSION' | |
| concurrency: | |
| group: pr-title-sync-${{ github.event.pull_request.number }} | |
| cancel-in-progress: true | |
| jobs: | |
| sync: | |
| name: Sync PR title to VERSION | |
| runs-on: ubicloud-standard-8 | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| if: github.actor != 'github-actions[bot]' | |
| steps: | |
| # Base repo only — trusted infra (the rewrite helper). No PR-head checkout. | |
| - name: Checkout base repo (trusted) | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 1 | |
| - name: Rewrite PR title to match VERSION | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| PR_NUM: ${{ github.event.pull_request.number }} | |
| # Attacker-controlled on fork PRs — env-only, never inlined into run:. | |
| OLD_TITLE: ${{ github.event.pull_request.title }} | |
| BASE_REPO: ${{ github.repository }} | |
| HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| set -euo pipefail | |
| chmod +x ./bin/gstack-pr-title-rewrite.sh | |
| if [ "$HEAD_REPO" = "$BASE_REPO" ]; then IS_FORK=0; else IS_FORK=1; fi | |
| # Read the PR-head VERSION as data (raw bytes), from the head repo at | |
| # the head sha. Guard the assignment itself: under `set -e` a bare | |
| # `VERSION=$(...)` would abort the step before any later [ -z ] check. | |
| if ! VERSION=$(gh api -H "Accept: application/vnd.github.raw" \ | |
| "repos/$HEAD_REPO/contents/VERSION?ref=$HEAD_SHA" 2>/dev/null | tr -d '[:space:]'); then | |
| VERSION="" | |
| fi | |
| if [ -z "$VERSION" ]; then | |
| # Same-repo read failure should never happen — fail loudly so we | |
| # notice. A fork miss (public-contents quirk, private fork) is a | |
| # convenience gap, not a gate — warn and skip so the check stays green. | |
| if [ "$IS_FORK" = "0" ]; then | |
| echo "::error::Could not read VERSION from same-repo PR head ($HEAD_SHA)." | |
| exit 1 | |
| fi | |
| echo "::warning::Could not read VERSION from fork $HEAD_REPO ($HEAD_SHA); skipping title sync." | |
| exit 0 | |
| fi | |
| # The helper rejects a malformed VERSION (exit 2). Same policy: loud for | |
| # same-repo, soft for forks. Never echo the raw (attacker-controlled) | |
| # title — Actions still parses ::workflow-command:: from stdout. | |
| if ! NEW_TITLE=$(./bin/gstack-pr-title-rewrite.sh "$VERSION" "$OLD_TITLE"); then | |
| if [ "$IS_FORK" = "0" ]; then | |
| echo "::error::Could not compute title for VERSION '$VERSION' on PR #$PR_NUM." | |
| exit 1 | |
| fi | |
| echo "::warning::Could not compute title for fork PR #$PR_NUM; skipping." | |
| exit 0 | |
| fi | |
| if [ "$NEW_TITLE" = "$OLD_TITLE" ]; then | |
| echo "PR #$PR_NUM title already correct; no change." | |
| exit 0 | |
| fi | |
| gh pr edit "$PR_NUM" --title "$NEW_TITLE" | |
| echo "PR #$PR_NUM title synced to VERSION." |