Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
- Status: Draft, under maintainer review
- Initially proposed by: NoKV Lab
- Widened by: LoopX maintainers
- Date: 2026-08-05; revised 2026-09-01
- Date: 2026-08-05; revised 2026-09-02
- Scope: one provider-neutral LoopX authority contract with built-in file,
optional NoKV, and optional PostgreSQL provider profiles, complementing
[`host-integration-surface-v0`](../../reference/protocols/host-integration-surface-v0.md)
- Source baseline: LoopX `a0c20f1779d273e7aaa4bd3ea166d145d466e6d5`
- Provider API baseline: NoKV `3d75d96965` (0.11.0 line). The Python
`publish_bytes` generation-CAS mapping was exercised once by hand against a
live NoKV stack at that pin (see the example README); the run is evidence for
the mapping only, not part of any merge gate
- Provider API baseline: NoKV `0f1995ebee96048e5d4f9d4745d84c3518c64351`
(release 0.11.0, Python API 1, Holt pinned to 0.8.6). The Stage 2A executable
qualification admits only that SDK contract and this checkout's helper. It
remains candidate evidence, not a merge gate or authority promotion
- PostgreSQL baseline: the TypeScript Stage 2B candidate implements the store
contract and has passed a real PostgreSQL 16 transaction matrix. No shared
authority service, runtime caller, authentication boundary, or authority
Expand Down Expand Up @@ -1078,6 +1078,33 @@ The sequence is:
cache, offline projection, and diagnostic material. Never keep a long-lived
dual-write or dual-master mode.

#### Stage 2C qualification slice: local post-commit shadow

The first half of Stage 2C is an explicit, default-off product path. Preview
and enable it with:

```bash
loopx configure-goal --goal-id GOAL --local-authority-shadow-file
loopx configure-goal --goal-id GOAL --local-authority-shadow-file --execute
```

Todo, handoff-mode, follow-up, and task-lease facades observe their committed
local result through `FileAuthorityStore`. Candidate bytes live under
`authority-shadow/file/` outside the legacy per-Goal runtime tree, so state
migration never copies a store identity or revision; an executed migration
seeds a new target lineage from the migrated local state. Candidate failure is
reported as evidence but never reverses the completed local write.

Disable the observer in one command with
`loopx configure-goal --goal-id GOAL --clear-local-authority-shadow --execute`.
This is rollback of observation only: the local Markdown and task-lease files
remain canonical throughout. The slice does not read the candidate for a
decision, fence a legacy writer, qualify a remote provider, or complete the
second Stage 2C promotion. A process crash after the local commit but before
the observer call may miss that individual observation; a later committed
write or migration seed refreshes the full current projection, but no durable
shadow outbox is claimed here.

### Implementation prerequisite: put local file mode behind the same coordination contract

Before wiring a live NoKV or another remote provider, the runtime should first
Expand Down Expand Up @@ -1428,6 +1455,20 @@ claim that the complete P0 acceptance gate above passes. Historical latency or
fault results are informative only; they are not a durability, recovery, HA,
or production qualification claim.

The additional TEST ONLY Stage 2A probe in
`examples/nokv-authority-store/` opens three independent SDK helper processes
and checks fresh create, exact generation update, a one-winner/two-contender
CAS, winner/loser receipt behavior, and fresh-process history readback. Its
executable fixes argv to one absolute Python executable plus this checkout's
production helper; the helper fails closed unless the SDK reports NoKV 0.11.0
and Python API 1, and validates every read/publish response against its requested
workbench, path, workspace incarnation, operation, revision, and generation.
Only a successful live JSON report is evidence for that single-node run;
deterministic tests are sequence tests only. This LoopX-only candidate changes
neither NoKV main nor its workbench/artifact data model or frozen-oracle-log use,
and it still does not prove HA, restart recovery, capacity, production routing,
or authority-source promotion.

## Appendix B: Handoff-Mode Decision Record (2026-08-10)

This appendix writes down a direction already agreed during the PR #2787
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
- 状态:Draft,正在接受 maintainer review
- 最初提案方:NoKV Lab
- 扩展修订方:LoopX maintainer
- 日期:2026-08-05;修订于 2026-09-01
- 日期:2026-08-05;修订于 2026-09-02
- 范围:一个 provider-neutral 的 LoopX 权威合同,支持内置 file、可选 NoKV
与可选 PostgreSQL provider profile,用来补充
[`host-integration-surface-v0`](../../reference/protocols/host-integration-surface-v0.md)
- 源码基线:LoopX `a0c20f1779d273e7aaa4bd3ea166d145d466e6d5`
- Provider API 基线:NoKV `3d75d96965`(0.11.0 线)。Python `publish_bytes`
generation-CAS 映射已在该基线的真实 NoKV stack 上手工跑过一次(见示例 README);
该次运行只是映射本身的证据,不属于任何合并门槛
- Provider API 基线:NoKV `0f1995ebee96048e5d4f9d4745d84c3518c64351`
(release 0.11.0、Python API 1、Holt 固定为 0.8.6)。Stage 2A 的可执行资格
验证只接受这份 SDK 合同与本 checkout 的 helper;它仍是候选证据,不是合并门槛
或 authority promotion
- PostgreSQL 基线:TypeScript Stage 2B candidate 已实现 store contract,且已通过
真实 PostgreSQL 16 transaction matrix;shared authority service、runtime caller、
authentication boundary 与 authority promotion 均尚未交付
Expand Down Expand Up @@ -865,6 +866,29 @@ Stage 3/4 qualification 必须保持以下 ownership 与 proof 边界:
LoopX service 成为唯一 writer。本地 `.loopx` 退为 cache、offline projection 与
诊断材料。绝不长期维持 dual-write 或 dual-master。

#### Stage 2C 资格验证切片:本地提交后 shadow

Stage 2C 的前半段是一个显式开启、默认关闭的产品路径。先预览,再开启:

```bash
loopx configure-goal --goal-id GOAL --local-authority-shadow-file
loopx configure-goal --goal-id GOAL --local-authority-shadow-file --execute
```

Todo、handoff-mode、follow-up 与 task-lease facade 会在本地主写成功后,通过
`FileAuthorityStore` 观察完整当前投影。候选数据位于 legacy 单 Goal runtime tree
之外的 `authority-shadow/file/`,因此 state migration 不会复制 store identity 或
revision;真正执行迁移时,会从迁移后的本地主状态为目标端建立一条新 lineage。
候选失败只形成 evidence,不会推翻已经完成的本地写入。

用
`loopx configure-goal --goal-id GOAL --clear-local-authority-shadow --execute`
即可关闭 observer。这里回退的只是观察路径:Markdown 与 task-lease 文件始终是
canonical。本切片不会读取候选来决策,不会 fence legacy writer,不会资格化远端
provider,也没有完成 Stage 2C 后半段的本地 canonical promotion。若进程恰好在本地
提交后、observer 调用前崩溃,该次 observation 可能丢失;后续成功写入或 migration
seed 会刷新完整当前投影,但这里不宣称已有 durable shadow outbox。

### 实施前置条件:先让本地文件模式经过同一协调合同

在接入 live NoKV 或其他远端 provider 之前,runtime 应先把当前 todo/lease 写路径中的
Expand Down Expand Up @@ -1145,6 +1169,17 @@ migration/promotion、service recovery 或 HA。
验收门通过。历史 latency 或 fault 结果只具有参考意义,不构成 durability、recovery、
HA 或 production qualification 声明。

`examples/nokv-authority-store/` 还包含一个 TEST ONLY 的 Stage 2A probe:它会
打开三个相互独立的 SDK helper 进程,验证 fresh create、精确 generation update、
两个竞争者恰一胜出的 CAS、胜负双方的 receipt 行为,以及新进程对完整 history 的
回读。该可执行入口把 argv 固定为一个绝对 Python executable 加本 checkout 的生产
helper;helper 只接受 NoKV 0.11.0 / Python API 1,并逐项核对 read/publish 回包与
请求的 workbench、path、workspace incarnation、operation、revision、generation
是否绑定。只有成功的 live JSON report 才是该次单节点运行的证据;确定性测试只证明
场景序列。这个纯 LoopX 候选既不修改 NoKV main,也不改变其 workbench/artifact
数据模型或 frozen-oracle-log 用途;它仍不证明 HA、重启恢复、容量、生产路由或
authority-source promotion。

## 附录 B:交接模式决策记录(2026-08-10)

本附录把 PR #2787 评审中已同意的方向落成文字,作为实施前置条件的一部分。
Expand Down
116 changes: 116 additions & 0 deletions examples/nokv-authority-store/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# NoKV authority-store live qualification (TEST ONLY)

This directory contains an explicit, write-producing qualification probe for
the candidate `NoKVAuthorityStore`. It is **TEST ONLY**. LoopX does not select
NoKV by importing this code, and a successful run does not flip the authority
source for any LoopX runtime.

The integration priority remains:

1. the native, full NoKV CLI as the primary operator and production surface;
2. the NoKV Python SDK as the secondary programmable surface; and
3. optional sidecars only as adapters around those surfaces, never as the main
authority API.

This probe intentionally exercises the current Python SDK bridge because it is
the available raw byte-CAS seam. It always starts this checkout's production
`NoKVJsonLinesTransport` and `nokv_jsonl_helper.py`; it has no fake, skip, or
"unverified but successful" CLI path. The helper admits exactly NoKV SDK
`0.11.0` / Python API `1`, and the successful report repeats both values.

## What it proves

Against one **already existing** NoKV workbench, the probe starts three
independent helper processes and verifies:

- the selected tenant/goal path is initially absent and can be created;
- the stored path generation advances from 1 to 2 under exact generation CAS;
- two writes released together against generation 2 produce exactly one
generation-3 winner and one typed conflict;
- the losing operation does not acquire a durable receipt; and
- a third, freshly opened transport reads the winning envelope, its complete
three-entry history, and the retained winner receipt.

If the SDK, helper, workbench, backend, CAS, or independent readback cannot be
proved, the process exits nonzero. The normal test suite uses deterministic
fakes only to test this sequence and does **not** count as live evidence.

The probe does not prove HA, failover, restart recovery, capacity, performance,
or a production authority migration. It also does not create a workbench. A
green single-node run is valid single-node storage evidence only.

## Inputs

Use a current NoKV Python environment. Keep the client configuration in an
ignored local file; do not commit credentials. Static routing is valid for a
single-node NoKV deployment—etcd is not required by this probe. The following
shape is illustrative:

```json
{
"root_id": "00000000000000000000000000000000",
"routing": {
"kind": "static",
"endpoint": "127.0.0.1:7412",
"logical_shard_id": "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
"object_namespace_id": "cccccccccccccccccccccccccccccccc",
"placement_generation": 1,
"owner_epoch": 1
},
"object_store": {
"kind": "s3",
"bucket": "qualification-bucket",
"region": "us-east-1",
"root": "/loopx-qualification",
"endpoint": "http://127.0.0.1:9000",
"access_key_id": "set-in-your-ignored-local-file",
"secret_access_key": "set-in-your-ignored-local-file",
"virtual_host_style": false,
"skip_signature": false
}
}
```

Configuration objects are exact-key contracts. An unknown top-level, routing,
or object-store key fails before an SDK routing config, object-store config, or
client is constructed. In particular, a misspelled explicit credential cannot
silently fall through to NoKV's ambient provider chain. Intentionally omitted
optional S3 credential fields retain the NoKV SDK's normal behavior.

Pass only the absolute path to the Python executable that resolves the qualified
NoKV SDK. The probe itself fixes the second and only other argv entry to the
production helper in this checkout; callers cannot supply a wrapper argument or
alternate helper path:

```text
/path/to/nokv-python-environment/bin/python
```

Choose a fresh tenant/goal pair for every run. The probe refuses to overwrite
an existing authority envelope and deliberately leaves its three-generation
test envelope behind for inspection. Use a disposable qualification namespace
or remove it later with the native NoKV CLI according to that environment's
retention policy.

## Run

From the LoopX repository root:

```bash
node --no-warnings --experimental-strip-types \
examples/nokv-authority-store/live-qualification.ts \
--execute-live \
--config-json /path/to/ignored/nokv-client.json \
--python-executable /path/to/nokv-python-environment/bin/python \
--tenant-id qualification-tenant-20260902 \
--goal-id qualification-goal-20260902-01 \
--workbench existing-qualification-workbench
```

`--execute-live` is mandatory and is checked before any helper starts. Exit 0
means every listed live check passed. Any unavailable, failed, ambiguous,
unfenced, pre-existing, or unreadable state exits nonzero with a compact JSON
reason; provider stderr, endpoints, credentials, and raw SDK errors are not
copied into that result. A successful JSON report includes
`"nokv_sdk_version":"0.11.0"` and `"nokv_api_version":1`; those fields are an
exact helper-admission claim, not an HA or production-readiness claim.
Loading
Loading