Repository navigation
fix: make runner refresh exchange work (Stage 1) - #8
eyevinn-developer[bot] wants to merge 1 commit into
Conversation
POST JSON body, parse with node (no jq in image), use fresh PAT for config load only, add OSC_REFRESH_TOKEN, warn instead of || true. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Research Review
Verified
- Endpoint contract:
POST /runner-token/refreshinosaas-token-servicesrc/api_service_token.ts:549takes body{ token }(destructured at :568), replies 200{ token, expiresIn: 3600 }, 401{ reason, code }withcodeinrefresh_token_expired | refresh_token_invalid | refresh_token_revoked, 500{ reason }with nocode. The PR's body, parsing of.tokenand.code, and thecode=nonefallback match this exactly. jqabsent /nodepresent: the repoDockerfileon main (python:3.12-slim, apt list without jq, nodesource Node install) confirms birme's decision comment, so parsing withnodeis correct.- Decision match: birme's Stage 1 decision on issue #6 (job-visible
OSC_ACCESS_TOKENunchanged, fresh PAT only forconfig-to-env,OSC_REFRESH_TOKENadded,|| truereplaced by a[CONFIG]warning, node-based parse, success test asserting the NEW token is used) is implemented point by point. - Token handling: body goes via mode-600 temp file (
--data @file), not argv; warning prints status and code only; the fresh PAT is passed inline to thenpxcommand and not assigned to the shell variable.
Needs Verification
- None blocking. The test stubs
curl/npxand extracts the block between markers, so the real@osaas/clihonouringOSC_ACCESS_TOKENfrom env is assumed (that is the existing behaviour of the unchangednpxline).
CI status
- The
buildcheck is failing. I read the log:failed to read dockerfile: open Dockerfile.osc: no such file or directory. The repo's Dockerfile on main isDockerfile, and the workflow still points atDockerfile.osc. This is a pre-existing workflow/file mismatch unrelated to this diff (the PR changes only README, the entrypoint and a test), and the PR body says so. It is not a blocker for this review, but the repo has no real test CI, so the new test only runs locally.
Adjacent Stubs Detected
- Swept
scripts/docker-entrypoint.sh: the only stub-pattern hit is|| trueat line 105, insidejson_field, which is intentional (empty output is treated as failure). Nothing else.
Orphaned Files Detected
- None.
tests/test-entrypoint-runner-refresh.shis a standalone script; the entrypoint is the container entry point. The# BEGIN/END CONFIG LOADmarkers are consumed by the test.
Escape Hatch Coverage
- No new terminal-rejection branch. The failure path explicitly never exits, and the test covers 401 x3, 500, empty/garbled/missing-token body, curl exit 22 and 28, and parser-unavailable, all continuing with the original token.
Object Shape Verification
- No fetched ORM or SDK object is spread. N/A.
Contract diff
- No HTTP request handler changed. Container entrypoint behaviour: job-visible
OSC_ACCESS_TOKENunchanged; one additive env varOSC_REFRESH_TOKEN(optional addition, parameter-store key of the same name still overrides; consumer audit is on issue #6); startup adds one call to the token service bounded by--connect-timeout 5 --max-time 10(the architect cites measured max 133 ms), and a timeout keeps the original token instead of failing (outcome-unknown is not treated as terminal). No new failure modes. Stage 2 swap is explicitly out of scope and birme-gated.
Impact Analysis
- Blast radius: My Jobs runs of this image with
CONFIG_SVCset. - Downstream consumers: jobs reading
OSC_ACCESS_TOKENsee no change. - Coordinated changes needed: none. Open PRs #3 and #5 touch the same lines; the second to merge needs a rebase (stated in the PR).
- Breaking change risk: low.
Risks Not Tested
- Live exchange against the real token service with a real runner refresh token was not exercised; verified from the handler source only.
- Behaviour of the real
@osaas/cliwith the inline env token was not run.
Research Suggestions
- Separately fix the
Dockerfile.oscreference in the docker workflow so the repo gets a green build.
Verdict
No blocking issues found.
Reviewed by PR Research Validator. This review checks whether code is based on verified sources rather than assumptions.
| CI-fix agent started for the failing checks (one cycle per PR). _daily-review Step 4.6_ |
CI failures addressed
A human can apply the one-line change in |
|
CI-fix cycle already ran on this PR (marker 2026-11-08T13:20Z) and the head did not change (last commit 2026-11-08T12:17Z), while the Needed now: look at why the |
Stage 1 of the decision on #6 (comment) (parent: python-runner#39).
Closes #6
What changed
scripts/docker-entrypoint.sh: the runner-token exchange now POSTs{"token": ...}asapplication/json(body from a mode-600 temp file,--connect-timeout 5 --max-time 10). The response is parsed withnode, becausejqis not installed in this image; an empty token counts as failure.config-to-envcommand only.OSC_REFRESH_TOKEN(original token; a parameter store key of the same name still overrides it).|| trueis replaced by a[CONFIG] WARNING: runner token exchange failed (HTTP <status>, code=<code>); using the original tokenon stderr (no token or body printed, never exits).OSC_REFRESH_TOKEN.tests/test-entrypoint-runner-refresh.sh: extracts the config-load block and runs it underset -ewith stub curl/npx. Success case asserts the config load used the NEW token, the job'sOSC_ACCESS_TOKENis unchanged andOSC_REFRESH_TOKENis the original. Failure cases: 401 expired/invalid/revoked, 500, empty and garbled body, missing token key, curl exit 22 and 28. Parser-unavailable case:nodestub exits 127, config load falls back to the original token (not empty). Run locally:ALL PASSED(the repo has no PR CI).Contract
Stage 1 keeps the job-visible
OSC_ACCESS_TOKENunchanged. The Stage 2 swap is out of scope (gated on theREJECT_RUNNER_REFRESH_TOKENSrollout).What a human does next
Nothing.
Notes
The
buildcheck is red on this repo regardless (Dockerfile.oscwas removed upstream); not part of this change. Open PRs #3 and #5 touch the same lines; whichever merges second needs a rebase.Lessons
set -emakes the original config-load error branch unreachable, so every new step in this block is guarded with||/ifand thenpxline is left untouched. A missingjqwould have turned the body-only fix into a silent tokenless config load; the parser-unavailable test pins that.🤖 Generated with Claude Code
Co-Authored-By: Claude noreply@anthropic.com