Measure navigation history and cache corroboration cycle
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
This commit is contained in:
parent
f3697c1447
commit
d32774da51
20 changed files with 2917 additions and 24 deletions
9
TREE.md
9
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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
45
research/evolution/cycles/2026-09-27-navigation-effort.json
Normal file
45
research/evolution/cycles/2026-09-27-navigation-effort.json
Normal file
|
|
@ -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."
|
||||
}
|
||||
|
|
@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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": []
|
||||
},
|
||||
|
|
|
|||
40
research/experiments/navigation-history/README.md
Normal file
40
research/experiments/navigation-history/README.md
Normal file
|
|
@ -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.
|
||||
114
research/experiments/navigation-history/experiment.mjs
Normal file
114
research/experiments/navigation-history/experiment.mjs
Normal file
|
|
@ -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=`<main id="content" hx-history-elt><h1>${topic}</h1><p id="article">Public article ${topic}</p><a id="next" href="${url.pathname}?topic=${topic==='alpha'?'beta':'alpha'}${fail}" hx-boost="true" hx-target="#content" hx-select="#content" hx-swap="outerHTML">Other topic</a><form action="${url.pathname}" method="get"><label>Topic <select name="topic"><option>alpha</option><option>beta</option></select></label><button>Filter</button></form><a id="broken" href="/articles?topic=beta&enhancedfail=1" hx-boost="true" hx-target="#content" hx-select="#content" hx-swap="outerHTML">Injected enhanced failure</a><a id="recover" href="/articles?topic=beta&enhancedfail=1">Native recovery</a></main>`;
|
||||
representation=hx&&!restore?'fragment':'full';
|
||||
const full=`<!doctype html><html lang="en"><head><meta charset="utf-8"><title>Public catalog</title><meta name="htmx-config" content='{"historyRestoreAsHxRequest":false}'><script src="/observe.js"></script><script src="/htmx.js${fail?'?fail=1':''}" defer></script></head><body><header id="shell">Catalog shell</header>${main}</body></html>`;
|
||||
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('<main'));
|
||||
const full=await cachedFetch(p,path);assert(full.text.includes('id="shell"'));return {fullThenFragmentThenFull:true};
|
||||
});
|
||||
await scenario('N09-missing-vary-negative',async p=>{
|
||||
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;
|
||||
768
research/experiments/navigation-history/initial-partial.json
Normal file
768
research/experiments/navigation-history/initial-partial.json
Normal file
|
|
@ -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": []
|
||||
}
|
||||
]
|
||||
}
|
||||
47
research/experiments/navigation-history/package-lock.json
generated
Normal file
47
research/experiments/navigation-history/package-lock.json
generated
Normal file
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
research/experiments/navigation-history/package.json
Normal file
1
research/experiments/navigation-history/package.json
Normal file
|
|
@ -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"}}
|
||||
1643
research/experiments/navigation-history/result.json
Normal file
1643
research/experiments/navigation-history/result.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -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.
|
||||
|
|
|
|||
75
research/reviews/NavigationHistoryExperiment.md
Normal file
75
research/reviews/NavigationHistoryExperiment.md
Normal file
|
|
@ -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.
|
||||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue