From ed84a5db205ffc041707dbbfe999b8392aef4ca4 Mon Sep 17 00:00:00 2001 From: Seungpyo Hong Date: Tue, 23 Jun 2026 15:00:26 +0900 Subject: [PATCH 1/3] ci: run verify from TechEngine (TECHAPI_DATA_DIR) instead of TechAPI checkout --- .github/workflows/techapi-verify-comment.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/techapi-verify-comment.yml b/.github/workflows/techapi-verify-comment.yml index d96fd8a..feb0e69 100644 --- a/.github/workflows/techapi-verify-comment.yml +++ b/.github/workflows/techapi-verify-comment.yml @@ -56,6 +56,9 @@ jobs: env: TECHAPI_COMMENT_ID: ${{ github.event.client_payload.comment_id }} + - name: Checkout TechEngine + uses: actions/checkout@v4 + - name: Checkout TechAPI PR head uses: actions/checkout@v4 with: @@ -67,15 +70,21 @@ jobs: - uses: actions/setup-python@v5 with: python-version: "3.12" + cache: pip - # app.verify is a stdlib-only TechAPI module; run it from the checkout. - # mode=tier0 (auto PR report): fast offline Tier 0 only (changed + baseline). - # mode=all (/verify on demand): `pr` runs Tiers 0-3 (3 = promotion DRY-RUN). + - name: Install TechEngine + run: pip install -e . + + # app.verify now lives in TechEngine; run it from the engine root with + # TECHAPI_DATA_DIR pointing at the TechAPI checkout (its `_changed_data_slugs` + # runs git inside that data repo). mode=tier0 = fast offline Tier 0 (auto PR + # report); mode=all = `pr` Tiers 0-3 (3 = promotion DRY-RUN). - name: Run verification id: verify + env: + TECHAPI_DATA_DIR: ${{ github.workspace }}/TechAPI/data run: | - cd TechAPI - git fetch origin main --depth=1 || true + git -C TechAPI fetch origin main --depth=1 || true { echo 'report< Date: Tue, 23 Jun 2026 15:00:27 +0900 Subject: [PATCH 2/3] ci: promotion workflow in TechEngine (bot PR to TechAPI) --- .github/workflows/verify-network.yml | 127 +++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 .github/workflows/verify-network.yml diff --git a/.github/workflows/verify-network.yml b/.github/workflows/verify-network.yml new file mode 100644 index 0000000..d78c1fd --- /dev/null +++ b/.github/workflows/verify-network.yml @@ -0,0 +1,127 @@ +name: verify-network + +# Network verification tiers (source-URL liveness + external cross-reference) and +# verified promotion, run in TechEngine against a TechAPI checkout. NEVER on +# pull_request — external sites, rate-limited. Scheduled + manual. Promotions are +# committed as TechEngineBot and opened as a human-gated PR on TechAPI; the job +# hard-guards that nothing but `verified` flags + the ledger changed. +on: + workflow_dispatch: + inputs: + apply: + description: "Flip verified->true and open a PR on TechAPI (else dry-run)" + type: boolean + default: false + max_urls: + description: "Frontier records to URL-check" + default: "2000" + max_crossref: + description: "Records to cross-reference" + default: "500" + schedule: + - cron: "0 4 * * 1" # Mondays 04:00 UTC + +permissions: + contents: read + +concurrency: + group: verify-network + cancel-in-progress: false + +jobs: + verify-network: + runs-on: ubuntu-latest + env: + PYTHONIOENCODING: utf-8 + APPLY: ${{ github.event_name == 'schedule' || github.event.inputs.apply == 'true' }} + TECHAPI_DATA_DIR: ${{ github.workspace }}/TechAPI/data + WRITE_TOKEN: ${{ secrets.TECHENGINEBOT_TOKEN || secrets.TECHAPI_TOKEN }} + steps: + - name: Checkout TechEngine + uses: actions/checkout@v4 + + - name: Checkout TechAPI + uses: actions/checkout@v4 + with: + repository: GetTechAPI/TechAPI + path: TechAPI + fetch-depth: 0 + token: ${{ secrets.TECHENGINEBOT_TOKEN || secrets.TECHAPI_TOKEN || secrets.GITHUB_TOKEN }} + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + + - name: Install TechEngine + run: pip install -e . + + - name: Tier 0 score (writes scores cache) + run: python -m app.verify score + + - name: Tier 1 source-URL liveness + run: python -m app.verify check-urls --max ${{ github.event.inputs.max_urls || '2000' }} + + - name: Tier 2 external cross-reference + run: python -m app.verify crossref --max ${{ github.event.inputs.max_crossref || '500' }} + + - name: Tier 3 promote (dry-run) + run: python -m app.verify promote + + - name: Tier 3 promote (apply) + if: ${{ env.APPLY == 'true' }} + run: python -m app.verify promote --apply + + - name: Structural validator self-check + if: ${{ env.APPLY == 'true' }} + run: python -m app.validate + + # Guard: the only tracked changes in TechAPI may be `verified` toggles in + # data/**.json (the ledger under data/_verify/ is expected to change too). + - name: Guard diff scope + if: ${{ env.APPLY == 'true' }} + run: | + python - <<'PY' + import subprocess, sys + out = subprocess.run( + ["git", "-C", "TechAPI", "diff", "--unified=0", "--", + "data/", ":(exclude)data/_verify/**"], + capture_output=True, text=True).stdout + bad = [] + for line in out.splitlines(): + if line.startswith(("+++", "---", "@@", "diff ", "index ")): + continue + if line.startswith(("+", "-")) and line[1:].strip(): + body = line[1:].strip().rstrip(",") + if body not in ('"verified": true', '"verified": false'): + bad.append(line) + if bad: + print("Unexpected non-verified changes:") + print("\n".join(bad[:50])) + sys.exit(1) + print("diff scope OK: only verified toggles") + PY + + - name: Open promotion PR on TechAPI (TechEngineBot) + if: ${{ env.APPLY == 'true' }} + env: + GH_TOKEN: ${{ env.WRITE_TOKEN }} + run: | + set -e + cd TechAPI + if git diff --quiet -- data/; then + echo "no promotions to commit"; exit 0 + fi + branch="verify/promote-${{ github.run_id }}" + git config user.name "TechEngineBot" + git config user.email "289859915+TechEngineBot@users.noreply.github.com" + git checkout -b "$branch" + git add data/ + git commit -m "data(verify): promote records to verified (reality cross-reference) + + Auto-promotions from the verification layer (green+live-source or crossref-confirm). + Each flip is verified:false->true only; see data/_verify/ledger.jsonl. Refs #1" + git push origin "$branch" + gh pr create --repo GetTechAPI/TechAPI --base main --head "$branch" \ + --title "data(verify): verified promotions ($(date -u +%Y-%m-%d))" \ + --body "Automated verified promotions from \`app.verify promote\` (run in TechEngine). Each change flips only the \`verified\` flag; structural validator passed and diff scope guarded. Review before merge. Refs #1" From 1b268004428b44f92213bb2376af659809d34118 Mon Sep 17 00:00:00 2001 From: Seungpyo Hong Date: Tue, 23 Jun 2026 15:00:29 +0900 Subject: [PATCH 3/3] ci: status.json sync in TechEngine (bot commit to TechAPI) --- .github/workflows/verify-status.yml | 61 +++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .github/workflows/verify-status.yml diff --git a/.github/workflows/verify-status.yml b/.github/workflows/verify-status.yml new file mode 100644 index 0000000..472ed2a --- /dev/null +++ b/.github/workflows/verify-status.yml @@ -0,0 +1,61 @@ +name: verify-status + +# Keep TechAPI's data/_verify/status.json (the verification-state aggregate: how +# many records are verified + Tier 0 bands per category) current. Runs in +# TechEngine against a TechAPI checkout and commits the refreshed file back to +# TechAPI main as TechEngineBot. Fires when TechAPI main changes (relayed by +# TechAPI's notify-engine -> techapi-updated) and daily as a backstop. The +# "commit only if changed" guard means the status commit can't loop. +on: + repository_dispatch: + types: [techapi-updated] + schedule: + - cron: "30 5 * * *" # daily 05:30 UTC backstop + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: verify-status + cancel-in-progress: false + +jobs: + status: + runs-on: ubuntu-latest + env: + PYTHONIOENCODING: utf-8 + TECHAPI_DATA_DIR: ${{ github.workspace }}/TechAPI/data + steps: + - name: Checkout TechEngine + uses: actions/checkout@v4 + + - name: Checkout TechAPI + uses: actions/checkout@v4 + with: + repository: GetTechAPI/TechAPI + path: TechAPI + token: ${{ secrets.TECHENGINEBOT_TOKEN || secrets.TECHAPI_TOKEN || secrets.GITHUB_TOKEN }} + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + + - name: Install TechEngine + run: pip install -e . + + - name: Regenerate verification status aggregate + run: python -m app.verify status --output TechAPI/data/_verify/status.json + + - name: Commit to TechAPI if changed (TechEngineBot) + run: | + cd TechAPI + git add data/_verify/status.json + if git diff --cached --quiet; then + echo "verification status unchanged"; exit 0 + fi + git config user.name "TechEngineBot" + git config user.email "289859915+TechEngineBot@users.noreply.github.com" + git commit -m "chore(verify): refresh verification status aggregate" + git push origin HEAD:main