diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 6ce50f22..a58a41b5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,12 +1,7 @@ # Code owners for ghfind. # -# Every pull request targeting a protected branch (main) requires an approval -# from one of the owners listed here, because the branch ruleset enables -# "Require review from Code Owners" with 1 required approval. -# -# GitHub never counts a pull request author's own approval, so listing all -# three core maintainers means every PR has to be cross-reviewed by one of the -# other two: whoever opens it cannot be the one who unblocks it. +# Pull request reviews are optional; required status checks still gate merges. +# Code owners identify the maintainers and remain available for requested reviews. # # Syntax: <@owner ...> (last matching line wins) diff --git a/.github/workflows/deploy-apps-production.yml b/.github/workflows/deploy-apps-production.yml index bb760057..e7378a41 100644 --- a/.github/workflows/deploy-apps-production.yml +++ b/.github/workflows/deploy-apps-production.yml @@ -22,7 +22,7 @@ permissions: jobs: deploy: if: >- - github.repository == 'hikariming/ghfind' && + github.repository == 'FindAny/ghfind' && ((github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success') || (github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main')) runs-on: ubuntu-latest diff --git a/.github/workflows/deploy-cf-dev.yml b/.github/workflows/deploy-cf-dev.yml index 83940f5d..c79e926e 100644 --- a/.github/workflows/deploy-cf-dev.yml +++ b/.github/workflows/deploy-cf-dev.yml @@ -29,13 +29,13 @@ concurrency: jobs: deploy: name: Build and deploy to Cloudflare Workers (dev) - if: ${{ github.repository == 'hikariming/ghfind' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'dev' && github.event.workflow_run.repository.full_name == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'dev' && github.event.workflow_run.repository.full_name == 'FindAny/ghfind' }} runs-on: ubuntu-latest timeout-minutes: 30 env: CI: "true" NEXT_TELEMETRY_DISABLED: "1" - EXPECTED_REPOSITORY: hikariming/ghfind + EXPECTED_REPOSITORY: FindAny/ghfind EXPECTED_ACCOUNT_ID: 8f19bebe359e4ec1a24c68c5f49c1584 RELEASE_SHA: ${{ github.event.workflow_run.head_sha }} CF_VERSION_TAG: dev-${{ github.event.workflow_run.head_sha }} diff --git a/.github/workflows/deploy-cf-production.yml b/.github/workflows/deploy-cf-production.yml index 2944fc74..373171cd 100644 --- a/.github/workflows/deploy-cf-production.yml +++ b/.github/workflows/deploy-cf-production.yml @@ -20,7 +20,7 @@ jobs: outputs: current: ${{ steps.authorization.outputs.current }} name: Require exact main CI and complete dual-profile E2E - if: ${{ github.repository == 'hikariming/ghfind' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.repository.full_name == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.repository.full_name == 'FindAny/ghfind' }} runs-on: ubuntu-latest timeout-minutes: 5 steps: @@ -304,7 +304,7 @@ jobs: deploy-bot: name: Deploy bot after its legacy SCORE backend needs: [deploy] - if: ${{ github.repository == 'hikariming/ghfind' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.repository.full_name == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push' && github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.repository.full_name == 'FindAny/ghfind' }} environment: Production concurrency: group: ghfind-bot-production diff --git a/.github/workflows/feed-capacity.yml b/.github/workflows/feed-capacity.yml index 202668f9..1689e3aa 100644 --- a/.github/workflows/feed-capacity.yml +++ b/.github/workflows/feed-capacity.yml @@ -19,7 +19,7 @@ concurrency: jobs: capacity: name: Synthetic 10 RPS and deletion recovery - if: ${{ github.repository == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' }} runs-on: ubuntu-24.04 timeout-minutes: 30 env: @@ -60,9 +60,9 @@ jobs: [[ "$RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]] test "$(git rev-parse HEAD)" = "$RELEASE_SHA" git merge-base --is-ancestor "$RELEASE_SHA" origin/main - gh api --method GET repos/hikariming/ghfind/actions/workflows/ci.yml/runs \ + gh api --method GET repos/FindAny/ghfind/actions/workflows/ci.yml/runs \ -f head_sha="$RELEASE_SHA" -f status=success -f per_page=20 \ - --jq '.workflow_runs | any(.head_repository.full_name == "hikariming/ghfind" and .conclusion == "success")' | jq -e '. == true' + --jq '.workflow_runs | any(.head_repository.full_name == "FindAny/ghfind" and .conclusion == "success")' | jq -e '. == true' - uses: actions/setup-go@v5 with: go-version-file: go.mod diff --git a/.github/workflows/feed-catalog-reconcile.yml b/.github/workflows/feed-catalog-reconcile.yml index 91bfcf5d..9dc78369 100644 --- a/.github/workflows/feed-catalog-reconcile.yml +++ b/.github/workflows/feed-catalog-reconcile.yml @@ -45,7 +45,7 @@ concurrency: jobs: reconcile: name: Bounded production catalog reconciliation - if: ${{ github.repository == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' }} runs-on: ubuntu-latest timeout-minutes: 15 env: @@ -81,7 +81,7 @@ jobs: - name: Validate bounded operator inputs run: | set -euo pipefail - test "$GITHUB_REPOSITORY" = "hikariming/ghfind" + test "$GITHUB_REPOSITORY" = "FindAny/ghfind" test "$CLOUDFLARE_ACCOUNT_ID" = "$EXPECTED_ACCOUNT_ID" test -n "$FEED_ADMIN_SECRET" case "$BOOTSTRAP_CREDENTIAL" in true|false) ;; *) echo "bootstrap_credential must be boolean" >&2; exit 1 ;; esac diff --git a/.github/workflows/feed-diagnose.yml b/.github/workflows/feed-diagnose.yml index 7c54e699..8d308059 100644 --- a/.github/workflows/feed-diagnose.yml +++ b/.github/workflows/feed-diagnose.yml @@ -19,7 +19,7 @@ concurrency: jobs: diagnose: name: Bounded synthetic query diagnosis - if: ${{ github.repository == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' }} runs-on: ubuntu-24.04 # Bounded preflight/execution steps leave time for evidence upload and cleanup. timeout-minutes: 25 @@ -61,9 +61,9 @@ jobs: [[ "$RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]] test "$(git rev-parse HEAD)" = "$RELEASE_SHA" git merge-base --is-ancestor "$RELEASE_SHA" origin/main - gh api --method GET repos/hikariming/ghfind/actions/workflows/ci.yml/runs \ + gh api --method GET repos/FindAny/ghfind/actions/workflows/ci.yml/runs \ -f head_sha="$RELEASE_SHA" -f status=success -f per_page=20 \ - --jq '.workflow_runs | any(.head_repository.full_name == "hikariming/ghfind" and .conclusion == "success")' | jq -e '. == true' + --jq '.workflow_runs | any(.head_repository.full_name == "FindAny/ghfind" and .conclusion == "success")' | jq -e '. == true' - uses: actions/setup-go@v5 timeout-minutes: 3 with: diff --git a/.github/workflows/feed-governance.yml b/.github/workflows/feed-governance.yml index cc5c7a94..bf9a136d 100644 --- a/.github/workflows/feed-governance.yml +++ b/.github/workflows/feed-governance.yml @@ -28,7 +28,7 @@ concurrency: jobs: validate: - if: ${{ github.repository == 'hikariming/ghfind' && github.ref == 'refs/heads/main' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest timeout-minutes: 5 outputs: @@ -52,14 +52,14 @@ jobs: [[ "$RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]] test "$(git rev-parse HEAD)" = "$RELEASE_SHA" git merge-base --is-ancestor "$RELEASE_SHA" origin/main - gh api --method GET repos/hikariming/ghfind/actions/workflows/ci.yml/runs \ + gh api --method GET repos/FindAny/ghfind/actions/workflows/ci.yml/runs \ -f head_sha="$RELEASE_SHA" -f status=success -f per_page=20 \ - --jq '.workflow_runs | any(.head_repository.full_name == "hikariming/ghfind" and .conclusion == "success")' | jq -e '. == true' + --jq '.workflow_runs | any(.head_repository.full_name == "FindAny/ghfind" and .conclusion == "success")' | jq -e '. == true' echo "sha=$RELEASE_SHA" >> "$GITHUB_OUTPUT" - name: Require an actually protected operations environment run: | set -euo pipefail - gh api repos/hikariming/ghfind/environments/Feed%20staging%20operations > "$RUNNER_TEMP/feed-governance-environment.json" + gh api repos/FindAny/ghfind/environments/Feed%20staging%20operations > "$RUNNER_TEMP/feed-governance-environment.json" node --input-type=module - <<'JS' import {readFileSync} from 'node:fs'; const env=JSON.parse(readFileSync(`${process.env.RUNNER_TEMP}/feed-governance-environment.json`,'utf8')); diff --git a/.github/workflows/feed-operator.yml b/.github/workflows/feed-operator.yml index e7c9b8e6..408e9e85 100644 --- a/.github/workflows/feed-operator.yml +++ b/.github/workflows/feed-operator.yml @@ -41,7 +41,7 @@ concurrency: jobs: validate: - if: ${{ github.repository == 'hikariming/ghfind' && github.ref == 'refs/heads/main' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest timeout-minutes: 5 outputs: @@ -65,14 +65,14 @@ jobs: [[ "$RELEASE_SHA" =~ ^[0-9a-f]{40}$ ]] test "$(git rev-parse HEAD)" = "$RELEASE_SHA" git merge-base --is-ancestor "$RELEASE_SHA" origin/main - gh api --method GET repos/hikariming/ghfind/actions/workflows/ci.yml/runs \ + gh api --method GET repos/FindAny/ghfind/actions/workflows/ci.yml/runs \ -f head_sha="$RELEASE_SHA" -f status=success -f per_page=20 \ - --jq '.workflow_runs | any(.head_repository.full_name == "hikariming/ghfind" and .conclusion == "success")' | jq -e '. == true' + --jq '.workflow_runs | any(.head_repository.full_name == "FindAny/ghfind" and .conclusion == "success")' | jq -e '. == true' echo "sha=$RELEASE_SHA" >> "$GITHUB_OUTPUT" - name: Require an actually protected operations environment run: | set -euo pipefail - gh api repos/hikariming/ghfind/environments/Feed%20staging%20operations > "$RUNNER_TEMP/feed-operator-environment.json" + gh api repos/FindAny/ghfind/environments/Feed%20staging%20operations > "$RUNNER_TEMP/feed-operator-environment.json" node --input-type=module - <<'JS' import {readFileSync} from 'node:fs'; const env=JSON.parse(readFileSync(`${process.env.RUNNER_TEMP}/feed-operator-environment.json`,'utf8')); diff --git a/.github/workflows/feed-production-pause.yml b/.github/workflows/feed-production-pause.yml index 544e4f38..c3b28db1 100644 --- a/.github/workflows/feed-production-pause.yml +++ b/.github/workflows/feed-production-pause.yml @@ -24,7 +24,7 @@ concurrency: jobs: protection: name: Verify manual main context and existing production protections - if: ${{ github.repository == 'hikariming/ghfind' && github.ref == 'refs/heads/main' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest timeout-minutes: 5 steps: @@ -54,7 +54,7 @@ jobs: pause: name: Verify exact candidate, pause Web and read back actual containment needs: [protection] - if: ${{ github.repository == 'hikariming/ghfind' && github.ref == 'refs/heads/main' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.ref == 'refs/heads/main' }} environment: Production runs-on: ubuntu-latest timeout-minutes: 12 diff --git a/.github/workflows/feed-production-projection-replay.yml b/.github/workflows/feed-production-projection-replay.yml index 6be609fb..ac65e9d2 100644 --- a/.github/workflows/feed-production-projection-replay.yml +++ b/.github/workflows/feed-production-projection-replay.yml @@ -14,7 +14,7 @@ concurrency: cancel-in-progress: false jobs: protection: - if: ${{ github.repository == 'hikariming/ghfind' && github.ref == 'refs/heads/main' }} + if: ${{ github.repository == 'FindAny/ghfind' && github.ref == 'refs/heads/main' }} runs-on: ubuntu-latest timeout-minutes: 5 steps: diff --git a/.github/workflows/feed-staging.yml b/.github/workflows/feed-staging.yml index f17f09e6..00657a8d 100644 --- a/.github/workflows/feed-staging.yml +++ b/.github/workflows/feed-staging.yml @@ -32,7 +32,7 @@ concurrency: jobs: protection: name: Verify actual repository release protections - if: ${{ github.repository == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' }} runs-on: ubuntu-latest timeout-minutes: 5 # No environment reference: GitHub must not silently create an unprotected @@ -63,7 +63,7 @@ jobs: deploy: name: Validate and deploy isolated Feed staging needs: [protection] - if: ${{ github.repository == 'hikariming/ghfind' }} + if: ${{ github.repository == 'FindAny/ghfind' }} environment: Feed staging runs-on: ubuntu-latest timeout-minutes: 60 diff --git a/.github/workflows/repair-prod-web.yml b/.github/workflows/repair-prod-web.yml index 022b56aa..af151479 100644 --- a/.github/workflows/repair-prod-web.yml +++ b/.github/workflows/repair-prod-web.yml @@ -28,7 +28,7 @@ concurrency: jobs: repair: name: Deploy paused web and populate incremental cache - if: ${{ github.repository == 'hikariming/ghfind' && github.ref == 'refs/heads/main' && (github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'failure') }} + if: ${{ github.repository == 'FindAny/ghfind' && github.ref == 'refs/heads/main' && (github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'failure') }} environment: Production runs-on: ubuntu-latest timeout-minutes: 30 diff --git a/docs/operations/cloudflare-deployment-runbook.md b/docs/operations/cloudflare-deployment-runbook.md index 782ccdf2..fa4d7f42 100644 --- a/docs/operations/cloudflare-deployment-runbook.md +++ b/docs/operations/cloudflare-deployment-runbook.md @@ -37,7 +37,7 @@ production Workers, D1, R2, or Secrets. ## Canonical GitHub source and CI ownership -`hikariming/ghfind` is the only canonical production repository. Production is +`FindAny/ghfind` is the only canonical production repository. Production is not connected to a personal fork or to a Cloudflare dashboard Git integration; the binding is enforced by the upstream workflow itself: @@ -45,7 +45,7 @@ the binding is enforced by the upstream workflow itself: upstream/main commit -> CI push run succeeds -> Deploy production (Cloudflare) workflow_run on that exact SHA - -> provenance guard confirms hikariming/ghfind + main + -> provenance guard confirms FindAny/ghfind + main -> deploy ghfind in Beiming's account ``` diff --git a/docs/operations/feed-github-protection.md b/docs/operations/feed-github-protection.md index a4be2ae1..47c627c5 100644 --- a/docs/operations/feed-github-protection.md +++ b/docs/operations/feed-github-protection.md @@ -4,16 +4,16 @@ 2026-09-09 用户更新:保留仓库的 squash 选项,本次 PR 使用 rebase 合入。是否允许其他 PR 使用 squash 不属于部署门禁;脚本不修改已有合并方式。准确 SHA CI、真实 CF E2E、required checks 和环境保护要求继续有效。 -目标固定为 `hikariming/ghfind`、ruleset `18206694`(`Protect main`)。当前账号具有 PR bypass 能力,但远端环境写入已返回 `403 Must have admin rights to Repository`;这不等于拥有仓库配置权限。2026-09-09 的只读核验也未返回 `bypass_actors`,该字段因缺少 ruleset 写权限而被 GitHub 隐藏,不能解释为没有 bypass 配置。[GitHub ruleset API](https://docs.github.com/en/rest/repos/rules#get-a-repository-ruleset) +目标固定为 `FindAny/ghfind`、ruleset `18206694`(`Protect main`)。当前账号具有 PR bypass 能力,但远端环境写入已返回 `403 Must have admin rights to Repository`;这不等于拥有仓库配置权限。2026-09-09 的只读核验也未返回 `bypass_actors`,该字段因缺少 ruleset 写权限而被 GitHub 隐藏,不能解释为没有 bypass 配置。[GitHub ruleset API](https://docs.github.com/en/rest/repos/rules#get-a-repository-ruleset) ## 预期变化 | 配置 | 必须达到的状态 | | --- | --- | -| Protect main | 保留原有分支范围、active 状态、所有合并方式、review 条件、其他 rules 和 bypass actors;确认本次 PR 可以使用 `rebase` | +| Protect main | 保留原有分支范围、active 状态、所有合并方式、其他 rules 和 bypass actors;必须开 PR,但 required approvals 为 `0`,作者可在 checks 通过后自行合并;确认本次 PR 可以使用 `rebase` | | Required checks | `Application checks`、`Feed storage contracts`、`Feed runtime builds`、`Complete local Feed E2E`;来源固定为已核验的 GitHub Actions integration `15368`;strict 模式 | | Feed staging | 自定义 branch policy,仅 `main` 和 `codex/feed-*`;不允许 tag;不新增人工等待 | -| Feed staging operations | 仅 `main`;新增环境时 reviewer 为仓库 owner `hikariming`(User ID `23065064`) | +| Feed staging operations | 仅 `main`;新增环境时 reviewer 为个人管理员 `hikariming`(User ID `23065064`);仓库 owner 为 `FindAny` 组织 | | Production | 仅 `main`;不新增 reviewer 或 wait timer,正常发布仍由 CI→staging→Production 自动推进 | 脚本检查本地 CI 配置中四个 job 都会在 PR 上报告结果,不选择只在 push 上执行的聚合任务作为 required check。完整本地 E2E 通过后才能推候选分支;准确 HEAD CI、PR merge 兼容性及真实 CF E2E 仍必须通过后才能合入。配置脚本不能替代这些验收。 @@ -63,6 +63,6 @@ node scripts/feed-github-protection.mjs --verify-existing "$RUNNER_TEMP/feed-git 只有该 job 成功,声明 `Feed staging` 环境的部署 job 才能运行。这样 GitHub 不会因为 workflow 提及了一个缺失环境,就先自动创建没有保护的空环境。 -该模式只执行 GET,不要求管理员身份,也不要求看到被隐藏的 bypass actors。它核验 active 的固定 ruleset、原有 PR review 约束、允许本次 PR 使用 rebase、来源固定的四个 strict required checks、三个环境的精确 branch allowlist,以及 operations 的 owner reviewer。仓库可以同时允许 squash 和 merge commit。既有更严格的 review、wait timer、额外 status checks 和保护规则不会被改写。 +该模式只执行 GET,不要求管理员身份,也不要求看到被隐藏的 bypass actors。它核验 active 的固定 ruleset、必须开 PR 且 required approvals 为 `0`、允许本次 PR 使用 rebase、来源固定的四个 strict required checks、三个环境的精确 branch allowlist,以及 operations 的 owner reviewer。仓库可以同时允许 squash 和 merge commit。既有 reviewer、wait timer、额外 status checks 和保护规则不会被改写;审核人数或其他固定策略漂移会失败。 成功输出 `ghfind-github-protection-verification-v1` 证据,包含核验时间、状态 hash、checks 和环境策略;不包含 bypass 列表。任何缺失、策略不符或 403 等读取错误都会失败,且不生成可用的通过证据。`--verify-existing` 不能与 `--apply`、计划输入或其他输出选项混用。 diff --git a/docs/operations/feed-platform-prerequisites.md b/docs/operations/feed-platform-prerequisites.md index 11a32797..a86c1397 100644 --- a/docs/operations/feed-platform-prerequisites.md +++ b/docs/operations/feed-platform-prerequisites.md @@ -48,11 +48,11 @@ Read back configuration after administrator changes; these commands do not retrieve secret values: ```sh -gh api repos/hikariming/ghfind/rulesets/18206694 -gh api repos/hikariming/ghfind/environments --jq \ +gh api repos/FindAny/ghfind/rulesets/18206694 +gh api repos/FindAny/ghfind/environments --jq \ '{environments:[.environments[]|{name,protection_rules,deployment_branch_policy}]}' -gh secret list --repo hikariming/ghfind -gh run list --repo hikariming/ghfind --workflow ci.yml --limit 5 +gh secret list --repo FindAny/ghfind +gh run list --repo FindAny/ghfind --workflow ci.yml --limit 5 ``` Save the resulting settings, check-run URL and tested rejection cases in the diff --git a/scripts/check-cf-release-workflow.mts b/scripts/check-cf-release-workflow.mts index 804336a9..49450560 100644 --- a/scripts/check-cf-release-workflow.mts +++ b/scripts/check-cf-release-workflow.mts @@ -21,9 +21,9 @@ const deployJob = jobBody(workflow, "deploy"); const botJob = jobBody(workflow, "deploy-bot"); for (const fragment of ['needs: [deploy]', 'environment: Production', 'group: ghfind-bot-production', 'cancel-in-progress: false', - "github.repository == 'hikariming/ghfind'", "github.event.workflow_run.conclusion == 'success'", + "github.repository == 'FindAny/ghfind'", "github.event.workflow_run.conclusion == 'success'", "github.event.workflow_run.event == 'push'", "github.event.workflow_run.head_branch == 'main'", - "github.event.workflow_run.repository.full_name == 'hikariming/ghfind'", + "github.event.workflow_run.repository.full_name == 'FindAny/ghfind'", 'ref: ${{ github.event.workflow_run.head_sha }}', 'persist-credentials: false', 'RELEASE_SHA: ${{ github.event.workflow_run.head_sha }}', 'test "$(git rev-parse HEAD)" = "$RELEASE_SHA"', @@ -40,7 +40,7 @@ for (let i = 1; i < botOrder.length; i++) for (const fragment of ['workflow_run:', 'workflows: ["CI"]', 'types: [completed]', 'branches: [main]', 'cancel-in-progress: false']) { if (!workflow.includes(fragment)) throw new Error(`Production trigger missing ${fragment}`); } -for (const fragment of ["github.repository == 'hikariming/ghfind'", "github.event.workflow_run.conclusion == 'success'", "github.event.workflow_run.event == 'push'", "github.event.workflow_run.head_branch == 'main'", "github.event.workflow_run.repository.full_name == 'hikariming/ghfind'", 'node scripts/feed-ci-evidence.mjs verify-ci-remote', 'node scripts/feed-github-protection.mjs --verify-existing']) { +for (const fragment of ["github.repository == 'FindAny/ghfind'", "github.event.workflow_run.conclusion == 'success'", "github.event.workflow_run.event == 'push'", "github.event.workflow_run.head_branch == 'main'", "github.event.workflow_run.repository.full_name == 'FindAny/ghfind'", 'node scripts/feed-ci-evidence.mjs verify-ci-remote', 'node scripts/feed-github-protection.mjs --verify-existing']) { if (!authorization.includes(fragment)) throw new Error(`Authorization missing ${fragment}`); } for (const job of [authorization,deployJob]) for (const fragment of ['ref: ${{ github.event.workflow_run.head_sha }}','persist-credentials: false']) { @@ -132,7 +132,7 @@ const requiredReconcileFragments = [ "max_pages:", "updated_at:", "repo_key:", - "github.repository == 'hikariming/ghfind'", + "github.repository == 'FindAny/ghfind'", "FEED_ADMIN_SECRET: ${{ secrets.FEED_ADMIN_SECRET }}", "CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }}", "wrangler secret put FEED_ADMIN_SECRET --env production", diff --git a/scripts/feed-ci-evidence.mjs b/scripts/feed-ci-evidence.mjs index 8f2152ca..54a85350 100644 --- a/scripts/feed-ci-evidence.mjs +++ b/scripts/feed-ci-evidence.mjs @@ -8,7 +8,7 @@ import { tmpdir } from 'node:os'; import { dirname, join, resolve } from 'node:path'; import { pathToFileURL } from 'node:url'; -export const repository = 'hikariming/ghfind'; +export const repository = 'FindAny/ghfind'; export const requiredJobs = Object.freeze({ verify: 'Application checks', 'feed-contracts': 'Feed storage contracts', 'feed-runtime': 'Feed runtime builds', 'feed-e2e': 'Complete local Feed E2E' }); export const evidenceVersion = 'ghfind.feed-ci.v1'; const shaPattern = /^[a-f0-9]{40}$/; diff --git a/scripts/feed-ci-evidence.test.mjs b/scripts/feed-ci-evidence.test.mjs index 3e7a1227..a87fb09e 100644 --- a/scripts/feed-ci-evidence.test.mjs +++ b/scripts/feed-ci-evidence.test.mjs @@ -8,7 +8,7 @@ import { join } from 'node:path'; import { aggregateEvidence, artifactName, contextFromEnvironment, eligibleBranch, localMilestones, makeJobReceipt, requiredJobs, validateLocalE2E, validateRemoteEvidence, verifyRemote } from './feed-ci-evidence.mjs'; const sha = 'a'.repeat(40), tree = 'b'.repeat(40); -const context = { repository: 'hikariming/ghfind', event: 'push', branch: 'codex/feed-test', sourceSha: sha, checkoutSha: sha, treeSha: tree, runId: '123', runAttempt: '2' }; +const context = { repository: 'FindAny/ghfind', event: 'push', branch: 'codex/feed-test', sourceSha: sha, checkoutSha: sha, treeSha: tree, runId: '123', runAttempt: '2' }; const createdAt = '2026-09-09T03:00:00Z'; function local(c = context) { return { format: 'ghfind-complete-local-e2e-v1', sourceSha: c.checkoutSha, sourceTree: c.treeSha, status: 'passed', cleanupSuccessful: true, externalProviders: 'local-fixture-transports', realOAuth: false, profiles: Object.fromEntries(['cf_d1_r2', 'postgres'].map(profile => [profile, { status: 'passed', milestones: Object.fromEntries(localMilestones.map(name => [name, true])), report: `${profile}/journey.json` }])) }; diff --git a/scripts/feed-e2e-remote.mjs b/scripts/feed-e2e-remote.mjs index 405d999d..37701fe1 100644 --- a/scripts/feed-e2e-remote.mjs +++ b/scripts/feed-e2e-remote.mjs @@ -277,7 +277,7 @@ async function main() { const { validateWebManifest } = await import("./feed-platform-web.mjs"); const m = validateTarget(validateWebManifest(JSON.parse(await readFile(values.manifest, "utf8")))); if (!values.execute) { console.log(JSON.stringify({ mode: "dry-run", sourceSha, worker: WEB, profiles: ["cf_d1_r2"], maxAssessments: 1, maxRequests: 450, realOAuthRequired: true })); return; } - check(process.env.GITHUB_ACTIONS === "true" && process.env.GITHUB_REPOSITORY === "hikariming/ghfind", "github_actions_required"); + check(process.env.GITHUB_ACTIONS === "true" && process.env.GITHUB_REPOSITORY === "FindAny/ghfind", "github_actions_required"); check(execFileSync("git", ["rev-parse", "HEAD"], { encoding: "utf8" }).trim() === sourceSha, "checkout_mismatch"); const sourceTree = execFileSync("git", ["rev-parse", "HEAD^{tree}"], { encoding: "utf8" }).trim(); await mkdir(values.directory, { mode: 0o700 }); diff --git a/scripts/feed-github-protection.mjs b/scripts/feed-github-protection.mjs index afb3d8f8..d9208b1d 100644 --- a/scripts/feed-github-protection.mjs +++ b/scripts/feed-github-protection.mjs @@ -8,7 +8,7 @@ import { resolve } from 'node:path'; import { pathToFileURL } from 'node:url'; import { requiredJobs } from './feed-ci-evidence.mjs'; -export const repository = 'hikariming/ghfind'; +export const repository = 'FindAny/ghfind'; export const rulesetId = 18206694; export const actionsIntegrationId = 15368; export const owner = { login: 'hikariming', id: 23065064, type: 'User' }; @@ -43,7 +43,7 @@ function environmentConfiguration(value, policies) { export async function captureState(request = githubRequest) { const metadata = await request('GET', base); - assert(metadata.full_name === repository && metadata.owner?.login === owner.login && metadata.owner?.type === 'User' && metadata.default_branch === 'main', 'Repository ownership/default branch drift'); + assert(metadata.full_name === repository && metadata.owner?.login === 'FindAny' && metadata.owner?.type === 'Organization' && metadata.default_branch === 'main', 'Repository ownership/default branch drift'); const account = await request('GET', `/users/${owner.login}`); assert(account.id === owner.id && account.login === owner.login && account.type === owner.type, 'Governance reviewer identity changed'); const ruleset = await request('GET', `${base}/rulesets/${rulesetId}`); @@ -89,7 +89,7 @@ export function buildPlan(state, workflow) { assert(desiredRuleset.enforcement === 'active', 'Protect main enforcement drift requires manual review'); assert(desiredRuleset.conditions?.ref_name?.exclude?.length === 0 && (equal(desiredRuleset.conditions.ref_name.include, ['~DEFAULT_BRANCH']) || equal(desiredRuleset.conditions.ref_name.include, ['refs/heads/main'])), 'Protect main branch scope drift requires manual review'); const pullRequests = desiredRuleset.rules.filter(rule => rule.type === 'pull_request'); - assert(pullRequests.length === 1 && pullRequests[0].parameters.required_approving_review_count >= 1, 'Existing mandatory PR review rule absent or ambiguous'); + assert(pullRequests.length === 1 && pullRequests[0].parameters.required_approving_review_count === 0, 'Existing mandatory PR review rule absent or ambiguous'); const methods = pullRequests[0].parameters.allowed_merge_methods; assert(Array.isArray(methods) && methods.includes('rebase'), 'The requested PR rebase merge must be allowed'); // This delivery uses rebase; preserve the repository's other merge options. @@ -145,7 +145,7 @@ export function verifyExistingState(state, checkedAt = new Date().toISOString()) const reviews = rule.rules.filter(item => item.type === 'pull_request'); assert(reviews.length === 1, 'Mandatory PR review rule missing or ambiguous', 'PROTECTION_NOT_ENFORCED'); const review = reviews[0].parameters; - assert(Number.isSafeInteger(review.required_approving_review_count) && review.required_approving_review_count >= 1, 'At least one independent PR approval is required', 'PROTECTION_NOT_ENFORCED'); + assert(Number.isSafeInteger(review.required_approving_review_count) && review.required_approving_review_count === 0, 'PR review rule must require zero approvals', 'PROTECTION_NOT_ENFORCED'); for (const field of ['dismiss_stale_reviews_on_push', 'require_code_owner_review', 'require_last_push_approval', 'require_extra_approval_for_unattributed_changes']) assert(review[field] === true, `Existing PR protection ${field} was weakened`, 'PROTECTION_NOT_ENFORCED'); assert(Array.isArray(review.allowed_merge_methods) && review.allowed_merge_methods.includes('rebase'), 'The requested PR rebase merge must be allowed', 'PROTECTION_NOT_ENFORCED'); const statuses = rule.rules.filter(item => item.type === 'required_status_checks'); diff --git a/scripts/feed-github-protection.test.mjs b/scripts/feed-github-protection.test.mjs index 6d781301..a221d45d 100644 --- a/scripts/feed-github-protection.test.mjs +++ b/scripts/feed-github-protection.test.mjs @@ -8,7 +8,7 @@ const clone = value => JSON.parse(JSON.stringify(value)); function server() { const data = { admin: true, - ruleset: { id: rulesetId, name: 'Protect main', target: 'branch', source_type: 'Repository', source: repository, enforcement: 'active', bypass_actors: [{ actor_id: 5, actor_type: 'RepositoryRole', bypass_mode: 'always' }], conditions: { ref_name: { include: ['~DEFAULT_BRANCH'], exclude: [] } }, rules: [{ type: 'deletion' }, { type: 'non_fast_forward' }, { type: 'pull_request', parameters: { required_approving_review_count: 1, dismiss_stale_reviews_on_push: true, require_code_owner_review: true, require_last_push_approval: true, required_review_thread_resolution: false, require_extra_approval_for_unattributed_changes: true, required_reviewers: [], allowed_merge_methods: ['merge', 'squash', 'rebase'] } }] }, + ruleset: { id: rulesetId, name: 'Protect main', target: 'branch', source_type: 'Repository', source: repository, enforcement: 'active', bypass_actors: [{ actor_id: 5, actor_type: 'RepositoryRole', bypass_mode: 'always' }], conditions: { ref_name: { include: ['~DEFAULT_BRANCH'], exclude: [] } }, rules: [{ type: 'deletion' }, { type: 'non_fast_forward' }, { type: 'pull_request', parameters: { required_approving_review_count: 0, dismiss_stale_reviews_on_push: true, require_code_owner_review: true, require_last_push_approval: true, required_review_thread_resolution: false, require_extra_approval_for_unattributed_changes: true, required_reviewers: [], allowed_merge_methods: ['merge', 'squash', 'rebase'] } }] }, environments: { Production: { name: 'Production', can_admins_bypass: true, protection_rules: [], deployment_branch_policy: null } }, policies: {}, writes: [], reads: [], failNextWrite: null, }; @@ -18,7 +18,7 @@ function server() { if (data.failNextWrite?.(method, path)) { const error = new Error('Must have admin rights to Repository'); error.code = 'ADMIN_REQUIRED'; throw error; } data.writes.push({ method, path, body: clone(body) }); } - if (path === `/repos/${repository}`) return { full_name: repository, default_branch: 'main', owner, permissions: { admin: data.admin } }; + if (path === `/repos/${repository}`) return { full_name: repository, default_branch: 'main', owner: { login: 'FindAny', id: 352470658, type: 'Organization' }, permissions: { admin: data.admin } }; if (path === `/users/${owner.login}`) return owner; if (path.endsWith(`/rulesets/${rulesetId}`)) { if (method === 'PUT') Object.assign(data.ruleset, clone(body)); return clone(data.ruleset); } if (path.includes('/environments?')) return { total_count: Object.keys(data.environments).length, environments: Object.values(data.environments).map(clone) }; @@ -249,6 +249,7 @@ test('verify-existing rejects inactive rules, weakened reviews, broad branches a for (const mutate of [ state => { state.ruleset.enforcement = 'disabled'; }, state => { state.ruleset.rules.find(rule => rule.type === 'pull_request').parameters.require_last_push_approval = false; }, + state => { state.ruleset.rules.find(rule => rule.type === 'pull_request').parameters.required_approving_review_count = 1; }, state => { state.ruleset.rules.find(rule => rule.type === 'required_status_checks').parameters.strict_required_status_checks_policy = false; }, state => { state.ruleset.rules.find(rule => rule.type === 'required_status_checks').parameters.required_status_checks[0].integration_id = 999; }, state => { state.environments['Feed staging'].branch_policies.push({ name: '*', type: 'branch' }); }, @@ -259,7 +260,6 @@ test('verify-existing rejects inactive rules, weakened reviews, broad branches a test('verify-existing preserves additional stricter rules and Production approval without needing administrator access', async () => { const { data, request } = await configuredServer(); - data.ruleset.rules.find(rule => rule.type === 'pull_request').parameters.required_approving_review_count = 2; data.ruleset.rules.find(rule => rule.type === 'pull_request').parameters.required_review_thread_resolution = true; data.ruleset.rules.find(rule => rule.type === 'required_status_checks').parameters.required_status_checks.push({ context: 'Security audit', integration_id: 99 }); data.environments.Production.can_admins_bypass = false; diff --git a/scripts/feed-operator.mjs b/scripts/feed-operator.mjs index b27a631a..c0e9f384 100644 --- a/scripts/feed-operator.mjs +++ b/scripts/feed-operator.mjs @@ -27,7 +27,7 @@ function ensure(value, code) { } export function runCommandId(repository, runId, kind, id) { ensure( - repository === "hikariming/ghfind" && /^\d+$/.test(runId), + repository === "FindAny/ghfind" && /^\d+$/.test(runId), "invalid_action_identity", ); const hash = createHash("sha256") diff --git a/scripts/feed-operator.test.mjs b/scripts/feed-operator.test.mjs index 8e617935..c7412d8c 100644 --- a/scripts/feed-operator.test.mjs +++ b/scripts/feed-operator.test.mjs @@ -230,12 +230,12 @@ test("a status action does no writes and returns only whitelisted operational me }); test("command UUID is stable across reruns and distinct across jobs and invalid bodies reject", () => { assert.equal( - runCommandId("hikariming/ghfind", "123", "deletion", "del:1"), - runCommandId("hikariming/ghfind", "123", "deletion", "del:1"), + runCommandId("FindAny/ghfind", "123", "deletion", "del:1"), + runCommandId("FindAny/ghfind", "123", "deletion", "del:1"), ); assert.notEqual( - runCommandId("hikariming/ghfind", "123", "deletion", "del:1"), - runCommandId("hikariming/ghfind", "124", "deletion", "del:1"), + runCommandId("FindAny/ghfind", "123", "deletion", "del:1"), + runCommandId("FindAny/ghfind", "124", "deletion", "del:1"), ); const f = scenario(); for (const command of [ diff --git a/scripts/feed-platform-production.test.mjs b/scripts/feed-platform-production.test.mjs index 402984a2..3d9238fb 100644 --- a/scripts/feed-platform-production.test.mjs +++ b/scripts/feed-platform-production.test.mjs @@ -38,7 +38,7 @@ const m = { ...template(), billing: { confirmed: true, - evidence: "https://github.com/hikariming/ghfind/commit/" + "a".repeat(40), + evidence: "https://github.com/FindAny/ghfind/commit/" + "a".repeat(40), maximumMonthlyUSD: 100, projectedMonthlyUSD: 75, }, @@ -1768,10 +1768,10 @@ test("documented script_name and pinned Wrangler legacy script/service agree wit const productionActions = { GITHUB_ACTIONS: "true", - GITHUB_REPOSITORY: "hikariming/ghfind", + GITHUB_REPOSITORY: "FindAny/ghfind", GITHUB_REF: "refs/heads/main", GITHUB_WORKFLOW_REF: - "hikariming/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main", + "FindAny/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main", GITHUB_RUN_ID: "123", GITHUB_RUN_ATTEMPT: "1", CLOUDFLARE_API_TOKEN: "synthetic-cf-token-".repeat(3), @@ -1875,7 +1875,7 @@ test("consumer detach is production Actions-only before any API request", async { GITHUB_REF: "refs/heads/dev" }, { GITHUB_WORKFLOW_REF: - "hikariming/ghfind/.github/workflows/ci.yml@refs/heads/main", + "FindAny/ghfind/.github/workflows/ci.yml@refs/heads/main", }, { CLOUDFLARE_API_TOKEN: "" }, ]) { diff --git a/scripts/feed-platform-staging-evidence.mjs b/scripts/feed-platform-staging-evidence.mjs index e591f644..592c2257 100644 --- a/scripts/feed-platform-staging-evidence.mjs +++ b/scripts/feed-platform-staging-evidence.mjs @@ -27,7 +27,7 @@ function passedProfile(profile, label) { requireThat(profile?.status === "passed" && milestones.every(k => profile.milestones?.[k] === true), `${label} incomplete`); } export function actionContext(env = process.env, root = repository) { - requireThat(env.GITHUB_REPOSITORY === "hikariming/ghfind" && decimal.test(env.GITHUB_RUN_ID) && decimal.test(env.GITHUB_RUN_ATTEMPT), "trusted current Actions context required"); + requireThat(env.GITHUB_REPOSITORY === "FindAny/ghfind" && decimal.test(env.GITHUB_RUN_ID) && decimal.test(env.GITHUB_RUN_ATTEMPT), "trusted current Actions context required"); const git = args => execFileSync("git", args, { cwd: root, encoding: "utf8", timeout: 10000 }).trim(); requireThat(!git(["status", "--porcelain", "--untracked-files=normal"]), "clean evidence checkout required"); return { repository: env.GITHUB_REPOSITORY, runId: env.GITHUB_RUN_ID, runAttempt: env.GITHUB_RUN_ATTEMPT, @@ -38,7 +38,7 @@ export function validateInputs(input, context, now = Date.now()) { runtimeDeployment: runtime, webDeployment: web, remoteJourney: journey } = input; validateWebManifest(m); const sha = context.sourceSha, tree = context.sourceTree; - requireThat(context.repository === "hikariming/ghfind" && sha40.test(sha) && sha40.test(tree) && decimal.test(context.runId) && decimal.test(context.runAttempt), "invalid source/run context"); + requireThat(context.repository === "FindAny/ghfind" && sha40.test(sha) && sha40.test(tree) && decimal.test(context.runId) && decimal.test(context.runAttempt), "invalid source/run context"); const c = ci?.context; requireThat(ci?.version === "ghfind.feed-ci.v1" && ci.kind === "release" && ci.eligible === true && c?.repository === context.repository && c.event === "push" && c.sourceSha === sha && c.checkoutSha === sha && c.treeSha === tree && diff --git a/scripts/feed-platform-staging-evidence.test.mjs b/scripts/feed-platform-staging-evidence.test.mjs index 8125ec33..4b5ff972 100644 --- a/scripts/feed-platform-staging-evidence.test.mjs +++ b/scripts/feed-platform-staging-evidence.test.mjs @@ -9,7 +9,7 @@ import { createEvidence, verifyEvidence, milestones, hash } from "./feed-platfor const now = Date.parse("2026-09-09T12:00:00Z"), stamp = seconds => new Date(now - seconds * 1000).toISOString(); function inputs() { const manifest = fixture(), sha = "a".repeat(40), tree = "b".repeat(40); - const context = { repository: "hikariming/ghfind", runId: "12345", runAttempt: "2", sourceSha: sha, sourceTree: tree }; + const context = { repository: "FindAny/ghfind", runId: "12345", runAttempt: "2", sourceSha: sha, sourceTree: tree }; const profile = () => ({ status: "passed", milestones: Object.fromEntries(milestones.map(k => [k, true])) }); const worker = "12345678-1234-4234-8234-123456789012", webVersion = "22345678-1234-4234-8234-123456789012"; const image = `registry.cloudflare.com/${ACCOUNT}/ghfind-feed@sha256:${"c".repeat(64)}`; diff --git a/scripts/feed-production-assessment-operator.test.mjs b/scripts/feed-production-assessment-operator.test.mjs index 30624169..ada76003 100644 --- a/scripts/feed-production-assessment-operator.test.mjs +++ b/scripts/feed-production-assessment-operator.test.mjs @@ -5,8 +5,8 @@ import { recoverInterrupted, operatorSender, limits } from './feed-production-as const oldSha='a'.repeat(40),releaseSha='b'.repeat(40),analysisId='11111111-1111-4111-8111-111111111111',requestId='22222222-2222-4222-8222-222222222222',intentId='33333333-3333-4333-8333-333333333333'; const manifest={format:'ghfind-production-assessment-operator-v1',requestId,analysisId,requestedRef:oldSha,expectedThreadId:'01M2EZ289XGFKNVH61YTXM8W5J',expectedRunId:'01M2EZ28DQ0Y9BDKVMT8N9BN73',agentId:'01M22PWZR0A7ZYCDKWTEA0YEHQ'}; const carryover={format:'ghfind-production-assessment-carryover-v1',runId:123,attempt:1,sourceSha:oldSha,intentId,analysisId}; -const original={format:'ghfind-production-assessment-intent-v1',intentId,sourceSha:oldSha,analysisId,postIssued:true,phase:'waiting',repository:'hikariming/ghfind',origin:'https://ghfind.beiming1201.workers.dev',web:{agentId:manifest.agentId},idempotencyKey:`ghfind-project-${analysisId}`,createdAt:1000,polls:60,projectionPolls:5,providerRunRetries:0}; -const env={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'hikariming/ghfind',GITHUB_REF:'refs/heads/main',GITHUB_WORKFLOW_REF:'hikariming/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main',GITHUB_RUN_ID:'456',GITHUB_RUN_ATTEMPT:'1',MOSOO_PROJECT_AGENT_ID:manifest.agentId}; +const original={format:'ghfind-production-assessment-intent-v1',intentId,sourceSha:oldSha,analysisId,postIssued:true,phase:'waiting',repository:'FindAny/ghfind',origin:'https://ghfind.beiming1201.workers.dev',web:{agentId:manifest.agentId},idempotencyKey:`ghfind-project-${analysisId}`,createdAt:1000,polls:60,projectionPolls:5,providerRunRetries:0}; +const env={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'FindAny/ghfind',GITHUB_REF:'refs/heads/main',GITHUB_WORKFLOW_REF:'FindAny/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main',GITHUB_RUN_ID:'456',GITHUB_RUN_ATTEMPT:'1',MOSOO_PROJECT_AGENT_ID:manifest.agentId}; const web={status:'passed',mode:'paused',sourceSha:releaseSha,backend:'go',store:'cf_d1_r2',workerVersionId:'44444444-4444-4444-8444-444444444444'}; function reply(status='running') {return {analysisId,requestedRef:oldSha,status,idempotencyKey:`${original.idempotencyKey}-retry-1`,threadId:status==='queued'?null:'01M2EZ289XGFKNVH61YTXM8W5K',runId:status==='queued'?null:'01M2EZ28DQ0Y9BDKVMT8N9BN74',startedAt:1000,createAttempts:2,secret:'must-not-output',recovery:{requestId,action:'retry_interrupted',executionDeadlineAt:1802000,createdAt:2000,priorThreadId:manifest.expectedThreadId,priorRunId:manifest.expectedRunId,nextIdempotencyKey:`${original.idempotencyKey}-retry-1`,secret:'must-not-output'}};} function setup(overrides={}) {const evidence=[],posts=[],receipt=structuredClone(original);return {evidence,posts,receipt,deps:{env,paused:async()=>web,record:r=>evidence.push(structuredClone(r)),send:async body=>{posts.push(structuredClone(body));return {status:200,uncertain:false,value:reply()};},...overrides}};} diff --git a/scripts/feed-production-assessment-recovery.mjs b/scripts/feed-production-assessment-recovery.mjs index 7e14a1a6..6026e871 100644 --- a/scripts/feed-production-assessment-recovery.mjs +++ b/scripts/feed-production-assessment-recovery.mjs @@ -8,7 +8,7 @@ import { tmpdir } from 'node:os'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; -export const repository = 'hikariming/ghfind'; +export const repository = 'FindAny/ghfind'; export const workflowPath = '.github/workflows/deploy-cf-production.yml'; export const startStep = 'Start or resume the single real production assessment'; export const receiptFile = 'assessment-intent.json'; @@ -79,7 +79,7 @@ export function validateCarryoverReceipt(receipt, manifest) { validateCarryover(manifest); requireThat(receipt?.sourceSha === manifest.sourceSha && receipt.intentId === manifest.intentId && receipt.analysisId === manifest.analysisId && receipt.postIssued === true && - ['selected', 'waiting', 'completed'].includes(receipt.phase) && receipt.repository === repository && + ['selected', 'waiting', 'completed'].includes(receipt.phase) && [repository, 'hikariming/ghfind'].includes(receipt.repository) && receipt.origin === 'https://ghfind.beiming1201.workers.dev', 'carryover requires the same selected paid assessment; uncertain or conflicting receipt refused'); return receipt; diff --git a/scripts/feed-production-assessment.mjs b/scripts/feed-production-assessment.mjs index e096c9ad..e2aea079 100644 --- a/scripts/feed-production-assessment.mjs +++ b/scripts/feed-production-assessment.mjs @@ -17,7 +17,7 @@ import { } from "./feed-production-assessment-recovery.mjs"; export const ACCOUNT = "8f19bebe359e4ec1a24c68c5f49c1584"; export const ORIGIN = "https://ghfind.beiming1201.workers.dev"; -export const REPO = "hikariming/ghfind"; +export const REPO = "FindAny/ghfind"; export const CORE = "60d45096-bfe7-4de1-8b85-c1b66a466b0d"; export const FEED = "9c4ac13a-4c90-40a8-9d56-d7141f864bbf"; export const LIMITS = Object.freeze({ @@ -370,7 +370,7 @@ function context( function candidate(row) { check( typeof row?.repo_key === "string" && - /^[a-z0-9_.-]+\/[a-z0-9_.-]+$/.test(row.repo_key) && + /^[a-z0-9_.-]+\/[a-z0-9_.-]+$/i.test(row.repo_key) && id(row.analysis_id) && hash(row.source_hash), "invalid_candidate_identity", @@ -546,7 +546,7 @@ export async function startAssessment(sha, path, options = {}) { return r; } const { response, data } = await c.request( - "https://api.github.com/repos/hikariming/ghfind/git/ref/heads/main", + "https://api.github.com/repos/FindAny/ghfind/git/ref/heads/main", { method: "GET", headers: { accept: "application/vnd.github+json" } }, ); check( diff --git a/scripts/feed-production-assessment.test.mjs b/scripts/feed-production-assessment.test.mjs index a37dec25..a517ffdd 100644 --- a/scripts/feed-production-assessment.test.mjs +++ b/scripts/feed-production-assessment.test.mjs @@ -253,7 +253,7 @@ async function harness(t, settings = {}) { assert.ok(!JSON.stringify(init.headers).includes(TOKEN)); if ( url === - "https://api.github.com/repos/hikariming/ghfind/git/ref/heads/main" + "https://api.github.com/repos/FindAny/ghfind/git/ref/heads/main" ) return json({ object: { sha: settings.mainSHA ?? SHA } }); if (url === `${ORIGIN}/api/project-analyses` && init.method === "POST") { diff --git a/scripts/feed-production-off-transition.test.mjs b/scripts/feed-production-off-transition.test.mjs index cecd183b..19fbea61 100644 --- a/scripts/feed-production-off-transition.test.mjs +++ b/scripts/feed-production-off-transition.test.mjs @@ -4,8 +4,8 @@ import { readFileSync } from 'node:fs'; import { transitionOffActors, validateConsumerReceipt, readOffResponse, OffRequestError } from './feed-production-off-transition.mjs'; import { ACCOUNT } from './feed-production-release.mjs'; const manifest=JSON.parse(readFileSync(new URL('../ops/feed-production-manifest.json',import.meta.url))); -const env={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'hikariming/ghfind',GITHUB_REF:'refs/heads/main', - GITHUB_WORKFLOW_REF:'hikariming/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main',GITHUB_RUN_ID:'123',GITHUB_RUN_ATTEMPT:'1'}; +const env={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'FindAny/ghfind',GITHUB_REF:'refs/heads/main', + GITHUB_WORKFLOW_REF:'FindAny/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main',GITHUB_RUN_ID:'123',GITHUB_RUN_ATTEMPT:'1'}; const identity={sourceSha:'a'.repeat(40),imageBuildId:'b'.repeat(64),image:`registry.cloudflare.com/${ACCOUNT}/ghfind-feed@sha256:${'c'.repeat(64)}`,mode:'off',writerEpoch:1}; const version='12345678-1234-1234-1234-123456789abc', anchor='12345678-1234-1234-1234-123456789abd'; const targets=['api-0','api-1','executor-0']; diff --git a/scripts/feed-production-pause.mjs b/scripts/feed-production-pause.mjs index ecce6e30..ef14384d 100644 --- a/scripts/feed-production-pause.mjs +++ b/scripts/feed-production-pause.mjs @@ -11,7 +11,7 @@ import { boundedJSON } from './feed-platform-web-verify.mjs'; export const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); export const accountId = '8f19bebe359e4ec1a24c68c5f49c1584'; export const worker = 'ghfind'; -export const workflow = 'hikariming/ghfind/.github/workflows/feed-production-pause.yml@refs/heads/main'; +export const workflow = 'FindAny/ghfind/.github/workflows/feed-production-pause.yml@refs/heads/main'; export const runtimeWorker = 'ghfind-feed-runtime-production'; const uuid = /^[a-f0-9]{8}(?:-[a-f0-9]{4}){3}-[a-f0-9]{12}$/; const sha = /^[a-f0-9]{40}$/; @@ -26,7 +26,7 @@ export function validateInput(sourceSha, pausedWebVersion) { } export function authorizeApply(env = process.env) { requireThat(env.GITHUB_ACTIONS === 'true' && env.GITHUB_EVENT_NAME === 'workflow_dispatch' && - env.GITHUB_REPOSITORY === 'hikariming/ghfind' && env.GITHUB_REF === 'refs/heads/main' && + env.GITHUB_REPOSITORY === 'FindAny/ghfind' && env.GITHUB_REF === 'refs/heads/main' && env.GITHUB_WORKFLOW_REF === workflow && sha.test(env.GITHUB_SHA ?? '') && /^[1-9][0-9]*$/.test(env.GITHUB_RUN_ID ?? '') && /^[1-9][0-9]*$/.test(env.GITHUB_RUN_ATTEMPT ?? ''), 'mutation requires the pinned manual production pause workflow on main'); diff --git a/scripts/feed-production-pause.test.mjs b/scripts/feed-production-pause.test.mjs index efc282ec..318e1f96 100644 --- a/scripts/feed-production-pause.test.mjs +++ b/scripts/feed-production-pause.test.mjs @@ -8,7 +8,7 @@ import { accountId, authorizeApply, expectedBindings, minimalEnvironment, parseA const sourceSha = 'a'.repeat(40); const pausedWebVersion = '11111111-1111-4111-8111-111111111111'; const deploymentId = '22222222-2222-4222-8222-222222222222'; -const env = { GITHUB_ACTIONS: 'true', GITHUB_EVENT_NAME: 'workflow_dispatch', GITHUB_REPOSITORY: 'hikariming/ghfind', +const env = { GITHUB_ACTIONS: 'true', GITHUB_EVENT_NAME: 'workflow_dispatch', GITHUB_REPOSITORY: 'FindAny/ghfind', GITHUB_REF: 'refs/heads/main', GITHUB_WORKFLOW_REF: workflow, GITHUB_SHA: 'b'.repeat(40), GITHUB_RUN_ID: '123', GITHUB_RUN_ATTEMPT: '1' }; const candidate = () => ({ id: pausedWebVersion, annotations: { 'workers/tag': `production-${sourceSha}` }, resources: { script: { etag: 'synthetic-script-etag' }, bindings: [...expectedBindings(sourceSha), { name: 'PRIVATE_EXISTING_METADATA', type: 'plain_text', text: 'NEVER_EMIT_THIS_VALUE' }] } }); diff --git a/scripts/feed-production-projection-replay.mjs b/scripts/feed-production-projection-replay.mjs index ad548d75..35c532cc 100644 --- a/scripts/feed-production-projection-replay.mjs +++ b/scripts/feed-production-projection-replay.mjs @@ -12,12 +12,12 @@ export const root = resolve(dirname(fileURLToPath(import.meta.url)), '..'); export const manifest = JSON.parse(readFileSync(resolve(root, 'ops/feed-production-manifest.json'))); export const events = JSON.parse(readFileSync(resolve(root, 'ops/feed-production-projection-replay.json'))); export const LIMITS = Object.freeze({ polls: 6, intervalMs: 20000, timeoutMs: 10000, observationStartDeadlineMs: 120000 }); -const workflow = 'hikariming/ghfind/.github/workflows/feed-production-projection-replay.yml@refs/heads/main'; +const workflow = 'FindAny/ghfind/.github/workflows/feed-production-projection-replay.yml@refs/heads/main'; const check = (value, code) => { if (!value) throw new Error(code); }; const hash = value => createHash('sha256').update(value).digest('hex'); export function authorize(env = process.env) { check(env.GITHUB_ACTIONS === 'true' && env.GITHUB_EVENT_NAME === 'workflow_dispatch' && - env.GITHUB_REPOSITORY === 'hikariming/ghfind' && env.GITHUB_REF === 'refs/heads/main' && + env.GITHUB_REPOSITORY === 'FindAny/ghfind' && env.GITHUB_REF === 'refs/heads/main' && env.GITHUB_WORKFLOW_REF === workflow && /^[0-9a-f]{40}$/.test(env.RELEASE_SHA ?? '') && env.RELEASE_SHA === env.GITHUB_SHA, 'protected_current_main_required'); } @@ -186,7 +186,7 @@ async function main() { const resultPath = resolve(directory, 'result.json'); try { check(process.argv[2] === '--execute' && JSON.stringify(JSON.parse(readFileSync(intentPath))) === JSON.stringify(expected), 'persisted_intent_changed'); - const current = execFileSync('gh', ['api', 'repos/hikariming/ghfind/git/ref/heads/main', '--jq', '.object.sha'], { encoding: 'utf8' }).trim(); + const current = execFileSync('gh', ['api', 'repos/FindAny/ghfind/git/ref/heads/main', '--jq', '.object.sha'], { encoding: 'utf8' }).trim(); check(current === sha && execFileSync('git', ['rev-parse', 'HEAD'], { encoding: 'utf8' }).trim() === sha, 'main_advanced'); const t = await transport(process.env); await execute(t, value => writeFileSync(resultPath, JSON.stringify(value, null, 2), { mode: 0o600 })); diff --git a/scripts/feed-production-projection-replay.test.mjs b/scripts/feed-production-projection-replay.test.mjs index 299e9d9f..2ab10821 100644 --- a/scripts/feed-production-projection-replay.test.mjs +++ b/scripts/feed-production-projection-replay.test.mjs @@ -2,7 +2,7 @@ import test from 'node:test'; import assert from 'node:assert/strict'; import { authorize, commandId, events, execute, intent, transport, validateProjection, validateSource, validateManifest, LIMITS, manifest } from './feed-production-projection-replay.mjs'; const sha = 'a'.repeat(40); -const context = { GITHUB_ACTIONS: 'true', GITHUB_EVENT_NAME: 'workflow_dispatch', GITHUB_REPOSITORY: 'hikariming/ghfind', GITHUB_REF: 'refs/heads/main', GITHUB_WORKFLOW_REF: 'hikariming/ghfind/.github/workflows/feed-production-projection-replay.yml@refs/heads/main', RELEASE_SHA: sha, GITHUB_SHA: sha }; +const context = { GITHUB_ACTIONS: 'true', GITHUB_EVENT_NAME: 'workflow_dispatch', GITHUB_REPOSITORY: 'FindAny/ghfind', GITHUB_REF: 'refs/heads/main', GITHUB_WORKFLOW_REF: 'FindAny/ghfind/.github/workflows/feed-production-projection-replay.yml@refs/heads/main', RELEASE_SHA: sha, GITHUB_SHA: sha }; function source(e) { return [{ sequence: e.sourceVersion, event_id: e.eventId, aggregate_key: e.repoKey, source_hash: e.sourceHash, analysis_sha256: e.sourceHash, analysis_id: e.analysisId, receipt_id: e.receiptId, latest_analysis_id: e.analysisId, resolved_commit_sha: e.expectedResolvedCommitSHA, status: 'completed', outbox_status: 'delivered' }]; } function job(e, status) { return [{ event_id: e.eventId, aggregate_key: e.repoKey, source_version: e.sourceVersion, analysis_id: e.analysisId, receipt_id: e.receiptId, source_hash: e.sourceHash, event_source_version: e.sourceVersion, envelope_event_id: e.eventId, contract_version: 1, event_kind: 'assessment.completed', status }]; } function projection(e) { return [{ analysis_id: e.analysisId, version_analysis_id: e.analysisId, source_hash: 'd'.repeat(64), version_source_hash: 'd'.repeat(64), resolved_commit_sha: e.expectedResolvedCommitSHA, event_id: e.eventId, source_version: e.sourceVersion, receipt_id: e.receiptId, job_status: 'completed', job_repo: e.repoKey, job_source_version: e.sourceVersion, job_event_id: e.eventId, event_analysis_id: e.analysisId, event_source_hash: e.sourceHash, event_receipt_id: e.receiptId, event_source_version: e.sourceVersion, event_contract_version: 1, revoked_at: null, published: e.expectedPublished, blocked_reason: e.expectedBlockedReason, removed: 0 }]; } diff --git a/scripts/feed-production-release.mjs b/scripts/feed-production-release.mjs index d896afa4..dccf4675 100644 --- a/scripts/feed-production-release.mjs +++ b/scripts/feed-production-release.mjs @@ -13,8 +13,8 @@ export const ACCOUNT = '8f19bebe359e4ec1a24c68c5f49c1584'; export const webConfig = resolve(repository, 'platform/runtime/wrangler.web.production.generated.json'); export const requireThat = (ok, text) => { if (!ok) throw new Error(text); }; export function authorizeMutation(env = process.env) { - requireThat(env.GITHUB_ACTIONS === 'true' && env.GITHUB_REPOSITORY === 'hikariming/ghfind' && - env.GITHUB_REF === 'refs/heads/main' && /^hikariming\/ghfind\/.github\/workflows\/deploy-cf-production.yml@refs\/heads\/main$/.test(env.GITHUB_WORKFLOW_REF ?? ''), 'only the production Actions workflow on main may mutate'); + requireThat(env.GITHUB_ACTIONS === 'true' && env.GITHUB_REPOSITORY === 'FindAny/ghfind' && + env.GITHUB_REF === 'refs/heads/main' && /^FindAny\/ghfind\/.github\/workflows\/deploy-cf-production.yml@refs\/heads\/main$/.test(env.GITHUB_WORKFLOW_REF ?? ''), 'only the production Actions workflow on main may mutate'); } const PRODUCTION_CACHE_KV = 'f7a7299eef224d899c21121c1979be32'; // ghfind-cache const COORDINATION_WORKER = 'ghfind-coord'; diff --git a/scripts/feed-production-release.test.mjs b/scripts/feed-production-release.test.mjs index b930d74a..0d6ce886 100644 --- a/scripts/feed-production-release.test.mjs +++ b/scripts/feed-production-release.test.mjs @@ -9,9 +9,9 @@ import { template } from './feed-platform-production.mjs'; const sha='a'.repeat(40); const provider={MOSOO_API_BASE:'https://cloud.mosoo.ai/api/v1',MOSOO_PROJECT_AGENT_ID:'01M22PWZR0A7ZYCDKWTEA0YEHQ',MOSOO_PROJECT_USER_ID:'ghfind-feed-staging'}; test('production mutations reject local, fork, branch and alternate workflow execution',()=>{ - const good={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'hikariming/ghfind',GITHUB_REF:'refs/heads/main',GITHUB_WORKFLOW_REF:'hikariming/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main'}; + const good={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'FindAny/ghfind',GITHUB_REF:'refs/heads/main',GITHUB_WORKFLOW_REF:'FindAny/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main'}; authorizeMutation(good); - for(const changed of [{GITHUB_ACTIONS:'false'},{GITHUB_REPOSITORY:'fork/ghfind'},{GITHUB_REF:'refs/heads/codex/feed-release'},{GITHUB_WORKFLOW_REF:'hikariming/ghfind/.github/workflows/ci.yml@refs/heads/main'}])assert.throws(()=>authorizeMutation({...good,...changed})); + for(const changed of [{GITHUB_ACTIONS:'false'},{GITHUB_REPOSITORY:'fork/ghfind'},{GITHUB_REF:'refs/heads/codex/feed-release'},{GITHUB_WORKFLOW_REF:'FindAny/ghfind/.github/workflows/ci.yml@refs/heads/main'}])assert.throws(()=>authorizeMutation({...good,...changed})); }); test('paused and all configurations share only the production D1 writer and private service binding',()=>{ for(const mode of ['paused','all']) { @@ -244,7 +244,7 @@ test('production Feed schema approval covers the complete fixed migrations witho assert.ok(!legacy.core.some(e=>e.name==='0005_feed_source_outbox.sql')); }); -const productionActions={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'hikariming/ghfind',GITHUB_REF:'refs/heads/main',GITHUB_WORKFLOW_REF:'hikariming/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main'}; +const productionActions={GITHUB_ACTIONS:'true',GITHUB_REPOSITORY:'FindAny/ghfind',GITHUB_REF:'refs/heads/main',GITHUB_WORKFLOW_REF:'FindAny/ghfind/.github/workflows/deploy-cf-production.yml@refs/heads/main'}; async function withActions(fn,changes={}) { const saved=Object.fromEntries(Object.keys(productionActions).map(k=>[k,process.env[k]])); Object.assign(process.env,productionActions,changes); @@ -288,7 +288,7 @@ function resourcesFixture({missing=[],pause=false,onRead,onWrite}={}) { return {m,names,ids,api,calls,rows,reads,mutations:()=>calls.filter(c=>c.method!=='GET')}; } test('resource initialization is Actions-only before even reading the API',async()=>{ - for(const changed of [{GITHUB_ACTIONS:'false'},{GITHUB_REPOSITORY:'fork/ghfind'},{GITHUB_REF:'refs/heads/feature'},{GITHUB_WORKFLOW_REF:'hikariming/ghfind/.github/workflows/ci.yml@refs/heads/main'}]) { + for(const changed of [{GITHUB_ACTIONS:'false'},{GITHUB_REPOSITORY:'fork/ghfind'},{GITHUB_REF:'refs/heads/feature'},{GITHUB_WORKFLOW_REF:'FindAny/ghfind/.github/workflows/ci.yml@refs/heads/main'}]) { const f=resourcesFixture();await withActions(()=>assert.rejects(ensureResources(f.m,f.api),/only the production Actions/),changed);assert.deepEqual(f.calls,[]); } });