Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/gate-topology.yml
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,42 @@ jobs:
done; } | /tmp/feed > /tmp/review.json 2> /tmp/stats || { echo "::warning::claw/suggest could not build a review"; exit 0; }
cat /tmp/stats >> "$GITHUB_STEP_SUMMARY"
if [ -s /tmp/review.json ]; then gh api -X POST "repos/$R/pulls/$N/reviews" --input /tmp/review.json -q .html_url >> "$GITHUB_STEP_SUMMARY"; fi

# #10397: after a push to master, bring every conflict-free open PR that fell behind up to date.
# The decision (which PRs, which order, the cap of 30, every skip) is specs/claw/refresh.t27 lowered
# to gen/c/claw/refresh.c; this job lists, feeds the C, and calls the endpoint for each `R` line.
# The token is the update-branch row of specs/claw/github_surface.t27: pull_requests write and
# nothing else. If GitHub answers 403 here, the App also needs contents:write for update-branch
# (REST docs); the failure is a warning with GitHub's own text, never a red job.
claw-refresh:
if: github.event_name == 'push'
runs-on: ubuntu-24.04
permissions: {contents: read, pull-requests: read}
concurrency: {group: claw-refresh, cancel-in-progress: true}
steps:
- id: have
env: {K: "${{ secrets.CLAW_APP_PRIVATE_KEY }}", I: "${{ vars.CLAW_APP_ID || secrets.CLAW_APP_ID }}"}
run: if [ -n "$K" ] && [ -n "$I" ]; then echo ok=1 >> "$GITHUB_OUTPUT"; else echo "claw/refresh updated nothing - secret CLAW_APP_PRIVATE_KEY or CLAW_APP_ID (variable or secret) is not set (docs/claw/README.md)." >> "$GITHUB_STEP_SUMMARY"; fi
- {id: tok, if: steps.have.outputs.ok, uses: actions/create-github-app-token@v2, with: {app-id: "${{ vars.CLAW_APP_ID || secrets.CLAW_APP_ID }}", private-key: "${{ secrets.CLAW_APP_PRIVATE_KEY }}", owner: gHashTag, repositories: t27, permission-pull-requests: write}}
- {if: steps.have.outputs.ok, uses: actions/checkout@v6, with: {persist-credentials: false}}
- if: steps.have.outputs.ok
env: {GH_TOKEN: "${{ github.token }}", CLAW_TOKEN: "${{ steps.tok.outputs.token }}", R: "${{ github.repository }}"}
run: |
printf '#include "gen/c/claw/refresh.c"\n#include <stdio.h>\n#include <stdlib.h>\nint main(void){size_t k=1<<22,n;uint8_t*b=malloc(k),*o=malloc(k);n=fread(b,1,k,stdin);if(n==k)return 3;size_t m=refresh_plan(b,n,o,k);if(m>k)return 4;fwrite(o,1,m,stdout);return 0;}\n' | cc -O1 -w -I . -x c -o /tmp/feed -
list() { gh api graphql --paginate -F owner="${R%/*}" -F name="${R#*/}" -f query='query($owner:String!,$name:String!,$endCursor:String){repository(owner:$owner,name:$name){pullRequests(states:OPEN,first:100,after:$endCursor,orderBy:{field:CREATED_AT,direction:ASC}){pageInfo{hasNextPage endCursor} nodes{number headRefOid createdAt isDraft isCrossRepository maintainerCanModify mergeable mergeStateStatus baseRefName headRepository{nameWithOwner} labels(first:50){nodes{name}}}}}}' --jq '.data.repository.pullRequests.nodes[]|[.number,.headRefOid,.createdAt,.isDraft,([.labels.nodes[].name]|join(",")),.isCrossRepository,(.headRepository.nameWithOwner//""),.maintainerCanModify,.mergeable,.mergeStateStatus,.baseRefName]|@tsv'; }
# GitHub computes mergeability lazily after a push: ask once, wait, ask again.
list > /dev/null
sleep 30
list > /tmp/prs.tsv
# Copy the facts; behind_by is the one thing the listing lacks (the ruleset is not strict, so no PR is ever reported BEHIND).
while IFS= read -r line; do
sha=$(printf '%s' "$line" | cut -f2); base=$(printf '%s' "$line" | cut -f11)
bh=$(gh api "repos/$R/compare/$base...$sha" -q .behind_by 2>/dev/null </dev/null) || bh=-
printf '%s\t%s\n' "$(printf '%s' "$line" | cut -f1-10)" "${bh:--}"
done < /tmp/prs.tsv | /tmp/feed > /tmp/plan || { echo "::warning::claw/refresh could not build a plan"; exit 0; }
while IFS=$'\t' read -r k a b; do
case "$k" in
R) if err=$(GH_TOKEN="$CLAW_TOKEN" gh api -X PUT "repos/$R/pulls/$a/update-branch" -f expected_head_sha="$b" 2>&1 </dev/null); then echo "claw/refresh: #$a updated"; else echo "::warning::claw/refresh could not update #$a: $err"; fi; sleep 1;;
M) printf '%s\n' "$a" >> "$GITHUB_STEP_SUMMARY";;
esac
done < /tmp/plan
3 changes: 2 additions & 1 deletion .github/workflows/spec-guards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ jobs:
./target/release/t27c gen-c specs/claw/t27f_gate.t27 > gen/c/claw/t27f_gate.c
./target/release/t27c gen-c specs/claw/sarif_feed.t27 > gen/c/claw/sarif_feed.c
./target/release/t27c gen-c specs/claw/suggest_feed.t27 > gen/c/claw/suggest_feed.c
./target/release/t27c gen-c specs/claw/refresh.t27 > gen/c/claw/refresh.c
./target/release/t27c gen-rust specs/tri/fmt_source.t27 > bootstrap/gen/rust/tri/fmt_source.rs
./target/release/t27c gen-json specs/igla/own_model_board.t27 > gen/json/igla/own_model_board.json
git diff --exit-code -- gen/c/claw/gates.c gen/c/claw/t27f_gate.c gen/c/claw/sarif_feed.c gen/c/claw/suggest_feed.c bootstrap/gen/rust/tri/fmt_source.rs gen/json/igla/own_model_board.json
git diff --exit-code -- gen/c/claw/gates.c gen/c/claw/t27f_gate.c gen/c/claw/sarif_feed.c gen/c/claw/suggest_feed.c gen/c/claw/refresh.c bootstrap/gen/rust/tri/fmt_source.rs gen/json/igla/own_model_board.json

# #7565: test only the specs this change can affect. specs/ci/affected.t27 picks them (the
# changed specs and every spec that imports one through `use`, transitively); the graph is the
Expand Down
37 changes: 37 additions & 0 deletions .trinity/seals/claw_ClawRefresh.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"built_by": "t27c-bootstrap@0.5.2+cd19e1370",
"closure": [
{
"spec": "specs/claw/sarif.t27",
"spec_hash": "sha256:22258cfd518c5b27ad46db8bf5c507d97e783bd79073f83ff26b20549c927db8"
},
{
"spec": "specs/claw/text.t27",
"spec_hash": "sha256:b65da69dff231c61a6d3a48558af9e17af42e1acbe3f4763348f1f0c2f118f21"
}
],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:1bc4f958fdddeb6935166a07e1059847cf77d92180371bfb85a7565ff6ce7495",
"gen_hash_rust": "sha256:6eac58459c46d6cd03c0ec4863738bf57d2be61ea794c729ff1405e6c6e66dbf",
"gen_hash_verilog": "sha256:a4fdfa74eaa36dba431047d9ac95c10df830c734aa0e8fdf01c89d7c79102e13",
"gen_hash_zig": "sha256:5479058d720ae4e923921aa3d03d2ce5c3cea5b97204827c562d265b851dca52",
"module": "ClawRefresh",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-18T14:05:32Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:924b8dd3d4093d1315a6bbc6c769cc63a4074c1910bdd8a2cfa9ab605a65d458",
"spec_path": "specs/claw/refresh.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 44,
"total": 44,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d",
"zig": "0.16.0"
}
}
1 change: 1 addition & 0 deletions docs/reports/t27b_expectations.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@
{"path": "specs/claw/github_surface.t27", "t27b": "pass"},
{"path": "specs/claw/preview.t27", "t27b": "pass"},
{"path": "specs/claw/recipes.t27", "t27b": "pass"},
{"path": "specs/claw/refresh.t27", "t27b": "pass"},
{"path": "specs/claw/sarif.t27", "t27b": "pass"},
{"path": "specs/claw/sarif_feed.t27", "t27b": "pass"},
{"path": "specs/claw/sarif_pins.t27", "t27b": "pass"},
Expand Down
Loading
Loading