Complete bounded recovery checks and reconcile blocked workplans
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e738-9e15-7600-87e6-90dec3a7beef
This commit is contained in:
parent
aea9796908
commit
9baf6f1829
21 changed files with 2301 additions and 53 deletions
|
|
@ -1,6 +1,6 @@
|
|||
# INTENT
|
||||
|
||||
Status: evolving research language · Reviewed: 2026-09-26
|
||||
Status: evolving research language · Reviewed: 2026-09-28
|
||||
|
||||
This records the initial direction inferred from the repository scaffold. The
|
||||
responsibility model, vocabulary and sequences remain hypotheses to test against
|
||||
|
|
@ -80,7 +80,7 @@ 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 corpus contains seventeen draft hypotheses, source reviews, bounded
|
||||
The current corpus contains eighteen 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.
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ Software patterns must describe when they become harmful, misleading, expensive
|
|||
|
||||
## Status
|
||||
|
||||
The corpus currently contains seventeen draft hypotheses, traceable source reviews,
|
||||
The corpus currently contains eighteen 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,
|
||||
|
|
@ -99,9 +99,9 @@ explains how the language continues learning over time.
|
|||
|
||||
Start with the [research program](research/plan/ResearchProgram.md), its
|
||||
[protocol](research/plan/ResearchProtocol.md) and [validation cases](research/plan/ValidationCases.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 seed investigation in [FEP-WP-0002](workplans/FEP-WP-0002-seed-language-validation.md)
|
||||
remains blocked on independent evidence for the connected seed corpus; metadata
|
||||
and documentary source work are complete. 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
|
||||
|
|
|
|||
9
SCOPE.md
9
SCOPE.md
|
|
@ -1,6 +1,6 @@
|
|||
# SCOPE
|
||||
|
||||
Reviewed: 2026-09-27 · Scope: ongoing research and a versioned knowledge base.
|
||||
Reviewed: 2026-09-28 · Scope: ongoing research and a versioned knowledge base.
|
||||
|
||||
## Purpose and deliverable
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ the corresponding capability is implemented or validated.
|
|||
|
||||
## Current capabilities and limits
|
||||
|
||||
As of 2026-09-27, seventeen developed research candidates remain draft hypotheses;
|
||||
As of 2026-09-28, eighteen developed research candidates remain draft hypotheses;
|
||||
none is canonically admitted. Sources and claim-level reviews, metadata contract
|
||||
checks, an infospace-bench adapter and bounded runtime research fixtures exist.
|
||||
Four walkthroughs are synthetic drafts or provisional studies, not validated
|
||||
|
|
@ -49,7 +49,7 @@ submitted model-review adjudication. It establishes neither a naming benefit nor
|
|||
equivalence; independent human validation and decision-time measurement remain open.
|
||||
|
||||
Evolution profiles, a baseline, learning ledger, snapshots and a generated report
|
||||
are implemented. Six effort-accounted prospective cycles belong to six different
|
||||
are implemented. Eight prospective cycles (seven effort-accounted) belong to seven different
|
||||
comparison groups: there is no comparable window for a diminishing-returns claim.
|
||||
Evidence types, implementation families and review provenance remain distinct.
|
||||
Static source mechanisms and authored runtime fixtures do not establish complete
|
||||
|
|
@ -101,7 +101,8 @@ The user-directed [WP-0008](workplans/FEP-WP-0008-use-driven-improvement.md) con
|
|||
qualified reference use to evidence-bearing consumer receipts and bounded autonomous
|
||||
improvement. It owns discovery, instrumentation and execution integration; monthly
|
||||
human review owns operating-policy decisions. The capability entry is prepared;
|
||||
automatic collection and three activity-core reporting schedules are operational.
|
||||
automatic collection and three activity-core reporting schedules passed scheduled
|
||||
smoke checks; the first natural daily receipt remains unverified.
|
||||
Hosted consumer integration and admitted pattern-editing execution remain blocked;
|
||||
there are no enrolled consumers yet.
|
||||
This operational loop can improve draft guidance without claiming M1/M2/M3 or
|
||||
|
|
|
|||
|
|
@ -124,3 +124,13 @@ or invalidate the interval. It cannot infer that history from the rollout timest
|
|||
Production credential admission, real invariant probes/signing issuers, Temporal
|
||||
registration and authenticated Kubernetes failure tests remain open. See the
|
||||
[broker implementation](../../activity-core/docs/release-broker.md) for that boundary.
|
||||
|
||||
|
||||
## Cadence evidence recheck — 2026-09-28
|
||||
|
||||
The expected first natural daily receipt (September 28 02:00 Berlin) was absent
|
||||
from the queried State Hub intake events before 09:00 UTC; the latest remained the
|
||||
September 27 14:07Z smoke receipt. See [recheck](evidence/2026-09-28-loop-recheck.json).
|
||||
Enabled schedules and prior smoke success do not prove this recurring execution.
|
||||
WP-0008 T03 retains cadence/sink diagnosis; no outage cause or live fix is claimed.
|
||||
The roster remains empty and mutation execution remains unadmitted.
|
||||
|
|
|
|||
21
docs/evidence/2026-09-28-loop-recheck.json
Normal file
21
docs/evidence/2026-09-28-loop-recheck.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"query": "GET /progress/?event_type=fep_feedback_intake&limit=10",
|
||||
"returned_count": 4,
|
||||
"receipt_ids": [
|
||||
"a552969b-59ac-4dc9-a4f8-b58856c129ab",
|
||||
"5b320b7b-1fbc-4023-b8b7-22fbbd7904af",
|
||||
"c5446c0a-125b-4703-b964-006aaef46241",
|
||||
"c92d55f5-5b29-43e8-b377-d639a1d4fd2c"
|
||||
],
|
||||
"latest_receipt": {
|
||||
"id": "a552969b-59ac-4dc9-a4f8-b58856c129ab",
|
||||
"created_at": "2026-09-27T14:07:04.567032Z",
|
||||
"scheduled_for": "2026-09-27T14:06:57.740055+00:00"
|
||||
},
|
||||
"expected_daily_scheduled_for": "2026-09-28T00:00:00Z",
|
||||
"expected_receipt_found": false,
|
||||
"consumer_roster_count": 0,
|
||||
"interpretation": "Expected natural daily receipt not returned; scheduler/worker failure cause not diagnosed. Existing WP-0008 T03 retains verification. No live mutation.",
|
||||
"checked_on": "2026-09-28",
|
||||
"check_time_note": "Queried during this closeout before 09:00 UTC; exact retrieval second not recorded."
|
||||
}
|
||||
|
|
@ -1,11 +1,29 @@
|
|||
{
|
||||
"schema_version": 1,
|
||||
"assessed_at": "2026-09-27",
|
||||
"assessed_at": "2026-09-28",
|
||||
"assessor": "Codex",
|
||||
"status": "provisional author-model classification",
|
||||
"basis_revision": "9ac6f6925be6743113338ad140f8465b2d99a404",
|
||||
"basis_revision": "aea9796",
|
||||
"counting_rule": "Count a candidate once per assigned label; labels overlap. Responsibilities describe the direct mechanism, not every prerequisite or downstream effect. Forces are selected trade-offs, not exhaustive coverage or measured outcomes.",
|
||||
"candidates": [
|
||||
{
|
||||
"path": "research/candidates/CapabilityContractBoundary.md",
|
||||
"sha256": "a678f88e9b53d7273e29e3aea2d23f2297055253dcf4518444d3089fa6da4331",
|
||||
"title": "Capability Contract Boundary",
|
||||
"responsibilities": [
|
||||
"composition"
|
||||
],
|
||||
"forces": {
|
||||
"improves": [
|
||||
"portability"
|
||||
],
|
||||
"worsens": [
|
||||
"implementation-complexity",
|
||||
"compatibility-pressure"
|
||||
]
|
||||
},
|
||||
"rationale": "Separates a semantic capability interface from its runtime carrier to support host portability; versioning, enforcement and cross-host compatibility add work. Declaring the contract alone supplies neither runtime isolation nor independent release."
|
||||
},
|
||||
{
|
||||
"path": "research/candidates/ConflictCopy.md",
|
||||
"sha256": "24f250d89ac17d96df287d67c275b5320b48c8356b57ae126a6c941e92a1c6e9",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Classification coverage
|
||||
|
||||
Generated by `python3 scripts/classification_coverage.py`; assessment: 2026-09-27.
|
||||
Generated by `python3 scripts/classification_coverage.py`; assessment: 2026-09-28.
|
||||
|
||||
17 developed drafts; 16 original seeds at `2a5dabd`. 7 original seeds developed, 9 without dedicated drafts, 10 later additions. All current candidates remain hypotheses; classification confers no admission or new evidence.
|
||||
18 developed drafts; 16 original seeds at `2a5dabd`. 7 original seeds developed, 9 without dedicated drafts, 11 later additions. All current candidates remain hypotheses; classification confers no admission or new evidence.
|
||||
|
||||
The original comparison above is the compact 16-entry table. The broader initial [patterns README](../../patterns/README.md) lists 59 seed names; it is a separate discovery inventory, not 59 developed records or a release quota.
|
||||
|
||||
|
|
@ -22,8 +22,8 @@ A zero means no assigned direct coverage, not absence of discussion. Force direc
|
|||
| affordance | 2 | 6 |
|
||||
| mutation | 0 | 4 |
|
||||
| synchronization | 2 | 5 |
|
||||
| composition | 2 | 4 |
|
||||
| execution | 0 | 3 |
|
||||
| composition | 2 | 5 |
|
||||
| execution | 0 | 4 |
|
||||
| quality | 2 | 3 |
|
||||
|
||||
## Scales
|
||||
|
|
@ -34,7 +34,7 @@ A zero means no assigned direct coverage, not absence of discussion. Force direc
|
|||
| L1 | 0 | 1 |
|
||||
| L2 | 3 | 6 |
|
||||
| L3 | 7 | 5 |
|
||||
| L4 | 2 | 3 |
|
||||
| L4 | 2 | 4 |
|
||||
| L5 | 1 | 2 |
|
||||
| L6 | 4 | 13 |
|
||||
| L7 | 0 | 0 |
|
||||
|
|
@ -53,7 +53,7 @@ These are direct-mechanism assignments, not family aliases. In particular, recon
|
|||
| mutation | 4 |
|
||||
| synchronization | 2 |
|
||||
| reconciliation | 4 |
|
||||
| composition | 3 |
|
||||
| composition | 4 |
|
||||
| execution | 3 |
|
||||
|
||||
## Forces
|
||||
|
|
@ -92,14 +92,14 @@ Selected trade-offs only. Counts are unique candidates per force, even if a forc
|
|||
| independent-deployability | 1 | 0 | 1 |
|
||||
| team-autonomy | 1 | 0 | 1 |
|
||||
| release-coupling | 0 | 0 | 0 |
|
||||
| compatibility-pressure | 0 | 2 | 2 |
|
||||
| implementation-complexity | 0 | 9 | 9 |
|
||||
| compatibility-pressure | 0 | 3 | 3 |
|
||||
| implementation-complexity | 0 | 10 | 10 |
|
||||
| reconciliation-complexity | 0 | 2 | 2 |
|
||||
| cognitive-load | 0 | 3 | 3 |
|
||||
| testability | 1 | 0 | 1 |
|
||||
| observability | 0 | 0 | 0 |
|
||||
| debuggability | 0 | 0 | 0 |
|
||||
| portability | 1 | 0 | 1 |
|
||||
| portability | 2 | 0 | 2 |
|
||||
| security-exposure | 0 | 0 | 0 |
|
||||
| scalability | 0 | 0 | 0 |
|
||||
| fault-containment | 1 | 0 | 1 |
|
||||
|
|
@ -112,6 +112,7 @@ Selected trade-offs only. Counts are unique candidates per force, even if a forc
|
|||
|
||||
| Candidate | Responsibilities | Intended benefit | Cost / tension | Rationale |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| [Capability Contract Boundary](../candidates/CapabilityContractBoundary.md) | composition | portability | implementation-complexity, compatibility-pressure | Separates a semantic capability interface from its runtime carrier to support host portability; versioning, enforcement and cross-host compatibility add work. Declaring the contract alone supplies neither runtime isolation nor independent release. |
|
||||
| [Conflict Copy](../candidates/ConflictCopy.md) | reconciliation | recoverability, information-completeness | cognitive-load, reconciliation-complexity | Preserves divergent content for later semantic resolution; unresolved copies impose review and merge work. |
|
||||
| [Derived State](../candidates/DerivedState.md) | projection | authoritative-consistency | client-compute-cost, cache-invalidation-complexity | Projects coherent inputs without separately mutable derived copies; recomputation and cached dependency tracking cost work. |
|
||||
| [Explicit Reconciliation](../candidates/ExplicitReconciliation.md) | reconciliation, affordance | information-completeness, recoverability | cognitive-load, continuity-of-interaction | Makes semantic resolution an explicit comparison task; deciding among versions interrupts ordinary work. |
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Language evolution report
|
||||
|
||||
Generated by `make evolution-report`; curated assessment date: 2026-09-27.
|
||||
Generated by `make evolution-report`; curated assessment date: 2026-09-28.
|
||||
|
||||
This is an evidence profile, not a completion percentage. Evidence presence does not establish full-contract recurrence or production fitness.
|
||||
|
||||
|
|
@ -14,7 +14,7 @@ The baseline profiles are author-model assessments by Codex; they do not confer
|
|||
| --- | ---: |
|
||||
| documentary | 18 |
|
||||
| static-code | 7 |
|
||||
| runtime | 8 |
|
||||
| runtime | 10 |
|
||||
|
||||
Categories overlap. Runtime includes authored fixtures and negative controls. Family labels group related evidence; they are not counts of independent applications.
|
||||
|
||||
|
|
@ -51,13 +51,13 @@ Ten selected retrospective outcomes (not a historical census), followed by prosp
|
|||
|
||||
| Outcome | Entries (not independent discoveries) |
|
||||
| --- | ---: |
|
||||
| corroboration | 4 |
|
||||
| corroboration | 5 |
|
||||
| inconclusive | 0 |
|
||||
| merge | 0 |
|
||||
| rejection | 0 |
|
||||
| revision | 13 |
|
||||
|
||||
Cycles with recorded research effort: 6/17. Unknown effort is neither zero nor estimated from commits, tokens or assertion counts.
|
||||
Cycles with recorded research effort: 7/18. Unknown effort is neither zero nor estimated from commits, tokens or assertion counts.
|
||||
|
||||
### Stream B / B-independent-navigation-source-v1
|
||||
|
||||
|
|
@ -76,6 +76,14 @@ One bounded question counts at most one consequential outcome. Corroboration and
|
|||
|
||||
One bounded question counts at most one consequential outcome. Corroboration and inconclusive work remain visible separately. Fewer than three comparable cycles: no trend assessment.
|
||||
|
||||
### Stream D / D-sqlite-git-recovery-v1
|
||||
|
||||
| Cycle | Outcome | Research minutes | Consequential outcome/hour |
|
||||
| --- | --- | ---: | ---: |
|
||||
| LEARN-0018 | corroboration | 4.123 | 0.00 |
|
||||
|
||||
One bounded question counts at most one consequential outcome. Corroboration and inconclusive work remain visible separately. Fewer than three comparable cycles: no trend assessment.
|
||||
|
||||
### Stream F / F-navigation-focus-v1
|
||||
|
||||
| Cycle | Outcome | Research minutes | Consequential outcome/hour |
|
||||
|
|
@ -145,8 +153,9 @@ Define when a local change is durably accepted.
|
|||
| --- | --- | --- | --- |
|
||||
| documentary | Ink & Switch | Local-first motivation. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
|
||||
| documentary | Joplin | Local storage and synchronization architecture. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
|
||||
| runtime | authored SQLite / Git recovery fixture | SQLite WAL/FULL: pre-commit process kill rolls back; post-commit kill preserves document and outbox. No power-loss/backup proof. | [StorageReceiverRecovery](../../research/reviews/StorageReceiverRecovery.md) |
|
||||
|
||||
Open limits: No executed storage crash or backup test. Local acceptance is not off-device recovery.
|
||||
Open limits: Process-kill recovery observed in SQLite fixture; power-loss, device-loss backup and full frontend contract remain unverified. Local acceptance is not off-device recovery.
|
||||
|
||||
Superseded by: none recorded.
|
||||
|
||||
|
|
@ -159,8 +168,9 @@ Keep accepted local intent visible until synchronization resolves.
|
|||
| Evidence | Family | Scope | Review |
|
||||
| --- | --- | --- | --- |
|
||||
| documentary | Joplin | Per-item synchronization metadata. | [LocalFirstEvidenceExpansion](../../research/reviews/LocalFirstEvidenceExpansion.md) |
|
||||
| runtime | authored SQLite / Git recovery fixture | SQLite atomic supersession/restart plus Git identity replay after lost local acknowledgement; one authored integration, no frontend recurrence. | [StorageReceiverRecovery](../../research/reviews/StorageReceiverRecovery.md) |
|
||||
|
||||
Open limits: Atomic supersession and retry contract proposed, not storage-tested.
|
||||
Open limits: Atomic supersession observed in SQLite fixture; concurrent in-flight supersession, UI states and general receiver retention remain unverified.
|
||||
|
||||
Superseded by: none recorded.
|
||||
|
||||
|
|
@ -207,6 +217,7 @@ Reject an operation whose observed base is stale.
|
|||
| 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) |
|
||||
| runtime | authored SQLite / Git recovery fixture | Actual Git receive-pack rejects a forced divergent branch update; related ancestry mechanism, not exact-version frontend semantics. | [StorageReceiverRecovery](../../research/reviews/StorageReceiverRecovery.md) |
|
||||
|
||||
Open limits: Distributed atomicity and complete frontend recurrence remain unverified. Refetch does not authorize overwriting conflicting intent.
|
||||
|
||||
|
|
@ -225,6 +236,7 @@ Retain operation identity when transport outcome is uncertain.
|
|||
| 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) |
|
||||
| runtime | authored SQLite / Git recovery fixture | Actual Git same-commit replay is a no-op, reachable identity survives GC, fresh identity repeats intent; no arbitrary operation ledger. | [StorageReceiverRecovery](../../research/reviews/StorageReceiverRecovery.md) |
|
||||
|
||||
Open limits: No production server deduplication or complete retention-window guarantee. Cancelling local UI is not remote compensation.
|
||||
|
||||
|
|
@ -645,3 +657,17 @@ Evidence: [ZulipTargetLookupCallPath](../../research/reviews/ZulipTargetLookupCa
|
|||
Remaining uncertainty: Static source trace only; no application, database or upstream test executed, and no race actually reproduced. show() performs its own state reset on entry, so a stale re-entry's externally observable effect is unverified without execution. Second cycle in comparison group B-independent-navigation-source-v1; still short of three comparable cycles, and the workplan's rule against manufacturing cycles to reach that count still applies.
|
||||
|
||||
Supersedes: none recorded.
|
||||
|
||||
### LEARN-0018 — Which process-recovery obligations can SQLite plus actual Git receive-pack satisfy, and where does object identity fail to supply an operation receipt?
|
||||
|
||||
2026-09-28 · stream D · prospective · corroboration
|
||||
|
||||
Before: Atomic local intent/outbox updates and stable receiver identity support recovery within explicit transaction, ancestry and retention boundaries.
|
||||
|
||||
Conclusion: Nine checks corroborate atomic SQLite process recovery, Git replay and server ancestry refusal; split-transaction and fresh-identity negative controls retain the limits. One authored integration, not a full frontend use.
|
||||
|
||||
Evidence: [StorageReceiverRecovery](../../research/reviews/StorageReceiverRecovery.md), [result](../../research/experiments/storage-receiver/result.json), [2026-09-28-storage-receiver-effort](../../research/evolution/cycles/2026-09-28-storage-receiver-effort.json).
|
||||
|
||||
Remaining uncertainty: Power-loss, device-loss backup, remote durability and arbitrary operation-ID retention remain unverified. No full frontend contract, independent human validation or M1/M2/M3 acceptance. New runtime group is not comparable with static studies; no learning trend.
|
||||
|
||||
Supersedes: none recorded.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"start_utc": "2026-09-28T08:55:43+00:00",
|
||||
"end_utc": "2026-09-28T08:59:51.273196+00:00",
|
||||
"research_minutes": 4.123,
|
||||
"execution_minutes": 0.014,
|
||||
"reported_tokens": null,
|
||||
"cost_usd": null,
|
||||
"status": "complete",
|
||||
"method": "Continuous single-agent active interval from recorded preregistration clock through implementation and evidence review, minus measured experiment subprocess duration. Includes protocol commit; excludes earlier orientation and subsequent ledger/check/sync administration. No overlap.",
|
||||
"budget": "30 active research minutes, 5 experiment execution minutes; within both."
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# LEARN-0018 — Durable pending intent and a concrete receiver
|
||||
|
||||
Status: preregistered before execution. Owner/reviewer: Codex, author-model.
|
||||
Status: complete; preregistered before execution at `aea9796`. Owner/reviewer: Codex, author-model.
|
||||
Date: 2026-09-28. Existing work: FEP-WP-0003 T04; no new work item.
|
||||
Stream D; new comparison group D-sqlite-git-recovery-v1. Do not pool this
|
||||
runtime protocol with source inspection or the Matrix synthetic receiver.
|
||||
|
|
@ -48,4 +48,13 @@ existing T01/T02 and WP-0002 T03. No new follow-up task is needed for exclusions
|
|||
|
||||
## Outcome
|
||||
|
||||
Pending execution.
|
||||
Corroboration: nine checks pass, including two negative controls. Evidence:
|
||||
[review](../../reviews/StorageReceiverRecovery.md),
|
||||
[result](../../experiments/storage-receiver/result.json), and
|
||||
[effort receipt](2026-09-28-storage-receiver-effort.json).
|
||||
One question/outcome; nine assertions are not nine independent uses. No failed
|
||||
development run, independent review, new inference call or maturity promotion.
|
||||
T04 completes for this bounded pair; full frontend recurrence remains T01,
|
||||
validated/human cases T02 and WP-0002 T03. Supersedes no prior ledger entry.
|
||||
Active research and execution times are recorded separately in the effort receipt;
|
||||
provider tokens/cost are unmeasured. Review: Codex, author-model, not independent.
|
||||
|
|
|
|||
|
|
@ -596,6 +596,46 @@
|
|||
"cost_usd": null
|
||||
},
|
||||
"supersedes": []
|
||||
},
|
||||
{
|
||||
"id": "LEARN-0018",
|
||||
"date": "2026-09-28",
|
||||
"recording": "prospective",
|
||||
"stream": "D",
|
||||
"comparison_group": "D-sqlite-git-recovery-v1",
|
||||
"protocol_ref": "research/evolution/cycles/2026-09-28-storage-receiver.md",
|
||||
"question": "Which process-recovery obligations can SQLite plus actual Git receive-pack satisfy, and where does object identity fail to supply an operation receipt?",
|
||||
"previous_belief": "Atomic local intent/outbox updates and stable receiver identity support recovery within explicit transaction, ancestry and retention boundaries.",
|
||||
"conclusion": "Nine checks corroborate atomic SQLite process recovery, Git replay and server ancestry refusal; split-transaction and fresh-identity negative controls retain the limits. One authored integration, not a full frontend use.",
|
||||
"disposition": "corroboration",
|
||||
"affected_patterns": [
|
||||
"CAND-0002",
|
||||
"CAND-0003",
|
||||
"CAND-0006",
|
||||
"CAND-0007"
|
||||
],
|
||||
"evidence": [
|
||||
"research/reviews/StorageReceiverRecovery.md",
|
||||
"research/experiments/storage-receiver/result.json",
|
||||
"research/evolution/cycles/2026-09-28-storage-receiver-effort.json"
|
||||
],
|
||||
"remaining_uncertainty": [
|
||||
"Power-loss, device-loss backup, remote durability and arbitrary operation-ID retention remain unverified.",
|
||||
"No full frontend contract, independent human validation or M1/M2/M3 acceptance.",
|
||||
"New runtime group is not comparable with static studies; no learning trend."
|
||||
],
|
||||
"reviewer": {
|
||||
"name": "Codex",
|
||||
"role": "author-model",
|
||||
"independent_human": false
|
||||
},
|
||||
"effort": {
|
||||
"research_minutes": 4.123,
|
||||
"execution_minutes": 0.014,
|
||||
"reported_tokens": null,
|
||||
"cost_usd": null
|
||||
},
|
||||
"supersedes": []
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"schema_version": 1,
|
||||
"assessed_at": "2026-09-27",
|
||||
"assessed_at": "2026-09-28",
|
||||
"profiles": [
|
||||
{
|
||||
"id": "CAND-0001",
|
||||
|
|
@ -60,20 +60,26 @@
|
|||
"family": "Joplin",
|
||||
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
|
||||
"scope": "Local storage and synchronization architecture."
|
||||
},
|
||||
{
|
||||
"kind": "runtime",
|
||||
"family": "authored SQLite / Git recovery fixture",
|
||||
"ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"scope": "SQLite WAL/FULL: pre-commit process kill rolls back; post-commit kill preserves document and outbox. No power-loss/backup proof."
|
||||
}
|
||||
],
|
||||
"independent_full_contract_uses": null,
|
||||
"review": {
|
||||
"assessed_at": "2026-09-27",
|
||||
"assessed_at": "2026-09-28",
|
||||
"reviewer": "Codex",
|
||||
"role": "author-model",
|
||||
"independent_human": false,
|
||||
"last_substantive_review_date": "2026-09-27",
|
||||
"substantive_review_ref": "research/reviews/M1-SeedReview.md",
|
||||
"substantive_review_scope": "Editorial review of the connected core; M1 revise/defer."
|
||||
"last_substantive_review_date": "2026-09-28",
|
||||
"substantive_review_ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"substantive_review_scope": "SQLite WAL/FULL: pre-commit process kill rolls back; post-commit kill preserves document and outbox. No power-loss/backup proof."
|
||||
},
|
||||
"gaps": [
|
||||
"No executed storage crash or backup test.",
|
||||
"Process-kill recovery observed in SQLite fixture; power-loss, device-loss backup and full frontend contract remain unverified.",
|
||||
"Local acceptance is not off-device recovery."
|
||||
],
|
||||
"superseded_by": []
|
||||
|
|
@ -92,20 +98,26 @@
|
|||
"family": "Joplin",
|
||||
"ref": "research/reviews/LocalFirstEvidenceExpansion.md",
|
||||
"scope": "Per-item synchronization metadata."
|
||||
},
|
||||
{
|
||||
"kind": "runtime",
|
||||
"family": "authored SQLite / Git recovery fixture",
|
||||
"ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"scope": "SQLite atomic supersession/restart plus Git identity replay after lost local acknowledgement; one authored integration, no frontend recurrence."
|
||||
}
|
||||
],
|
||||
"independent_full_contract_uses": null,
|
||||
"review": {
|
||||
"assessed_at": "2026-09-27",
|
||||
"assessed_at": "2026-09-28",
|
||||
"reviewer": "Codex",
|
||||
"role": "author-model",
|
||||
"independent_human": false,
|
||||
"last_substantive_review_date": "2026-09-27",
|
||||
"substantive_review_ref": "research/reviews/M1-SeedReview.md",
|
||||
"substantive_review_scope": "Editorial review of the connected core; M1 revise/defer."
|
||||
"last_substantive_review_date": "2026-09-28",
|
||||
"substantive_review_ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"substantive_review_scope": "SQLite atomic supersession/restart plus Git identity replay after lost local acknowledgement; one authored integration, no frontend recurrence."
|
||||
},
|
||||
"gaps": [
|
||||
"Atomic supersession and retry contract proposed, not storage-tested."
|
||||
"Atomic supersession observed in SQLite fixture; concurrent in-flight supersession, UI states and general receiver retention remain unverified."
|
||||
],
|
||||
"superseded_by": []
|
||||
},
|
||||
|
|
@ -223,17 +235,23 @@
|
|||
"family": "authored release fixture",
|
||||
"ref": "research/reviews/ActivationConflictsAndReload.md",
|
||||
"scope": "Related conditional activation-map mechanism in one process, not the full frontend pattern."
|
||||
},
|
||||
{
|
||||
"kind": "runtime",
|
||||
"family": "authored SQLite / Git recovery fixture",
|
||||
"ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"scope": "Actual Git receive-pack rejects a forced divergent branch update; related ancestry mechanism, not exact-version frontend semantics."
|
||||
}
|
||||
],
|
||||
"independent_full_contract_uses": null,
|
||||
"review": {
|
||||
"assessed_at": "2026-09-27",
|
||||
"assessed_at": "2026-09-28",
|
||||
"reviewer": "Codex",
|
||||
"role": "author-model",
|
||||
"independent_human": false,
|
||||
"last_substantive_review_date": "2026-09-27",
|
||||
"substantive_review_ref": "research/reviews/M1-SeedReview.md",
|
||||
"substantive_review_scope": "Editorial review of the connected core; M1 revise/defer."
|
||||
"last_substantive_review_date": "2026-09-28",
|
||||
"substantive_review_ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"substantive_review_scope": "Actual Git receive-pack rejects a forced divergent branch update; related ancestry mechanism, not exact-version frontend semantics."
|
||||
},
|
||||
"gaps": [
|
||||
"Distributed atomicity and complete frontend recurrence remain unverified.",
|
||||
|
|
@ -279,17 +297,23 @@
|
|||
"family": "Element / Matrix",
|
||||
"ref": "research/reviews/MatrixRecoveryExperiment.md",
|
||||
"scope": "Real SDK with synthetic transport: lost acknowledgement, identity reuse and authoritative echo."
|
||||
},
|
||||
{
|
||||
"kind": "runtime",
|
||||
"family": "authored SQLite / Git recovery fixture",
|
||||
"ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"scope": "Actual Git same-commit replay is a no-op, reachable identity survives GC, fresh identity repeats intent; no arbitrary operation ledger."
|
||||
}
|
||||
],
|
||||
"independent_full_contract_uses": null,
|
||||
"review": {
|
||||
"assessed_at": "2026-09-27",
|
||||
"assessed_at": "2026-09-28",
|
||||
"reviewer": "Codex",
|
||||
"role": "author-model",
|
||||
"independent_human": false,
|
||||
"last_substantive_review_date": "2026-09-27",
|
||||
"substantive_review_ref": "research/reviews/M1-SeedReview.md",
|
||||
"substantive_review_scope": "Editorial review of the connected core; M1 revise/defer."
|
||||
"last_substantive_review_date": "2026-09-28",
|
||||
"substantive_review_ref": "research/reviews/StorageReceiverRecovery.md",
|
||||
"substantive_review_scope": "Actual Git same-commit replay is a no-op, reachable identity survives GC, fresh identity repeats intent; no arbitrary operation ledger."
|
||||
},
|
||||
"gaps": [
|
||||
"No production server deduplication or complete retention-window guarantee.",
|
||||
|
|
|
|||
1530
research/evolution/snapshots/cycle-2026-09-28-storage-receiver.json
Normal file
1530
research/evolution/snapshots/cycle-2026-09-28-storage-receiver.json
Normal file
File diff suppressed because it is too large
Load diff
29
research/experiments/storage-receiver/README.md
Normal file
29
research/experiments/storage-receiver/README.md
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
# SQLite / Git recovery experiment
|
||||
|
||||
Existing owner: FEP-WP-0003 T04. Preregistered as LEARN-0018 in commit `aea9796`.
|
||||
[Review](../../reviews/StorageReceiverRecovery.md) explains the acceptance scope.
|
||||
|
||||
Run from the repository root with ordinary Python (assertions enabled), SQLite
|
||||
and Git; no dependency installation or service is needed:
|
||||
|
||||
```sh
|
||||
python3 research/experiments/storage-receiver/experiment.py --output /tmp/fep-recovery-new.json
|
||||
```
|
||||
|
||||
The output must be a new path. The runner retains a failure receipt before raising;
|
||||
never overwrite the committed result. Compare the receipt's engine versions and
|
||||
binary/source hashes before treating another environment as a replication.
|
||||
|
||||
Temporary databases and bare repositories are isolated and removed on exit. Git
|
||||
configuration is isolated from user/system configuration. Each killed process is a
|
||||
new fixture worker, stopped only after an explicit checkpoint. Every read of the
|
||||
receiver runs a new Git process; the receiver itself is real `git receive-pack`
|
||||
using Git's local transport, not an authored protocol substitute. No port is opened.
|
||||
|
||||
Nine checks pass, including two intentionally broken negative controls. The sender
|
||||
is killed after Git reports success but before the application persists its receipt:
|
||||
this models lost **local** acknowledgement, not network packet loss. SQLite kills
|
||||
bracket commit and interrupt a multi-statement transaction; they do not inject a
|
||||
crash inside the commit syscall or simulate power loss. Receiver fsync/disk-failure
|
||||
behavior, remote authentication, backup, UI behavior and full-contract recurrence
|
||||
remain untested. A reachable commit is not an indefinitely retained operation ledger.
|
||||
238
research/experiments/storage-receiver/experiment.py
Normal file
238
research/experiments/storage-receiver/experiment.py
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Bounded local mechanism experiment; never touches the checkout's Git refs."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
import selectors
|
||||
import shutil
|
||||
import signal
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import time
|
||||
from datetime import datetime, timezone
|
||||
|
||||
HERE = Path(__file__).resolve()
|
||||
|
||||
|
||||
def connect(path):
|
||||
db = sqlite3.connect(path)
|
||||
assert db.execute('PRAGMA journal_mode=WAL').fetchone()[0] == 'wal'
|
||||
db.execute('PRAGMA synchronous=FULL')
|
||||
assert db.execute('PRAGMA synchronous').fetchone()[0] == 2
|
||||
return db
|
||||
|
||||
|
||||
def run(*args, cwd=None, check=True, input=None):
|
||||
# Ignore user Git configuration/hooks and inherited repository targeting.
|
||||
env = {k: v for k, v in os.environ.items() if not k.startswith('GIT_')}
|
||||
env.update(GIT_CONFIG_NOSYSTEM='1', GIT_CONFIG_GLOBAL='/dev/null',
|
||||
GIT_AUTHOR_NAME='Recovery Fixture', GIT_AUTHOR_EMAIL='fixture@example.invalid',
|
||||
GIT_COMMITTER_NAME='Recovery Fixture', GIT_COMMITTER_EMAIL='fixture@example.invalid',
|
||||
GIT_AUTHOR_DATE='2026-09-28T00:00:00Z', GIT_COMMITTER_DATE='2026-09-28T00:00:00Z')
|
||||
return subprocess.run(args, cwd=cwd, env=env, text=True, input=input,
|
||||
capture_output=True, check=check, timeout=20)
|
||||
|
||||
|
||||
def checkpoint():
|
||||
print('checkpoint', flush=True)
|
||||
# Parent kills only this dedicated fixture subprocess, after its marker.
|
||||
signal.pause()
|
||||
|
||||
|
||||
def worker(mode, root):
|
||||
db = connect(root / 'local.db')
|
||||
if mode == 'send':
|
||||
oid = db.execute("SELECT oid FROM pending WHERE id='send'").fetchone()[0]
|
||||
run('git', 'push', str(root / 'receiver.git'), f'{oid}:refs/heads/main', cwd=root / 'client')
|
||||
checkpoint() # Accepted remotely, local acknowledgement deliberately absent.
|
||||
return
|
||||
db.execute('BEGIN IMMEDIATE')
|
||||
db.execute("UPDATE pending SET state='superseded' WHERE id='old'")
|
||||
if mode == 'split':
|
||||
db.commit() # Deliberately broken negative control.
|
||||
checkpoint()
|
||||
return
|
||||
db.execute("UPDATE document SET body='new'")
|
||||
if mode == 'middle':
|
||||
checkpoint()
|
||||
return
|
||||
db.execute("INSERT INTO pending VALUES ('new','new-identity','pending')")
|
||||
if mode == 'before':
|
||||
checkpoint()
|
||||
return
|
||||
db.commit()
|
||||
checkpoint()
|
||||
|
||||
|
||||
def kill_at(mode, root):
|
||||
p = subprocess.Popen([sys.executable, str(HERE), '--worker', mode, '--root', str(root)],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
|
||||
try:
|
||||
with selectors.DefaultSelector() as selector:
|
||||
selector.register(p.stdout, selectors.EVENT_READ)
|
||||
if not selector.select(timeout=20):
|
||||
raise RuntimeError(f'{mode}: checkpoint timeout')
|
||||
line = p.stdout.readline().strip()
|
||||
if line != 'checkpoint':
|
||||
raise RuntimeError(f'{mode}: no checkpoint: {line} {p.stderr.read()}')
|
||||
p.kill()
|
||||
p.communicate(timeout=5)
|
||||
assert p.returncode == -signal.SIGKILL
|
||||
return p.returncode
|
||||
finally:
|
||||
if p.poll() is None:
|
||||
p.kill()
|
||||
p.communicate(timeout=5)
|
||||
|
||||
|
||||
def initialize(root):
|
||||
root.mkdir()
|
||||
with connect(root / 'local.db') as db:
|
||||
db.executescript('CREATE TABLE document(body TEXT); '
|
||||
'CREATE TABLE pending(id TEXT PRIMARY KEY, oid TEXT, state TEXT); '
|
||||
"INSERT INTO document VALUES ('old'); "
|
||||
"INSERT INTO pending VALUES ('old','old-identity','pending');")
|
||||
|
||||
|
||||
def state(root):
|
||||
with connect(root / 'local.db') as db:
|
||||
assert db.execute('PRAGMA integrity_check').fetchone()[0] == 'ok'
|
||||
return {'body': db.execute('SELECT body FROM document').fetchone()[0],
|
||||
'pending': db.execute('SELECT * FROM pending ORDER BY id').fetchall()}
|
||||
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(Path(path).read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def experiment(report):
|
||||
with tempfile.TemporaryDirectory(prefix='fep-storage-receiver-') as temp:
|
||||
root = Path(temp)
|
||||
old = {'body': 'old', 'pending': [('old', 'old-identity', 'pending')]}
|
||||
new = {'body': 'new', 'pending': [('new', 'new-identity', 'pending'),
|
||||
('old', 'old-identity', 'superseded')]}
|
||||
for mode, expected in [('before', old), ('after', new), ('middle', old),
|
||||
('split', {'body': 'old', 'pending': [('old', 'old-identity', 'superseded')]})]:
|
||||
case = root / mode
|
||||
initialize(case)
|
||||
code = kill_at(mode, case)
|
||||
observed = state(case)
|
||||
report['checks'].append({'id': f'local-{mode}', 'pass': observed == expected,
|
||||
'negative_control': mode == 'split', 'worker_exit': code,
|
||||
'observed': observed})
|
||||
assert observed == expected
|
||||
case = root / 'receiver'
|
||||
initialize(case)
|
||||
client = case / 'client'
|
||||
receiver = case / 'receiver.git'
|
||||
run('git', 'init', '--quiet', '--initial-branch=main', str(client))
|
||||
run('git', 'init', '--quiet', '--bare', '--initial-branch=main', str(receiver))
|
||||
run('git', 'config', 'receive.denyNonFastForwards', 'true', cwd=receiver)
|
||||
tree = run('git', 'mktree', cwd=client, input='').stdout.strip()
|
||||
|
||||
def commit(parent, text):
|
||||
args = ['git', 'commit-tree', tree]
|
||||
if parent:
|
||||
args += ['-p', parent]
|
||||
return run(*args, cwd=client, input=text + '\n').stdout.strip()
|
||||
|
||||
def push(oid, force=False):
|
||||
return run('git', 'push', '--porcelain', str(receiver),
|
||||
('+' if force else '') + f'{oid}:refs/heads/main', cwd=client, check=False)
|
||||
|
||||
def tip():
|
||||
return run('git', 'rev-parse', 'refs/heads/main', cwd=receiver).stdout.strip()
|
||||
|
||||
base = commit(None, 'base')
|
||||
accepted = commit(base, 'operation A: synthetic intent')
|
||||
assert push(base).returncode == 0
|
||||
with connect(case / 'local.db') as db:
|
||||
db.execute("INSERT INTO pending VALUES ('send',?,'pending')", (accepted,))
|
||||
code = kill_at('send', case)
|
||||
with connect(case / 'local.db') as db:
|
||||
pending = db.execute("SELECT state FROM pending WHERE id='send'").fetchone()[0]
|
||||
report['checks'].append({'id': 'lost-local-ack', 'pass': tip() == accepted and pending == 'pending',
|
||||
'worker_exit': code, 'receiver_tip': tip(), 'outbox_state': pending})
|
||||
assert tip() == accepted and pending == 'pending'
|
||||
replay = push(accepted)
|
||||
count = int(run('git', 'rev-list', '--count', 'main', cwd=receiver).stdout)
|
||||
report['checks'].append({'id': 'same-identity-replay', 'pass': replay.returncode == 0 and count == 2,
|
||||
'exit': replay.returncode, 'history_count': count,
|
||||
'up_to_date': 'up to date' in replay.stdout})
|
||||
assert replay.returncode == 0 and count == 2
|
||||
with connect(case / 'local.db') as db:
|
||||
db.execute("UPDATE pending SET state='acknowledged' WHERE id='send'")
|
||||
concurrent = commit(accepted, 'operation B')
|
||||
assert push(concurrent).returncode == 0
|
||||
stale = commit(base, 'stale operation C')
|
||||
with connect(case / 'local.db') as db:
|
||||
db.execute("INSERT INTO pending VALUES ('stale',?,'pending')", (stale,))
|
||||
rejected = push(stale, force=True) # Force transmission; real server denies it.
|
||||
with connect(case / 'local.db') as db:
|
||||
pending = db.execute("SELECT state FROM pending WHERE id='stale'").fetchone()[0]
|
||||
server_refused = 'non-fast-forward' in rejected.stderr and 'remote rejected' in rejected.stdout
|
||||
report['checks'].append({'id': 'stale-ancestry', 'pass': rejected.returncode != 0 and server_refused and tip() == concurrent and pending == 'pending',
|
||||
'exit': rejected.returncode, 'server_refused': server_refused,
|
||||
'receiver_tip_unchanged': tip() == concurrent, 'outbox_state': pending})
|
||||
assert report['checks'][-1]['pass']
|
||||
run('git', 'gc', '--prune=now', cwd=receiver)
|
||||
retained = run('git', 'cat-file', '-t', accepted, cwd=receiver).stdout.strip()
|
||||
ancestor = run('git', 'merge-base', '--is-ancestor', accepted, 'main', cwd=receiver, check=False)
|
||||
report['checks'].append({'id': 'reachable-identity-after-gc', 'pass': retained == 'commit' and ancestor.returncode == 0})
|
||||
assert report['checks'][-1]['pass']
|
||||
# The same business intent under a NEW identity is another accepted commit.
|
||||
fresh = commit(concurrent, 'operation A: synthetic intent')
|
||||
assert push(fresh).returncode == 0
|
||||
count = int(run('git', 'rev-list', '--count', 'main', cwd=receiver).stdout)
|
||||
report['checks'].append({'id': 'fresh-identity-duplicates-intent', 'negative_control': True,
|
||||
'pass': fresh != accepted and count == 4, 'history_count': count})
|
||||
assert report['checks'][-1]['pass']
|
||||
report['identities'] = {'base': base, 'accepted': accepted, 'concurrent': concurrent,
|
||||
'stale': stale, 'fresh': fresh}
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--worker', choices=['before', 'after', 'middle', 'split', 'send'])
|
||||
parser.add_argument('--root', type=Path)
|
||||
parser.add_argument('--output', type=Path)
|
||||
args = parser.parse_args()
|
||||
if args.worker:
|
||||
worker(args.worker, args.root)
|
||||
return
|
||||
if not args.output:
|
||||
parser.error('--output is required (use a new file to preserve prior receipts)')
|
||||
# Reserve the receipt before execution and refuse to overwrite retained evidence.
|
||||
with args.output.open('x') as output:
|
||||
start = time.monotonic()
|
||||
import _sqlite3
|
||||
report = {'started_utc': datetime.now(timezone.utc).isoformat(), 'checks': [],
|
||||
'provenance': {'python': sys.version.split()[0], 'sqlite': sqlite3.sqlite_version,
|
||||
'sqlite_source_id': sqlite3.connect(':memory:').execute('SELECT sqlite_source_id()').fetchone()[0],
|
||||
'git': run('git', '--version').stdout.strip(),
|
||||
'git_binary_sha256': sha(shutil.which('git')),
|
||||
'sqlite_python_extension_sha256': sha(_sqlite3.__file__),
|
||||
'experiment_sha256': sha(HERE)},
|
||||
'settings': {'sqlite_journal': 'wal', 'sqlite_synchronous': 'FULL',
|
||||
'receiver': 'local bare git receive-pack', 'denyNonFastForwards': True},
|
||||
'scope': 'Process kills and discarded local acknowledgement; no power-loss or network-loss simulation.'}
|
||||
try:
|
||||
experiment(report)
|
||||
report['status'] = 'passed'
|
||||
except Exception as exc:
|
||||
report['status'] = 'failed'
|
||||
report['error'] = f'{type(exc).__name__}: {exc}'
|
||||
raise
|
||||
finally:
|
||||
report['execution_seconds'] = round(time.monotonic() - start, 6)
|
||||
json.dump(report, output, indent=2)
|
||||
output.write('\n')
|
||||
print(f"{len(report['checks'])} checks: {report['status']}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
131
research/experiments/storage-receiver/result.json
Normal file
131
research/experiments/storage-receiver/result.json
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
{
|
||||
"started_utc": "2026-09-28T08:57:26.496125+00:00",
|
||||
"checks": [
|
||||
{
|
||||
"id": "local-before",
|
||||
"pass": true,
|
||||
"negative_control": false,
|
||||
"worker_exit": -9,
|
||||
"observed": {
|
||||
"body": "old",
|
||||
"pending": [
|
||||
[
|
||||
"old",
|
||||
"old-identity",
|
||||
"pending"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "local-after",
|
||||
"pass": true,
|
||||
"negative_control": false,
|
||||
"worker_exit": -9,
|
||||
"observed": {
|
||||
"body": "new",
|
||||
"pending": [
|
||||
[
|
||||
"new",
|
||||
"new-identity",
|
||||
"pending"
|
||||
],
|
||||
[
|
||||
"old",
|
||||
"old-identity",
|
||||
"superseded"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "local-middle",
|
||||
"pass": true,
|
||||
"negative_control": false,
|
||||
"worker_exit": -9,
|
||||
"observed": {
|
||||
"body": "old",
|
||||
"pending": [
|
||||
[
|
||||
"old",
|
||||
"old-identity",
|
||||
"pending"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "local-split",
|
||||
"pass": true,
|
||||
"negative_control": true,
|
||||
"worker_exit": -9,
|
||||
"observed": {
|
||||
"body": "old",
|
||||
"pending": [
|
||||
[
|
||||
"old",
|
||||
"old-identity",
|
||||
"superseded"
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "lost-local-ack",
|
||||
"pass": true,
|
||||
"worker_exit": -9,
|
||||
"receiver_tip": "c55e497766915672901a3fb34181c6322d87a352",
|
||||
"outbox_state": "pending"
|
||||
},
|
||||
{
|
||||
"id": "same-identity-replay",
|
||||
"pass": true,
|
||||
"exit": 0,
|
||||
"history_count": 2,
|
||||
"up_to_date": true
|
||||
},
|
||||
{
|
||||
"id": "stale-ancestry",
|
||||
"pass": true,
|
||||
"exit": 1,
|
||||
"server_refused": true,
|
||||
"receiver_tip_unchanged": true,
|
||||
"outbox_state": "pending"
|
||||
},
|
||||
{
|
||||
"id": "reachable-identity-after-gc",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"id": "fresh-identity-duplicates-intent",
|
||||
"negative_control": true,
|
||||
"pass": true,
|
||||
"history_count": 4
|
||||
}
|
||||
],
|
||||
"provenance": {
|
||||
"python": "3.12.3",
|
||||
"sqlite": "3.45.1",
|
||||
"sqlite_source_id": "2024-01-30 16:01:20 e876e51a0ed5c5b3126f52e532044363a014bc594cfefa87ffb5b82257ccalt1",
|
||||
"git": "git version 2.43.0",
|
||||
"git_binary_sha256": "2a8c18fbf43da9f692d75474c72bea9dfd796c260b0f3dfe456376abc3bbd668",
|
||||
"sqlite_python_extension_sha256": "ecf54958b24c533f5c8dc67ca82cdce236aeb322864140bfe93eb8a69b729f4d",
|
||||
"experiment_sha256": "5fe558214648636878816a35d0d63632de08a3391bd07f3eb4e6c81c7747063f"
|
||||
},
|
||||
"settings": {
|
||||
"sqlite_journal": "wal",
|
||||
"sqlite_synchronous": "FULL",
|
||||
"receiver": "local bare git receive-pack",
|
||||
"denyNonFastForwards": true
|
||||
},
|
||||
"scope": "Process kills and discarded local acknowledgement; no power-loss or network-loss simulation.",
|
||||
"identities": {
|
||||
"base": "8581afcccc64516084339b8d633daf4b01ecef35",
|
||||
"accepted": "c55e497766915672901a3fb34181c6322d87a352",
|
||||
"concurrent": "ce6b4356d194fef30d6246a2ed7f526c9e9a5f2f",
|
||||
"stale": "e0e578fa81bb53fed8192623f3489529b6ddd710",
|
||||
"fresh": "98a5ada629763dba0706264e88814e87d90883c1"
|
||||
},
|
||||
"status": "passed",
|
||||
"execution_seconds": 0.868828
|
||||
}
|
||||
43
research/reviews/LooseEnds-2026-09-28.md
Normal file
43
research/reviews/LooseEnds-2026-09-28.md
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# Loose-end review — 2026-09-28
|
||||
|
||||
Reviewed all eight local workplans, including finished records. Initially WP-0006
|
||||
was active; WP-0002/0003/0004/0008 blocked; WP-0001/0005/0007 finished. No ready or
|
||||
proposed workplan remained. Working tree was clean. State Hub inbox and FEP human-
|
||||
needed task results were empty; source files take precedence over the stale brief.
|
||||
|
||||
| Existing task(s) | Closeout disposition | Remaining prerequisite / resume condition |
|
||||
| --- | --- | --- |
|
||||
| WP-0003 T04 | **Done:** implemented and executed the preregistered concrete SQLite/Git recovery experiment; nine checks, including two negative controls | [Bounded evidence and exclusions](StorageReceiverRecovery.md); no stronger frontend/durability claim |
|
||||
| WP-0002 T03 | Wait; plan blocked | Independent usefulness/validated seed-case evidence; submitted model worksheet is not independent human review |
|
||||
| WP-0003 T01 | Progress; plan remains blocked by T02 | Six-stream full-contract implementation evidence remains incomplete. Static source paths, authored fixtures and documentary leads are not independent full uses; existing navigation fixture remains paused |
|
||||
| WP-0003 T02 | Wait; plan blocked | M1 acceptance, then completed contrasting cases and quality/human/AT evidence |
|
||||
| WP-0004 T01 | Wait; plan blocked | M1 acceptance before canonical validator/export |
|
||||
| WP-0004 T02/T03 | Wait; plan blocked | M2 acceptance before held-out evaluation and complete real-repository applicability studies |
|
||||
| WP-0006 T03 | Changed to wait; plan changed to blocked | Useful comparable research window; largest group has two cycles and incomplete effort. Today's different runtime protocol cannot make three |
|
||||
| WP-0008 T01 | Wait; plan blocked | Hosted discovery/common-template integration and first real pinned consumer decision |
|
||||
| WP-0008 T02 | Wait; plan blocked | Actual consumer closeout hook, real use and linked observed outcome; roster still empty |
|
||||
| WP-0008 T03 | Wait; plan blocked | Admitted budget-enforced executor, standing release/rollback evidence, natural cadence proof and a real unassisted cycle/monthly packet |
|
||||
|
||||
Other tasks remain done. No task or workplan was created or cancelled; no evidence
|
||||
gate was waived. No finished workplan was reopened. WP-0003 T01 remains actionable
|
||||
research, not an invented external blocker; completing its broad independent-use
|
||||
contract cannot be substituted by further author-only synthesis in this closeout.
|
||||
WP-0006 waits on a qualifying evidence window rather than running repetitions for
|
||||
a count. Existing tasks retain all obligations; no residual work is parked here alone.
|
||||
|
||||
The WP-0008 recheck found only September 27 intake smoke/manual receipts, not the
|
||||
expected September 28 natural daily receipt. [Query evidence](../../docs/evidence/2026-09-28-loop-recheck.json)
|
||||
records absence without diagnosing the scheduler. The owner plans ACTIVITY-WP-0041
|
||||
and GLAS-WP-0012 remain blocked; this session grants no runtime authority. The
|
||||
October 1 packet remains due even without consumers. No schedule or service changed.
|
||||
|
||||
Current profiles and evolution reporting now include the bounded recovery evidence;
|
||||
all eighteen candidates remain hypotheses. Current orientation counts are corrected;
|
||||
frozen seventeen-record 0.1 publication and historical reviews remain immutable.
|
||||
|
||||
Validation also exposed a pre-existing missing CAND-0018 classification record.
|
||||
Completed that local T01 repair after reading the candidate: composition/portability
|
||||
with implementation and compatibility costs. No new pattern or maturity change.
|
||||
Checks: 69 tests passed across evolution, schema, bench/admission and reference;
|
||||
synthetic bench plan, evolution/reference/classification freshness and whitespace.
|
||||
The classification failure before repair is recorded here rather than hidden.
|
||||
65
research/reviews/StorageReceiverRecovery.md
Normal file
65
research/reviews/StorageReceiverRecovery.md
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Concrete storage and receiver recovery
|
||||
|
||||
2026-09-28, Codex author-model review; no independent human validation.
|
||||
Owner: FEP-WP-0003 T04. [Preregistration](../evolution/cycles/2026-09-28-storage-receiver.md)
|
||||
at `aea9796`; [runner and reproduction](../experiments/storage-receiver/README.md),
|
||||
[retained receipt](../experiments/storage-receiver/result.json).
|
||||
|
||||
## Result and task disposition
|
||||
|
||||
Nine checks pass on SQLite 3.45.1 and Git 2.43.0. This completes T04's bounded
|
||||
concrete-pair investigation with explicit negative controls and remaining unknowns.
|
||||
The Git receiver is upstream receive-pack, launched against a disposable bare
|
||||
repository; the sender/outbox integration is authored research code. It is neither
|
||||
a deployed frontend nor a replacement for the Matrix experiment's missing real
|
||||
Matrix-server proof. No candidate contract or maturity is promoted.
|
||||
|
||||
| Obligation | Observation | Boundary |
|
||||
| --- | --- | --- |
|
||||
| Interrupted local transaction | SIGKILL before commit leaves old document and pending operation intact after reopen/integrity check | Process interruption, not power loss or a kill inside commit I/O |
|
||||
| Commit before acknowledgement | SIGKILL after commit retains new document, new pending identity and old superseded state | SQLite WAL, synchronous FULL on this host |
|
||||
| Supersession | Kill between statements rolls the transaction back; committed path changes all three facts | No sender concurrency or transmitted-operation recall guarantee |
|
||||
| Negative local control | Committing old-operation supersession separately leaves no replacement after interruption | Atomic grouping is necessary in this fixture |
|
||||
| Lost local receipt | Actual receive-pack accepts A; killed sender leaves A pending in SQLite | Git response arrived at sender; local acknowledgement was not persisted |
|
||||
| Same-identity replay | New push of A reports up-to-date; history still has only base plus A | Identity is the immutable commit, not arbitrary business intent |
|
||||
| Stale ancestry | A forced divergent update after B is refused by the receiver's denyNonFastForwards setting; branch stays at B and local work remains pending | Ancestry policy differs from exact expected-version comparison |
|
||||
| Identity retention | Fresh processes and garbage collection preserve reachable A and show it is an ancestor of B | Reachability is the tested retention scope, not indefinite retention or an authenticated receipt |
|
||||
| Negative receiver control | Rebuilding the same intent as a new commit on B adds a fourth history entry | Git cannot deduplicate business intent with different identities |
|
||||
|
||||
## Interpretation and documentary basis
|
||||
|
||||
The SQLite [atomic commit description](https://www.sqlite.org/atomiccommit.html)
|
||||
explains transaction recovery. Its [synchronous pragma](https://sqlite.org/pragma.html#pragma_synchronous)
|
||||
defines FULL synchronization for WAL. These are engine contracts, not observations
|
||||
of this machine's power-loss resilience; the fixture tests ordinary process kills.
|
||||
|
||||
Git's [receive configuration](https://git-scm.com/docs/git-config#Documentation/git-config.txt-receivedenyNonFastForwards)
|
||||
and [push documentation](https://git-scm.com/docs/git-push) distinguish ref updates,
|
||||
ancestry and expected-value leases. The experiment forces a divergent transmission
|
||||
and observes server refusal, rather than counting a client-side lease refusal as
|
||||
receiver evidence. Replay while A is the tip is a no-op. Once B is the tip, checking
|
||||
A's reachable ancestry supplies scoped evidence of inclusion; trying to push A
|
||||
again is not a general outcome-lookup API. A fresh identity does not prove freshness
|
||||
of intent, and object existence alone does not prove a branch accepted that object.
|
||||
|
||||
This corroborates the existing separation among Local Commit Boundary (CAND-0002),
|
||||
Pending Synchronization (CAND-0003), Version-Checked Mutation (CAND-0006) and Mutation
|
||||
Outcome Tracking (CAND-0007). Git's ancestry rule is only a related mechanism for
|
||||
CAND-0006: it is not exact version equality or a frontend implementation. SQLite
|
||||
and Git observations are one authored integration, not two independent full uses.
|
||||
|
||||
## Evidence limits and existing ownership
|
||||
|
||||
No failed development run occurred; the negative-control failures of the proposed
|
||||
contracts are retained as successful detection checks. There were no inference calls.
|
||||
No power failure, filesystem fault, device-loss restore, remote durability guarantee,
|
||||
identity-expiry test, authorization change, user interaction or accessibility test
|
||||
was performed. SQLite and Git cannot form one distributed transaction here. Full
|
||||
frontend contracts and production recurrence remain unknown.
|
||||
|
||||
T04 is done for this selected pair and tested process-failure envelope. Broader
|
||||
implementation evidence remains WP-0003 T01; validated cases/human/AT evidence remain
|
||||
WP-0003 T02 and WP-0002 T03. Those existing obligations retain the stronger claims;
|
||||
this review opens no task, workplan or stronger recovery promise. Device-loss backup
|
||||
is an explicit exclusion, not silently inferred from synchronization. Frozen 0.1
|
||||
publication and historical assessments remain unchanged.
|
||||
|
|
@ -290,7 +290,7 @@ T02/T03 gates and WP-0006 T03 review dates/comparable measurement remain open.
|
|||
|
||||
```task
|
||||
id: FEP-WP-0003-T04
|
||||
status: progress
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "7cbb845d-0e13-5356-8da0-41aa8495de2a"
|
||||
```
|
||||
|
|
@ -379,3 +379,26 @@ from Independent Feature Boundary (release cadence) and Vertical Feature Slice
|
|||
(source grouping). Eighteen hypotheses now exist; no known use of an explicit
|
||||
capability contract located, no application/runtime evidence, no canonical
|
||||
admission or M1/M2 change.
|
||||
|
||||
## Concrete storage/receiver closeout — 2026-09-28
|
||||
|
||||
T04 done: preregistered LEARN-0018 at `aea9796`, implemented and ran the SQLite
|
||||
3.45.1 / actual Git 2.43.0 receive-pack experiment. Nine checks cover transaction
|
||||
interruption/restart, atomic supersession, lost local acknowledgement, replay,
|
||||
reachable identity retention and server-side stale-ancestry refusal. Two negative
|
||||
controls expose split-transaction loss and fresh-identity duplicate intent.
|
||||
[Review and limits](../research/reviews/StorageReceiverRecovery.md).
|
||||
|
||||
This closes the concrete-pair mechanism investigation, not power-loss/device-loss
|
||||
recovery, Matrix-server behavior, arbitrary operation deduplication or full frontend
|
||||
recurrence. Existing T01 retains broader implementation evidence and T02/WP-0002
|
||||
T03 retain validated cases and human/AT evidence. No new task/workplan. T01 remains
|
||||
progress for its six-stream independent-use obligations; the workplan stays blocked
|
||||
because T02 still lacks M1 acceptance. Existing local navigation-fixture pause stands.
|
||||
|
||||
T01 local inventory repair: the pre-existing CAND-0018 addition lacked a
|
||||
ClassificationCoverage entry and caused classification-check to fail. Reviewed its
|
||||
composition responsibility, portability benefit and implementation/compatibility
|
||||
costs; added the mapping and regenerated the report. Runtime-carrier choice is not
|
||||
itself an execution-responsibility claim. Eighteen hypotheses now classify without
|
||||
changing candidate content or the frozen seventeen-record preview.
|
||||
|
|
|
|||
|
|
@ -4,11 +4,11 @@ type: workplan
|
|||
title: "Make ongoing language learning observable"
|
||||
domain: infotech
|
||||
repo: frontend-patterns
|
||||
status: active
|
||||
status: blocked
|
||||
owner: codex
|
||||
topic_slug: canon
|
||||
created: "2026-09-26"
|
||||
updated: "2026-09-27"
|
||||
updated: "2026-09-28"
|
||||
state_hub_workstream_id: "528d24c1-c2c4-5914-a065-992b0dd877c8"
|
||||
---
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ experiment receipts. Intent/protocol/program now describe continuous learning.
|
|||
|
||||
```task
|
||||
id: FEP-WP-0006-T03
|
||||
status: progress
|
||||
status: wait
|
||||
priority: medium
|
||||
state_hub_task_id: "2c5c4bae-a0a9-54bf-ac86-49b2803fdd8c"
|
||||
```
|
||||
|
|
@ -204,3 +204,17 @@ a third cycle there was considered and explicitly declined, per the existing agr
|
|||
pause and this task's own rule against forcing a count. A third comparable cycle in
|
||||
this or another group should only happen when a genuinely useful next question
|
||||
arises. No trend claim, no M1/M2/M3 closure.
|
||||
|
||||
## Loose-end review — 2026-09-28
|
||||
|
||||
T03 waits; workplan blocked on the comparable-evidence prerequisite. The largest
|
||||
prospective group still has only LEARN-0014/0017 (two cycles; 0017 effort unknown).
|
||||
LEARN-0018 completes WP-0003 T04's concrete storage/receiver experiment in a new
|
||||
runtime group; it cannot be pooled with those static-source inspections. Review-date
|
||||
reconciliation remains complete. No qualified three-cycle returns window exists.
|
||||
|
||||
This is an evidence dependency, not a credential or implementation blocker. Resume
|
||||
when useful research under existing WP-0003 T01 or consumer-led WP-0008 supplies a
|
||||
comparable window with honest effort accounting. Do not restart the paused navigation
|
||||
fixture or manufacture repeated studies merely to close T03. No new task/workplan;
|
||||
no diminishing-returns, independent-human or maturity claim.
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ lane: blue
|
|||
owner: codex
|
||||
topic_slug: canon
|
||||
created: "2026-09-27"
|
||||
updated: "2026-09-27"
|
||||
updated: "2026-09-28"
|
||||
state_hub_workstream_id: "9f719719-ed4e-5c57-a62f-855fe1876e17"
|
||||
---
|
||||
|
||||
|
|
@ -202,3 +202,17 @@ operational; their three schedules remain enabled. The first monthly packet rema
|
|||
due October 1; missing consumer/executor evidence must be reported as such. This audit
|
||||
does not disable schedules or conflate the reporting worker with mutation authority.
|
||||
Existing owner work records retain all dependencies; no replacement workplan is opened.
|
||||
|
||||
## Dependency and cadence recheck — 2026-09-28
|
||||
|
||||
T01/T02/T03 remain wait and workplan blocked. Consumer roster is still empty;
|
||||
ACTIVITY-WP-0041 T02/T03 and GLAS-WP-0012 remain blocked in their owner files.
|
||||
No real-use receipt, admitted executor or standing release authority is inferred.
|
||||
|
||||
The State Hub intake query before 09:00 UTC returned only September 27 smoke/manual
|
||||
receipts, latest `a552969b-59ac-4dc9-a4f8-b58856c129ab` at 14:07:04Z. It did not
|
||||
supply the expected September 28 00:00Z natural daily run. This is missing cadence
|
||||
evidence, not a diagnosed scheduler outage. T03 retains cadence/sink verification
|
||||
with activity-core; no schedule was changed and no new task or workplan opened.
|
||||
[Recheck evidence](../docs/evidence/2026-09-28-loop-recheck.json). October 1's
|
||||
monthly packet remains due even with no consumers or executor.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue