BuilderProof editorial team21 min read7 views

Does the link you shared last month still work? A permalink durability axis proposal (October 2026)

The person who renames a record is the one holding the new address, so the only copy of the old one is in somebody else's bookmark. This proposal scores whether a retired address still resolves, whether the redirect is resolved from data at request time, and whether a deliberate removal is distinguishable from a typo.

Updated on October 2, 2026

Flat minimal diagram, off-white background: two horizontal rounded rectangles in thin slate-grey. The upper has a dashed outline; the lower is solid and slightly shorter. One curved arrow drops from the dashed shape to the solid one. No text.
Flat minimal diagram, off-white background: two horizontal rounded rectangles in thin slate-grey. The upper has a dashed outline; the lower is solid and slightly shorter. One curved arrow drops from the dashed shape to the solid one. No text.
On this page

Quick answer (October 2026): this is a pre-registration, not a result. It proposes that AI app builders be scored on permalink durability: whether an address that already worked keeps working after the thing it names is renamed, merged or removed. The failure is invisible to the person who causes it, because the only copy of the retired address is in somebody else's bookmark, inbox or hyperlink. Seven weighted signals, four postures and a ten-step protocol are proposed below. No builder is scored and no placement is published.

Why we are proposing this axis

A generated application almost always puts something human-readable in the address. A project becomes /projects/q4-pricing-review. A customer becomes /customers/northwind-trading. A document becomes /docs/onboarding-checklist. This is good practice and we have said so ourselves.

Then somebody edits the title. The heading updates, the list updates, the address bar updates, and the application reports nothing at all, because from where it is standing nothing has gone wrong. The record is intact. The new address works. Every surface the application controls has been brought into agreement.

What has changed is a string the application no longer emits anywhere. That string is sitting in a Slack message from three weeks ago, in a bookmark, in a client email, in a ticket, and possibly in another site's hyperlink. None of those are places the application can reach, and none of them will tell it what happened.

This axis is about that interval: the time between an address being handed out and that address being used, during which the thing it names is allowed to change.

Every axis we propose names the illusion that hides its defect. This one is the fresh-link illusion, and it is the thirty-third member of the one-actor family we have been tracking: a defect whose only cheap evidence at test time is generated by the same actor who would have to notice it.

The person who renames a record is already looking at that record. Their browser is on the page. The application navigates them to the new address in place, and that address works. That is the entire observation the act of renaming produces, and it is a confirming one.

To obtain a disconfirming observation you need the old address. Here is the sub-form that makes this trap distinct from the ones we have already named, and it is an inversion of the one we described two days ago: the input required to exercise this failure is a string the application has deliberately stopped emitting. You cannot ask for it. The address bar has moved on. The share button produces the new one. The list links to the new one. The sitemap, if there is one, has been regenerated with the new one. Every channel through which the application would normally hand you a URL has been updated, correctly, as part of the same operation that broke the old one.

So the test input has to be kept by hand, outside the system, before the change, by somebody who already suspected. That is a different shape from the round-trip illusion we named in our bulk-import correctness proposal, where the test input is manufactured by the system under test and therefore cannot fail. Here the test input is one the system under test refuses to produce. The two are duals, and both resolve the same way: the input has to come from outside, and nothing in the ordinary act of building will ever put it there.

The loop is closed at the other end as well. Nobody who hits the dead address has a channel back. They get a 404 page belonging to an application they may not have an account for, about a record whose new name they do not know, and the overwhelmingly likely outcome is that they give up and say nothing.

What the specification actually says, including the part that undercuts the obvious remedy

IETF logo The obvious remedy is a redirect, and HTTP has had one for a very long time. It is worth reading what the current specification says it does, because one sentence in it is routinely assumed away.

RFC 9110 describes 301 as indicating 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", and says the server "is suggesting that a user agent with link-editing capability can permanently replace references to the target URI". Then it adds the part that matters:

RFC 9110, section 15.4.2, verbatim: "However, this suggestion is usually ignored unless the user agent is actively editing references (e.g., engaged in authoring content), the connection is secured, and the origin server is a trusted authority for the content being edited."

Section 15.4.9 says the same thing, word for word, about 308.

So a permanent redirect does not repair the shared link. It keeps the old address resolving. The copy in the Slack message stays wrong forever and simply continues to work by indirection. That is a good outcome, and it is a weaker one than the status code's name implies, and it means the redirect can never be retired on the theory that references have caught up by now. The specification says they have not.

Two further details from the same document shape the rubric below.

Cacheability. RFC 9110 states that a 301 response "is heuristically cacheable" and says the same of a 308. Permanence is therefore sticky in both directions: the status that best serves durability is also the one that is hardest to take back if the move turns out to be wrong.

410 and the facility to determine. Section 15.5.11 says 410 "indicates that access to the target resource is no longer available at the origin server and that this condition is likely to be permanent", that it is "primarily intended to assist the task of web maintenance by notifying the recipient that the resource is intentionally unavailable and that the server owners desire that remote links to that resource be removed", and, decisively for a generated app:

RFC 9110, section 15.5.11, verbatim: "If the origin server does not know, or has no facility to determine, whether or not the condition is permanent, the status code 404 (Not Found) ought to be used instead."

Read that as a requirement on the data model rather than on the response layer. To answer 410 honestly an application must still hold the knowledge that this address once named something and that the something was deliberately removed. An application that deletes the row has destroyed exactly that knowledge, and is then correct to answer 404.

Where the framework pushes back

The dominant output format among the builders we track is a Next.js application, so what that framework makes easy is a large part of what gets generated.

Next.js logo Next.js documents redirects as a key in next.config.js. The documentation states that redirects "can be defined as a synchronous or async function" which "should return, or resolve to, an array of objects with source, destination, and permanent properties", that permanent: true "will use the 308 status code which instructs clients/search engines to cache the redirect forever", that false uses 307 which "is temporary and is not cached", and that "Redirects are checked before the filesystem which includes pages and /public files".

This is a good mechanism and it is a build-time one. That is the structural finding of this proposal, and it is worth stating plainly:

A rename performed by a user at three in the afternoon cannot add an entry to a configuration array. The array is read when the application is built. Honouring a user-caused address change therefore requires something the framework's headline redirect feature cannot provide: a lookup, at request time, against persisted data recording which addresses have been retired and what replaced them. Next.js can do that, through a route handler, the redirect function or a proxy, and none of it is what the redirects key is. It has to be authored.

That is the gap this axis exists to measure. The built-in affordance covers the case a developer anticipates at build time, which is the case a developer is thinking about while building. The case nobody is thinking about is the one the users will cause later, repeatedly, forever.

One credit where it is due, and it is the fifth-shape observation this proposal records in the inverted direction. permanent is not optional and has no default: the documentation lists it among the three properties the object should carry, and notes that the alternative statusCode property may be used "instead of the permanent property, but not both". The framework forces a decision about permanence at the moment a redirect is written. One layer up, nothing asks whether the address should have been derived from a mutable title in the first place. That decision is never presented, and so it is never taken.

What the crawler side says, and the documented disincentive for the lazy fix

Google logo Google's site-move documentation is a primary source about how a search engine treats a retired address, and it supplies both a duration and an explicit warning against the cheap remedy.

On duration: "Keep the redirects for as long as possible, generally at least 1 year." The same page continues, "From users' perspective, consider keeping redirects indefinitely."

On the cheap remedy: "Don't redirect many old URLs to one irrelevant single URL destination, such as the home page of the new site. This can confuse users and might be treated as a soft 404 error."

That second quotation is why signal 7 below exists. Sweeping every unmatched address to the root is the fix a generated application is most likely to already contain, because a catch-all route is easy and it makes the 404 go away. It converts a legible failure into an illegible success, and the search engine's own documentation says it may be read as a soft 404 anyway.

Google's redirect documentation also states the split that makes signal 5 matter: "Permanent redirects: Show the new redirect target in search results. Temporary redirects: Show the source page in search results." Choosing the wrong one does not merely mislabel the move, it decides which of two addresses a search engine goes on showing.

The rubric

Seven signals, weights summing to 100. The failing description is what a zero looks like, so the rubric can be applied by inspection and by probe rather than from a vendor's description of itself. The weights are the part we most want argued with.

Scroll to see more

SignalWeightWhat a failing case looks like
A former address still resolves to the thing it named22The address is derived from mutable text and regenerated whenever that text is saved, so an ordinary edit retires the old address and every external copy of it returns 404
The redirect is resolved at request time from data20The only redirect mechanism in the application is a static array in the framework configuration, so an address change caused by a user cannot be honoured without a code change and a redeploy
The retired address is persisted at the moment it is retired16The slug column is overwritten in place, so the one string needed to honour the old address is destroyed by the same write that invalidates it, and no later fix can recover it
A removed resource is distinguished from one that never existed14Every unrecognised address returns the same generic 404, so nothing tells a reader or a crawler the difference between a record that was deliberately deleted and a mistyped identifier
Permanence is a recorded decision, not a default12The status code is whatever the first redirect anyone wrote happened to use, with nothing recording whether the retirement was meant to be permanent, and so no basis for ever changing it
A merge is honoured, not just a rename9Two records are combined and only the surviving address works, so the absorbed record's address returns 404 rather than resolving to the record that now contains its contents
Unmatched addresses are not swept to a root7A catch-all rule redirects anything unrecognised to the home page or a dashboard, so the application returns success for an address it cannot honour and the reader lands somewhere that does not contain what they were sent to

Two deliberate choices. Request-time resolution carries 20, nearly as much as the outcome it produces, because it is the only signal that discriminates between an application that has been made durable and one that merely has not been renamed yet. And persisting the retired address carries 16 despite producing no visible behaviour on its own, because it is the only step in the list that cannot be performed retrospectively. Everything else on this rubric can be added next quarter. A slug overwritten in place last March is gone.

Four postures

Level 0, Volatile. The address is a pure function of mutable text and is recomputed whenever that text is saved. No record of any previous address exists anywhere in the system. Every edit silently retires every external copy. This is the natural output of generating a resource route from a title field and never being asked what happens to the old one.

Level 1, Stable by construction. The address is built from an identifier no user can change. Nothing a person does in the interface can break a link. There is no durability mechanism because nothing has yet needed one.

Level 2, Redirected. Retired addresses are persisted and resolved at request time against stored data, with a declared permanence, and they survive a deploy.

Level 3, Durable and accountable. As level 2, and additionally a deliberate removal is distinguishable from an address that never existed, a merge resolves to the absorbing record, and the application can state when an address was retired and what replaced it.

The ladder is uneven and we think that is correct rather than a defect in the scale. Moving from 0 to 1 is a schema decision taken once, before anything ships, about what belongs in an address. Moving from 1 to 2 is a permanent operational obligation: a table of retired addresses that grows forever and may never be truncated, which is precisely what the specification's "usually ignored" sentence implies. Those are not two steps of one loop and a scorer should not expect them to cost the same.

The measurement protocol

  1. Enumerate the routes that address a record rather than a screen, and note for each one what the address is derived from.
  2. Create a record with a distinctive title. Record its address verbatim in a file outside the application. This step is not ceremony. It is the only opportunity to capture the test input, because every later step destroys it.
  3. Rename the record through the ordinary interface, the way a user would.
  4. Control, carrying no information. Open the new address. It will work. Record it anyway, so the log distinguishes a check that was performed and proved nothing from a check that was skipped. This step is the trap itself written down: it is the whole of the evidence that renaming ordinarily generates, and it is confirming by construction.
  5. Request the address recorded in step 2 with redirect following disabled. Record the status code, the Location value if any, and whether a body was returned.
  6. Follow the redirect if there is one. Record whether the destination is the renamed record, a list, a root, or an error. A redirect that resolves to something other than the thing originally named is a different failure from no redirect at all, and should be scored as one.
  7. Trigger a deploy, or wait for the next one, and repeat steps 5 and 6. This separates a redirect resolved from data at request time from a configuration entry a human added by hand, and only the first survives the next rename.
  8. Delete a record. Request its address. Record whether the response is 404, 410, or a 200 carrying a page that says nothing was found.
  9. If the application supports merging two records, merge them and request the absorbed record's address.
  10. Request an address of the same shape that has never existed, and compare the response byte for byte against step 8. If they are identical, the application is not distinguishing deliberate removal from a typo, whatever any documentation claims.

Steps 5 and 6 are deliberately separated. A status code and a destination are two independent observations, and an application can get one right while getting the other wrong.

How this relates to axes already published here

It is not URL-state addressability, and the two rubrics disagree about the same property. Our URL-state addressability proposal asks whether a view can be reached a second time at all, which presumes a stable address and asks whether that address is expressive. This axis presumes the address existed and asks whether it survives a change in the world.

The disagreement is worth stating precisely, because it is the sharpest relationship we have found between two of our own axes. That proposal's fifth signal, at weight 12, awards full marks to an address that "carries intent, not internals", and its failing case is an address whose "only record of position is a raw primary key, a session identifier or an opaque continuation cursor". On this axis the sign is reversed. A title-derived slug is precisely the address that an edit can retire; an immutable primary key is precisely the address that no user action can break. The other rubric's pass condition is this axis's most common cause of failure, and its fail condition is close to perfect durability.

Neither rubric needs amending. They are scoring different intervals: that one is about the moment an address is handed over, where legibility genuinely helps, and this one is about the interval afterwards, where mutability genuinely hurts. An application can hold both at once by keeping the legible slug and also keeping every slug it has retired, which is what level 2 describes. Stating the tension is more useful than resolving it in favour of one side, because a build that optimises either rubric alone will score badly on the other and the reason will not be visible from inside either one.

It is not deletion and data-retention posture, and there is a genuine conflict. Our deletion and data-retention proposal scores how completely a record and its dependents are erased. Signal 4 of this axis asks an application to answer 410 rather than 404, and RFC 9110 permits that only where the server has the facility to determine that the removal was deliberate. Complete erasure destroys that facility. A build scoring at the top of the deletion rubric is therefore specification-bound to answer 404, and loses points here.

We think the resolution is classification rather than choice, and we would rather state it than pretend the conflict is not there. A tombstone carrying only a retired address string and a timestamp is not a reconstruction of the erased record and restores none of its contents. If a scorer disagrees, the right outcome is to re-scope signal 4 rather than to weaken either erasure requirement, and we would take that correction.

It is not generated-app SEO and meta output. Our generated-app SEO and meta output proposal scores what a crawler receives on a first arrival at a page, and its canonical signal asks for a self-referencing canonical "matching the served URL". That is a statement about the address being served now. It is silent about the address somebody was given last month, and a correct self-referencing canonical on the new address is in fact what instructs a crawler to stop showing the old one. Both are right; they are about different addresses.

Two further relationships are compositions rather than boundaries, and we name them without claiming a line exists. Our HTTP caching and revalidation proposal and this one meet at the cacheability of a permanent redirect: a wrong 308 is not merely wrong, it is cached, and the caching axis is where the retraction cost lives. Our data-export proposal meets it too, in a way neither axis can see alone, because an exported file full of addresses is a durable artefact that ages exactly as badly as an email full of them.

Limitations and open questions

  • Signal 2 may be unscorable from the outside on some builds. Distinguishing a request-time lookup from a build-time configuration entry requires either reading the generated source or performing step 7, and step 7 requires the ability to trigger a deploy. A black-box scorer without deploy access should report signal 2 as unscored rather than guess it from behaviour, and a rubric that cannot be fully applied black-box is a weakness in the rubric, not in the build.
  • Level 1 may be the better design, and a naive application of this rubric would punish it. An application whose addresses are opaque identifiers cannot suffer this defect at all. Signals 2 and 3 should score it a full pass rather than a blank, because having no retired address to persist is a consequence of a design decision that makes the failure impossible, not an omission. We say this explicitly because a scorer following the rubric mechanically would do the opposite.
  • The weights encode an opinion we cannot yet defend with data. Putting request-time resolution at 20 asserts that mechanism predicts outcome. It is plausible and it is unmeasured, and if scoring shows that build-time redirects maintained by hand hold up in practice, 20 is too high.
  • Much of this is inherited rather than authored. Routing comes from the framework. Two builders emitting the same framework will score similarly on the parts the framework decides, which says little about either. This is the same problem our pagination and URL-state proposals record, and we do not have a better answer than reporting inherited and authored behaviour separately.
  • Signal 6 may not apply. Many generated applications have no merge operation at all, in which case the signal is not a failure and should be recorded as not applicable rather than zero. Whether that distorts the total is an open question we would rather have answered by a scorer than by us.
  • We have read specifications, framework documentation and search-engine documentation for this proposal, and no builder output. That is a deliberate scope choice for a pre-registration and it is also the largest gap on this page. The postures are structural. None has been tested against a generated application, and nothing here is a score.
  • The one-year figure is somebody else's. It comes from search-engine guidance about site moves and is about signal transfer to a crawler, not about how long a colleague keeps a bookmark. We quote it because it is the only published duration we found from a primary source, and we do not claim it is the right retention period for a retired address inside an application.

Counter-rubrics, corrections and reproduction attempts are welcome. The most useful thing anyone can send us is a step 5 and step 7 result from a project of their own, with a note on whether the address was derived from a title or an identifier, because that single fact may turn out to predict the whole score.

References

  1. RFC 9110, HTTP Semantics, sections 15.4.2 (301 Moved Permanently), 15.4.3 (302 Found), 15.4.9 (308 Permanent Redirect) and 15.5.11 (410 Gone). https://www.rfc-editor.org/rfc/rfc9110.txt
  2. Next.js documentation, redirects in next.config.js, version 16.3.8, last updated June 30 2026. https://nextjs.org/docs/app/api-reference/config/next-config-js/redirects
  3. Next.js documentation, the redirect function, last updated July 28 2026. https://nextjs.org/docs/app/api-reference/functions/redirect
  4. Google Search Central, Site move with URL changes. https://developers.google.com/search/docs/crawling-indexing/site-move-with-url-changes
  5. Google Search Central, Redirects and Google Search. https://developers.google.com/search/docs/crawling-indexing/301-redirects

Cite this benchmark

Plain text
BuilderProof editorial team. "Does the link you shared last month still work? A permalink durability axis proposal (October 2026)". BuilderProof, October 2026. https://www.builderproof.org/benchmarks/does-the-link-you-shared-last-month-still-work-permalink-durability-axis-october-2026.
BibTeX
@misc{builderproof-does-the-link-you-shared-last-month-still-work-permalink-durability-axis-october-2026,
  title  = {{Does the link you shared last month still work? A permalink durability axis proposal (October 2026)}},
  author = {{BuilderProof editorial team}},
  year   = {2026},
  month  = {oct},
  howpublished = {\url{https://www.builderproof.org/benchmarks/does-the-link-you-shared-last-month-still-work-permalink-durability-axis-october-2026}},
  note   = {BuilderProof, builderproof.org}
}

Frequently asked questions

What is the permalink durability axis?

It is a proposed BuilderProof benchmark axis that scores whether an address a generated application already handed out keeps working after the thing it names is renamed, merged or removed. It is a pre-registration, not a result, and no builder is scored on this page.

Why does a redirect not fix a shared link?

Because RFC 9110 says so about its own mechanism. Sections 15.4.2 and 15.4.9 describe 301 and 308 as suggesting that a user agent replace its references, and then add that this suggestion is usually ignored unless the user agent is actively editing references. The redirect keeps the old address resolving; it does not repair the copy sitting in somebody's inbox, and so it can never be retired on the theory that references have caught up.

Why can a framework redirect config not handle a user rename?

Because it is read at build time. Next.js documents redirects as an array of objects in next.config.js carrying source, destination and permanent properties. A rename performed by a user in the afternoon cannot add an entry to that array without a code change and a redeploy, so honouring a user-caused address change requires a lookup against persisted data at request time, which has to be authored separately.

When should a generated app return 410 instead of 404?

Only when it can honestly tell the difference. RFC 9110 section 15.5.11 says that if the origin server does not know, or has no facility to determine, whether the condition is permanent, 404 ought to be used instead. An application that deletes the row has destroyed the knowledge that the address ever named anything, so 404 is the correct answer for it, and that is a conflict with complete erasure rather than a defect.

Does this axis score any AI app builder?

No. This page proposes a rubric, four postures and a measurement protocol, and publishes no placements, levels or scores. It was written from specifications, framework documentation and search-engine documentation, and no builder output was tested. Counter-rubrics and corrections are welcome before the rubric produces any score.

Methodology

Deletion and Data-Retention Posture: A Proposed Axis for What an AI Builder's Generated App Actually Removes (August 2026)

A proposed BuilderProof benchmark axis measuring what an AI app builder's generated application actually does when a record or an account is removed: declared referential semantics, identity deletion, retention exemptions, soft-delete coherence, third-party fan-out and residue disclosure. Six weighted signals, four posture levels, a reproducible protocol. Pre-registration only.

18 min read145
Methodology

Generated-App SEO and Meta Output Quality: A Proposed Axis for What AI App Builders Actually Emit to Crawlers (August 2026)

A candidate BuilderProof benchmark axis that scores the crawler-facing artifacts AI app builders emit by default: per-route titles, canonicals, social cards, robots.txt, sitemap.xml, structured data, and whether route content reaches a crawler at all. Rubric, four rendering postures found in the vendor docs, a dual user-agent reproduction protocol, and an open call for comment.

17 min read129