ScaffoldBench

RunOpus 5.5repeat 1

Plan-execute-verify on HTTP 301 vs 308

claude-opus-5-5__plan-execute-verify__research-http-redirects__r1

Score

1.000

passed
design ran as designed
Cost
$0.669
+ $0.080 judging
Latency
1m 51s
setup 0.0s, grading 4.6s
Turns
32
Tool calls
27
Subagents
0
Tokens in / out
217k / 11k
158,881 read from cache

Did the design run?

every check held
  • Run completed: heldharness.run-completedThe environment was built, the architecture returned and grading finished, none of them throwing.
  • No API failures: heldharness.apiNo model call failed at the API.
  • Every call ended: heldharness.calls-endedEvery call ended with a result, or was stopped by the run's own limits.
  • No harness tool denied: heldharness.harness-toolsThe sandbox guard never denied a harness tool, nor a tool the session itself offered.
  • Tool servers connected: heldharness.mcp-connectedEvery tool server the harness gave a call was connected when the session started.
  • No foreign tool servers: heldharness.mcp-hermeticNo call loaded a tool server the harness did not give it.
  • Builtin tools: heldharness.builtin-toolsA check recorded with the run.
  • Structured replies arrived: heldharness.structured-outputEvery call that asked for structured output and ran to the end got it.
  • No silent fallbacks: heldharness.not-degradedNo phase fell back on a default (an empty plan, a default winner) instead of its output.
  • Judge answered: heldharness.judgeAt least one grading call returned a usable verdict.
  • The plan was a plan: heldplan-execute-verify.planThe planner’s reply was read through its schema and held at least one step.
  • Every verdict was read: heldplan-execute-verify.verdictsEvery review round ended with a verdict read from the schema reply, not a default.
  • The loop did what its verdicts said: heldplan-execute-verify.loopEvery verdict that called for a revision got one, and nothing was revised without such a verdict.
  • Each call was shown the right tools: heldplan-execute-verify.toolsThe planner was shown no tools, the verifier the read-only ones, and the executor and reviser the full toolset.

Phases

Plan: 0.0s to 15.3s, finished, 0 tool calls, $0.029
Execute: 15.3s to 1m 15s, finished, 15 tool calls, $0.377
Verify: 1m 15s to 1m 51s, finished, 12 tool calls, $0.262

Drawn from the phase records: timing and cost per call, no tool calls or messages.

PhaseDurationCostTurnsToolsModel
Plan15.3s$0.02920claude-opus-5-5
Execute1m 0s$0.3771615claude-opus-5-5
Verify35.4s$0.2621412claude-opus-5-5

The call-by-call replay is not published for this run. Traces are large, so the repository keeps 9 of this run set’s 900 and leaves the rest out; the score, phases and final answer on this page come from the committed run record.

Runs you can replay

Record this cell yourself: npm run bench -- run --strategies plan-execute-verify --tasks research-http-redirects --models claude-opus-5-5 --repeats 1

Score breakdown

  • passStates that 301 is "Moved Permanently" and 308 is "Permanent Redirect", and that both indicate the target resource has been assigned a new permanent URI.
    1.00weight 0.17

    met, backed by verified evidence E1, E2. “The target resource "has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs"”

  • passStates that a client following a 308 must not change the request method: a POST is repeated as a POST, with its body.
    1.00weight 0.25

    met, backed by verified evidence E7, E10, E9. “After a 308, the client must send the same method and body to the new URI.”

  • passStates that when following a 301 a user agent MAY change the request method from POST to GET (for historical reasons), which is the behaviour 308 exists to rule out.
    1.00weight 0.25

    met, backed by verified evidence E4, E7. “RFC 9110 lets a user agent change POST to GET "for historical reasons,"”

  • passStates that both 301 and 308 responses are heuristically cacheable, i.e. a cache may reuse them by default unless the method definition or explicit cache controls say otherwise.
    1.00weight 0.17

    met, backed by verified evidence E12, E13, E14. “RFC 9110 says both 301 and 308 are "heuristically cacheable." That means a cache may store and reuse them with an estimated lifetime, unless the method definition or explicit cache controls say otherwise.”

  • passStates that both codes are currently specified in RFC 9110 (HTTP Semantics), and that 308 was originally defined in RFC 7538, which RFC 9110 obsoletes.
    1.00weight 0.17

    met, backed by verified evidence E17, E18. “RFC 9110 obsoletes RFC 7231, the earlier home of 301, and RFC 7538 (April 2015), the standalone 308 spec.”

Penalties

No penalties were applied.

Scorer metadata

corpus
{"version":2,"snapshot":"2026-10-01","hash":"25fbed79c4f7f9e1b850436e0e4872f8e25dd80142f3177231c456f21817b817","documents":8}
opened documents
["rfc9110","rfc7538","rfc9111","mdn-status-301","mdn-status-308"]
opened by role
{"primary":["rfc9110"],"superseded":["rfc7538"],"secondary":["rfc9111","mdn-status-301","mdn-status-308"]}
displayed share
{"rfc9110":0.0818,"rfc7538":0.782,"rfc9111":0.1073,"mdn-status-301":1,"mdn-status-308":1}
cited count
5
verified count
5
hallucinated count
0
citation integrity
1
hallucinated urls
[]
evidence block
true
evidence block repaired
false
evidence count
18
verified quote count
17
verified quote rate
0.9444444444444444 (94%)
evidence
[{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"RFC 9110 defines 301 as a resource that has been given a new permanent URI.","quote":"The 301 (Moved Permanently) status code indicates that the target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"RFC 9110 defines 308 with the same permanent-move meaning.","quote":"The 308 (Permanent Redirect) status code indicates that the target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"For both codes the server should send a Location header with the new permanent URI.","quote":"The server SHOULD generate a Location header field in the response containing a preferred URI reference for the new permanent URI.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"For 301, RFC 9110 allows a user agent to change POST to GET.","quote":"request method from POST to GET for the subsequent request.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"Historically, practice settled on changing the method to GET for 301/302.","quote":"Prevailing practice","verified":false,"document":"rfc9110","failure":"the quote has fewer than 6 consecutive words"},{"url":"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301","claim":"Under the Fetch Standard, browsers send a GET after a 301 response to a POST.","quote":"Note: In the Fetch Standard, when a user agent receives a 301 in response to a POST request, it uses the GET method in the subsequent redirection request, as permitted by the HTTP specification.","verified":true,"document":"mdn-status-301"},{"url":"https://www.rfc-editor.org/rfc/rfc7538.html","claim":"308 is like 301 except that the method may not be changed from POST to GET.","quote":"Note: This status code is similar to 301 (Moved Permanently) ([RFC7231], Section 6.4.2), except that it does not allow changing the request method from POST to GET.","verified":true,"document":"rfc7538"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"When following a redirect, the user agent should resend the original request with only certain changes.","quote":"When automatically following a redirected request, the user agent SHOULD resend the original request message with the following modifications:","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"Body-related headers are removed only when the method is changed to GET or HEAD, so a 308 keeps the body.","quote":"If the request method has been changed to GET or HEAD, remove content-specific header fields, including (but not limited to) Content-Encoding, Content-Language, Content-Location, Content-Type, Content-Length, Digest, Last-Modified.","verified":true,"document":"rfc9110"},{"url":"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308","claim":"MDN says that with 308 the method and body stay the same.","quote":"The request method and the body will not be modified by the client in the redirected request.","verified":true,"document":"mdn-status-308"},{"url":"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308","claim":"MDN's 308 page says 301 requires the method to stay the same, which conflicts with RFC 9110.","quote":"A 301 Moved Permanently requires the request method and the body to remain unchanged when redirection is performed, but this is incorrectly handled by older clients to use the GET method instead.","verified":true,"document":"mdn-status-308"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"A 301 is heuristically cacheable.","quote":"A 301 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]).","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"A 308 is heuristically cacheable.","quote":"A 308 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]).","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"RFC 9110 lists 301 and 308 among the heuristically cacheable status codes.","quote":"Responses with status codes that are defined as heuristically cacheable (e.g., 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 501 in this specification) can be reused by a cache with heuristic expiration unless otherwise indicated by the method definition or explicit cache controls [CACH\n…[truncated 61 chars]","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9111.html","claim":"\"Heuristically cacheable\" used to be called \"cacheable by default\".","quote":"Note that in previous specifications, heuristically cacheable response status codes were called \"cacheable by default\".","verified":true,"document":"rfc9111"},{"url":"https://www.rfc-editor.org/rfc/rfc7538.html","claim":"RFC 7538 said 308 was cacheable by default.","quote":"A 308 response is cacheable by default; i.e., unless otherwise indicated by the method definition or explicit cache controls (see [RFC7234], Section 4.2.2).","verified":true,"document":"rfc7538"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"RFC 9110 obsoletes RFC 7231 and RFC 7538.","quote":"This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc7538.html","claim":"RFC 7538 added 308 as the missing permanent version of 307.","quote":"Section 6.4.7 of [RFC7231] states that it does not define a permanent variant of status code 307; this specification adds the status code 308, defining this missing variant (Section 3).","verified":true,"document":"rfc7538"}]
judge unverified quotes
0
judge verdicts
[{"names":{"status":"met","support":["E1","E2"]},"method-preserved-308":{"status":"met","support":["E7","E10","E9"]},"method-change-301":{"status":"met","support":["E4","E5","E7"]},"cacheable":{"status":"met","support":["E12","E13","E14"]},"specifications":{"status":"met","support":["E17","E18"]}},{"names":{"status":"met","support":["E1","E2"]},"method-preserved-308":{"status":"met","support":["E7","E10","E9"]},"method-change-301":{"status":"met","support":["E4","E5","E7"]},"cacheable":{"status":"met","support":["E12","E13","E14"]},"specifications":{"status":"met","support":["E17","E18","E7"]}},{"names":{"status":"met","support":["E1","E2"]},"method-preserved-308":{"status":"met","support":["E7","E10","E9"]},"method-change-301":{"status":"met","support":["E4","E5","E7"]},"cacheable":{"status":"met","support":["E12","E13","E14"]},"specifications":{"status":"met","support":["E17","E18"]}}]
judge failures
0
grounded weight share
1

Final answer

301 vs 308: what's the difference?

Both codes mean "this resource has moved permanently." The difference is what a client may do with the request. After a 301, a client is allowed to turn a POST into a GET, and browsers do. After a 308, the client must send the same method and body to the new URI. Both are cacheable by default, and both are defined today in RFC 9110 (June 2022).

What each code means. RFC 9110 gives 301 and 308 the same opening definition. The target resource "has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs" (https://www.rfc-editor.org/rfc/rfc9110.html). For both codes the server SHOULD send a Location header with the preferred new URI, and the user agent MAY use it to redirect automatically. RFC 9110 puts 301, 302, 307 and 308 in the same group: redirects that point to a different URI given in the Location header.

Method and body.

  • 301: RFC 9110 lets a user agent change POST to GET "for historical reasons," and says to use 308 if you don't want that. It also explains the history. In HTTP/1.0, 301 and 302 were meant to keep the method. Early browsers disagreed on whether to resend POST as POST or as GET, and "Prevailing practice eventually converged on changing the method to GET." So 307 and 308 were added to mark redirects that keep the method. MDN says that under the Fetch Standard, a browser that gets a 301 in response to a POST does send a GET next (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301).
  • 308: RFC 7538, which first defined 308, says it is like 301 "except that it does not allow changing the request method from POST to GET" (https://www.rfc-editor.org/rfc/rfc7538.html).
  • The request body: RFC 9110's general redirect rule says the user agent SHOULD resend the original request with only certain changes. It removes the body-related headers (Content-Type, Content-Length and so on) only when the method has been changed to GET or HEAD. So after a 308, the original body is sent again. After a 301 that turns POST into GET, the body is dropped. MDN's 308 page says the same: "The request method and the body will not be modified" (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308).
  • Wording difference: RFC 9110's own 308 section doesn't contain a "MUST NOT change the request method" sentence. The 307 section has one, but 308 doesn't. In RFC 9110 the method-keeping rule for 308 comes from the 3xx overview and from RFC 7538.

Where the sources disagree. MDN's 308 page says "A 301 Moved Permanently requires the request method and the body to remain unchanged" and that older clients get this wrong by switching to GET. That doesn't match RFC 9110, which explicitly allows POST→GET on a 301, or MDN's own 301 page, which calls the switch to GET "permitted by the HTTP specification." I'd go with RFC 9110: on a 301, changing POST to GET is allowed, not a client bug.

Caching. RFC 9110 says both 301 and 308 are "heuristically cacheable." That means a cache may store and reuse them with an estimated lifetime, unless the method definition or explicit cache controls say otherwise. Section 15.1 lists both codes among the heuristically cacheable ones. RFC 9111 (HTTP Caching) explains that this applies to responses that don't state their own freshness. Earlier specs called this "cacheable by default," which is the wording RFC 7538 uses for 308 (https://www.rfc-editor.org/rfc/rfc9111.html).

Where they're specified. The current spec is RFC 9110, HTTP Semantics (June 2022): §15.4.2 for 301 and §15.4.9 for 308. RFC 9110 obsoletes RFC 7231, the earlier home of 301, and RFC 7538 (April 2015), the standalone 308 spec. RFC 7538 itself replaced the Experimental RFC 7238. RFC 9110 also notes that 308 is newer (June 2014), so some clients may not recognise it.

{"evidence": [
{"claim": "RFC 9110 defines 301 as a resource that has been given a new permanent URI.", "quote": "The 301 (Moved Permanently) status code indicates that the target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "RFC 9110 defines 308 with the same permanent-move meaning.", "quote": "The 308 (Permanent Redirect) status code indicates that the target resource has been assigned a new permanent URI and any future references to this resource ought to use one of the enclosed URIs.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "For both codes the server should send a Location header with the new permanent URI.", "quote": "The server SHOULD generate a Location header field in the response containing a preferred URI reference for the new permanent URI.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "For 301, RFC 9110 allows a user agent to change POST to GET.", "quote": "request method from POST to GET for the subsequent request.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "Historically, practice settled on changing the method to GET for 301/302.", "quote": "Prevailing practice", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "Under the Fetch Standard, browsers send a GET after a 301 response to a POST.", "quote": "Note: In the Fetch Standard, when a user agent receives a 301 in response to a POST request, it uses the GET method in the subsequent redirection request, as permitted by the HTTP specification.", "url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301"},
{"claim": "308 is like 301 except that the method may not be changed from POST to GET.", "quote": "Note: This status code is similar to 301 (Moved Permanently) ([RFC7231], Section 6.4.2), except that it does not allow changing the request method from POST to GET.", "url": "https://www.rfc-editor.org/rfc/rfc7538.html"},
{"claim": "When following a redirect, the user agent should resend the original request with only certain changes.", "quote": "When automatically following a redirected request, the user agent SHOULD resend the original request message with the following modifications:", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "Body-related headers are removed only when the method is changed to GET or HEAD, so a 308 keeps the body.", "quote": "If the request method has been changed to GET or HEAD, remove content-specific header fields, including (but not limited to) Content-Encoding, Content-Language, Content-Location, Content-Type, Content-Length, Digest, Last-Modified.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "MDN says that with 308 the method and body stay the same.", "quote": "The request method and the body will not be modified by the client in the redirected request.", "url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308"},
{"claim": "MDN's 308 page says 301 requires the method to stay the same, which conflicts with RFC 9110.", "quote": "A 301 Moved Permanently requires the request method and the body to remain unchanged when redirection is performed, but this is incorrectly handled by older clients to use the GET method instead.", "url": "https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308"},
{"claim": "A 301 is heuristically cacheable.", "quote": "A 301 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]).", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "A 308 is heuristically cacheable.", "quote": "A 308 response is heuristically cacheable; i.e., unless otherwise indicated by the method definition or explicit cache controls (see Section 4.2.2 of [CACHING]).", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "RFC 9110 lists 301 and 308 among the heuristically cacheable status codes.", "quote": "Responses with status codes that are defined as heuristically cacheable (e.g., 200, 203, 204, 206, 300, 301, 308, 404, 405, 410, 414, and 501 in this specification) can be reused by a cache with heuristic expiration unless otherwise indicated by the method definition or explicit cache controls [CACHING]; all other status codes are not heuristically cacheable.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "\"Heuristically cacheable\" used to be called \"cacheable by default\".", "quote": "Note that in previous specifications, heuristically cacheable response status codes were called \"cacheable by default\".", "url": "https://www.rfc-editor.org/rfc/rfc9111.html"},
{"claim": "RFC 7538 said 308 was cacheable by default.", "quote": "A 308 response is cacheable by default; i.e., unless otherwise indicated by the method definition or explicit cache controls (see [RFC7234], Section 4.2.2).", "url": "https://www.rfc-editor.org/rfc/rfc7538.html"},
{"claim": "RFC 9110 obsoletes RFC 7231 and RFC 7538.", "quote": "This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "RFC 7538 added 308 as the missing permanent version of 307.", "quote": "Section 6.4.7 of [RFC7231] states that it does not define a permanent variant of status code 307; this specification adds the status code 308, defining this missing variant (Section 3).", "url": "https://www.rfc-editor.org/rfc/rfc7538.html"}
]}

Provenance of the numbers on this page

run set
scaffold-or-scale-v1
models
Haiku 4.5, Sonnet 5.5, Opus 5.5
effort
high
repeats
2
fixtures
replay
runs
900 / 900
strategy cost
$354.44
judge cost
$9.19
wall clock
9h 48m
git
fce5807b2d

Cost excludes judge calls, which are tracked separately so a scoring model never flatters or penalises an architecture. Every figure on this site is read from results/ at build time.