diff --git a/TREE.md b/TREE.md index 1435145..1dc1b1e 100644 --- a/TREE.md +++ b/TREE.md @@ -350,6 +350,8 @@ research/evaluations/language-pilot-01/summary.json research/evolution/EvolutionReport.md research/evolution/README.md research/evolution/context.json +research/evolution/cycles/2026-09-27-navigation-effort.json +research/evolution/cycles/2026-09-27-navigation.md research/evolution/ledger.json research/evolution/profiles.json research/evolution/snapshots/baseline-2026-09-26.json @@ -395,6 +397,12 @@ research/experiments/matrix-recovery/package-lock.json research/experiments/matrix-recovery/package.json research/experiments/matrix-recovery/provenance.json research/experiments/matrix-recovery/result.json +research/experiments/navigation-history/README.md +research/experiments/navigation-history/experiment.mjs +research/experiments/navigation-history/initial-partial.json +research/experiments/navigation-history/package-lock.json +research/experiments/navigation-history/package.json +research/experiments/navigation-history/result.json research/plan/OpenQuestions.md research/plan/ResearchProgram.md research/plan/ResearchProtocol.md @@ -414,6 +422,7 @@ research/reviews/LocalFirstAdmissionScreen.json research/reviews/LocalFirstEvidenceExpansion.md research/reviews/MatrixRecoveryExperiment.md research/reviews/NavigationCoverage.md +research/reviews/NavigationHistoryExperiment.md research/reviews/NavigationRenderingEvidence.md research/reviews/NestedDismissalIsolation.md research/reviews/NestedOwnershipRouting.md diff --git a/research/candidates/ProgressiveEnhancement.md b/research/candidates/ProgressiveEnhancement.md index 78b902e..64e4add 100644 --- a/research/candidates/ProgressiveEnhancement.md +++ b/research/candidates/ProgressiveEnhancement.md @@ -41,3 +41,12 @@ Proposed connections: [URL-addressable State](URLAddressableState.md) supports s view selection; [Mutation Outcome Tracking](MutationOutcomeTracking.md) matters when an enhanced write becomes uncertain. Neither is a universal dependency. [VC-03](../walkthroughs/VC03-ContentPublication.md) explores a read-only core. + +## Prospective runtime corroboration — 2026-09-27 + +Native links and GET filtering remain usable with JavaScript disabled or htmx +loading failed. An enhanced 503 keeps the old URL/view, and an explicitly provided +native recovery link navigates successfully. This does not establish automatic fallback, +late-script safety, accessible focus/announcements or offline availability. +See [NH01–NH06](../reviews/NavigationHistoryExperiment.md). One authored application +with a real package, not independent deployed recurrence. Hypothesis retained. diff --git a/research/candidates/URLAddressableState.md b/research/candidates/URLAddressableState.md index 75ca13d..1932fed 100644 --- a/research/candidates/URLAddressableState.md +++ b/research/candidates/URLAddressableState.md @@ -38,3 +38,12 @@ Application State seed; no canonical identity or admitted relations. Proposed connection: [Progressive Enhancement](ProgressiveEnhancement.md) can preserve native navigation while adding faster transitions; it is optional, not required by addressability. [VC-03](../walkthroughs/VC03-ContentPublication.md) is a synthetic trace. + +## Prospective runtime corroboration — 2026-09-27 + +Direct filtered entry, reload, snapshot restoration and explicit history-miss recovery +preserve selection in a pinned htmx fixture. Omitting representation Vary reproduces +a fragment served as a full document in Chromium and Firefox; correct selection +keeps representations distinct, without promising cache retention or freshness. +See [NH01–NH06](../reviews/NavigationHistoryExperiment.md). One authored application +with a real package, not independent deployed recurrence. Hypothesis retained. diff --git a/research/catalog/SourceCatalog.md b/research/catalog/SourceCatalog.md index 4ef2941..c9d35b5 100644 --- a/research/catalog/SourceCatalog.md +++ b/research/catalog/SourceCatalog.md @@ -164,3 +164,12 @@ SRC-0036 follow-up: [activation conflicts and update reload](../reviews/Activati adds an authored conditional-write server and reload policy with sessionStorage. Three HTTP cases plus nine cases per browser, 21/21 expected observations; negative controls included. Same synthetic evidence family, not an independently deployed use. + +## Prospective navigation runtime — 2026-09-27 + +SRC-0038: [navigation/history fixture](../experiments/navigation-history/README.md), +htmx 2.0.11 and Playwright 1.63.0 with locked packages and hashed inputs/browser +binaries. Authored HTTP application; 18 browser cases plus explicit HTTP validator +sequence repeated twice. [NH01–NH06 review](../reviews/NavigationHistoryExperiment.md), +preregistered prospective corroboration. This is one implementation family, not +an independent production deployment. Initial launch failure receipt preserved. diff --git a/research/evolution/EvolutionReport.md b/research/evolution/EvolutionReport.md index fd82282..545d758 100644 --- a/research/evolution/EvolutionReport.md +++ b/research/evolution/EvolutionReport.md @@ -1,6 +1,6 @@ # Language evolution report -Generated by `make evolution-report`; curated assessment date: 2026-09-26. +Generated by `make evolution-report`; curated assessment date: 2026-09-27. This is an evidence profile, not a completion percentage. Evidence presence does not establish full-contract recurrence or production fitness. @@ -14,7 +14,7 @@ The baseline profiles are author-model assessments by Codex; they do not confer | --- | ---: | | documentary | 17 | | static-code | 5 | -| runtime | 6 | +| runtime | 8 | Categories overlap. Runtime includes authored fixtures and negative controls. Family labels group related evidence; they are not counts of independent applications. @@ -22,7 +22,7 @@ Independent human profile reviews: 0/17. Full-contract independent-use counts un ## Change since baseline -Baseline baseline-2026-09-26; source revision `f273a190f0e08b8cfe0bb7260d0e7d889f1c090a`. Added: 0; removed: 0; shared candidates with changed content: 0; changed evidence/review assessments: 0; maturity transitions: 0. +Baseline baseline-2026-09-26; source revision `f273a190f0e08b8cfe0bb7260d0e7d889f1c090a`. Added: 0; removed: 0; shared candidates with changed content: 2; changed evidence/review assessments: 2; maturity transitions: 0. The shared cohort is compared separately from additions. Changed text or evidence counts are not learning gains. @@ -47,25 +47,31 @@ One frozen development pilot with submitted model review; six matched briefs. Eq ## Learning and effort -Selected retrospective outcomes, not a complete historical census. All entered 2026-09-26; historical effort unmeasured. Prospective cycles begin after this baseline. +Ten selected retrospective outcomes (not a historical census), followed by prospectively registered bounded cycles. Retrospective effort remains unknown. | Outcome | Entries (not independent discoveries) | | --- | ---: | -| corroboration | 0 | +| corroboration | 1 | | inconclusive | 0 | | merge | 0 | | rejection | 0 | | revision | 10 | -Cycles with recorded research effort: 0/10. Unknown effort is neither zero nor estimated from commits, tokens or assertion counts. +Cycles with recorded research effort: 1/11. Unknown effort is neither zero nor estimated from commits, tokens or assertion counts. -No prospective comparison windows yet. Learning rate and diminishing returns: **not measurable from this baseline**. +### Stream B / B-navigation-mechanism-v1 + +| Cycle | Outcome | Research minutes | Consequential outcome/hour | +| --- | --- | ---: | ---: | +| LEARN-0011 | corroboration | 6.177 | 0.00 | + +One bounded question counts at most one consequential outcome. Corroboration and inconclusive work remain visible separately. Fewer than three comparable cycles: no trend assessment. ## Coherence and maintainability Profile hashes and local references passed validation when this report was generated. That checks traceability, not source truth or external URL freshness. -Profiles with unknown last substantive review date: 17. Assessment dates record this metadata review, not a new substantive validation. No age-based freshness claim is available for those profiles. +Profiles with unknown last substantive review date: 15. Assessment dates record this metadata review, not a new substantive validation. No age-based freshness claim is available for those profiles. Coherence metrics (ambiguous selections, unjustified relations and overlap resolved): not measured. Conflict Copy / Explicit Reconciliation overlap remains an explicit open question. @@ -207,8 +213,9 @@ Make a navigable state reconstructible from its URL. | --- | --- | --- | --- | | documentary | htmx | History behavior and history-cache misses. | [NavigationRenderingEvidence](../../research/reviews/NavigationRenderingEvidence.md) | | documentary | Web platform | pushState changes history, not server dereferenceability. | [NavigationRenderingEvidence](../../research/reviews/NavigationRenderingEvidence.md) | +| runtime | htmx in authored public-catalog fixture | NH01–NH06: native/enhanced routes, history hit/miss, actual browser cache ordering and missing-Vary negative control; explicit Node validator checks separate. | [NavigationHistoryExperiment](../../research/reviews/NavigationHistoryExperiment.md) | -Open limits: Direct load, history miss and full/fragment cache runtime checks pending. +Open limits: Independent deployed full-contract recurrence remains unverified. Keyboard/focus/announcements, late-script activation, interrupted transport, invalid/deleted routes, offline availability and real intermediary behavior remain open. Superseded by: none recorded. @@ -222,8 +229,9 @@ Keep essential actions usable when enhancement is unavailable. | --- | --- | --- | --- | | documentary | htmx | Boosted links and forms. | [NavigationRenderingEvidence](../../research/reviews/NavigationRenderingEvidence.md) | | documentary | SvelteKit | Form actions and rendering/page options. | [NavigationRenderingEvidence](../../research/reviews/NavigationRenderingEvidence.md) | +| runtime | htmx in authored public-catalog fixture | NH01–NH06: native/enhanced routes, history hit/miss, actual browser cache ordering and missing-Vary negative control; explicit Node validator checks separate. | [NavigationHistoryExperiment](../../research/reviews/NavigationHistoryExperiment.md) | -Open limits: No executed no-script workflow or deployed independent recurrence study. +Open limits: Independent deployed full-contract recurrence remains unverified. Keyboard/focus/announcements, late-script activation, interrupted transport, invalid/deleted routes, offline availability and real intermediary behavior remain open. Superseded by: none recorded. @@ -473,3 +481,17 @@ Evidence: [ActivationConflictsAndReload](../../research/reviews/ActivationConfli Remaining uncertainty: One-process atomicity; no native unload, crash or real remote-outcome coverage. Supersedes: none recorded. + +### LEARN-0011 — Can a public route preserve selection and complete-document availability across native/enhanced entry, history and HTTP caching? + +2026-09-27 · stream B · prospective · corroboration + +Before: Native href/GET contracts plus representation-aware routing and cache selection should satisfy this narrow obligation; documentary support lacked runtime checks. + +Conclusion: Corroborated in pinned htmx fixture: native and history paths work; missing Vary reproduces fragment-as-document reuse in both browsers. Existing obligations stand; no new pattern or promotion. + +Evidence: [NavigationHistoryExperiment](../../research/reviews/NavigationHistoryExperiment.md), [result](../../research/experiments/navigation-history/result.json), [2026-09-27-navigation-effort](../../research/evolution/cycles/2026-09-27-navigation-effort.json). + +Remaining uncertainty: One authored application, no independent recurrence or usefulness gain. Accessibility, delayed scripts, interrupted transport, real intermediaries and offline availability remain open. + +Supersedes: none recorded. diff --git a/research/evolution/cycles/2026-09-27-navigation-effort.json b/research/evolution/cycles/2026-09-27-navigation-effort.json new file mode 100644 index 0000000..464c484 --- /dev/null +++ b/research/evolution/cycles/2026-09-27-navigation-effort.json @@ -0,0 +1,45 @@ +{ + "start_utc": "2026-09-26T22:02:55Z", + "start_monotonic": 198212.69757878, + "execution_seconds": 61.257515474018874, + "method": "Single-agent continuous active session; subtract timed experiment and verification subprocess durations. Includes planning, implementation and analysis; excludes final commit/sync after cutoff. No overlap.", + "start_utc_note": "UTC label is initial orientation clock reading; monotonic measurement began after orientation as preregistered.", + "executions": [ + { + "command": [ + "node", + "research/experiments/navigation-history/experiment.mjs" + ], + "seconds": 12.89531968801748, + "exit_code": 1 + }, + { + "command": [ + "node", + "research/experiments/navigation-history/experiment.mjs" + ], + "seconds": 34.61645083199255, + "exit_code": 0 + }, + { + "command": [ + "make", + "evolution-check", + "evolution-test", + "schema-test", + "bench-test" + ], + "seconds": 13.745744954008842, + "exit_code": 0 + } + ], + "status": "complete", + "end_utc": "2026-09-26T22:11:04.416742+00:00", + "measured_start_utc_approx": "2026-09-26T22:03:52.518569+00:00", + "elapsed_seconds": 431.898, + "research_minutes": 6.177, + "execution_minutes": 1.021, + "precision": "Monotonic subprocess durations; minute fields rounded to 0.001, not a claim of human effort precision.", + "excluded": "Orientation before timer start and administration/final receipt refresh after this cutoff. Checkpoint inspection during experiment assigned to execution only.", + "budget_review": "Within 45 active research minutes and 10 execution minutes; no scope extension." +} diff --git a/research/evolution/ledger.json b/research/evolution/ledger.json index 7202512..fa33cfa 100644 --- a/research/evolution/ledger.json +++ b/research/evolution/ledger.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "coverage": "Selected retrospective outcomes, not a complete historical census. All entered 2026-09-26; historical effort unmeasured. Prospective cycles begin after this baseline.", + "coverage": "Ten selected retrospective outcomes (not a historical census), followed by prospectively registered bounded cycles. Retrospective effort remains unknown.", "events": [ { "id": "LEARN-0001", @@ -336,6 +336,43 @@ "cost_usd": null }, "supersedes": [] + }, + { + "id": "LEARN-0011", + "date": "2026-09-27", + "recording": "prospective", + "stream": "B", + "comparison_group": "B-navigation-mechanism-v1", + "protocol_ref": "research/evolution/cycles/2026-09-27-navigation.md", + "question": "Can a public route preserve selection and complete-document availability across native/enhanced entry, history and HTTP caching?", + "previous_belief": "Native href/GET contracts plus representation-aware routing and cache selection should satisfy this narrow obligation; documentary support lacked runtime checks.", + "conclusion": "Corroborated in pinned htmx fixture: native and history paths work; missing Vary reproduces fragment-as-document reuse in both browsers. Existing obligations stand; no new pattern or promotion.", + "disposition": "corroboration", + "affected_patterns": [ + "CAND-0009", + "CAND-0010" + ], + "evidence": [ + "research/reviews/NavigationHistoryExperiment.md", + "research/experiments/navigation-history/result.json", + "research/evolution/cycles/2026-09-27-navigation-effort.json" + ], + "remaining_uncertainty": [ + "One authored application, no independent recurrence or usefulness gain.", + "Accessibility, delayed scripts, interrupted transport, real intermediaries and offline availability remain open." + ], + "reviewer": { + "name": "Codex", + "role": "author-model", + "independent_human": false + }, + "effort": { + "research_minutes": 6.177, + "execution_minutes": 1.021, + "reported_tokens": null, + "cost_usd": null + }, + "supersedes": [] } ] } diff --git a/research/evolution/profiles.json b/research/evolution/profiles.json index fd2fd4e..f56613d 100644 --- a/research/evolution/profiles.json +++ b/research/evolution/profiles.json @@ -1,6 +1,6 @@ { "schema_version": 1, - "assessed_at": "2026-09-26", + "assessed_at": "2026-09-27", "profiles": [ { "id": "CAND-0001", @@ -317,7 +317,7 @@ "id": "CAND-0009", "path": "research/candidates/URLAddressableState.md", "title": "URL-addressable State", - "sha256": "45132f34aa762b453c36c9bc6b418ab7f9ce17097365995b2792fd173f6aa11e", + "sha256": "3edc087c5b4b0a332dd9097334022cdb138437413b933f271e5cf96096cc63be", "status": "draft", "maturity": "hypothesis", "decision": "Make a navigable state reconstructible from its URL.", @@ -333,18 +333,25 @@ "family": "Web platform", "ref": "research/reviews/NavigationRenderingEvidence.md", "scope": "pushState changes history, not server dereferenceability." + }, + { + "kind": "runtime", + "family": "htmx in authored public-catalog fixture", + "ref": "research/reviews/NavigationHistoryExperiment.md", + "scope": "NH01–NH06: native/enhanced routes, history hit/miss, actual browser cache ordering and missing-Vary negative control; explicit Node validator checks separate." } ], "independent_full_contract_uses": null, "review": { - "assessed_at": "2026-09-26", + "assessed_at": "2026-09-27", "reviewer": "Codex", "role": "author-model", "independent_human": false, - "last_substantive_review_date": null + "last_substantive_review_date": "2026-09-27" }, "gaps": [ - "Direct load, history miss and full/fragment cache runtime checks pending." + "Independent deployed full-contract recurrence remains unverified.", + "Keyboard/focus/announcements, late-script activation, interrupted transport, invalid/deleted routes, offline availability and real intermediary behavior remain open." ], "superseded_by": [] }, @@ -352,7 +359,7 @@ "id": "CAND-0010", "path": "research/candidates/ProgressiveEnhancement.md", "title": "Progressive Enhancement", - "sha256": "e8bfc9997336b62f67081434528dc3d3dd280c349156da7620bc76f2197f6414", + "sha256": "e9ca2b046cb69fff16379e22e1a9d0d61d2a5801ff92bbfc1b56ae3e3be16c7c", "status": "draft", "maturity": "hypothesis", "decision": "Keep essential actions usable when enhancement is unavailable.", @@ -368,18 +375,25 @@ "family": "SvelteKit", "ref": "research/reviews/NavigationRenderingEvidence.md", "scope": "Form actions and rendering/page options." + }, + { + "kind": "runtime", + "family": "htmx in authored public-catalog fixture", + "ref": "research/reviews/NavigationHistoryExperiment.md", + "scope": "NH01–NH06: native/enhanced routes, history hit/miss, actual browser cache ordering and missing-Vary negative control; explicit Node validator checks separate." } ], "independent_full_contract_uses": null, "review": { - "assessed_at": "2026-09-26", + "assessed_at": "2026-09-27", "reviewer": "Codex", "role": "author-model", "independent_human": false, - "last_substantive_review_date": null + "last_substantive_review_date": "2026-09-27" }, "gaps": [ - "No executed no-script workflow or deployed independent recurrence study." + "Independent deployed full-contract recurrence remains unverified.", + "Keyboard/focus/announcements, late-script activation, interrupted transport, invalid/deleted routes, offline availability and real intermediary behavior remain open." ], "superseded_by": [] }, diff --git a/research/experiments/navigation-history/README.md b/research/experiments/navigation-history/README.md new file mode 100644 index 0000000..30274c9 --- /dev/null +++ b/research/experiments/navigation-history/README.md @@ -0,0 +1,40 @@ +# Navigation, history and representation-cache experiment + +First prospective cycle: [preregistration](../../evolution/cycles/2026-09-27-navigation.md) +at commit `f3697c1`, before implementation/execution. [Review](../../reviews/NavigationHistoryExperiment.md). +Pinned htmx 2.0.11 and Playwright 1.63.0, authored public read-only HTTP fixture. +[Result](result.json) includes input hashes, exact browser versions/binary hashes, +request traces and final DOM/event observations. No real application/CDN or model call. + +```bash +npm ci --ignore-scripts --cache /tmp/fep-npm-cache +PLAYWRIGHT_BROWSERS_PATH=/tmp/fep-playwright-browsers node node_modules/playwright/cli.js install firefox +PLAYWRIGHT_BROWSERS_PATH=/tmp/fep-playwright-browsers FEP_CHROMIUM_PATH=/path/to/chrome npm test +``` + +Firefox profile access required execution outside the workspace sandbox. Chromium +was an explicit preinstalled binary override, not claimed to be Playwright's bundled +revision. Default output `/tmp/fep-navigation-result.json`; `FEP_RESULT_PATH` overrides +it. The runner writes checkpoints to that output and a complete receipt on completion. +Choose a new output per run; committed receipts are never default outputs. + +[Initial partial receipt](initial-partial.json) retains ten passing Chromium rows; +launch then failed because Firefox was not in Playwright's default cache. Setting the +existing browser-cache path fixed execution, without changing runner or criteria. +The full run repeated Chromium and completed Firefox: 20/20 registered checks, not +30 independent observations. N10 repeats explicit Node HTTP checks in each browser +group; those two rows are not evidence of browser-specific automatic revalidation. +N09 records the negative control, including non-reproduction if that ever occurs. + +N01–N06 cover direct/native/enhanced/history/recovery paths; N07–N09 use actual browser +HTTP cache with no request interception. N08's final full fetch reaches the server +again in both browsers: correctness does not imply simultaneous retention of both +variants or optimal cache hit rate. Both N09 runs reuse the fragment without another +request. The server varies on both request selectors and computes ETags from response +bytes. htmx history requests explicitly disable HX-Request; the server separately +supports the history-restore header overriding fragment selection. + +History eviction uses htmx 2.0.11's sessionStorage key, an experimental control tied +to the pinned implementation. No assertion of identical content freshness across +history, general offline availability, accessibility, script-late races, writes, +real intermediary correctness or independent full-pattern recurrence follows. diff --git a/research/experiments/navigation-history/experiment.mjs b/research/experiments/navigation-history/experiment.mjs new file mode 100644 index 0000000..695ec3a --- /dev/null +++ b/research/experiments/navigation-history/experiment.mjs @@ -0,0 +1,114 @@ +import {chromium, firefox} from 'playwright'; +import {createServer} from 'node:http'; +import {once} from 'node:events'; +import {readFile, writeFile} from 'node:fs/promises'; +import {createHash} from 'node:crypto'; +import assert from 'node:assert/strict'; +const dir=new URL('.',import.meta.url); +const htmx=await readFile(new URL('node_modules/htmx.org/dist/htmx.js',dir)); +let requests=[]; +const observer=`window.probe=[];for(const name of ['htmx:afterSettle','htmx:historyRestore','htmx:responseError'])document.addEventListener(name,e=>window.probe.push({name,url:location.href,cacheMiss:e.detail.cacheMiss}));`; +const server=createServer((req,res)=>{ + const url=new URL(req.url,'http://localhost'); + const hx=req.headers['hx-request']==='true', restore=req.headers['hx-history-restore-request']==='true'; + let status=200,body='',representation='asset'; + res.setHeader('Cache-Control','no-store'); + if(url.pathname==='/htmx.js'){ + status=url.searchParams.has('fail')?503:200;body=status===200?htmx:'blocked enhancement';res.setHeader('Content-Type','application/javascript'); + }else if(url.pathname==='/observe.js'){body=observer;res.setHeader('Content-Type','application/javascript');} + else if(['/articles','/cache-good','/cache-bad'].includes(url.pathname)){ + const topic=url.searchParams.get('topic')==='beta'?'beta':'alpha'; + const fail=url.searchParams.has('scriptfail')?'&scriptfail=1':''; + const main=`

${topic}

Public article ${topic}

Injected enhanced failureNative recovery
`; + representation=hx&&!restore?'fragment':'full'; + const full=`Public catalog
Catalog shell
${main}`; + body=representation==='full'?full:main; + if(hx&&url.searchParams.has('enhancedfail')){status=503;body='Injected enhancement outage';} + res.setHeader('Content-Type','text/html; charset=utf-8'); + if(url.pathname.startsWith('/cache-')){ + res.setHeader('Cache-Control','public, max-age=3600'); + const etag='"'+createHash('sha256').update(body).digest('hex')+'"';res.setHeader('ETag',etag); + if(url.pathname==='/cache-good')res.setHeader('Vary','HX-Request, HX-History-Restore-Request'); + if(req.headers['if-none-match']===etag){status=304;body='';} + } + } + else{status=404;body='Not found';} + requests.push({path:req.url,hx,restore,ifNoneMatch:req.headers['if-none-match']||null,status,representation,vary:res.getHeader('Vary')||null,etag:res.getHeader('ETag')||null}); + res.writeHead(status);res.end(body); +}); +server.listen(0,'127.0.0.1');await once(server,'listening'); +const base=`http://127.0.0.1:${server.address().port}`; +const results=[], browsers={}; +const output=process.env.FEP_RESULT_PATH||'/tmp/fep-navigation-result.json'; +try{ + for(const [engine,launcher] of [['chromium',chromium],['firefox',firefox]]){ + const executablePath=engine==='chromium'?process.env.FEP_CHROMIUM_PATH:undefined; + const browser=await launcher.launch({headless:true,...(executablePath?{executablePath}:{})}); + const binary=executablePath||launcher.executablePath(); + browsers[engine]={version:browser.version(),executable:binary,sha256:createHash('sha256').update(await readFile(binary)).digest('hex')}; + try{ + async function scenario(id,run,javaScriptEnabled=true){ + requests=[];const context=await browser.newContext({javaScriptEnabled});const page=await context.newPage();page.setDefaultTimeout(4000); + const result={id,engine,status:'pass'}; + try{result.observation=await run(page,context);}catch(e){result.status='fail';result.error=e.message;} + result.requests=[...requests];result.url=page.url();result.body=await page.locator('body').innerText().catch(()=>null); + result.events=javaScriptEnabled?await page.evaluate(()=>window.probe||[]).catch(()=>[]):[]; + results.push(result);await context.close(); + await writeFile(output,JSON.stringify({status:'incomplete',results},null,2)+'\n'); + } + async function selected(p,topic){await p.locator('h1').filter({hasText:topic}).waitFor();assert.equal(new URL(p.url()).searchParams.get('topic'),topic);} + async function enhanced(p){await p.waitForFunction(()=>window.htmx?.version==='2.0.11');} + async function next(p,topic){await p.locator('#next').click();await selected(p,topic);await p.waitForFunction(()=>window.probe.some(e=>e.name==='htmx:afterSettle'));} + await scenario('N01-no-script-native',async p=>{ + await p.goto(base+'/articles?topic=alpha');await selected(p,'alpha');assert.equal(await p.locator('#shell').count(),1); + await p.locator('#next').click();await selected(p,'beta');await p.locator('select').selectOption('alpha');await p.getByRole('button',{name:'Filter'}).click();await selected(p,'alpha'); + assert(requests.filter(r=>r.path.startsWith('/articles')).every(r=>!r.hx&&r.representation==='full'));return {directLinkAndGetForm:true,fullShell:true}; + },false); + await scenario('N02-enhance-reload-direct',async(p,c)=>{ + await p.goto(base+'/articles?topic=alpha');await enhanced(p);await next(p,'beta');assert(requests.some(r=>r.hx&&r.representation==='fragment')); + await p.reload();await selected(p,'beta');assert.equal(await p.locator('#shell').count(),1); + const fresh=await c.newPage();await fresh.goto(base+'/articles?topic=beta');assert.equal(await fresh.locator('#shell').count(),1);await fresh.close();return {pushReloadAndFreshEntry:true}; + }); + await scenario('N03-history-hit',async p=>{ + await p.goto(base+'/articles?topic=alpha');await enhanced(p);await next(p,'beta');const before=requests.length; + await p.goBack();await selected(p,'alpha');await p.waitForFunction(()=>window.probe.some(e=>e.name==='htmx:historyRestore')); + await p.goForward();await selected(p,'beta'); + assert(!requests.slice(before).some(r=>r.path.startsWith('/articles')));return {backForward:true,additionalArticleRequests:0}; + }); + await scenario('N04-history-miss',async p=>{ + await p.goto(base+'/articles?topic=alpha');await enhanced(p);await next(p,'beta');await p.evaluate(()=>sessionStorage.removeItem('htmx-history-cache')); + await p.goBack();await selected(p,'alpha');assert(requests.some(r=>r.restore&&r.representation==='full'&&!r.hx));return {evictedSnapshotFetchedFull:true}; + }); + await scenario('N05-enhancement-failure',async p=>{ + await p.goto(base+'/articles?topic=alpha');await enhanced(p);await p.locator('#broken').click();await p.waitForFunction(()=>window.probe.some(e=>e.name==='htmx:responseError'));await selected(p,'alpha'); + assert(requests.some(r=>r.hx&&r.status===503));await p.locator('#recover').click();await selected(p,'beta');assert.equal(await p.locator('#shell').count(),1);return {oldViewAndUrlRetained:true,explicitNativeRecovery:true}; + }); + await scenario('N06-script-failure',async p=>{ + await p.goto(base+'/articles?topic=alpha&scriptfail=1');assert(requests.some(r=>r.path==='/htmx.js?fail=1'&&r.status===503));assert.equal(await p.evaluate(()=>typeof window.htmx),'undefined'); + await p.locator('#next').click();await selected(p,'beta');await p.locator('select').selectOption('alpha');await p.getByRole('button',{name:'Filter'}).click();await selected(p,'alpha');return {nativeLinkAndFormDespiteScript503:true}; + }); + async function cachedFetch(p,path,hx=false){return p.evaluate(async({path,hx})=>{const r=await fetch(path,{headers:hx?{'HX-Request':'true'}:{}});return {status:r.status,text:await r.text(),etag:r.headers.get('etag')};},{path,hx});} + await scenario('N07-fragment-before-document',async p=>{ + await p.goto(base+'/articles?topic=alpha');const path='/cache-good?topic=beta';const frag=await cachedFetch(p,path,true);assert(!frag.text.includes('id="shell"')); + await p.goto(base+path);assert.equal(await p.locator('#shell').count(),1);await selected(p,'beta');return {fragmentThenFull:true}; + }); + await scenario('N08-document-before-fragment',async p=>{ + const path='/cache-good?topic=alpha';await p.goto(base+path);const frag=await cachedFetch(p,path,true);assert(!frag.text.includes('id="shell"'));assert(frag.text.includes('{ + await p.goto(base+'/articles?topic=alpha');const path='/cache-bad?topic=beta';await cachedFetch(p,path,true);const before=requests.length;await p.goto(base+path); + return {fragmentServedAsDocument:await p.locator('#shell').count()===0,additionalRequests:requests.slice(before),negativeControl:true}; + }); + await scenario('N10-conditional-representations',async()=>{ + const path=base+'/cache-good?topic=beta';const fragment=await fetch(path,{headers:{'HX-Request':'true'}});const etag=fragment.headers.get('etag');await fragment.text(); + const same=await fetch(path,{headers:{'HX-Request':'true','If-None-Match':etag}});assert.equal(same.status,304); + const full=await fetch(path,{headers:{'If-None-Match':etag}});assert.equal(full.status,200);assert((await full.text()).includes('id="shell"'));assert.notEqual(full.headers.get('etag'),etag); + const restore=await fetch(path,{headers:{'HX-Request':'true','HX-History-Restore-Request':'true'}});assert((await restore.text()).includes('id="shell"'));return {transport:'explicit Node HTTP requests; duplicated per browser group, not independent browser evidence',sameRepresentation:304,crossRepresentation:200,restoreFull:true}; + }); + }finally{await browser.close();} + } +}finally{await new Promise(resolve=>server.close(resolve));} +const files={};for(const f of ['experiment.mjs','package.json','package-lock.json','node_modules/htmx.org/dist/htmx.js'])files[f]=createHash('sha256').update(await readFile(new URL(f,dir))).digest('hex'); +const receipt={date:new Date().toISOString(),node:process.version,kind:'authored-http-fixture-with-pinned-htmx',browsers,files,results,passed:results.filter(r=>r.status==='pass').length,total:results.length}; +await writeFile(output,JSON.stringify(receipt,null,2)+'\n');console.log(JSON.stringify({output,passed:receipt.passed,total:receipt.total,failures:results.filter(r=>r.status==='fail')},null,2));if(receipt.passed!==receipt.total)process.exitCode=1; diff --git a/research/experiments/navigation-history/initial-partial.json b/research/experiments/navigation-history/initial-partial.json new file mode 100644 index 0000000..24b7d4d --- /dev/null +++ b/research/experiments/navigation-history/initial-partial.json @@ -0,0 +1,768 @@ +{ + "status": "incomplete", + "results": [ + { + "id": "N01-no-script-native", + "engine": "chromium", + "status": "pass", + "observation": { + "directLinkAndGetForm": true, + "fullShell": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:39749/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N02-enhance-reload-direct", + "engine": "chromium", + "status": "pass", + "observation": { + "pushReloadAndFreshEntry": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:39749/articles?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N03-history-hit", + "engine": "chromium", + "status": "pass", + "observation": { + "backForward": true, + "additionalArticleRequests": 0 + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:39749/articles?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [ + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:39749/articles?topic=beta" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:39749/articles?topic=alpha" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:39749/articles?topic=alpha" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:39749/articles?topic=beta" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:39749/articles?topic=beta" + } + ] + }, + { + "id": "N04-history-miss", + "engine": "chromium", + "status": "pass", + "observation": { + "evictedSnapshotFetchedFull": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": true, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:39749/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [ + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:39749/articles?topic=beta" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:39749/articles?topic=alpha" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:39749/articles?topic=alpha", + "cacheMiss": true + } + ] + }, + { + "id": "N05-enhancement-failure", + "engine": "chromium", + "status": "pass", + "observation": { + "oldViewAndUrlRetained": true, + "explicitNativeRecovery": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&enhancedfail=1", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&enhancedfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:39749/articles?topic=beta&enhancedfail=1", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N06-script-failure", + "engine": "chromium", + "status": "pass", + "observation": { + "nativeLinkAndFormDespiteScript503": true + }, + "requests": [ + { + "path": "/articles?topic=alpha&scriptfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js?fail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&scriptfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js?fail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:39749/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N07-fragment-before-document", + "engine": "chromium", + "status": "pass", + "observation": { + "fragmentThenFull": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:39749/cache-good?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N08-document-before-fragment", + "engine": "chromium", + "status": "pass", + "observation": { + "fullThenFragmentThenFull": true + }, + "requests": [ + { + "path": "/cache-good?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"" + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-good?topic=alpha", + "hx": true, + "restore": false, + "ifNoneMatch": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"", + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"af6404a0e852c5f75ab2abf25f61de82db30f85e21abeb19055a6b5caf854229\"" + }, + { + "path": "/cache-good?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": "\"af6404a0e852c5f75ab2abf25f61de82db30f85e21abeb19055a6b5caf854229\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"" + } + ], + "url": "http://127.0.0.1:39749/cache-good?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N09-missing-vary-negative", + "engine": "chromium", + "status": "pass", + "observation": { + "fragmentServedAsDocument": true, + "additionalRequests": [], + "negativeControl": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-bad?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": "\"69c19e9840aa688ca34f4768e33ab28e0b994aeb5191251db7c0ab9a36b2699b\"" + } + ], + "url": "http://127.0.0.1:39749/cache-bad?topic=beta", + "body": "beta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N10-conditional-representations", + "engine": "chromium", + "status": "pass", + "observation": { + "transport": "explicit Node HTTP requests; duplicated per browser group, not independent browser evidence", + "sameRepresentation": 304, + "crossRepresentation": 200, + "restoreFull": true + }, + "requests": [ + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 304, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": true, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + } + ], + "url": "about:blank", + "body": "", + "events": [] + } + ] +} diff --git a/research/experiments/navigation-history/package-lock.json b/research/experiments/navigation-history/package-lock.json new file mode 100644 index 0000000..916fcd7 --- /dev/null +++ b/research/experiments/navigation-history/package-lock.json @@ -0,0 +1,47 @@ +{ + "name": "fep-navigation-history", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "fep-navigation-history", + "dependencies": { + "htmx.org": "2.0.11", + "playwright": "1.63.0" + } + }, + "node_modules/htmx.org": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/htmx.org/-/htmx.org-2.0.11.tgz", + "integrity": "sha512-Thx/WtpeOQqSrqBCw/A1cwGJGg4UrVa3+sW0GmrM3p4gJgO89ecH4qtbnyzDDWFvBTqjnIMCgELTNt636dtamA==", + "license": "0BSD" + }, + "node_modules/playwright": { + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.63.0.tgz", + "integrity": "sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==", + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.63.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/playwright-core": { + "version": "1.63.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.63.0.tgz", + "integrity": "sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==", + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=20" + } + } + } +} diff --git a/research/experiments/navigation-history/package.json b/research/experiments/navigation-history/package.json new file mode 100644 index 0000000..5d1d622 --- /dev/null +++ b/research/experiments/navigation-history/package.json @@ -0,0 +1 @@ +{"name":"fep-navigation-history","private":true,"type":"module","scripts":{"test":"node experiment.mjs"},"dependencies":{"htmx.org":"2.0.11","playwright":"1.63.0"}} diff --git a/research/experiments/navigation-history/result.json b/research/experiments/navigation-history/result.json new file mode 100644 index 0000000..f8c7bff --- /dev/null +++ b/research/experiments/navigation-history/result.json @@ -0,0 +1,1643 @@ +{ + "date": "2026-09-26T22:08:02.902Z", + "node": "v24.11.1", + "kind": "authored-http-fixture-with-pinned-htmx", + "browsers": { + "chromium": { + "version": "151.0.7922.34", + "executable": "/home/worsch/.cache/ms-playwright/chromium-1234/chrome-linux64/chrome", + "sha256": "0b20b130e7edd9dd51873be867761295fe0cfad490c2b9a64f95bd3cfc08fa71" + }, + "firefox": { + "version": "155.0", + "executable": "/tmp/fep-playwright-browsers/firefox-1543/firefox/firefox", + "sha256": "062272ac4d851eade5b75db2dc7c14569d96cb3ca38f949337cdc1b74367e35b" + } + }, + "files": { + "experiment.mjs": "e46a931a4d6aaaed62d0a39d7997bbd3811bc321cf0239e41eb9bd570b2cb956", + "package.json": "373e05f4d2b9e043abc9391e6ec28bcf6ffdd5530e52f3e5db88ed20e4462ed5", + "package-lock.json": "6fb5a45148a199c10fd9b67b1d5468a0334e5fcc154f1f079fd88462a89328d3", + "node_modules/htmx.org/dist/htmx.js": "30612ca7e3d3baf407481f1798281c4481dcb93390a9722d328ce07290250426" + }, + "results": [ + { + "id": "N01-no-script-native", + "engine": "chromium", + "status": "pass", + "observation": { + "directLinkAndGetForm": true, + "fullShell": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N02-enhance-reload-direct", + "engine": "chromium", + "status": "pass", + "observation": { + "pushReloadAndFreshEntry": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N03-history-hit", + "engine": "chromium", + "status": "pass", + "observation": { + "backForward": true, + "additionalArticleRequests": 0 + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [ + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=beta" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=alpha" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:45429/articles?topic=alpha" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=beta" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:45429/articles?topic=beta" + } + ] + }, + { + "id": "N04-history-miss", + "engine": "chromium", + "status": "pass", + "observation": { + "evictedSnapshotFetchedFull": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": true, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [ + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=beta" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=alpha" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "cacheMiss": true + } + ] + }, + { + "id": "N05-enhancement-failure", + "engine": "chromium", + "status": "pass", + "observation": { + "oldViewAndUrlRetained": true, + "explicitNativeRecovery": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&enhancedfail=1", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&enhancedfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=beta&enhancedfail=1", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N06-script-failure", + "engine": "chromium", + "status": "pass", + "observation": { + "nativeLinkAndFormDespiteScript503": true + }, + "requests": [ + { + "path": "/articles?topic=alpha&scriptfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js?fail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&scriptfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js?fail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N07-fragment-before-document", + "engine": "chromium", + "status": "pass", + "observation": { + "fragmentThenFull": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/cache-good?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N08-document-before-fragment", + "engine": "chromium", + "status": "pass", + "observation": { + "fullThenFragmentThenFull": true + }, + "requests": [ + { + "path": "/cache-good?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"" + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-good?topic=alpha", + "hx": true, + "restore": false, + "ifNoneMatch": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"", + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"af6404a0e852c5f75ab2abf25f61de82db30f85e21abeb19055a6b5caf854229\"" + }, + { + "path": "/cache-good?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": "\"af6404a0e852c5f75ab2abf25f61de82db30f85e21abeb19055a6b5caf854229\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"" + } + ], + "url": "http://127.0.0.1:45429/cache-good?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N09-missing-vary-negative", + "engine": "chromium", + "status": "pass", + "observation": { + "fragmentServedAsDocument": true, + "additionalRequests": [], + "negativeControl": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-bad?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": "\"69c19e9840aa688ca34f4768e33ab28e0b994aeb5191251db7c0ab9a36b2699b\"" + } + ], + "url": "http://127.0.0.1:45429/cache-bad?topic=beta", + "body": "beta\n\nPublic article beta\n\nOther topic\nTopic \nalpha\nbeta\nFilter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N10-conditional-representations", + "engine": "chromium", + "status": "pass", + "observation": { + "transport": "explicit Node HTTP requests; duplicated per browser group, not independent browser evidence", + "sameRepresentation": 304, + "crossRepresentation": 200, + "restoreFull": true + }, + "requests": [ + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 304, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": true, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + } + ], + "url": "about:blank", + "body": "", + "events": [] + }, + { + "id": "N01-no-script-native", + "engine": "firefox", + "status": "pass", + "observation": { + "directLinkAndGetForm": true, + "fullShell": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N02-enhance-reload-direct", + "engine": "firefox", + "status": "pass", + "observation": { + "pushReloadAndFreshEntry": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N03-history-hit", + "engine": "firefox", + "status": "pass", + "observation": { + "backForward": true, + "additionalArticleRequests": 0 + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [ + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=beta" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=alpha" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:45429/articles?topic=alpha" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=beta" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:45429/articles?topic=beta" + } + ] + }, + { + "id": "N04-history-miss", + "engine": "firefox", + "status": "pass", + "observation": { + "evictedSnapshotFetchedFull": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": true, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [ + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=beta" + }, + { + "name": "htmx:afterSettle", + "url": "http://127.0.0.1:45429/articles?topic=alpha" + }, + { + "name": "htmx:historyRestore", + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "cacheMiss": true + } + ] + }, + { + "id": "N05-enhancement-failure", + "engine": "firefox", + "status": "pass", + "observation": { + "oldViewAndUrlRetained": true, + "explicitNativeRecovery": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&enhancedfail=1", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "fragment", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&enhancedfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=beta&enhancedfail=1", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N06-script-failure", + "engine": "firefox", + "status": "pass", + "observation": { + "nativeLinkAndFormDespiteScript503": true + }, + "requests": [ + { + "path": "/articles?topic=alpha&scriptfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js?fail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=beta&scriptfail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js?fail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js?fail=1", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 503, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/articles?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N07-fragment-before-document", + "engine": "firefox", + "status": "pass", + "observation": { + "fragmentThenFull": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + } + ], + "url": "http://127.0.0.1:45429/cache-good?topic=beta", + "body": "Catalog shell\nbeta\n\nPublic article beta\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N08-document-before-fragment", + "engine": "firefox", + "status": "pass", + "observation": { + "fullThenFragmentThenFull": true + }, + "requests": [ + { + "path": "/cache-good?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"" + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-good?topic=alpha", + "hx": true, + "restore": false, + "ifNoneMatch": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"", + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"af6404a0e852c5f75ab2abf25f61de82db30f85e21abeb19055a6b5caf854229\"" + }, + { + "path": "/cache-good?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": "\"af6404a0e852c5f75ab2abf25f61de82db30f85e21abeb19055a6b5caf854229\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"3a9bd4c1596afe87253606468ccd0909f3748af4a479926917695e13f45b15c3\"" + } + ], + "url": "http://127.0.0.1:45429/cache-good?topic=alpha", + "body": "Catalog shell\nalpha\n\nPublic article alpha\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N09-missing-vary-negative", + "engine": "firefox", + "status": "pass", + "observation": { + "fragmentServedAsDocument": true, + "additionalRequests": [], + "negativeControl": true + }, + "requests": [ + { + "path": "/articles?topic=alpha", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": null, + "etag": null + }, + { + "path": "/observe.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/htmx.js", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/favicon.ico", + "hx": false, + "restore": false, + "ifNoneMatch": null, + "status": 404, + "representation": "asset", + "vary": null, + "etag": null + }, + { + "path": "/cache-bad?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": null, + "etag": "\"69c19e9840aa688ca34f4768e33ab28e0b994aeb5191251db7c0ab9a36b2699b\"" + } + ], + "url": "http://127.0.0.1:45429/cache-bad?topic=beta", + "body": "beta\n\nPublic article beta\n\nOther topic\nTopic Filter\nInjected enhanced failureNative recovery", + "events": [] + }, + { + "id": "N10-conditional-representations", + "engine": "firefox", + "status": "pass", + "observation": { + "transport": "explicit Node HTTP requests; duplicated per browser group, not independent browser evidence", + "sameRepresentation": 304, + "crossRepresentation": 200, + "restoreFull": true + }, + "requests": [ + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": null, + "status": 200, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 304, + "representation": "fragment", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": false, + "restore": false, + "ifNoneMatch": "\"d4a2e4af8c3671d399ddcbbc92984556a75f795817fba6404ea84e1805892663\"", + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + }, + { + "path": "/cache-good?topic=beta", + "hx": true, + "restore": true, + "ifNoneMatch": null, + "status": 200, + "representation": "full", + "vary": "HX-Request, HX-History-Restore-Request", + "etag": "\"843d827eaa297ed04d5424a03a78a7049356060ac71f73bc7e1b85d3b5691c41\"" + } + ], + "url": "about:blank", + "body": "", + "events": [] + } + ], + "passed": 20, + "total": 20 +} diff --git a/research/reviews/NavigationCoverage.md b/research/reviews/NavigationCoverage.md index d81cee6..8980f6a 100644 --- a/research/reviews/NavigationCoverage.md +++ b/research/reviews/NavigationCoverage.md @@ -25,3 +25,11 @@ Stream E follow-up: [feature/deployment contrast](FeatureDeploymentBoundaries.md adds pinned example code and release workflow definitions; operational independence remains unverified. VC-06 now has a provisional synthetic draft; VC-04/05 and VC-07–10 remain planned. One new developed seed brings the current corpus to seventeen hypotheses. + +## Prospective navigation evidence — 2026-09-27 + +[First measured cycle](NavigationHistoryExperiment.md) adds pinned htmx runtime +corroboration to VC-03, URL-addressable State and Progressive Enhancement. Direct/ +native/enhanced/history and representation-cache subset exercised in two browsers; +missing-Vary negative control reproduced. VC-03 stays provisional and offline/ +accessibility work remains open. No maturity or M1/M2 promotion. diff --git a/research/reviews/NavigationHistoryExperiment.md b/research/reviews/NavigationHistoryExperiment.md new file mode 100644 index 0000000..8645def --- /dev/null +++ b/research/reviews/NavigationHistoryExperiment.md @@ -0,0 +1,75 @@ +# First prospective navigation cycle — 2026-09-27 + +Author/reviewer: Codex, author-model; no independent human validation. Stream B, +LEARN-0011. [Registered protocol](../evolution/cycles/2026-09-27-navigation.md) committed +as `f3697c1` before implementation/execution. [Runner and reproduction](../experiments/navigation-history/README.md), +[complete receipt](../experiments/navigation-history/result.json), +[partial first run](../experiments/navigation-history/initial-partial.json). + +## Evidence and observations + +Real htmx 2.0.11 in an authored public-catalog server; Playwright 1.63.0, Chromium +151.0.7922.34 and Firefox 155.0. Dependencies locked, inputs and browser binaries +hashed in the complete receipt. Existing [htmx history/cache documentation](https://htmx.org/docs/) +was consulted for mechanism context (accessed local date 2026-09-27, living revision +unknown); execution is evidence only for the pinned package and declared server policy. + +| Claim | Registered checks | Observation in both browsers | +| --- | --- | --- | +| NH01 | N01/N02 | Direct filtered entry, native link/GET form, enhanced navigation, reload and fresh direct entry preserve selection; document entries include the shell | +| NH02 | N03/N04 | Snapshot back/forward makes no additional article request; evicting the pinned sessionStorage history cache causes a history-restore request and full response | +| NH03 | N05/N06 | Enhanced 503 leaves the old committed URL/content; explicit native recovery works. A failed htmx script load leaves native link/form usable | +| NH04 | N07/N08 | Correct Vary selection returns full versus fragment content in both population orders; N08's final full fetch recontacts the server, not proof that both variants stay cached | +| NH05 | N09 | Without Vary, the browser reuses the cached fragment as a full document, loses the shell, and sends no additional request | +| NH06 | N10 | Explicit Node requests receive 304 for a matching representation validator and 200/full body for the other representation; a history-restore selector returns full content | + +20/20 registered rows met expectations, including the intentionally broken N09. +There are 18 browser cases and the same explicit HTTP sequence repeated twice; do +not describe N10 as browser automatic revalidation. Snapshot hits restore selected +views, not a tested guarantee of current publisher bytes. HTTP cache and htmx history +storage are different mechanisms. Vary names both HX-Request and +HX-History-Restore-Request because both influence the fixture's representation. +The fixture's historyRestoreAsHxRequest=false is explicit, not a claim about defaults. + +The first run completed ten Chromium rows, then failed to locate Firefox in its +default installation path. Its incomplete receipt is preserved. The second run used +the existing `/tmp/fep-playwright-browsers` installation and unrestricted temporary +profile access. No source/criteria changes between runs; repetition is not new learning. +No unexpected assertion failure was discarded. Initial launch error: executable absent +at `/home/worsch/.cache/ms-playwright/firefox-1543/firefox/firefox`. + +## Learning disposition: corroboration + +Before: documentary evidence and synthetic reasoning predicted native contracts, +history recovery and representation-aware caching were necessary for coherent routes. +After: one pinned library plus our server policy supplies bounded runtime support, +including a concrete fragment-as-document counterexample when cache selection is broken. +The existing obligations stand; no new pattern or consequential conceptual revision is +claimed. Updating evidence text is not automatically a new discovery. This is one +question/outcome, not twenty discoveries, and not independent deployed recurrence. + +CAND-0009 and CAND-0010 remain draft/hypothesis. VC-03 remains provisional: its tested +read-only navigation subset is stronger, while keyboard/focus/announcements, delayed +script activation, interrupted transport, invalid/deleted routes, numerical delivery +budgets and offline availability remain open. Native recovery was explicitly offered +by the fixture; no automatic fallback or full accessibility claim follows. No real +CDN/intermediary, private cache policy or publisher-freshness guarantee was tested. + +## Measurement and next decision + +[Effort receipt](../evolution/cycles/2026-09-27-navigation-effort.json) records the +monotonic measured window and subtracted execution intervals. Active time includes +registration, fixture development, source inspection, analysis and recording. The +initial orientation is excluded; subprocess execution includes the failed launch and +full rerun. Administrative commit/snapshot/sync time after cutoff is unmeasured overhead. +This is single-agent elapsed effort, not human labor or model compute time. Token/cost +telemetry is unknown. Brief checkpoint inspection during execution is assigned wholly +to execution, never counted twice. Clock start UTC label was read during orientation; +monotonic start after orientation is the duration authority. + +No diminishing-returns claim follows from one corroborating cycle. WP-0006 T03 keeps +comparison-window review and review-date reconciliation open. WP-0003 T01 next owns +bounded keyboard/focus/error-feedback checks if we continue this navigation stream; +use a new comparison group if the accessibility question/protocol is materially different. +WP-0003 T02 still owns the independent walkthrough review and offline branch. M1/M2, +independent human review and language usefulness remain unresolved. diff --git a/research/walkthroughs/VC03-ContentPublication.md b/research/walkthroughs/VC03-ContentPublication.md index 93d28ec..bd274a2 100644 --- a/research/walkthroughs/VC03-ContentPublication.md +++ b/research/walkthroughs/VC03-ContentPublication.md @@ -98,3 +98,13 @@ representation-cache checks. Test interrupted enhancement separately from entire absent scripts. Establish a measurable content-delivery budget before performance claims. Keep offline cache research bounded; do not add another draft merely to make the diagram complete. Independent decision-usefulness review remains open. + +## Prospective runtime subset — 2026-09-27 + +[Navigation/history experiment](../reviews/NavigationHistoryExperiment.md) NH01–NH06 +corroborates direct/native/enhanced navigation, snapshot hit/miss recovery and full/ +fragment cache selection in an authored htmx fixture. Both browsers reproduce shell +loss under missing Vary. Validator checks use explicit Node requests. This strengthens +the read-only trace; the case remains provisional. Keyboard/focus/announcements, late +scripts, interrupted transport, invalid/deleted routes and the offline branch remain +open. No performance, independent-human or decision-usefulness gate is completed. diff --git a/tests/test_research_evolution.py b/tests/test_research_evolution.py index 10dc6ae..faf7db5 100644 --- a/tests/test_research_evolution.py +++ b/tests/test_research_evolution.py @@ -43,11 +43,12 @@ def test_rejects_misleading_or_untraceable_records(data, mutation, match): def test_unknown_effort_and_retrospective_sample_cannot_create_a_trend(data): + data['ledger']['events'] = [e for e in data['ledger']['events'] if e['recording'] == 'retrospective'] for entry in data['ledger']['events']: entry['effort']['research_minutes'] = None report = evolution.render(data) assert 'Learning rate and diminishing returns: **not measurable' in report - assert '0/10' in report + assert f"0/{len(data['ledger']['events'])}" in report assert 'historical only' in report assert 'no revised numeric count' in report assert 'Consequential outcome/hour' not in report diff --git a/workplans/FEP-WP-0003-contrasting-schools.md b/workplans/FEP-WP-0003-contrasting-schools.md index b3a746e..d10f851 100644 --- a/workplans/FEP-WP-0003-contrasting-schools.md +++ b/workplans/FEP-WP-0003-contrasting-schools.md @@ -8,7 +8,7 @@ status: active owner: codex topic_slug: canon created: "2026-09-24" -updated: "2026-09-26" +updated: "2026-09-27" state_hub_workstream_id: "13c123f1-a470-560e-ab8e-b270c387930a" --- @@ -185,3 +185,19 @@ real backend outcome or retention authorization claim. These remain T01 limits f any production recommendation. Next breadth task: pending VC-03 navigation/history/ full-versus-fragment cache evidence. Seventeen hypotheses; T02/T03 and M1/M2 gates unchanged. No model inference or production actions. + +## First prospective cycle completed — 2026-09-27 + +LEARN-0011 preregistered at f3697c1; htmx 2.0.11 navigation/history/cache experiment +meets 20/20 registered checks (18 browser rows and repeated explicit HTTP checks). +Both browsers reproduce missing-Vary fragment-as-document failure. Outcome is +corroboration, not a new discovery. Active/execution effort recorded in +research/evolution/cycles/2026-09-27-navigation-effort.json; one cycle cannot show a trend. +Candidate profiles/report updated; hypothesis status and provisional VC-03 retained. + +WP-0003 T01 retains keyboard/focus/error-feedback and delayed/interrupted enhancement +questions; T02 retains independent walkthrough review and offline-reading branch. +WP-0006 T03 remains progress for comparable-window review and remaining substantive +review-date reconciliation. Choose a new comparison group for materially different +questions. M1/M2 and independent-human validation remain open. See +research/reviews/NavigationHistoryExperiment.md. diff --git a/workplans/FEP-WP-0006-language-evolution.md b/workplans/FEP-WP-0006-language-evolution.md index 54ed927..038a60c 100644 --- a/workplans/FEP-WP-0006-language-evolution.md +++ b/workplans/FEP-WP-0006-language-evolution.md @@ -8,7 +8,7 @@ status: active owner: codex topic_slug: canon created: "2026-09-26" -updated: "2026-09-26" +updated: "2026-09-27" state_hub_workstream_id: "528d24c1-c2c4-5914-a065-992b0dd877c8" --- @@ -49,7 +49,7 @@ experiment receipts. Intent/protocol/program now describe continuous learning. ```task id: FEP-WP-0006-T03 -status: todo +status: progress priority: medium state_hub_task_id: "2c5c4bae-a0a9-54bf-ac86-49b2803fdd8c" ``` @@ -64,3 +64,19 @@ then and no automatic plateau declaration. Preserve independent confirmation val Reconcile substantive-review dates from original artifacts; baseline assessment dates must not fabricate freshness. Future usefulness work retains stable development anchors and preregisters fresh tasks under WP-0004; it does not alter the consumed pilot. + +## First prospective cycle completed — 2026-09-27 + +LEARN-0011 preregistered at f3697c1; htmx 2.0.11 navigation/history/cache experiment +meets 20/20 registered checks (18 browser rows and repeated explicit HTTP checks). +Both browsers reproduce missing-Vary fragment-as-document failure. Outcome is +corroboration, not a new discovery. Active/execution effort recorded in +research/evolution/cycles/2026-09-27-navigation-effort.json; one cycle cannot show a trend. +Candidate profiles/report updated; hypothesis status and provisional VC-03 retained. + +WP-0003 T01 retains keyboard/focus/error-feedback and delayed/interrupted enhancement +questions; T02 retains independent walkthrough review and offline-reading branch. +WP-0006 T03 remains progress for comparable-window review and remaining substantive +review-date reconciliation. Choose a new comparison group for materially different +questions. M1/M2 and independent-human validation remain open. See +research/reviews/NavigationHistoryExperiment.md.