Track pattern evidence and ongoing language learning

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0cffe-206f-7323-89d3-b20ca4cf4bf9
This commit is contained in:
tegwick 2026-09-27 00:00:39 +02:00
parent f273a190f0
commit b8a03a3bee
16 changed files with 3223 additions and 12 deletions

View file

@ -1,6 +1,6 @@
# INTENT
Status: preliminary · Reviewed: 2026-09-23
Status: evolving research language · Reviewed: 2026-09-26
This records the initial direction inferred from the repository scaffold. The
responsibility model, vocabulary and sequences remain hypotheses to test against
@ -80,11 +80,12 @@ The deliverable is a versioned Markdown knowledge base: vocabulary, patterns,
relations, architecture decompositions, decision sequences, technology mappings
and traceable evidence. A running application or framework is not required.
The current repository is a scaffold. Pattern families contain candidate lists;
architecture descriptions and most sequences are research stubs. There are no
completed canonical pattern records, technology mappings, graph exports or
automated validators. The first source case is an initial interpretation, not a
completed source review.
The current corpus contains seventeen draft hypotheses, source reviews, bounded
runtime experiments and four synthetic/provisional walkthroughs. Canonical admission,
independent human validation and the M1/M2 gates remain open. Metadata and research
checks exist; full graph export and demonstrated generativity remain future work.
See the [evolution report](research/evolution/EvolutionReport.md) for the versioned
evidence profile and limitations.
## Preliminary priorities
@ -118,3 +119,19 @@ evidence quality or the ability to explain a concrete design decision.
`research/plan/ResearchProgram.md` provides a provisional roadmap; its milestones
describe planned work, not completed capabilities.
## Continuous learning
The language is intended to evolve indefinitely. Complete bounded investigations and
review milestones; do not treat the language as finished. Maturity is a reversible
evidence judgment, including for canonical records. Preserve superseded claims and
explain what new evidence changed, what remains uncertain and what the investigation
cost when measured.
Track applicability, trustworthiness, usefulness, coherence, maintainability and
learning efficiency separately. Never infer health from catalog size or combine these
into a maturity percentage. Rapid initial learning and eventual diminishing returns
are hypotheses to assess within comparable streams and effort-accounted cycles.
Independent confirmation remains valuable even when it does not change wording.
The [evolution method](research/evolution/README.md) defines the baseline, ledger,
reporting and prospective measurement protocol.

View file

@ -9,3 +9,13 @@ bench-plan:
schema-test:
PYTHONDONTWRITEBYTECODE=1 "$(BENCH_PY)" -m pytest -q -p no:cacheprovider tests/test_pattern_contract.py
.PHONY: evolution-report evolution-check evolution-test
evolution-report:
python3 scripts/research_evolution.py generate
evolution-check:
python3 scripts/research_evolution.py check
evolution-test:
PYTHONDONTWRITEBYTECODE=1 "$(BENCH_PY)" -m pytest -q -p no:cacheprovider tests/test_research_evolution.py

View file

@ -80,19 +80,23 @@ Software patterns must describe when they become harmful, misleading, expensive
## Status
This repository begins as a v0.1 research scaffold with evidence collection still pending. The first research case is Ryan Carniato's
"The Grand Unifying Architecture of Frontend", used as a starting point for decomposing modern frontend
architectures into deeper responsibilities and forces.
The corpus currently contains seventeen draft hypotheses, traceable source reviews,
bounded runtime experiments and four synthetic/provisional walkthroughs. Independent
human validation, canonical admission and demonstrated generativity remain open.
The [evolution report](research/evolution/EvolutionReport.md) makes evidence, gaps,
learning outcomes and unknowns visible; the [method](research/evolution/README.md)
explains how the language continues learning over time.
## Research entry point
Start with the [research program](research/plan/ResearchProgram.md), its
[protocol](research/plan/ResearchProtocol.md) and [validation cases](research/plan/ValidationCases.md).
The first cycle is ready in [FEP-WP-0002](workplans/FEP-WP-0002-seed-language-validation.md):
The seed investigation remains active in [FEP-WP-0002](workplans/FEP-WP-0002-seed-language-validation.md):
resolve the metadata contract, review contrasting sources and test a connected seed
corpus. Later phases broaden coverage and evaluate retrieval against real systems.
The [research bench](research/bench/README.md) now provides executable source
investigations through infospace-bench. Run `make bench-test` to verify the adapter
and `make bench-plan` to inspect the synthetic pilot. Real source review is pending.
and `make bench-plan` to inspect the synthetic pilot. Source reviews and live pilot receipts are retained under `research/`.
Run `make evolution-check evolution-test` to verify evolution records and reporting.

10
TREE.md
View file

@ -347,6 +347,12 @@ research/evaluations/language-pilot-01/submitted-review-01/scores.json
research/evaluations/language-pilot-01/submitted-review-01/worksheet-completed.md
research/evaluations/language-pilot-01/summarize.py
research/evaluations/language-pilot-01/summary.json
research/evolution/EvolutionReport.md
research/evolution/README.md
research/evolution/context.json
research/evolution/ledger.json
research/evolution/profiles.json
research/evolution/snapshots/baseline-2026-09-26.json
research/examples/SchemaEvidence.md
research/examples/schema-contract.yaml
research/experiments/boundary-recovery/README.md
@ -437,6 +443,7 @@ research/walkthroughs/VC03-ContentPublication.md
research/walkthroughs/VC06-MicrofrontendEstate.md
scripts/research_admission.py
scripts/research_bench.py
scripts/research_evolution.py
scripts/research_execution.py
sequences/CollaborativeApplication.md
sequences/ContentSite.md
@ -446,6 +453,7 @@ sequences/README.md
sequences/TransactionalApplication.md
technologies/README.md
templates/ArchitectureWalkthrough.md
templates/LearningCycle.md
templates/Pattern.md
templates/ResearchReviewMetrics.yaml
templates/SourceReview.md
@ -453,9 +461,11 @@ templates/TechnologyMapping.md
tests/test_pattern_contract.py
tests/test_research_admission.py
tests/test_research_bench.py
tests/test_research_evolution.py
workplans/FEP-WP-0001-statehub-bootstrap.md
workplans/FEP-WP-0002-seed-language-validation.md
workplans/FEP-WP-0003-contrasting-schools.md
workplans/FEP-WP-0004-reference-surface.md
workplans/FEP-WP-0005-research-bench-setup.md
workplans/FEP-WP-0006-language-evolution.md
```

View file

@ -0,0 +1,475 @@
# Language evolution report
Generated by `make evolution-report`; curated assessment date: 2026-09-26.
This is an evidence profile, not a completion percentage. Evidence presence does not establish full-contract recurrence or production fitness.
The baseline profiles are author-model assessments by Codex; they do not confer independent validation.
## Current corpus
17 candidates: 17 hypothesis.
| Evidence attached to a candidate | Candidates |
| --- | ---: |
| documentary | 17 |
| static-code | 5 |
| runtime | 6 |
Categories overlap. Runtime includes authored fixtures and negative controls. Family labels group related evidence; they are not counts of independent applications.
Independent human profile reviews: 0/17. Full-contract independent-use counts unassessed: 17/17.
## 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.
The shared cohort is compared separately from additions. Changed text or evidence counts are not learning gains.
## Applicability and usefulness
| Case | State |
| --- | --- |
| [VC-01](../../research/walkthroughs/VC01-TransactionalAdministration.md) | synthetic draft |
| [VC-02](../../research/walkthroughs/VC02-OfflineFieldNotes.md) | synthetic draft |
| [VC-03](../../research/walkthroughs/VC03-ContentPublication.md) | provisional |
| [VC-04](../../research/plan/ValidationCases.md) | planned |
| [VC-05](../../research/plan/ValidationCases.md) | planned |
| [VC-06](../../research/walkthroughs/VC06-MicrofrontendEstate.md) | provisional |
| [VC-07](../../research/plan/ValidationCases.md) | planned |
| [VC-08](../../research/plan/ValidationCases.md) | planned |
| [VC-09](../../research/plan/ValidationCases.md) | planned |
| [VC-10](../../research/plan/ValidationCases.md) | planned |
Frozen pilot after adjudication: named 18/24; prose 18/24. Initial unsupported-claim count: 2 per condition (historical only); adjudicated flags remain qualitative, with no revised numeric count. Independent human validation: pending. Decision time: unknown. [Adjudication](../../research/evaluations/language-pilot-01/submitted-review-01/adjudication.md).
One frozen development pilot with submitted model review; six matched briefs. Equal aggregate scores do not establish equivalence. Stable anchors are consumed development cases, not fresh held-out tasks.
## 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.
| Outcome | Entries (not independent discoveries) |
| --- | ---: |
| corroboration | 0 |
| 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.
No prospective comparison windows yet. Learning rate and diminishing returns: **not measurable from this baseline**.
## 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.
Coherence metrics (ambiguous selections, unjustified relations and overlap resolved): not measured. Conflict Copy / Explicit Reconciliation overlap remains an explicit open question.
Review backlog and evidence gaps remain in [FEP-WP-0002-seed-language-validation](../../workplans/FEP-WP-0002-seed-language-validation.md), [FEP-WP-0003-contrasting-schools](../../workplans/FEP-WP-0003-contrasting-schools.md), [FEP-WP-0006-language-evolution](../../workplans/FEP-WP-0006-language-evolution.md).
## Pattern profiles
### CAND-0001 — Conflict Copy
[ConflictCopy](../../research/candidates/ConflictCopy.md) · draft / hypothesis
Preserve competing versions instead of silently losing one.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Joplin | Documented detected-note conflict copy. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
| documentary | Obsidian | Optional conflict-file mode, not default behavior. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
Open limits: Authorized retention and export are separate decisions. Complete contract recurrence and fault-tested deployed behavior remain unverified.
Superseded by: none recorded.
### CAND-0002 — Local Commit Boundary
[LocalCommitBoundary](../../research/candidates/LocalCommitBoundary.md) · draft / hypothesis
Define when a local change is durably accepted.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Ink & Switch | Local-first motivation. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
| documentary | Joplin | Local storage and synchronization architecture. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
Open limits: No executed storage crash or backup test. Local acceptance is not off-device recovery.
Superseded by: none recorded.
### CAND-0003 — Pending Synchronization
[PendingSynchronization](../../research/candidates/PendingSynchronization.md) · draft / hypothesis
Keep accepted local intent visible until synchronization resolves.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Joplin | Per-item synchronization metadata. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
Open limits: Atomic supersession and retry contract proposed, not storage-tested.
Superseded by: none recorded.
### CAND-0004 — Explicit Reconciliation
[ExplicitReconciliation](../../research/candidates/ExplicitReconciliation.md) · draft / hypothesis
Resolve divergent content while retaining provenance.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Joplin | Documented manual conflict resolution. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
| documentary | Obsidian | Conflict comparison workflow. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
Open limits: Atomic resolution/provenance UI not executed. Overlap with Conflict Copy remains an open merge question.
Superseded by: none recorded.
### CAND-0005 — Local Draft State
[LocalDraftState](../../research/candidates/LocalDraftState.md) · draft / hypothesis
Separate unfinished intent from refreshed authoritative data.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Kubernetes / GitLab / React Router | Rejection and pending-input mechanisms motivate recovery. | [TransactionalEvidenceExpansion](../../research/reviews/TransactionalEvidenceExpansion.md) |
| static-code | Zulip | Pinned composer draft storage; partial lifecycle. | [FrontendRecoveryImplementations](../../research/reviews/FrontendRecoveryImplementations.md) |
| static-code | Element / Matrix | Pinned composer draft restoration; partial lifecycle. | [FrontendRecoveryImplementations](../../research/reviews/FrontendRecoveryImplementations.md) |
| runtime | authored release fixture | Same-tab preservation/refusal/discard and post-navigation schema check. | [ActivationConflictsAndReload](../../research/reviews/ActivationConflictsAndReload.md) |
Open limits: No native-unload, crash, multiple-tab or access-revocation guarantee. Full base/draft/current merge contract is not verified in deployed frontends.
Superseded by: none recorded.
### CAND-0006 — Version-Checked Mutation
[VersionCheckedMutation](../../research/candidates/VersionCheckedMutation.md) · draft / hypothesis
Reject an operation whose observed base is stale.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Kubernetes | Conditional PUT; precise version mechanism. | [TransactionalEvidenceExpansion](../../research/reviews/TransactionalEvidenceExpansion.md) |
| documentary | GitLab | Optional last_commit_id; different failure surface. | [TransactionalEvidenceExpansion](../../research/reviews/TransactionalEvidenceExpansion.md) |
| runtime | authored release fixture | Related conditional activation-map mechanism in one process, not the full frontend pattern. | [ActivationConflictsAndReload](../../research/reviews/ActivationConflictsAndReload.md) |
Open limits: Distributed atomicity and complete frontend recurrence remain unverified. Refetch does not authorize overwriting conflicting intent.
Superseded by: none recorded.
### CAND-0007 — Mutation Outcome Tracking
[MutationOutcomeTracking](../../research/candidates/MutationOutcomeTracking.md) · draft / hypothesis
Retain operation identity when transport outcome is uncertain.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Stripe | Idempotency mechanism. | [TransactionalEvidenceExpansion](../../research/reviews/TransactionalEvidenceExpansion.md) |
| documentary | React Router | Cancellation does not imply server rollback. | [TransactionalEvidenceExpansion](../../research/reviews/TransactionalEvidenceExpansion.md) |
| static-code | Zulip | Pinned send/recovery state. | [FrontendRecoveryImplementations](../../research/reviews/FrontendRecoveryImplementations.md) |
| static-code | Element / Matrix | Pinned client and SDK transaction/echo paths. | [FrontendRecoveryImplementations](../../research/reviews/FrontendRecoveryImplementations.md) |
| runtime | Element / Matrix | Real SDK with synthetic transport: lost acknowledgement, identity reuse and authoritative echo. | [MatrixRecoveryExperiment](../../research/reviews/MatrixRecoveryExperiment.md) |
Open limits: No production server deduplication or complete retention-window guarantee. Cancelling local UI is not remote compensation.
Superseded by: none recorded.
### CAND-0008 — Invalidate and Reproject
[InvalidateAndReproject](../../research/candidates/InvalidateAndReproject.md) · draft / hypothesis
Refresh a projection after mutation without equating acceptance and visibility.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | React Router | Concurrency and pending-state guidance. | [TransactionalEvidenceExpansion](../../research/reviews/TransactionalEvidenceExpansion.md) |
Open limits: Read-your-write and acceptance/refresh distinction still proposed. No independent deployed full-contract observation.
Superseded by: none recorded.
### CAND-0009 — URL-addressable State
[URLAddressableState](../../research/candidates/URLAddressableState.md) · draft / hypothesis
Make a navigable state reconstructible from its URL.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| 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) |
Open limits: Direct load, history miss and full/fragment cache runtime checks pending.
Superseded by: none recorded.
### CAND-0010 — Progressive Enhancement
[ProgressiveEnhancement](../../research/candidates/ProgressiveEnhancement.md) · draft / hypothesis
Keep essential actions usable when enhancement is unavailable.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | htmx | Boosted links and forms. | [NavigationRenderingEvidence](../../research/reviews/NavigationRenderingEvidence.md) |
| documentary | SvelteKit | Form actions and rendering/page options. | [NavigationRenderingEvidence](../../research/reviews/NavigationRenderingEvidence.md) |
Open limits: No executed no-script workflow or deployed independent recurrence study.
Superseded by: none recorded.
### CAND-0011 — Presentation Model
[PresentationModel](../../research/candidates/PresentationModel.md) · draft / hypothesis
Separate presentation decisions from view mechanisms.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Fowler | Named pattern and illustrative model/view discussion. | [PatternBreadthExpansion](../../research/reviews/PatternBreadthExpansion.md) |
Open limits: No executed model/view integration or independently reviewed full-contract use.
Superseded by: none recorded.
### CAND-0012 — Derived State
[DerivedState](../../research/candidates/DerivedState.md) · draft / hypothesis
Compute a result from explicit authoritative inputs.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Redux | Selector guidance, not a requirement for a global store. | [PatternBreadthExpansion](../../research/reviews/PatternBreadthExpansion.md) |
Open limits: Snapshot coherence and changed-locale cache test still planned.
Superseded by: none recorded.
### CAND-0013 — Vertical Feature Slice
[VerticalFeatureSlice](../../research/candidates/VerticalFeatureSlice.md) · draft / hypothesis
Group a capability across UI, state and behavior with explicit interfaces.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Feature-Sliced Design | Layer/slice and public-interface guidance. | [PatternBreadthExpansion](../../research/reviews/PatternBreadthExpansion.md) |
| static-code | Feature-Sliced Design | Pinned todo-app interfaces coexist with one application build. | [FeatureDeploymentBoundaries](../../research/reviews/FeatureDeploymentBoundaries.md) |
Open limits: Build/import enforcement not executed. Feature organization does not establish independent activation.
Superseded by: none recorded.
### CAND-0014 — Islands of Interactivity
[IslandsOfInteractivity](../../research/candidates/IslandsOfInteractivity.md) · draft / hypothesis
Activate selected interactive regions within a document.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | Astro | Client-island mechanism and execution placement. | [PatternBreadthExpansion](../../research/reviews/PatternBreadthExpansion.md) |
Open limits: No executed island fixture, performance comparison or complete recurrence study.
Superseded by: none recorded.
### CAND-0015 — Failure Boundary
[FailureBoundary](../../research/candidates/FailureBoundary.md) · draft / hypothesis
Contain specified failure classes while preserving useful neighboring work.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | React | Error boundary scope and exclusions. | [PatternBreadthExpansion](../../research/reviews/PatternBreadthExpansion.md) |
| runtime | React | Real package in authored host: render/event/request distinction and fallback escalation. | [BoundaryRecoveryExperiment](../../research/reviews/BoundaryRecoveryExperiment.md) |
Open limits: Synthetic host, not full application recurrence. Boundary cannot imply containment for all asynchronous failures.
Superseded by: none recorded.
### CAND-0016 — Focus Return
[FocusReturn](../../research/candidates/FocusReturn.md) · draft / hypothesis
Restore meaningful focus after a temporary interaction ends.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | WAI-ARIA APG | Dialog focus obligations. | [PatternBreadthExpansion](../../research/reviews/PatternBreadthExpansion.md) |
| static-code | Radix | Pinned layer/listener ownership implementation. | [NestedDismissalIsolation](../../research/reviews/NestedDismissalIsolation.md) |
| runtime | Radix | Authored fixture: raw 20/24 versus routed 24/24; browser/build limits retained. | [NestedOwnershipRouting](../../research/reviews/NestedOwnershipRouting.md) |
Open limits: One implementation family; repeated trials are not independent uses. Animated exits and competing owners remain untested; no production repair claim.
Superseded by: none recorded.
### CAND-0017 — Independent Feature Boundary
[IndependentFeatureBoundary](../../research/candidates/IndependentFeatureBoundary.md) · draft / hypothesis
Separate feature release, activation and session transition contracts.
| Evidence | Family | Scope | Review |
| --- | --- | --- | --- |
| documentary | single-spa / webpack | Mechanism documentation, not deployed independence proof. | [FeatureDeploymentBoundaries](../../research/reviews/FeatureDeploymentBoundaries.md) |
| static-code | react-microfrontends examples | Root config/navbar are one example family with shared startup gating. | [FeatureDeploymentBoundaries](../../research/reviews/FeatureDeploymentBoundaries.md) |
| runtime | authored release fixture | Publication/activation/rollback across fresh, loaded and lazy sessions. | [FeatureReleaseExperiment](../../research/reviews/FeatureReleaseExperiment.md) |
| runtime | authored release fixture | Conditional activation updates and safe reload policies, including negative controls. | [ActivationConflictsAndReload](../../research/reviews/ActivationConflictsAndReload.md) |
Open limits: No upstream deployment or real team/release-independence validation. Distributed atomicity, retention authorization and native-unload/crash behavior remain open.
Superseded by: none recorded.
## Recorded learning
### LEARN-0001 — What do pinned recovery implementations establish?
2026-09-25 · stream D · retrospective · revision
Before: Documentary motivation did not locate draft/outcome mechanisms in frontend code.
Conclusion: Zulip and Element locate partial draft/outcome mechanisms; complete pattern recurrence is still unknown.
Evidence: [FrontendRecoveryImplementations](../../research/reviews/FrontendRecoveryImplementations.md).
Remaining uncertainty: Deployed full lifecycle remains unverified.
Supersedes: none recorded.
### LEARN-0002 — Does cancellation or a transport error settle mutation outcome?
2026-09-25 · stream D · retrospective · revision
Before: Recovery identity and authoritative echo required executable checks.
Conclusion: Synthetic transport with the real Matrix SDK distinguishes replay identity, duplicate commits and authoritative echo.
Evidence: [MatrixRecoveryExperiment](../../research/reviews/MatrixRecoveryExperiment.md).
Remaining uncertainty: No real server deduplication guarantee.
Supersedes: none recorded.
### LEARN-0003 — Does naming patterns improve the frozen pilot decisions?
2026-09-26 · stream cross-stream · retrospective · revision
Before: Initial editorial scores were 21/24 named and 19/24 prose.
Conclusion: Submitted model review adjudication yields 18/24 in each condition; this does not establish equivalence or a presentation benefit.
Evidence: [adjudication](../../research/evaluations/language-pilot-01/submitted-review-01/adjudication.md).
Remaining uncertainty: Independent human validation pending. Historical effort unknown; this entry does not allocate whole-pilot telemetry.
Supersedes: none recorded.
### LEARN-0004 — Which recovery recommendations overstate their guarantees?
2026-09-26 · stream D · retrospective · revision
Before: Shared guidance left retention/export policy, cancellation and local backup boundaries insufficiently explicit.
Conclusion: Guidance now separates authorization, remote compensation, atomic supersession and off-device backup.
Evidence: [SharedGuidanceRevision](../../research/reviews/SharedGuidanceRevision.md).
Remaining uncertainty: Editorial correction is not new production evidence.
Supersedes: none recorded.
### LEARN-0005 — What does URL/history and enhancement documentation actually promise?
2026-09-26 · stream B · retrospective · revision
Before: Navigation and rendering seeds lacked explicit dereferenceability and fallback distinctions.
Conclusion: Developed two hypotheses separating address-bar updates from direct loads, and HTML delivery from usable no-script actions.
Evidence: [NavigationRenderingEvidence](../../research/reviews/NavigationRenderingEvidence.md).
Remaining uncertainty: Navigation/history/cache runtime checks remain pending.
Supersedes: none recorded.
### LEARN-0006 — Why can immediate nested dismissal close the outer task?
2026-09-26 · stream F · retrospective · revision
Before: The first fixture exposed a timing failure with unresolved ownership.
Conclusion: Trace locates stale Escape listener ownership despite inner registration/focus; a guard can lose input.
Evidence: [BoundaryRecoveryExperiment](../../research/reviews/BoundaryRecoveryExperiment.md), [NestedDismissalIsolation](../../research/reviews/NestedDismissalIsolation.md).
Remaining uncertainty: Readiness waits are not a public product repair.
Supersedes: none recorded.
### LEARN-0007 — Can event-time ownership route dismissal without a settling delay?
2026-09-26 · stream F · retrospective · revision
Before: Isolation supplied a mechanism but no lifecycle-safe candidate routing experiment.
Conclusion: Controlled fixture routed 24/24 versus raw 20/24; initial measurement error and corrected results retained.
Evidence: [NestedOwnershipRouting](../../research/reviews/NestedOwnershipRouting.md).
Remaining uncertainty: Animated exit and competing-owner coverage remain open.
Supersedes: none recorded.
### LEARN-0008 — Are feature organization and independent activation the same boundary?
2026-09-26 · stream E · retrospective · revision
Before: The feature-slice hypothesis needed a source-layout/release contrast.
Conclusion: Pinned examples distinguish organizational slicing from activation contracts; added Independent Feature Boundary.
Evidence: [FeatureDeploymentBoundaries](../../research/reviews/FeatureDeploymentBoundaries.md).
Remaining uncertainty: Shared startup dependencies still couple nominally separate features.
Supersedes: none recorded.
### LEARN-0009 — Does publication or rollback update every session?
2026-09-26 · stream E · retrospective · revision
Before: Static source review could not establish loaded/lazy-session behavior.
Conclusion: Native-module experiment distinguishes publication, activation and already-bound sessions; artifact retirement breaks old lazy sessions.
Evidence: [FeatureReleaseExperiment](../../research/reviews/FeatureReleaseExperiment.md).
Remaining uncertainty: No CDN or upstream deployment validation.
Supersedes: none recorded.
### LEARN-0010 — How do stale activation writers and unfinished drafts constrain updates?
2026-09-26 · stream E · retrospective · revision
Before: Release experiment left activation conflicts and reload policy unexecuted.
Conclusion: Conditional replacement rejects stale writers; explicit reload policies preserve or refuse transition, with schema recheck after navigation.
Evidence: [ActivationConflictsAndReload](../../research/reviews/ActivationConflictsAndReload.md).
Remaining uncertainty: One-process atomicity; no native unload, crash or real remote-outcome coverage.
Supersedes: none recorded.

View file

@ -0,0 +1,114 @@
# Learning and language evolution
Start with the generated [evolution report](EvolutionReport.md). The language is an
ongoing learning system; a completed investigation is a bounded result, not a claim
that the language is finished. Maturity can rise or fall when evidence changes.
Even `canonical` means reviewed for reference use, not permanently true.
## Records and ownership
- [profiles.json](profiles.json) holds current, manually reviewed evidence profiles.
`CAND-*` identifiers are stable research identities, not admitted `FEP-*` pattern
identities. Preserve identity across renames. For a merge, retain the retired
candidate with deprecated metadata and `superseded_by`; explain the decision in
the ledger. Promotion and relations still require the PatternSchema review gates.
- [ledger.json](ledger.json) records consequential outcomes, independent confirmation,
rejection/merge and inconclusive investigation. Its initial ten entries are a
selected retrospective account, not a complete historical census. Historical
effort is unknown. Never rewrite an old conclusion to hide its failure; append a
correction with `supersedes`. Git preserves corrections to recording errors.
- [context.json](context.json) records walkthrough state, usefulness results and live
work records. These are curated assessments, not automatically inferred findings.
- [baseline-2026-09-26](snapshots/baseline-2026-09-26.json) freezes all three assessments
and the source commit for the 17 candidate hashes. The assessment itself is new
metadata, versioned by the commit adding the snapshot, not claimed to exist at
that older source revision. Later snapshots never overwrite earlier ones.
A profile explains a decision and records documentary, static-code and runtime
support separately. Each evidence item identifies a family, scope and local review.
Related packages/examples, multiple files and repeated fixture runs do not establish
independence. Family labels are provenance groupings, not an independence score.
`independent_full_contract_uses: null` means unassessed, not zero known mechanisms.
A numeric value requires an explicit review locating independent full-contract uses.
Review provenance distinguishes author/model, independent model and human review.
The baseline is an author-model metadata assessment; no independent human review is
implied. `assessed_at` does not reset `last_substantive_review_date`: the latter is
unknown until the evidence review's date and scope have been reconciled. Open limits
include counterexamples and contexts still untested. Supersession is explicit.
## Closing a bounded cycle
1. Before execution, copy [LearningCycle](../../templates/LearningCycle.md) into a
dated research plan. State one question, belief, disconfirming observation,
stream, protocol, comparison group, intended decision and effort budget. Include
the evidence needed to distinguish revision from simple corroboration.
2. Execute and retain failures and negative controls. Live inference uses llm-connect.
Record active research minutes and execution minutes separately; do not infer
effort from token count or elapsed calendar time. Allocate overlapping activity
once. Record the clock/method and missing portions in the cycle plan. Tokens and
cost are optional receipt-backed telemetry, not substitutes for effort.
3. Close one ledger entry per bounded question, including inconclusive work. Add a
protocol reference for prospective cycles. One question can count at most one
consequential outcome even if it revises several files. Repeat trials belong
under that entry; a genuinely new question needs its own preregistered cycle.
Choose revision, corroboration, rejection, merge or inconclusive, with rationale.
4. Update affected profiles and their candidate hashes after reviewing the actual
changes; update case/usefulness status only when supporting review changes.
Regenerate and check the report. Commit candidate edits before taking a snapshot.
5. At a review boundary, run `python3 scripts/research_evolution.py snapshot --name
cycle-YYYY-MM-DD-short-name`, commit the snapshot and sync the workplan. Reopen
decisions when contradictions, new contexts, dependency changes or failed use
undermine their scope. Never promote automatically from metric thresholds.
Commands: `make evolution-report`, `make evolution-check`, `make evolution-test`.
The check rejects stale candidate hashes, missing references, inventory drift,
invalid provenance, unknown identities, corrupted baseline candidate hashes and stale
generated output. It does not
validate source truth, external URLs, semantic independence or full-contract scope.
Snapshot creation pins committed candidate content and refuses to overwrite a file.
## Measuring viability without a composite score
| Dimension | Observation to collect | Current limit |
| --- | --- | --- |
| Applicability | Reviewed decisions and failure contexts across the ten validation cases | Four synthetic/provisional walkthroughs; six planned |
| Trustworthiness | Scoped evidence, independent full-contract uses, unresolved contradictions, provenance and review age | Independent recurrence and substantive-review ages unassessed |
| Usefulness | Constraint misses, unsupported recommendations, decision quality and time against equivalent prose | Frozen small model-reviewed pilot; human gate open |
| Coherence | Ambiguous selections, redundant candidates and unjustified relations found/resolved in reviews | No measured baseline; reconciliation/copy overlap remains open |
| Maintainability | Reference checks, overdue review obligations, remaining gaps and effort per revision | Local links/hash checks automated; age/backlog estimates not yet measured |
| Learning efficiency | Consequential changes per recorded research hour, alongside corroboration and inconclusive outcomes | Retrospective effort unknown; no trend yet |
Usefulness evaluations retain stable development anchors for regression and add
fresh generalization tasks. Register tasks, criteria and equivalent-information
conditions before execution; preserve negative results and reviewer provenance.
Do not tune on the frozen pilot and relabel it held-out. The six consumed pilot
briefs cannot demonstrate fresh generalization. Keep time, decision quality and
unsupported claims separate; equal aggregate scores do not establish equivalence.
## Assessing diminishing returns
Fast initial learning followed by slower change is a hypothesis, not an assumed
trajectory. Compare prospective cycles only within the same stream, evidence tier,
question granularity, effort accounting and evaluation protocol. A comparison-group
name refers to that declared contract. Split the group when the contract changes;
do not pool unrelated research just to obtain a trend.
The report shows per-cycle consequential outcomes per recorded active research hour
for prospective groups. Unknown or zero time yields an unknown rate. Corroboration
is shown separately: no revision can be valuable confirmation, and inconclusive
work may reveal a faulty method. Execution time, tokens and cost remain separate
ledger fields; the active-effort rate is not a total-cost productivity claim.
After at least three comparable cycles, review the sequence qualitatively: did new
sources change decisions or limits, did uncertainty shrink, and do fresh cases still
fail? Three is a review trigger, not statistical proof of a plateau. Record any
conclusion and its window/protocol in a new review. Do not infer a slope from this
baseline or the selected retrospective entries. Prefer more independent validation
when beliefs stabilize; broaden when new contexts expose missing decisions; repair
structure when ambiguity prevents use. Low novelty alone is not a stopping rule.
Keep both the unchanged candidate cohort and additions/removals visible when
comparing snapshots. A growing inventory must not hide weakening evidence for old
claims. Learning continues after milestones; finite workplans carry the next bounded
question and explicit residuals.

View file

@ -0,0 +1,71 @@
{
"schema_version": 1,
"cases": [
{
"id": "VC-01",
"state": "synthetic draft",
"ref": "research/walkthroughs/VC01-TransactionalAdministration.md"
},
{
"id": "VC-02",
"state": "synthetic draft",
"ref": "research/walkthroughs/VC02-OfflineFieldNotes.md"
},
{
"id": "VC-03",
"state": "provisional",
"ref": "research/walkthroughs/VC03-ContentPublication.md"
},
{
"id": "VC-04",
"state": "planned",
"ref": "research/plan/ValidationCases.md"
},
{
"id": "VC-05",
"state": "planned",
"ref": "research/plan/ValidationCases.md"
},
{
"id": "VC-06",
"state": "provisional",
"ref": "research/walkthroughs/VC06-MicrofrontendEstate.md"
},
{
"id": "VC-07",
"state": "planned",
"ref": "research/plan/ValidationCases.md"
},
{
"id": "VC-08",
"state": "planned",
"ref": "research/plan/ValidationCases.md"
},
{
"id": "VC-09",
"state": "planned",
"ref": "research/plan/ValidationCases.md"
},
{
"id": "VC-10",
"state": "planned",
"ref": "research/plan/ValidationCases.md"
}
],
"usefulness": {
"named_score": 18,
"prose_score": 18,
"denominator": 24,
"independent_human": false,
"decision_time_minutes": null,
"ref": "research/evaluations/language-pilot-01/submitted-review-01/adjudication.md",
"limit": "One frozen development pilot with submitted model review; six matched briefs. Equal aggregate scores do not establish equivalence. Stable anchors are consumed development cases, not fresh held-out tasks.",
"initial_unsupported_claims_each": 2,
"adjudicated_unsupported_claim_count": null
},
"open_work": [
"workplans/FEP-WP-0002-seed-language-validation.md",
"workplans/FEP-WP-0003-contrasting-schools.md",
"workplans/FEP-WP-0006-language-evolution.md"
]
}

View file

@ -0,0 +1,341 @@
{
"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.",
"events": [
{
"id": "LEARN-0001",
"date": "2026-09-25",
"recording": "retrospective",
"stream": "D",
"comparison_group": null,
"question": "What do pinned recovery implementations establish?",
"previous_belief": "Documentary motivation did not locate draft/outcome mechanisms in frontend code.",
"conclusion": "Zulip and Element locate partial draft/outcome mechanisms; complete pattern recurrence is still unknown.",
"disposition": "revision",
"affected_patterns": [
"CAND-0005",
"CAND-0007"
],
"evidence": [
"research/reviews/FrontendRecoveryImplementations.md"
],
"remaining_uncertainty": [
"Deployed full lifecycle remains unverified."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0002",
"date": "2026-09-25",
"recording": "retrospective",
"stream": "D",
"comparison_group": null,
"question": "Does cancellation or a transport error settle mutation outcome?",
"previous_belief": "Recovery identity and authoritative echo required executable checks.",
"conclusion": "Synthetic transport with the real Matrix SDK distinguishes replay identity, duplicate commits and authoritative echo.",
"disposition": "revision",
"affected_patterns": [
"CAND-0007"
],
"evidence": [
"research/reviews/MatrixRecoveryExperiment.md"
],
"remaining_uncertainty": [
"No real server deduplication guarantee."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0003",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "cross-stream",
"comparison_group": null,
"question": "Does naming patterns improve the frozen pilot decisions?",
"previous_belief": "Initial editorial scores were 21/24 named and 19/24 prose.",
"conclusion": "Submitted model review adjudication yields 18/24 in each condition; this does not establish equivalence or a presentation benefit.",
"disposition": "revision",
"affected_patterns": [
"CAND-0005",
"CAND-0007",
"CAND-0001",
"CAND-0002"
],
"evidence": [
"research/evaluations/language-pilot-01/submitted-review-01/adjudication.md"
],
"remaining_uncertainty": [
"Independent human validation pending.",
"Historical effort unknown; this entry does not allocate whole-pilot telemetry."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0004",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "D",
"comparison_group": null,
"question": "Which recovery recommendations overstate their guarantees?",
"previous_belief": "Shared guidance left retention/export policy, cancellation and local backup boundaries insufficiently explicit.",
"conclusion": "Guidance now separates authorization, remote compensation, atomic supersession and off-device backup.",
"disposition": "revision",
"affected_patterns": [
"CAND-0001",
"CAND-0002",
"CAND-0003",
"CAND-0005",
"CAND-0007"
],
"evidence": [
"research/reviews/SharedGuidanceRevision.md"
],
"remaining_uncertainty": [
"Editorial correction is not new production evidence."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0005",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "B",
"comparison_group": null,
"question": "What does URL/history and enhancement documentation actually promise?",
"previous_belief": "Navigation and rendering seeds lacked explicit dereferenceability and fallback distinctions.",
"conclusion": "Developed two hypotheses separating address-bar updates from direct loads, and HTML delivery from usable no-script actions.",
"disposition": "revision",
"affected_patterns": [
"CAND-0009",
"CAND-0010"
],
"evidence": [
"research/reviews/NavigationRenderingEvidence.md"
],
"remaining_uncertainty": [
"Navigation/history/cache runtime checks remain pending."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0006",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "F",
"comparison_group": null,
"question": "Why can immediate nested dismissal close the outer task?",
"previous_belief": "The first fixture exposed a timing failure with unresolved ownership.",
"conclusion": "Trace locates stale Escape listener ownership despite inner registration/focus; a guard can lose input.",
"disposition": "revision",
"affected_patterns": [
"CAND-0016",
"CAND-0015"
],
"evidence": [
"research/reviews/BoundaryRecoveryExperiment.md",
"research/reviews/NestedDismissalIsolation.md"
],
"remaining_uncertainty": [
"Readiness waits are not a public product repair."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0007",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "F",
"comparison_group": null,
"question": "Can event-time ownership route dismissal without a settling delay?",
"previous_belief": "Isolation supplied a mechanism but no lifecycle-safe candidate routing experiment.",
"conclusion": "Controlled fixture routed 24/24 versus raw 20/24; initial measurement error and corrected results retained.",
"disposition": "revision",
"affected_patterns": [
"CAND-0016"
],
"evidence": [
"research/reviews/NestedOwnershipRouting.md"
],
"remaining_uncertainty": [
"Animated exit and competing-owner coverage remain open."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0008",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "E",
"comparison_group": null,
"question": "Are feature organization and independent activation the same boundary?",
"previous_belief": "The feature-slice hypothesis needed a source-layout/release contrast.",
"conclusion": "Pinned examples distinguish organizational slicing from activation contracts; added Independent Feature Boundary.",
"disposition": "revision",
"affected_patterns": [
"CAND-0013",
"CAND-0017"
],
"evidence": [
"research/reviews/FeatureDeploymentBoundaries.md"
],
"remaining_uncertainty": [
"Shared startup dependencies still couple nominally separate features."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0009",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "E",
"comparison_group": null,
"question": "Does publication or rollback update every session?",
"previous_belief": "Static source review could not establish loaded/lazy-session behavior.",
"conclusion": "Native-module experiment distinguishes publication, activation and already-bound sessions; artifact retirement breaks old lazy sessions.",
"disposition": "revision",
"affected_patterns": [
"CAND-0017"
],
"evidence": [
"research/reviews/FeatureReleaseExperiment.md"
],
"remaining_uncertainty": [
"No CDN or upstream deployment validation."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
},
{
"id": "LEARN-0010",
"date": "2026-09-26",
"recording": "retrospective",
"stream": "E",
"comparison_group": null,
"question": "How do stale activation writers and unfinished drafts constrain updates?",
"previous_belief": "Release experiment left activation conflicts and reload policy unexecuted.",
"conclusion": "Conditional replacement rejects stale writers; explicit reload policies preserve or refuse transition, with schema recheck after navigation.",
"disposition": "revision",
"affected_patterns": [
"CAND-0017",
"CAND-0005",
"CAND-0006"
],
"evidence": [
"research/reviews/ActivationConflictsAndReload.md"
],
"remaining_uncertainty": [
"One-process atomicity; no native unload, crash or real remote-outcome coverage."
],
"reviewer": {
"name": "Codex",
"role": "author-model",
"independent_human": false
},
"effort": {
"research_minutes": null,
"execution_minutes": null,
"reported_tokens": null,
"cost_usd": null
},
"supersedes": []
}
]
}

View file

@ -0,0 +1,636 @@
{
"schema_version": 1,
"assessed_at": "2026-09-26",
"profiles": [
{
"id": "CAND-0001",
"path": "research/candidates/ConflictCopy.md",
"title": "Conflict Copy",
"sha256": "24f250d89ac17d96df287d67c275b5320b48c8356b57ae126a6c941e92a1c6e9",
"status": "draft",
"maturity": "hypothesis",
"decision": "Preserve competing versions instead of silently losing one.",
"evidence": [
{
"kind": "documentary",
"family": "Joplin",
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
"scope": "Documented detected-note conflict copy."
},
{
"kind": "documentary",
"family": "Obsidian",
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
"scope": "Optional conflict-file mode, not default behavior."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Authorized retention and export are separate decisions.",
"Complete contract recurrence and fault-tested deployed behavior remain unverified."
],
"superseded_by": []
},
{
"id": "CAND-0002",
"path": "research/candidates/LocalCommitBoundary.md",
"title": "Local Commit Boundary",
"sha256": "22165fc2979e8f4d8859b34417cb71e7b5ec7a8440ad045aee2383d499648013",
"status": "draft",
"maturity": "hypothesis",
"decision": "Define when a local change is durably accepted.",
"evidence": [
{
"kind": "documentary",
"family": "Ink & Switch",
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
"scope": "Local-first motivation."
},
{
"kind": "documentary",
"family": "Joplin",
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
"scope": "Local storage and synchronization architecture."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"No executed storage crash or backup test.",
"Local acceptance is not off-device recovery."
],
"superseded_by": []
},
{
"id": "CAND-0003",
"path": "research/candidates/PendingSynchronization.md",
"title": "Pending Synchronization",
"sha256": "9c5cb0f4ea4e6f4406ce55513ca2c252172427a49d8280ae1a9c713f1d11b070",
"status": "draft",
"maturity": "hypothesis",
"decision": "Keep accepted local intent visible until synchronization resolves.",
"evidence": [
{
"kind": "documentary",
"family": "Joplin",
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
"scope": "Per-item synchronization metadata."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Atomic supersession and retry contract proposed, not storage-tested."
],
"superseded_by": []
},
{
"id": "CAND-0004",
"path": "research/candidates/ExplicitReconciliation.md",
"title": "Explicit Reconciliation",
"sha256": "d48a40aab7417b8b8f8406094c84b9e90d0ca8c2f94d6e616d0b80499dc04959",
"status": "draft",
"maturity": "hypothesis",
"decision": "Resolve divergent content while retaining provenance.",
"evidence": [
{
"kind": "documentary",
"family": "Joplin",
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
"scope": "Documented manual conflict resolution."
},
{
"kind": "documentary",
"family": "Obsidian",
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
"scope": "Conflict comparison workflow."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Atomic resolution/provenance UI not executed.",
"Overlap with Conflict Copy remains an open merge question."
],
"superseded_by": []
},
{
"id": "CAND-0005",
"path": "research/candidates/LocalDraftState.md",
"title": "Local Draft State",
"sha256": "8e5f427975c76083c80b895bc68b7130b249be5129c2854f3df11cc374b4b240",
"status": "draft",
"maturity": "hypothesis",
"decision": "Separate unfinished intent from refreshed authoritative data.",
"evidence": [
{
"kind": "documentary",
"family": "Kubernetes / GitLab / React Router",
"ref": "research/reviews/TransactionalEvidenceExpansion.md",
"scope": "Rejection and pending-input mechanisms motivate recovery."
},
{
"kind": "static-code",
"family": "Zulip",
"ref": "research/reviews/FrontendRecoveryImplementations.md",
"scope": "Pinned composer draft storage; partial lifecycle."
},
{
"kind": "static-code",
"family": "Element / Matrix",
"ref": "research/reviews/FrontendRecoveryImplementations.md",
"scope": "Pinned composer draft restoration; partial lifecycle."
},
{
"kind": "runtime",
"family": "authored release fixture",
"ref": "research/reviews/ActivationConflictsAndReload.md",
"scope": "Same-tab preservation/refusal/discard and post-navigation schema check."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"No native-unload, crash, multiple-tab or access-revocation guarantee.",
"Full base/draft/current merge contract is not verified in deployed frontends."
],
"superseded_by": []
},
{
"id": "CAND-0006",
"path": "research/candidates/VersionCheckedMutation.md",
"title": "Version-Checked Mutation",
"sha256": "6a3335ae2fa1de51c95dcbfa8d766d988a3f7a9604fb608b8a0bcf9a10b64198",
"status": "draft",
"maturity": "hypothesis",
"decision": "Reject an operation whose observed base is stale.",
"evidence": [
{
"kind": "documentary",
"family": "Kubernetes",
"ref": "research/reviews/TransactionalEvidenceExpansion.md",
"scope": "Conditional PUT; precise version mechanism."
},
{
"kind": "documentary",
"family": "GitLab",
"ref": "research/reviews/TransactionalEvidenceExpansion.md",
"scope": "Optional last_commit_id; different failure surface."
},
{
"kind": "runtime",
"family": "authored release fixture",
"ref": "research/reviews/ActivationConflictsAndReload.md",
"scope": "Related conditional activation-map mechanism in one process, not the full frontend pattern."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Distributed atomicity and complete frontend recurrence remain unverified.",
"Refetch does not authorize overwriting conflicting intent."
],
"superseded_by": []
},
{
"id": "CAND-0007",
"path": "research/candidates/MutationOutcomeTracking.md",
"title": "Mutation Outcome Tracking",
"sha256": "e04cb835fd054bfaf88616375bd0262deffb2801ea04105be92543bfa9582179",
"status": "draft",
"maturity": "hypothesis",
"decision": "Retain operation identity when transport outcome is uncertain.",
"evidence": [
{
"kind": "documentary",
"family": "Stripe",
"ref": "research/reviews/TransactionalEvidenceExpansion.md",
"scope": "Idempotency mechanism."
},
{
"kind": "documentary",
"family": "React Router",
"ref": "research/reviews/TransactionalEvidenceExpansion.md",
"scope": "Cancellation does not imply server rollback."
},
{
"kind": "static-code",
"family": "Zulip",
"ref": "research/reviews/FrontendRecoveryImplementations.md",
"scope": "Pinned send/recovery state."
},
{
"kind": "static-code",
"family": "Element / Matrix",
"ref": "research/reviews/FrontendRecoveryImplementations.md",
"scope": "Pinned client and SDK transaction/echo paths."
},
{
"kind": "runtime",
"family": "Element / Matrix",
"ref": "research/reviews/MatrixRecoveryExperiment.md",
"scope": "Real SDK with synthetic transport: lost acknowledgement, identity reuse and authoritative echo."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"No production server deduplication or complete retention-window guarantee.",
"Cancelling local UI is not remote compensation."
],
"superseded_by": []
},
{
"id": "CAND-0008",
"path": "research/candidates/InvalidateAndReproject.md",
"title": "Invalidate and Reproject",
"sha256": "47c405adbc3caac2383768ed3d30b6a2e7ff1f44f4954c340049e78944227844",
"status": "draft",
"maturity": "hypothesis",
"decision": "Refresh a projection after mutation without equating acceptance and visibility.",
"evidence": [
{
"kind": "documentary",
"family": "React Router",
"ref": "research/reviews/TransactionalEvidenceExpansion.md",
"scope": "Concurrency and pending-state guidance."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Read-your-write and acceptance/refresh distinction still proposed.",
"No independent deployed full-contract observation."
],
"superseded_by": []
},
{
"id": "CAND-0009",
"path": "research/candidates/URLAddressableState.md",
"title": "URL-addressable State",
"sha256": "45132f34aa762b453c36c9bc6b418ab7f9ce17097365995b2792fd173f6aa11e",
"status": "draft",
"maturity": "hypothesis",
"decision": "Make a navigable state reconstructible from its URL.",
"evidence": [
{
"kind": "documentary",
"family": "htmx",
"ref": "research/reviews/NavigationRenderingEvidence.md",
"scope": "History behavior and history-cache misses."
},
{
"kind": "documentary",
"family": "Web platform",
"ref": "research/reviews/NavigationRenderingEvidence.md",
"scope": "pushState changes history, not server dereferenceability."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Direct load, history miss and full/fragment cache runtime checks pending."
],
"superseded_by": []
},
{
"id": "CAND-0010",
"path": "research/candidates/ProgressiveEnhancement.md",
"title": "Progressive Enhancement",
"sha256": "e8bfc9997336b62f67081434528dc3d3dd280c349156da7620bc76f2197f6414",
"status": "draft",
"maturity": "hypothesis",
"decision": "Keep essential actions usable when enhancement is unavailable.",
"evidence": [
{
"kind": "documentary",
"family": "htmx",
"ref": "research/reviews/NavigationRenderingEvidence.md",
"scope": "Boosted links and forms."
},
{
"kind": "documentary",
"family": "SvelteKit",
"ref": "research/reviews/NavigationRenderingEvidence.md",
"scope": "Form actions and rendering/page options."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"No executed no-script workflow or deployed independent recurrence study."
],
"superseded_by": []
},
{
"id": "CAND-0011",
"path": "research/candidates/PresentationModel.md",
"title": "Presentation Model",
"sha256": "5ff03b5799b0a9e5ec6b54b21034720d89dbc8ffde7c4cdcf71616cdf57baf49",
"status": "draft",
"maturity": "hypothesis",
"decision": "Separate presentation decisions from view mechanisms.",
"evidence": [
{
"kind": "documentary",
"family": "Fowler",
"ref": "research/reviews/PatternBreadthExpansion.md",
"scope": "Named pattern and illustrative model/view discussion."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"No executed model/view integration or independently reviewed full-contract use."
],
"superseded_by": []
},
{
"id": "CAND-0012",
"path": "research/candidates/DerivedState.md",
"title": "Derived State",
"sha256": "9f29b9f1296a52b83f08dfd97437c4dc16e4949ddac1ff3b3830e3fc9831bd4f",
"status": "draft",
"maturity": "hypothesis",
"decision": "Compute a result from explicit authoritative inputs.",
"evidence": [
{
"kind": "documentary",
"family": "Redux",
"ref": "research/reviews/PatternBreadthExpansion.md",
"scope": "Selector guidance, not a requirement for a global store."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Snapshot coherence and changed-locale cache test still planned."
],
"superseded_by": []
},
{
"id": "CAND-0013",
"path": "research/candidates/VerticalFeatureSlice.md",
"title": "Vertical Feature Slice",
"sha256": "d6b332b9c104a079bd4b72512b8ddd1a889199b2e2e531753c411688053e647a",
"status": "draft",
"maturity": "hypothesis",
"decision": "Group a capability across UI, state and behavior with explicit interfaces.",
"evidence": [
{
"kind": "documentary",
"family": "Feature-Sliced Design",
"ref": "research/reviews/PatternBreadthExpansion.md",
"scope": "Layer/slice and public-interface guidance."
},
{
"kind": "static-code",
"family": "Feature-Sliced Design",
"ref": "research/reviews/FeatureDeploymentBoundaries.md",
"scope": "Pinned todo-app interfaces coexist with one application build."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Build/import enforcement not executed.",
"Feature organization does not establish independent activation."
],
"superseded_by": []
},
{
"id": "CAND-0014",
"path": "research/candidates/IslandsOfInteractivity.md",
"title": "Islands of Interactivity",
"sha256": "821a1497da10c02ae11fa6f56cb8e205a4f32c40b39770ab8ca3f907561a260a",
"status": "draft",
"maturity": "hypothesis",
"decision": "Activate selected interactive regions within a document.",
"evidence": [
{
"kind": "documentary",
"family": "Astro",
"ref": "research/reviews/PatternBreadthExpansion.md",
"scope": "Client-island mechanism and execution placement."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"No executed island fixture, performance comparison or complete recurrence study."
],
"superseded_by": []
},
{
"id": "CAND-0015",
"path": "research/candidates/FailureBoundary.md",
"title": "Failure Boundary",
"sha256": "a6e76ed17a92baade683d5df96fa8ecd066c593661e6a14983a86d046e7d9c2c",
"status": "draft",
"maturity": "hypothesis",
"decision": "Contain specified failure classes while preserving useful neighboring work.",
"evidence": [
{
"kind": "documentary",
"family": "React",
"ref": "research/reviews/PatternBreadthExpansion.md",
"scope": "Error boundary scope and exclusions."
},
{
"kind": "runtime",
"family": "React",
"ref": "research/reviews/BoundaryRecoveryExperiment.md",
"scope": "Real package in authored host: render/event/request distinction and fallback escalation."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"Synthetic host, not full application recurrence.",
"Boundary cannot imply containment for all asynchronous failures."
],
"superseded_by": []
},
{
"id": "CAND-0016",
"path": "research/candidates/FocusReturn.md",
"title": "Focus Return",
"sha256": "b44f976684d7f2a9186e09aaa6fd6fdb51dc5674a53bcc90afa08748a641f041",
"status": "draft",
"maturity": "hypothesis",
"decision": "Restore meaningful focus after a temporary interaction ends.",
"evidence": [
{
"kind": "documentary",
"family": "WAI-ARIA APG",
"ref": "research/reviews/PatternBreadthExpansion.md",
"scope": "Dialog focus obligations."
},
{
"kind": "static-code",
"family": "Radix",
"ref": "research/reviews/NestedDismissalIsolation.md",
"scope": "Pinned layer/listener ownership implementation."
},
{
"kind": "runtime",
"family": "Radix",
"ref": "research/reviews/NestedOwnershipRouting.md",
"scope": "Authored fixture: raw 20/24 versus routed 24/24; browser/build limits retained."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"One implementation family; repeated trials are not independent uses.",
"Animated exits and competing owners remain untested; no production repair claim."
],
"superseded_by": []
},
{
"id": "CAND-0017",
"path": "research/candidates/IndependentFeatureBoundary.md",
"title": "Independent Feature Boundary",
"sha256": "60b78725ed4036681675d4c68244fc25aea6e0dffb09d54a7108e3fcbf527b4f",
"status": "draft",
"maturity": "hypothesis",
"decision": "Separate feature release, activation and session transition contracts.",
"evidence": [
{
"kind": "documentary",
"family": "single-spa / webpack",
"ref": "research/reviews/FeatureDeploymentBoundaries.md",
"scope": "Mechanism documentation, not deployed independence proof."
},
{
"kind": "static-code",
"family": "react-microfrontends examples",
"ref": "research/reviews/FeatureDeploymentBoundaries.md",
"scope": "Root config/navbar are one example family with shared startup gating."
},
{
"kind": "runtime",
"family": "authored release fixture",
"ref": "research/reviews/FeatureReleaseExperiment.md",
"scope": "Publication/activation/rollback across fresh, loaded and lazy sessions."
},
{
"kind": "runtime",
"family": "authored release fixture",
"ref": "research/reviews/ActivationConflictsAndReload.md",
"scope": "Conditional activation updates and safe reload policies, including negative controls."
}
],
"independent_full_contract_uses": null,
"review": {
"assessed_at": "2026-09-26",
"reviewer": "Codex",
"role": "author-model",
"independent_human": false,
"last_substantive_review_date": null
},
"gaps": [
"No upstream deployment or real team/release-independence validation.",
"Distributed atomicity, retention authorization and native-unload/crash behavior remain open."
],
"superseded_by": []
}
]
}

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
# Frontend Patterns Research Program
Status: planned · Program established: 2026-09-24
Status: ongoing · Program established: 2026-09-24
Start with [Research Protocol](ResearchProtocol.md), the
[executable research bench](../bench/README.md), then the
@ -388,3 +388,20 @@ Useful progress means improving one or more of:
- evidence quality,
- applicability across architectures,
- retrieval quality for humans and agents.
## 13. Continuous learning and transparent evolution
Milestones are finite review boundaries within an ongoing research program. Passing
a gate does not finish the language. Evidence can narrow, supersede or demote a
pattern; preserve those changes as part of the knowledge base.
[FEP-WP-0006](../../workplans/FEP-WP-0006-language-evolution.md) establishes the
[evidence baseline and evolution method](../evolution/README.md). Its generated
[report](../evolution/EvolutionReport.md) separates current maturity, support tiers,
coverage, usefulness and learning outcomes. Early rapid learning and later diminishing
returns are testable expectations, not a prescribed curve or catalog-size target.
Measure prospective comparable cycles, retain unknown historical effort, and record
corroboration separately from consequential revisions. Broaden contexts when they
expose new decisions; improve structure when ambiguity prevents use; seek independent
validation when mechanisms stabilize. Keep fresh evaluation tasks separate from
consumed development anchors, including the immutable language pilot.

View file

@ -64,3 +64,19 @@ support or reject the current hypothesis; record remaining uncertainty. Do not
stretch source claims to meet a pattern-count target. Preserve superseded conclusions
through Git history and link the replacement. Reopen a conclusion when new evidence
invalidates a stated assumption.
## Evolution record at cycle close
Register a bounded question with the [learning-cycle template](../../templates/LearningCycle.md)
before execution. Follow the [evolution method](../evolution/README.md): append the
outcome (including corroboration or inconclusive results), record effort or explicit
unknowns, update affected evidence profiles, and run `make evolution-report
evolution-check evolution-test`. Capture a snapshot at the review boundary after
candidate changes are committed. Preserve superseded conclusions and failed trials.
Research milestones close bounded work; the language keeps learning. Compare returns
only across prospective cycles with comparable stream/protocol/question scope and
effort accounting. Review at least three such cycles before discussing a trend; that
review is not proof of a plateau. Do not pool historical assertion or citation counts
as discoveries. Human validation, independent recurrence and demonstrated usefulness
remain separate obligations from metadata correctness.

View file

@ -0,0 +1,239 @@
#!/usr/bin/env python3
"""Validate curated evolution records and render their deterministic report (stdlib)."""
import argparse
from collections import Counter, defaultdict
from datetime import date
import hashlib
import json
from pathlib import Path
import re
import subprocess
ROOT = Path(__file__).resolve().parents[1]
DATA = Path('research/evolution')
MATURITIES = {'hypothesis', 'emerging', 'established', 'canonical'}
DISPOSITIONS = {'revision', 'corroboration', 'rejection', 'merge', 'inconclusive'}
EFFORT = {'research_minutes', 'execution_minutes', 'reported_tokens', 'cost_usd'}
def require(condition, message):
if not condition:
raise ValueError(message)
def load(root=ROOT):
return {name: json.loads((root / DATA / f'{name}.json').read_text())
for name in ('profiles', 'ledger', 'context')}
def ref_check(root, ref):
path = (root / ref).resolve()
require(path.is_relative_to(root.resolve()) and path.is_file(), f'Missing/unsafe reference: {ref}')
def validate(data, root=ROOT):
for name, record in data.items():
require(record['schema_version'] == 1, f'Unsupported schema: {name}')
profiles = data['profiles']['profiles']
ids = [p['id'] for p in profiles]
require(len(ids) == len(set(ids)), 'Duplicate candidate identity')
paths = [p['path'] for p in profiles]
require(len(paths) == len(set(paths)), 'Duplicate candidate path')
require(set(paths) == {str(p.relative_to(root)) for p in (root / 'research/candidates').glob('*.md')}, 'Candidate inventory mismatch')
for p in profiles:
require(re.fullmatch(r'CAND-\d{4}', p['id']), 'Invalid research identity')
ref_check(root, p['path'])
content = (root / p['path']).read_bytes()
require(hashlib.sha256(content).hexdigest() == p['sha256'], f'Stale profile: {p["path"]}')
for field in ('title', 'status', 'maturity'):
require(f'{field}: {p[field]}\n' in content.decode(), f'Metadata mismatch: {p["id"]} {field}')
require(p['maturity'] in MATURITIES, 'Invalid maturity')
require(p['decision'] and p['gaps'] and p['evidence'], 'Missing decision, limits or evidence')
require(p['review']['role'] in {'author-model', 'independent-model', 'human'}, 'Invalid reviewer role')
require(not p['review']['independent_human'] or p['review']['role'] == 'human', 'Model review cannot be human validation')
date.fromisoformat(p['review']['assessed_at'])
if p['review']['last_substantive_review_date'] is not None:
date.fromisoformat(p['review']['last_substantive_review_date'])
require(p['independent_full_contract_uses'] is None or type(p['independent_full_contract_uses']) is int and p['independent_full_contract_uses'] >= 0, 'Invalid independent-use count')
require(set(p['superseded_by']) <= set(ids) - {p['id']}, 'Unknown/self successor')
for e in p['evidence']:
require(e['kind'] in {'documentary', 'static-code', 'runtime'}, 'Invalid evidence kind')
require(e['family'] and e['scope'], 'Unscoped evidence')
ref_check(root, e['ref'])
seen = set()
for e in data['ledger']['events']:
require(e['id'] not in seen, 'Duplicate learning identity')
require(re.fullmatch(r'LEARN-\d{4}', e['id']), 'Invalid learning identity')
require(set(e['supersedes']) <= seen, 'Supersession must reference earlier entries')
seen.add(e['id'])
date.fromisoformat(e['date'])
require(e['disposition'] in DISPOSITIONS, 'Invalid learning disposition')
require(e['recording'] in {'retrospective', 'prospective'}, 'Invalid recording mode')
require(e['stream'] in {'A', 'B', 'C', 'D', 'E', 'F', 'cross-stream'}, 'Invalid stream')
require(set(e['affected_patterns']) <= set(ids), 'Unknown affected pattern')
require(e['question'] and e['previous_belief'] and e['conclusion'] and e['remaining_uncertainty'] and e['evidence'], 'Incomplete learning entry')
require(not e['reviewer']['independent_human'] or e['reviewer']['role'] == 'human', 'Model review cannot be human validation')
require(set(e['effort']) == EFFORT, 'Effort fields mismatch')
for value in e['effort'].values():
require(value is None or type(value) in (int, float) and value >= 0 and value < float('inf'), 'Invalid effort')
for ref in e['evidence']:
ref_check(root, ref)
if e['recording'] == 'prospective':
require(e['comparison_group'] and e.get('protocol_ref'), 'Prospective cycle needs a comparison group and preregistered protocol')
ref_check(root, e['protocol_ref'])
cases = data['context']['cases']
require({c['id'] for c in cases} == {f'VC-{n:02d}' for n in range(1, 11)} and len(cases) == 10, 'Case coverage inventory mismatch')
for c in cases:
require(c['state'] in {'planned', 'synthetic draft', 'provisional', 'reviewed'}, 'Invalid case state')
ref_check(root, c['ref'])
for ref in data['context']['open_work']:
ref_check(root, ref)
u = data['context']['usefulness']
ref_check(root, u['ref'])
require(u['denominator'] > 0 and all(0 <= u[k] <= u['denominator'] for k in ('named_score', 'prose_score')), 'Invalid usefulness result')
def link(ref, label=None):
# Report is two directories below repository root.
return f'[{label or Path(ref).stem}](../../{ref})'
def cell(value):
return str(value).replace('|', '\\|').replace('\n', ' ')
def render(data, baseline=None):
profiles = data['profiles']['profiles']
events = data['ledger']['events']
context = data['context']
maturity = Counter(p['maturity'] for p in profiles)
kinds = Counter(k for p in profiles for k in {e['kind'] for e in p['evidence']})
lines = ['# Language evolution report', '',
'Generated by `make evolution-report`; curated assessment date: ' + data['profiles']['assessed_at'] + '.', '',
'This is an evidence profile, not a completion percentage. Evidence presence does not establish full-contract recurrence or production fitness.', '',
'The baseline profiles are author-model assessments by Codex; they do not confer independent validation.', '',
'## Current corpus', '',
f'{len(profiles)} candidates: ' + ', '.join(f'{n} {m}' for m, n in sorted(maturity.items())) + '.', '',
'| Evidence attached to a candidate | Candidates |', '| --- | ---: |']
lines += [f'| {kind} | {kinds[kind]} |' for kind in ('documentary', 'static-code', 'runtime')]
lines += ['', 'Categories overlap. Runtime includes authored fixtures and negative controls. Family labels group related evidence; they are not counts of independent applications.', '',
f'Independent human profile reviews: {sum(p["review"]["independent_human"] for p in profiles)}/{len(profiles)}. '
f'Full-contract independent-use counts unassessed: {sum(p["independent_full_contract_uses"] is None for p in profiles)}/{len(profiles)}.', '']
if baseline:
old = {p['id']: p for p in baseline['assessment']['profiles']['profiles']}
now = {p['id']: p for p in profiles}
shared = old.keys() & now.keys()
lines += ['## Change since baseline', '',
f'Baseline {baseline["id"]}; source revision `{baseline["source_revision"]}`. '
f'Added: {len(now.keys()-old.keys())}; removed: {len(old.keys()-now.keys())}; '
f'shared candidates with changed content: {sum(old[i]["sha256"] != now[i]["sha256"] for i in shared)}; '
f'changed evidence/review assessments: {sum(old[i] != now[i] for i in shared)}; '
f'maturity transitions: {sum(old[i]["maturity"] != now[i]["maturity"] for i in shared)}.', '',
'The shared cohort is compared separately from additions. Changed text or evidence counts are not learning gains.', '']
lines += ['## Applicability and usefulness', '', '| Case | State |', '| --- | --- |']
lines += [f'| {link(c["ref"], c["id"])} | {c["state"]} |' for c in context['cases']]
u = context['usefulness']
lines += ['', f'Frozen pilot after adjudication: named {u["named_score"]}/{u["denominator"]}; prose {u["prose_score"]}/{u["denominator"]}. '
f'Initial unsupported-claim count: {u["initial_unsupported_claims_each"]} per condition (historical only); adjudicated flags remain qualitative, with no revised numeric count. '
f'Independent human validation: {"recorded" if u["independent_human"] else "pending"}. '
f'Decision time: {"unknown" if u["decision_time_minutes"] is None else str(u["decision_time_minutes"])+" minutes"}. '
+ link(u['ref'], 'Adjudication') + '.', '', u['limit'], '',
'## Learning and effort', '', data['ledger']['coverage'], '',
'| Outcome | Entries (not independent discoveries) |', '| --- | ---: |']
counts = Counter(e['disposition'] for e in events)
lines += [f'| {k} | {counts[k]} |' for k in sorted(DISPOSITIONS)]
lines += ['', f'Cycles with recorded research effort: {sum(e["effort"]["research_minutes"] is not None for e in events)}/{len(events)}. '
'Unknown effort is neither zero nor estimated from commits, tokens or assertion counts.', '']
groups = defaultdict(list)
for e in events:
if e['recording'] == 'prospective':
groups[(e['stream'], e['comparison_group'])].append(e)
if not groups:
lines += ['No prospective comparison windows yet. Learning rate and diminishing returns: **not measurable from this baseline**.', '']
for (stream, group), entries in sorted(groups.items()):
entries = sorted(entries, key=lambda e: (e['date'], e['id']))
lines += [f'### Stream {stream} / {cell(group)}', '',
'| Cycle | Outcome | Research minutes | Consequential outcome/hour |', '| --- | --- | ---: | ---: |']
for e in entries:
minutes = e['effort']['research_minutes']
consequential = e['disposition'] in {'revision', 'rejection', 'merge'}
rate = f'{60/minutes:.2f}' if consequential and minutes else ('0.00' if minutes else 'unknown')
lines.append(f'| {e["id"]} | {e["disposition"]} | {minutes if minutes is not None else "unknown"} | {rate} |')
lines += ['', 'One bounded question counts at most one consequential outcome. Corroboration and inconclusive work remain visible separately. '
+ ('Fewer than three comparable cycles: no trend assessment.' if len(entries) < 3 else 'At least three cycles: eligible for a qualitative review of returns; this does not demonstrate a plateau.'), '']
lines += ['## 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.', '',
f'Profiles with unknown last substantive review date: {sum(p["review"]["last_substantive_review_date"] is None for p in profiles)}. '
'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.', '',
'Review backlog and evidence gaps remain in ' + ', '.join(link(r) for r in context['open_work']) + '.', '',
'## Pattern profiles', '']
for p in profiles:
lines += [f'### {p["id"]} — {p["title"]}', '', link(p['path']) + f' · {p["status"]} / {p["maturity"]}', '', p['decision'], '',
'| Evidence | Family | Scope | Review |', '| --- | --- | --- | --- |']
lines += [f'| {e["kind"]} | {cell(e["family"])} | {cell(e["scope"])} | {link(e["ref"])} |' for e in p['evidence']]
lines += ['', 'Open limits: ' + ' '.join(p['gaps']), '',
'Superseded by: ' + (', '.join(p['superseded_by']) or 'none recorded') + '.', '']
lines += ['## Recorded learning', '']
for e in events:
lines += [f'### {e["id"]} — {e["question"]}', '',
f'{e["date"]} · stream {e["stream"]} · {e["recording"]} · {e["disposition"]}', '',
'Before: ' + e['previous_belief'], '', 'Conclusion: ' + e['conclusion'], '',
'Evidence: ' + ', '.join(link(r) for r in e['evidence']) + '.', '',
'Remaining uncertainty: ' + ' '.join(e['remaining_uncertainty']), '',
'Supersedes: ' + (', '.join(e['supersedes']) or 'none recorded') + '.', '']
return '\n'.join(lines)
def snapshot(data, name, root=ROOT):
require(re.fullmatch(r'[a-z0-9-]+', name), 'Unsafe snapshot name')
revision = subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=root, text=True).strip()
for p in data['profiles']['profiles']:
blob = subprocess.check_output(['git', 'show', f'{revision}:{p["path"]}'], cwd=root)
require(hashlib.sha256(blob).hexdigest() == p['sha256'], 'Commit candidate changes before taking snapshot')
result = dict(schema_version=1, id=name, source_revision=revision, assessment=data)
path = root / DATA / 'snapshots' / (name + '.json')
with path.open('x') as f: # Never overwrite a historical snapshot.
f.write(json.dumps(result, indent=2, ensure_ascii=False) + '\n')
return path
def validate_snapshot(baseline, root=ROOT):
require(baseline['schema_version'] == 1, 'Unsupported snapshot schema')
require(re.fullmatch(r'[0-9a-f]{40}', baseline['source_revision']), 'Invalid snapshot revision')
for p in baseline['assessment']['profiles']['profiles']:
blob = subprocess.check_output(
['git', 'show', f'{baseline["source_revision"]}:{p["path"]}'], cwd=root)
require(hashlib.sha256(blob).hexdigest() == p['sha256'], 'Snapshot does not match its pinned source')
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('command', choices=['generate', 'check', 'snapshot'])
parser.add_argument('--name')
parser.add_argument('--baseline', default='baseline-2026-09-26')
args = parser.parse_args()
try:
data = load()
validate(data)
if args.command == 'snapshot':
require(args.name, 'snapshot requires --name')
print(snapshot(data, args.name))
return
baseline = json.loads((ROOT / DATA / 'snapshots' / (args.baseline + '.json')).read_text())
validate_snapshot(baseline)
output = render(data, baseline)
path = ROOT / DATA / 'EvolutionReport.md'
if args.command == 'check':
require(path.read_text() == output, 'Stale report: run make evolution-report')
print('Evolution records and generated report are consistent.')
else:
path.write_text(output)
print(path.relative_to(ROOT))
except (ValueError, KeyError, OSError) as exc:
parser.exit(1, f'Evolution validation failed: {exc}\n')
if __name__ == '__main__':
main()

View file

@ -0,0 +1,30 @@
# Learning cycle — <stable identifier>
Status: planned; register before execution. One bounded question per cycle.
- Date and owner:
- Stream (A–F or cross-stream):
- Comparison group and shared protocol (question size, evidence tier, evaluation,
and effort accounting must match; use a new group when they change):
- Question and affected CAND identities:
- Previous belief and expected decision:
- Observation that would contradict the belief:
- Evidence/contexts to inspect; what remains outside scope:
- Effort budget and recording method (active research versus execution, overlaps):
- Review provenance and acceptance criteria:
## Outcome (complete after execution)
- Evidence references, retained failures and counterexamples:
- Changed understanding and applicability limits:
- Disposition: revision | corroboration | rejection | merge | inconclusive
- Why this is one outcome, not a count of assertions/files:
- Remaining uncertainty and live workplan/task:
- Superseded ledger entries, if any:
- Active research minutes / execution minutes (unknown if not measured):
- Reported tokens / cost USD, with receipts (unknown if not measured):
- Reviewer name, role and independence:
Append an entry to research/evolution/ledger.json with `recording: prospective` and
`protocol_ref` pointing here. Update profiles, run evolution checks, then snapshot at
the agreed review boundary. No automatic maturity promotion.

View file

@ -0,0 +1,114 @@
"""Guard the distinctions that make evolution reporting honest."""
from copy import deepcopy
import importlib.util
import json
from pathlib import Path
import subprocess
import pytest
ROOT = Path(__file__).resolve().parents[1]
spec = importlib.util.spec_from_file_location('evolution', ROOT / 'scripts/research_evolution.py')
evolution = importlib.util.module_from_spec(spec)
spec.loader.exec_module(evolution)
@pytest.fixture
def data():
return evolution.load()
def test_current_records_and_report_are_consistent(data):
evolution.validate(data)
baseline = json.loads((ROOT / evolution.DATA / 'snapshots/baseline-2026-09-26.json').read_text())
evolution.validate_snapshot(baseline)
assert evolution.render(data, baseline) == (ROOT / evolution.DATA / 'EvolutionReport.md').read_text()
@pytest.mark.parametrize('mutation,match', [
(lambda d: d['profiles']['profiles'][0].update(sha256='0'*64), 'Stale profile'),
(lambda d: d['profiles']['profiles'].pop(), 'inventory mismatch'),
(lambda d: d['profiles']['profiles'][1].update(id='CAND-0001'), 'Duplicate candidate'),
(lambda d: d['profiles']['profiles'][0]['review'].update(independent_human=True), 'human validation'),
(lambda d: d['profiles']['profiles'][0]['evidence'][0].update(ref='../missing.md'), 'Missing/unsafe'),
(lambda d: d['ledger']['events'][0].update(affected_patterns=['FEP-9999']), 'Unknown affected'),
(lambda d: d['ledger']['events'][0].update(supersedes=['LEARN-9999']), 'Supersession'),
(lambda d: d['ledger']['events'][0]['effort'].update(research_minutes=-1), 'Invalid effort'),
(lambda d: d['ledger']['events'][0].update(recording='prospective'), 'preregistered protocol'),
])
def test_rejects_misleading_or_untraceable_records(data, mutation, match):
mutation(data)
with pytest.raises(ValueError, match=match):
evolution.validate(data)
def test_unknown_effort_and_retrospective_sample_cannot_create_a_trend(data):
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 'historical only' in report
assert 'no revised numeric count' in report
assert 'Consequential outcome/hour' not in report
# Even retrospectively supplied time cannot enter a prospective comparison group.
for entry in data['ledger']['events']:
entry['effort']['research_minutes'] = 10
entry['comparison_group'] = 'same-label'
assert 'Consequential outcome/hour' not in evolution.render(data)
def test_rates_separate_corroboration_unknown_effort_and_streams(data):
events = data['ledger']['events'][:4]
data['ledger']['events'] = events
for entry in events:
entry.update(recording='prospective', comparison_group='controlled-mechanism', stream='D', protocol_ref='templates/LearningCycle.md')
entry['effort']['research_minutes'] = 30
events[1]['disposition'] = 'corroboration'
events[2]['effort']['research_minutes'] = None
events[3]['stream'] = 'F'
evolution.validate(data)
report = evolution.render(data)
assert '| LEARN-0001 | revision | 30 | 2.00 |' in report
assert '| LEARN-0002 | corroboration | 30 | 0.00 |' in report
assert '| LEARN-0003 | revision | unknown | unknown |' in report
assert '### Stream F / controlled-mechanism' in report
assert 'Fewer than three comparable cycles' in report
assert 'does not demonstrate a plateau' in report
events[0]['effort']['research_minutes'] = 0
assert '| LEARN-0001 | revision | 0 | unknown |' in evolution.render(data)
def test_snapshot_delta_does_not_count_additions_as_maturity_changes(data):
old = deepcopy(data)
old['profiles']['profiles'].pop()
old['profiles']['profiles'][0]['sha256'] = 'old-content'
baseline = {'id': 'test', 'source_revision': 'test-revision', 'assessment': old}
report = evolution.render(data, baseline)
assert 'Added: 1; removed: 0; shared candidates with changed content: 1' in report
assert 'maturity transitions: 0' in report
def test_snapshot_pins_committed_candidates_and_refuses_overwrite(tmp_path, data):
subprocess.run(['git', 'init', '-q', str(tmp_path)], check=True)
for p in data['profiles']['profiles']:
path = tmp_path / p['path']
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes((ROOT / p['path']).read_bytes())
subprocess.run(['git', 'add', '.'], cwd=tmp_path, check=True)
subprocess.run(['git', '-c', 'user.name=Test', '-c', 'user.email=test@example.invalid', 'commit', '-qm', 'fixture'], cwd=tmp_path, check=True)
(tmp_path / evolution.DATA / 'snapshots').mkdir(parents=True)
first = evolution.snapshot(data, 'test-baseline', tmp_path)
assert json.loads(first.read_text())['assessment'] == data
with pytest.raises(FileExistsError):
evolution.snapshot(data, 'test-baseline', tmp_path)
data['profiles']['profiles'][0]['sha256'] = 'uncommitted'
with pytest.raises(ValueError, match='Commit candidate changes'):
evolution.snapshot(data, 'second', tmp_path)
def test_corrupt_baseline_cannot_masquerade_as_pinned_history():
baseline = json.loads((ROOT / evolution.DATA / 'snapshots/baseline-2026-09-26.json').read_text())
baseline['assessment']['profiles']['profiles'][0]['sha256'] = '0'*64
with pytest.raises(ValueError, match='pinned source'):
evolution.validate_snapshot(baseline)

View file

@ -0,0 +1,62 @@
---
id: FEP-WP-0006
type: workplan
title: "Make ongoing language learning observable"
domain: infotech
repo: frontend-patterns
status: active
owner: codex
topic_slug: canon
created: "2026-09-26"
updated: "2026-09-26"
---
# Make ongoing language learning observable
User-approved baseline, learning ledger and generated evolution report. Finite
investigations support an ongoing language; no composite maturity score or automatic
promotion. M1/M2 and independent human validation remain open in WP-0002/WP-0003.
## Establish the versioned evidence baseline
```task
id: FEP-WP-0006-T01
status: done
priority: high
```
Seventeen research identities, current profiles and immutable baseline pin candidate
content and distinguish documentary/static/runtime evidence, implementation families,
review provenance and limits. Full-contract independence and historical effort remain
unknown. See research/evolution/README.md and snapshots/baseline-2026-09-26.json.
## Record learning and generate transparent reporting
```task
id: FEP-WP-0006-T02
status: done
priority: high
```
Selected retrospective ledger, prospective cycle template, generated evidence/case/
usefulness report, validation and tests. Preserve the frozen pilot and all historical
experiment receipts. Intent/protocol/program now describe continuous learning.
## Measure the first comparable prospective cycles
```task
id: FEP-WP-0006-T03
status: todo
priority: medium
```
Before WP-0003 T01's next navigation/history/cache investigation, register one bounded
cycle using templates/LearningCycle.md. Record effort, outcomes and counterevidence;
update profiles/report and snapshot at the review boundary. Continue with comparable
questions only where they are useful, not to meet a count target. After at least three
comparable cycles review returns within that stream/protocol; no trend claim before
then and no automatic plateau declaration. Preserve independent confirmation value.
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.