ScaffoldBench

RunOpus 5.5repeat 1

Plan-execute on HTTP 301 vs 308

claude-opus-5-5__plan-execute__research-http-redirects__r1

Score

1.000

passed
design ran as designed
Cost
$0.319
+ $0.076 judging
Latency
1m 4s
setup 0.0s, grading 5.4s
Turns
13
Tool calls
10
Subagents
0
Tokens in / out
91k / 6.3k
65,726 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.planThe planner’s reply was read through its schema and held at least one step.
  • Each call was shown the right tools: heldplan-execute.toolsThe planner was shown no tools and the executor the task’s full toolset.

Phases

Plan: 0.0s to 15.7s, finished, 0 tool calls, $0.039
Execute: 15.7s to 1m 4s, finished, 10 tool calls, $0.280

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

PhaseDurationCostTurnsToolsModel
Plan15.7s$0.03920claude-opus-5-5
Execute47.8s$0.2801110claude-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 --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. “Each one says 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 E6, E7. “The client must keep the original method and body.”

  • 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 E3, E4. “For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request.”

  • 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 E10, E11. “Both are "heuristically cacheable," meaning a cache can store them by default 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 E13, E12, E14. “Both are currently defined in RFC 9110, *HTTP Semantics* (June 2022): 301 in §15.4.2 and 308 in §15.4.9.”

Penalties

No penalties were applied.

Scorer metadata

corpus
{"version":2,"snapshot":"2026-10-01","hash":"25fbed79c4f7f9e1b850436e0e4872f8e25dd80142f3177231c456f21817b817","documents":8}
opened documents
["rfc9110","rfc7538","mdn-status-308","mdn-status-301"]
opened by role
{"primary":["rfc9110"],"superseded":["rfc7538"],"secondary":["mdn-status-308","mdn-status-301"]}
displayed share
{"rfc9110":0.0629,"rfc7538":0.782,"mdn-status-308":1,"mdn-status-301":1}
cited count
4
verified count
4
hallucinated count
0
citation integrity
1
hallucinated urls
[]
evidence block
true
evidence block repaired
false
evidence count
14
verified quote count
14
verified quote rate
1
evidence
[{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"301 means the resource has a new permanent URI that future references should use.","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":"308 has the same permanent-redirect 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":"On a 301, a user agent may change POST to GET for historical reasons; 308 is the alternative.","quote":"For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"307 and 308 were added as unambiguously method-preserving redirects, while 301 and 302 were adjusted to allow POST to become GET.","quote":"307\n | (Temporary Redirect) and 308 (Permanent Redirect) [RFC7538]\n | were later added to unambiguously indicate method-preserving\n | redirects, and status codes 301 and 302 have been adjusted to\n | allow a POST request to be redirected as GET.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"If the method changes to GET or HEAD when following a redirect, content-specific headers are removed, so the body is dropped.","quote":"If the request method has been changed to GET or HEAD, remove\n content-specific header fields, including (but not limited to)\n Content-Encoding, Content-Language, Content-Location,\n Content-Type, Content-Length, Digest, Last-Modified.","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc7538.html","claim":"308 is like 301 but does not allow changing POST to GET.","quote":"Note: This status code is similar to 301 (Moved Permanently)\n ([RFC7231], Section 6.4.2), except that it does not allow changing\n the request method from POST to GET.","verified":true,"document":"rfc7538"},{"url":"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308","claim":"MDN says the method and body are unchanged on a 308.","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 claims 301 requires the method and body to stay unchanged, 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://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301","claim":"Under the Fetch Standard, browsers use GET after a 301 response to a POST, as the HTTP spec permits.","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/rfc9110.html","claim":"301 is heuristically cacheable.","quote":"A 301 response is heuristically cacheable; i.e., unless otherwise\n indicated by the method definition or explicit cache controls (see\n Section 4.2.2 of [CACHING]).","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"308 is heuristically cacheable.","quote":"A 308 response is heuristically cacheable; i.e., unless otherwise\n indicated by the method definition or explicit cache controls (see\n Section 4.2.2 of [CACHING]).","verified":true,"document":"rfc9110"},{"url":"https://www.rfc-editor.org/rfc/rfc7538.html","claim":"RFC 7538 originally described 308 as cacheable by default.","quote":"A 308 response is cacheable by default; i.e., unless otherwise\n indicated by the method definition or explicit cache controls (see\n [RFC7234], Section 4.2.2).","verified":true,"document":"rfc7538"},{"url":"https://www.rfc-editor.org/rfc/rfc9110.html","claim":"RFC 9110 obsoletes RFC 7231 (the earlier home of 301) and RFC 7538 (the earlier home of 308).","quote":"This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232,\n 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 replaced the experimental RFC 7238 with no technical changes.","quote":"This specification contains no technical changes from the\n Experimental RFC 7238, which it obsoletes.","verified":true,"document":"rfc7538"}]
judge unverified quotes
0
judge verdicts
[{"names":{"status":"partial","support":["E1","E2"]},"method-preserved-308":{"status":"met","support":["E6","E7"]},"method-change-301":{"status":"met","support":["E3","E4"]},"cacheable":{"status":"met","support":["E10","E11"]},"specifications":{"status":"met","support":["E13","E12","E14"]}},{"names":{"status":"met","support":["E1","E2"]},"method-preserved-308":{"status":"met","support":["E6","E7"]},"method-change-301":{"status":"met","support":["E3","E4"]},"cacheable":{"status":"met","support":["E10","E11"]},"specifications":{"status":"met","support":["E13"]}},{"names":{"status":"met","support":["E1","E2"]},"method-preserved-308":{"status":"met","support":["E6","E7"]},"method-change-301":{"status":"met","support":["E3","E4"]},"cacheable":{"status":"met","support":["E10","E11"]},"specifications":{"status":"met","support":["E13","E4"]}}]
judge failures
0
grounded weight share
1

Final answer

I've finished reading RFC 9110, RFC 7538 and MDN, and I'm writing up the answer now.

301 vs 308

What they mean. Both are permanent redirects, and RFC 9110 defines them in nearly the same words. Each one says 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." For each, the server SHOULD send a Location header with the new URI, and the user agent MAY follow it automatically (https://www.rfc-editor.org/rfc/rfc9110.html, §15.4.2 and §15.4.9). The only real difference is how the request method and body are handled.

Method and body.

  • 301: RFC 9110 says: "For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request." If you don't want that, it recommends using 308 instead (https://www.rfc-editor.org/rfc/rfc9110.html, §15.4.2).

    • The reason is history. In HTTP/1.0, 301 and 302 were meant to keep the method. Early browsers disagreed on this, and "Prevailing practice eventually converged on changing the method to GET." 307 and 308 "were later added to unambiguously indicate method-preserving redirects." At the same time, 301 and 302 were adjusted to allow POST to become GET (§15.4).
    • When a client follows a redirect, it resends the original request. If the method has become GET or HEAD, it removes content-specific headers such as Content-Type and Content-Length (§15.4, step 5). So a POST that is redirected by a 301 usually loses its body.
    • MDN says the Fetch Standard (which browsers follow) uses GET after a 301 response to a POST (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/301).
  • 308: The client must keep the original method and body. RFC 7538 says 308 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). Since the method stays the same, the client resends the original request, body included, under the general rule in RFC 9110 §15.4.

    • One detail: RFC 9110's own §15.4.9 has no "MUST NOT change the method" sentence, unlike its §15.4.8 for 307. The method-preserving rule for 308 comes from the §15.4 history note and the 301 note.
    • MDN agrees: "The request method and the body will not be modified by the client in the redirected request" (https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/308).

Where MDN disagrees with the RFC. MDN's 308 page also says that 301 "requires the request method and the body to remain unchanged," and that older clients get this wrong. That doesn't match RFC 9110, which explicitly allows changing POST to GET after a 301. It also doesn't match MDN's own 301 page, which says this change is "permitted by the HTTP specification." The RFC is the authoritative source here.

Caching. Both are "heuristically cacheable," meaning a cache can store them by default unless the method definition or explicit cache controls say otherwise (https://www.rfc-editor.org/rfc/rfc9110.html, §15.4.2 and §15.4.9). RFC 7538 described 308 as "cacheable by default," which means essentially the same thing (https://www.rfc-editor.org/rfc/rfc7538.html).

Where they are specified. Both are currently defined in RFC 9110, HTTP Semantics (June 2022): 301 in §15.4.2 and 308 in §15.4.9.

  • 308 first appeared in the experimental RFC 7238. RFC 7538 (April 2015) replaced that "with no technical changes," and RFC 9110 has since replaced RFC 7538.
  • 301 was previously defined in RFC 7231, which RFC 9110 also replaces. RFC 9110's front matter says it "obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230."
  • The copy of RFC 7538 I fetched doesn't show an "Obsoleted by" note, so that fact comes from RFC 9110 alone.
  • RFC 9110 also warns that 308 is newer than the other codes and "might not be recognized everywhere."
{"evidence": [
{"claim": "301 means the resource has a new permanent URI that future references should use.", "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": "308 has the same permanent-redirect 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": "On a 301, a user agent may change POST to GET for historical reasons; 308 is the alternative.", "quote": "For historical reasons, a user agent MAY change the request method from POST to GET for the subsequent request.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "307 and 308 were added as unambiguously method-preserving redirects, while 301 and 302 were adjusted to allow POST to become GET.", "quote": "307\n      |  (Temporary Redirect) and 308 (Permanent Redirect) [RFC7538]\n      |  were later added to unambiguously indicate method-preserving\n      |  redirects, and status codes 301 and 302 have been adjusted to\n      |  allow a POST request to be redirected as GET.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "If the method changes to GET or HEAD when following a redirect, content-specific headers are removed, so the body is dropped.", "quote": "If the request method has been changed to GET or HEAD, remove\n       content-specific header fields, including (but not limited to)\n       Content-Encoding, Content-Language, Content-Location,\n       Content-Type, Content-Length, Digest, Last-Modified.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "308 is like 301 but does not allow changing POST to GET.", "quote": "Note: This status code is similar to 301 (Moved Permanently)\n      ([RFC7231], Section 6.4.2), except that it does not allow changing\n      the request method from POST to GET.", "url": "https://www.rfc-editor.org/rfc/rfc7538.html"},
{"claim": "MDN says the method and body are unchanged on a 308.", "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 claims 301 requires the method and body to stay unchanged, 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": "Under the Fetch Standard, browsers use GET after a 301 response to a POST, as the HTTP spec permits.", "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": "301 is heuristically cacheable.", "quote": "A 301 response is heuristically cacheable; i.e., unless otherwise\n   indicated by the method definition or explicit cache controls (see\n   Section 4.2.2 of [CACHING]).", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "308 is heuristically cacheable.", "quote": "A 308 response is heuristically cacheable; i.e., unless otherwise\n   indicated by the method definition or explicit cache controls (see\n   Section 4.2.2 of [CACHING]).", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "RFC 7538 originally described 308 as cacheable by default.", "quote": "A 308 response is cacheable by default; i.e., unless otherwise\n   indicated by the method definition or explicit cache controls (see\n   [RFC7234], Section 4.2.2).", "url": "https://www.rfc-editor.org/rfc/rfc7538.html"},
{"claim": "RFC 9110 obsoletes RFC 7231 (the earlier home of 301) and RFC 7538 (the earlier home of 308).", "quote": "This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232,\n   7233, 7235, 7538, 7615, 7694, and portions of 7230.", "url": "https://www.rfc-editor.org/rfc/rfc9110.html"},
{"claim": "RFC 7538 replaced the experimental RFC 7238 with no technical changes.", "quote": "This specification contains no technical changes from the\n   Experimental RFC 7238, which it obsoletes.", "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.