diff --git a/apps/presentation/site/public/blog/context-delivery/example.py b/apps/presentation/site/public/blog/context-delivery/example.py new file mode 100644 index 0000000000..f8bb013320 --- /dev/null +++ b/apps/presentation/site/public/blog/context-delivery/example.py @@ -0,0 +1,229 @@ +"""Reproduce a synthetic context-delivery lesson with the existing owners. + +Run with a LoopX source checkout's Python environment. This never registers a +Goal, admits/spends a Turn, contacts a model/provider or changes live state. +""" +import argparse +import copy +import hashlib +import json +import os +from pathlib import Path +import shlex +import subprocess +import sys + +p = argparse.ArgumentParser(description=__doc__) +p.add_argument('--loopx-root', type=Path, required=True) +p.add_argument('--output', type=Path, required=True, help='Empty directory for generated synthetic outputs.') +p.add_argument('--private-receipts', type=Path) +a = p.parse_args() +repo = a.loopx_root.resolve() +out = a.output.resolve() +if out.exists() and any(out.iterdir()): + p.error('Use an empty output directory; existing material will not be overwritten.') +out.mkdir(parents=True, exist_ok=True) +sys.path.insert(0, str(repo)) +from loopx.control_plane.quota.turn_envelope import prepare_context_delivery, restore_context_delivery +import loopx +assert Path(loopx.__file__).resolve().parent == repo / 'loopx' + +def raw(value): + return (json.dumps(value, ensure_ascii=False, separators=(',', ':')) + '\n').encode() + +def save(name, value): + content = raw(value) + (out / name).write_bytes(content) + return {'fixture': name, 'sha256': hashlib.sha256(content).hexdigest(), 'bytes': len(content)} + +goal = { + 'objective': '让管家理解语音消息,并在原对话返回结果 / Understand a voice note and reply in its original chat', + 'constraints': { + 'provider': '优先已有语音服务 / Prefer the already configured speech service', + 'privacy': '音频不能公开;外部处理仍需已有授权 / Do not publish audio; external processing still needs authorization', + }, + 'acceptance': '转写正确,结果回到原对话;服务不可用时明确告知 / Correct transcript and same-chat reply; state service unavailability explicitly', +} +providers = { + 'configured': {'formats': ['m4a', 'mp3'], 'authorization': 'must_check_current_grant'}, + 'alternative': {'formats': ['wav'], 'authorization': 'not_established'}, +} +evidence = { + 'sample-1': {'conditions': {'reply_chat': 'original-chat', 'format': 'm4a'}, 'result': '正确回到原对话 / Replied in the original chat'}, + 'sample-2': {'conditions': {'reply_chat': 'another-chat', 'format': 'm4a'}, 'result': '转写正确,但回复到了另一对话 / Correct transcript, wrong reply chat', 'reviewer': None}, +} +history = [ + {'entry': i, 'topic': ['formats', 'privacy', 'failure-recovery', 'same-chat-return'][i % 4], + 'discussion': f'教学历史记录 {i}。接入方案要分别检查输入格式、当前服务授权、原对话身份和结果来源。' + '转写文本正确并不足以通过验收,还需要返回同一条原始工作流。网络失败、响应丢失、格式不支持和用户撤回都保留为独立事实。' + '比较候选服务时,原目标、隐私约束和接受条件继续有效;引用资料可以深入读取,不能用一段新摘要替换原要求。' + '这是合成材料中的讨论,不记录任何真实用户、语音、账号、对话或服务调用。', + 'related_sample': 'sample-1' if i % 2 == 0 else 'sample-2'} + for i in range(80) +] +lesson = {'goal': goal, 'providers': providers, 'evidence': evidence, 'history': history} +captures = {'capture': save('capture.json', lesson)} + +env = {**os.environ, 'PYTHONPATH': str(repo), 'LOOPX_CONTEXT_DELIVERY': 'off'} +cli = [sys.executable, '-c', 'from loopx.cli import main; main()', '--format', 'json', 'quota', 'context-read'] +all_receipts = {} + +def read(label, capture, args): + """Count complete actual CLI responses, following its verified byte cursors.""" + pages, bodies, offset, selection_digest = [], [], 0, None + while True: + cmd = cli + ['--capture-file', capture['fixture'], '--capture-sha256', capture['sha256'], + '--offset', str(offset), '--page-bytes', '16000', '--max-page-output-bytes', '20000'] + args + if selection_digest: + cmd += ['--selection-sha256', selection_digest] + r = subprocess.run(cmd, cwd=out, env=env, capture_output=True) + page = json.loads(r.stdout) + pages.append({'exit_code': r.returncode, 'stdout': r.stdout.decode(), 'stderr': r.stderr.decode()}) + if not page.get('ok'): + assert 'content' not in page + all_receipts[label] = pages + return {'calls': len(pages), 'output_bytes': sum(len(x['stdout'].encode()) for x in pages), 'error': page} + assert page['sha256'] == capture['sha256'] and page['offset'] == offset + b = page['content'].encode() + bodies.append(b) + offset += len(b) + if 'selection_sha256' in page: + selection_digest = selection_digest or page['selection_sha256'] + assert selection_digest == page['selection_sha256'] + if page['eof']: + assert page['next_offset'] is None and offset == page['total_bytes'] + break + assert page['next_offset'] == offset and page.get('next_command') + joined = b''.join(bodies) + assert hashlib.sha256(joined).hexdigest() == (selection_digest or capture['sha256']) + all_receipts[label] = pages + return {'calls': len(pages), 'body_bytes': len(joined), + 'output_bytes': sum(len(x['stdout'].encode()) for x in pages), 'body': json.loads(joined)} + +paths = ['/goal/objective', '/goal/constraints', '/goal/acceptance'] +full = read('full', captures['capture'], []) +separate = [read('goal-' + str(i), captures['capture'], ['--select', path]) for i, path in enumerate(paths)] +batch = read('batch', captures['capture'], [arg for path in paths for arg in ['--select', path]]) +assert {s['pointer']: s['value'] for r in separate for s in r['body']['selections']} == {s['pointer']: s['value'] for s in batch['body']['selections']} +assert full['body'] == lesson +indexes = [read('index-' + pointer, captures['capture'], ['--select', pointer, '--list']) + for pointer in ['/providers', '/providers/configured', '/providers/alternative']] +deep_index = read('index-depth-2', captures['capture'], ['--select', '/providers', '--list', '--list-depth', '2']) +fields = lambda r: r['body']['selections'][0]['fields'] +assert {f['pointer'] for r in indexes for f in fields(r)} == {f['pointer'] for f in fields(deep_index)} +sample = read('sample-result', captures['capture'], ['--select', '/evidence/sample-2/result']) +conditions = read('sample-conditions', captures['capture'], ['--select', '/evidence/sample-1/conditions', '--select', '/evidence/sample-2/conditions']) +missing = read('missing', captures['capture'], ['--select', '/goal/objective', '--select', '/providers/missing']) +assert missing['error']['diagnostic_code'] == 'context_selection_missing_pointer' +null = read('null', captures['capture'], ['--select', '/evidence/sample-2/reviewer']) +assert null['body']['selections'][0]['value'] is None + +# Registered native acceptance shape: exercise the actual typed progressive owner. +clauses = [ + '优先复用已配置的语音服务;模型或工具配置不是一次外部发送授权。', + '原始音频不可公开;外部处理、受众与保存边界沿当前授权核验。', + '转写结果回到原对话,保留消息来源、顺序及原始音频引用。', + '明确支持的格式;不支持或过大的输入返回可理解的失败结果。', + '服务不可用和未获授权分别告知,不伪造已转写或已发送。', + '响应丢失后核对原请求结果,同一次输入不重复计费或回传。', + '取消与撤回保留真实边界,无法取消的外部操作不伪装已停止。', + '识别不确定时说明来源和不确定性;原始证据继续可查。', + '刷新和继续工作后仍保留全部原要求、当前状态及失败理由。', + '验收区分组件自测、实际原会话采用与独立核验,不从配置推断完成。', +] +requirements = [{'id': 'voice-' + str(i), 'description': c, 'status': 'unverified', 'planning_satisfied': False} + for i, c in enumerate(clauses)] +requirements[2]['agent_review'] = {'id': 'voice-2', 'conclusion': 'unmet', 'basis_current': False, + 'independently_verified': False, 'note': evidence['sample-2']['result'], 'evidence_refs': ['fixture:sample-2']} +outcome = {'id': 'voice-output', 'owner_agent_id': 'demo-agent', 'objective': goal['objective'], 'revision': 1, + 'requirements': requirements, 'todo_ids': ['todo_voice'], + 'sources': [{'ref': 'fixture:voice-brief', 'summary': json.dumps(history, ensure_ascii=False)}]} +row = {'schema_version': 'todo_item_v0', 'todo_id': 'todo_voice', 'text': '在原对话接入语音读取并核验完整返回。', + 'note': '\n'.join(clauses), 'content_revision': 'fixture:revision-1', 'claimed_by': 'demo-agent'} +native = {'ok': True, 'planning_horizon': {'core_goal': {'objective': goal['objective'], + 'acceptance_contract': {'outcome_requirements': {'schema_version': 'loopx_goal_outcomes_v0', 'outcomes': [outcome]}}}}, + 'agent_todo_summary': {'schema_version': 'todo_summary_v0', 'first_open_items': [row], 'backlog_items': [copy.deepcopy(row)]}, + 'work_state': {'phase': 'verify-original-chat', 'samples': ['sample-1', 'sample-2']}} +captures['original'] = save('projection.json', native) +scope = {'goal_id': 'voice-demo', 'agent_id': 'demo-agent', 'session_id': 'demo-session', 'context_epoch': 'epoch-1'} + +def project(payload, capture, capture_id, **kwargs): + return prepare_context_delivery(payload, scope=scope, capture_id=capture_id, surface='quota_packet', + native_projection={'path': capture['fixture'], 'sha256': capture['sha256'], + 'command_template': 'loopx --format json quota context-read --capture-file ' + capture['fixture'] + + ' --capture-sha256 ' + capture['sha256'] + " --select ''"}, **kwargs) + +cold = project(native, captures['original'], 'fixture-capture-1') +assert cold['projected'] is True +required = cold['context'] +captures['required'] = save('required-context.json', required) +current_outcome = required['planning_horizon']['core_goal']['acceptance_contract']['outcome_requirements']['outcomes'][0] +assert len(current_outcome['requirements']) == 10 and 'sources' not in current_outcome +assert all(x['description'] == y['description'] for x, y in zip(current_outcome['requirements'], requirements)) +review = current_outcome['requirements'][2]['agent_review'] +assert review == {'id': 'voice-2', 'conclusion': 'unmet', 'basis_current': False, 'independently_verified': False} +assert required['agent_todo_summary']['backlog_items'][0] == {'todo_id': 'todo_voice', 'context_ref': '/agent_todo_summary/first_open_items/0'} +parent = current_outcome['supporting_material_pointer'] +detail = read('native-reason', captures['original'], ['--select', parent + '/requirements/2/agent_review/note']) +assert detail['body']['selections'][0]['value'] == evidence['sample-2']['result'] + +changed = copy.deepcopy(native) +changed['work_state']['samples'].append('sample-3') +changed['work_state']['phase'] = 'verify-repaired-return' +changed['planning_horizon']['core_goal']['acceptance_contract']['outcome_requirements']['outcomes'][0]['requirements'][2]['agent_review']['basis_current'] = True +captures['original_next'] = save('projection-next.json', changed) +current_full = project(changed, captures['original_next'], 'fixture-capture-2') +warm = project(changed, captures['original_next'], 'fixture-capture-2', baseline=cold['delivery'], + continuity={'basis': 'captured_file', 'capture_bytes_verified': True, 'target': cold['delivery']['target']}) +assert warm['delivery']['mode'] == 'delta' +restored = restore_context_delivery(warm['delivery'], baseline=cold['delivery'], current=current_full['delivery']) +assert restored['context'] == current_full['context'] +save('cycle-base.json', cold['delivery']); save('cycle-delta.json', warm['delivery']) +new_epoch = prepare_context_delivery(current_full['context'], scope={**scope, 'context_epoch': 'epoch-2'}, + capture_id='fixture-capture-3', surface='quota_packet', baseline=cold['delivery'], + continuity={'basis': 'captured_file', 'capture_bytes_verified': True, 'target': cold['delivery']['target']}) +assert new_epoch['mode'] == 'full' +broken = copy.deepcopy(warm['delivery']); broken['changes'] = {'value': {'invented': True}} +recovery = restore_context_delivery(broken, baseline=cold['delivery'], current=current_full['delivery']) +assert recovery['mode'] == 'full' and recovery['context'] == current_full['context'] +tiny = {'ok': True, 'state': 'a'} +tiny_base = prepare_context_delivery(tiny, scope=scope, capture_id='tiny-1', surface='quota_packet') +tiny_next = prepare_context_delivery({'ok': True, 'state': 'b'}, scope=scope, capture_id='tiny-2', surface='quota_packet', + baseline=tiny_base, continuity={'basis':'captured_file', 'capture_bytes_verified': True, 'target': tiny_base['target']}) +assert tiny_next['mode'] == 'full' + +summary = lambda r: {k: r[k] for k in ['calls', 'body_bytes', 'output_bytes']} +rows = [ + {'case': 'complete_capture', **summary(full)}, + {'case': 'three_separate_selects', 'calls': sum(r['calls'] for r in separate), 'body_bytes': sum(r['body_bytes'] for r in separate), 'output_bytes': sum(r['output_bytes'] for r in separate)}, + {'case': 'one_batched_select', **summary(batch)}, + {'case': 'three_single_level_indexes', 'calls': sum(r['calls'] for r in indexes), 'body_bytes': sum(r['body_bytes'] for r in indexes), 'output_bytes': sum(r['output_bytes'] for r in indexes)}, + {'case': 'one_depth_two_index', **summary(deep_index)}, +] +measurements = {'fixture':'synthetic voice-assistant task, 80 history entries; no model/provider call', + 'source_revision': subprocess.check_output(['git','-C',str(repo),'rev-parse','HEAD'],text=True).strip(), + 'reader_page_bytes':16000,'reader_output_limit':20000,'reader_rows':rows, + 'output_bytes_include_cli_page_metadata':True,'page_envelope_size_can_vary_with_local_path':True, + 'native_projection':{'original_bytes':captures['original']['bytes'],'required_bytes':captures['required']['bytes'], + 'requirements_retained':10,'original_unchanged':hashlib.sha256((out/'projection.json').read_bytes()).hexdigest()==captures['original']['sha256'], + 'shared_row_before_bytes':len(raw(row)),'shared_row_reference_bytes':len(raw(required['agent_todo_summary']['backlog_items'][0]))}, + 'cycle_codec':{'current_full_bytes':len(raw(current_full['delivery'])),'delta_bytes':len(raw(warm['delivery'])), + 'same_epoch_mode':warm['delivery']['mode'],'new_epoch_mode':new_epoch['mode'], + 'damaged_delta_recovery':recovery['mode'],'tiny_mode':tiny_next['mode'],'reconstructed_exactly':True}, + 'not_measured':['model tokens','prompt cache effects','paid cost','long-horizon effectiveness','native host integration'], + 'live_goal_or_authority_state_changed':False} +save('measurements.json', measurements) +save('manifest.json', {**captures['capture'], 'captures':captures, 'boundary':'Synthetic teaching fixture. Source-based owner and real CLI reader exercised; no native host or model qualification.'}) +questions=[ + ('requirement',batch,{'zh':'先读齐目标、约束与验收','en':'Read the goal, constraints and acceptance together'},[arg for path in paths for arg in ['--select',path]]), + ('index',deep_index,{'zh':'一次看清服务目录的两层结构','en':'Inspect two levels of the provider directory'},['--select','/providers','--list','--list-depth','2']), + ('result',sample,{'zh':'转写正确,为什么仍没通过?','en':'The transcript is correct. Why did acceptance fail?'},['--select','/evidence/sample-2/result']), + ('conditions',conditions,{'zh':'并排读两次回传条件','en':'Read both return conditions side by side'},['--select','/evidence/sample-1/conditions','--select','/evidence/sample-2/conditions']), + ('missing',missing,{'zh':'路径不存在时,整个批次拒绝','en':'A missing path rejects the whole batch'},['--select','/goal/objective','--select','/providers/missing']), +] +save('display-cases.json',{'fixture':'capture.json','capture_sha256':captures['capture']['sha256'],'source':{'goal':goal,'providers':providers,'evidence':evidence,'history':'80 complete entries are retained in the downloadable capture.json'}, + 'source_preview_is_complete':False,'cases':[{'id':i,'body':r.get('body',r.get('error')),'questions':q,'args':args} for i,r,q,args in questions]}) +if a.private_receipts: + a.private_receipts.mkdir(parents=True,exist_ok=True) + (a.private_receipts/'reader-responses.json').write_text(json.dumps(all_receipts,ensure_ascii=False,indent=2)+'\n') +print(json.dumps(measurements,ensure_ascii=False)) diff --git a/apps/presentation/site/public/blog/context-delivery/index.html b/apps/presentation/site/public/blog/context-delivery/index.html new file mode 100644 index 0000000000..7f5396eb8b --- /dev/null +++ b/apps/presentation/site/public/blog/context-delivery/index.html @@ -0,0 +1,213 @@ + + + +An Agent needs a way to look things up, too · LoopX + + + + +
← All articles

Context delivery

An Agent needs a way to look things up, too

Follow one voice task through progressive reads, JSON Pointers, exact sharing, compaction-cycle deltas, and complete recovery.

+

Long-running work accumulates material: the original goal, later constraints, attempted routes, failed experiments and current progress. Sending everything again on each continuation repeats more and more content; keeping only a summary can make the original basis of a decision difficult to recover.

+

LoopX's context delivery separates these jobs: preserve complete sources, read the facts needed for the current decision, expand supporting material around questions, and reuse unchanged structures exactly within a valid compaction cycle.

+

This article checks the native Codex path at 73cf83ed, a 2.2 candidate source. Consult Releases for publication status. In that implementation, supported POSIX Codex App/SSH sessions and new benchmark heartbeat trials default to context delivery; saved off remains effective and explicit off is available. When enabled, complete content is saved first and the Agent receives an entrypoint for current facts.

+

Think of a capture as a complete book. An index locates its chapters; a JSON Pointer addresses a place inside it. Progressive reading determines how deeply to open the material now. Differential delivery determines what can be reused on the next continuation.

+

Follow one task: give an assistant voice input

+

Suppose an assistant needs to understand a voice note and reply in its original chat. Its complete material contains the goal, provider constraints, privacy requirements, acceptance and a long discussion of alternatives. This is a teaching example; the example program below generates the complete data in an isolated directory.

+
capture.json
+├── goal
+│   ├── objective: understand a voice note and reply in its original chat
+│   ├── constraints
+│   │   ├── provider: prefer the already configured speech service
+│   │   └── privacy: no public audio; external processing needs authorization
+│   └── acceptance: correct transcript, same-chat reply, explicit unavailability
+├── providers
+│   ├── configured
+│   │   ├── formats
+│   │   └── authorization
+│   └── alternative
+│       ├── formats
+│       └── authorization
+├── evidence: trial results, input formats and reply destinations
+└── history: 80 complete discussion entries
+
+

First, the Agent needs to understand the integration boundary. It must see both the preference for an existing service and the authorization requirement. A provider preference does not authorize sending audio. The historical discussions remain available when comparing alternatives or checking their basis.

+

Complete sources are assembled from existing typed owners, with Goal material, full tasks, cumulative acceptance and revisions. Marked generated regions are supplied by canonical tasks; other original narrative, comments and stops remain complete. Headings do not determine which prose may be deleted. This example places its current integration requirements in goal; any additional source-owned mandatory reads still apply.

+

The figures below are actual reader and codec measurements on this synthetic material. They make no model or speech-service calls. The example program generates the complete sources; the original measurement record preserves the reported figures.

+

When you know the locations, read them together

+

/goal/constraints is a JSON Pointer: enter goal from the JSON root, then constraints. It resembles a file path but addresses a value inside JSON.

+

The file, Pointer and digest answer different questions. capture.json identifies the complete file; the Pointer identifies a location; SHA-256 pins its version. /requirements/0 addresses the first array item. Reordering can change what that index addresses, so use a Pointer with its capture version.

+

After running the example, $CAPTURE denotes the output directory’s capture.json; $SHA comes from its manifest.json. Select the three known locations in one request:

+
loopx --format json quota context-read \
+  --capture-file "$CAPTURE" --capture-sha256 "$SHA" \
+  --select /goal/objective \
+  --select /goal/constraints \
+  --select /goal/acceptance
+
+

This retrieves the objective, complete constraints and acceptance together, including both provider preference and privacy. Repeated --select arguments combine the read request; each value retains its own Pointer.

+

The complete capture is 51,547 bytes. Using the same file, 16,000-byte pages and a 20,000-byte CLI output limit:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ReadCLI callsReturned bodyComplete CLI responses
Page through the complete capture451,547 B55,607 B
Select the three locations separately3804 B2,694 B
Select all three in one batch1674 B1,362 B
+

The last two rows retrieve identical Pointer/value pairs; repeated requests and framing account for the difference. The first also retrieves the complete history, so its information scope is larger. This table compares the step of reading those three facts now. Capture generation, storage and the initial reference are shared prerequisites.

+

When the structure is unfamiliar, index the relevant subtree

+

If the Agent does not know the provider record's fields, it can expand /providers locally. --list returns metadata: Pointers, types, sizes, and member counts for objects and arrays.

+
loopx --format json quota context-read \
+  --capture-file "$CAPTURE" --capture-sha256 "$SHA" \
+  --select /providers --list --list-depth 2
+
+

Depth two exposes the provider entries and their fields together:

+
/providers/configured                 object
+/providers/configured/formats         array
+/providers/configured/authorization   string
+/providers/alternative                object
+/providers/alternative/formats        array
+/providers/alternative/authorization  string
+
+

Next, batch the format and authorization fields. The index locates them; their values must actually be read before dependent decisions.

+

Listing /providers and each of its two children separately takes 3 calls and 2,784 bytes of CLI responses here. Depth two returns the same set of field addresses in 1 call and 1,283 bytes.

+

Read known addresses directly; index relevant structure when you need discovery. A small reference may already include the top-level index when it fits. Progressive reading follows the question rather than prescribing a fixed index–single-field–next-level sequence.

+

See requirements first, then open their evidence

+

A correct transcript alone does not establish successful integration. The result must return to the original chat.

+

The two example records say:

+
sample-1: correct transcript, returned to the original chat
+sample-2: correct transcript, replied in another chat
+
+

A summary saying “transcription succeeded” can hide the second failure. The implemented native acceptance projection preserves complete requirements and current review state so the Agent first sees the relevant fields:

+
{
+  "description": "Return the transcript to its original chat, preserving source, order and audio reference.",
+  "status": "unverified",
+  "agent_review": {
+    "conclusion": "unmet",
+    "basis_current": false,
+    "independently_verified": false
+  }
+}
+
+

Unmet acceptance and a stale basis stay in the decision layer. Follow the original-material entrypoint to inspect why it failed and which evidence supports the judgment. Agent review and independent verification remain separate facts.

+

The implementation returns supporting_material_pointer, locating the outcome in the original capture. Call that returned prefix $P: append /requirements/2/agent_review/note for the explanation, or /requirements/2/agent_review/evidence_refs for evidence references. Use this capture's prefix rather than copying an array position from another file.

+

After assembling the voice task into the existing typed acceptance structure, its complete original capture is 57,014 bytes and necessary view 5,107 bytes. All 10 requirement descriptions remain complete, together with unmet/stale/independent-verification facts. The original 57,014 bytes also remain intact. Supporting history and long explanations have exact expansion addresses.

+

Relationship navigation can suggest which outcomes to inspect first using task dependencies, shared acceptance, sources and evidence. Incomplete relationships widen scope, and contrary evidence from other routes stays accessible. Navigation helps order reading; the Agent still determines what affects this decision.

+

Share exact records within one delivery

+

A task can appear in both current work and a queue summary. Repeating an identical complete record adds no fact.

+

The native necessary view can retain one complete task and reference it elsewhere:

+
{
+  "todo_id": "todo_voice",
+  "context_ref": "/agent_todo_summary/first_open_items/0"
+}
+
+

The Pointer addresses the complete record in this same current view. Serialized separately with a trailing newline, the task record is 1,052 bytes, versus 80 bytes for its reference. Complete constraints remain at the original location, and every queue retains its membership and order.

+

This is exact sharing. Different revisions, owners, evidence or constraints remain separate even when titles match. Unknown fields and unsupported structures retain their original content. Response-local sharing needs no old session baseline; cross-Turn deltas are a separate mechanism.

+

On the next continuation, deliver what changed

+

The voice task progresses: a third sample is added, work moves from checking the original-chat return to checking a repaired return, and the review basis changes. The objective and most requirements remain unchanged.

+

This is where structured context deltas within a compaction cycle apply.

+

Within a valid cycle, a verified saved baseline supports exact reuse of unchanged text, arrays and objects. Additions, edits, removals and array reordering are explicit. A relocated subtree can reference its original position with current edits overlaid. Reconstruction must match the complete current source.

+
One valid cycle
+Previous: complete objective + all requirements + samples 1, 2 + old work state
+Current:  add sample 3; update work state and review basis
+Restore:  the complete current context
+
+

For the same synthetic task and scope, the codec produces:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ConditionResultSize or readback
Encode the complete current viewfull5,543 B
Reuse a verified baseline within the cycledelta2,164 B; exact value-by-value reconstruction
Change context epochfullNo reuse of the old cycle's baseline
Damage the deltaRecover current fullExact match with the complete current view
Change a tiny two-field inputfullKeep complete delivery when delta overhead is unsuitable
+

This table measures codec output. The native adapter also compares actual delivery bytes including references, page framing and reading instructions, selecting full when preferable. Size comparisons serve efficient delivery without replacing completeness.

+

When enabled, the default output is a reading entrypoint

+

Connect these operations back to the currently supported native Codex quota path:

+ +

The enabled delivery path

  1. Complete source: projection.json preserves current facts.
  2. Necessary view: required-context.json keeps complete requirements and points back to supporting originals.
  3. Cycle delivery: verify baseline and scope; choose full or delta.
  4. Current reader: first read admission, stops, the original task and accumulated requirements; include an index and short overview when they fit. Follow Pointers for supporting detail.
Saved files are verifiable sources. Model input still depends on the reads actually completed.
+

One useful property is that even with mode: "delta", the Agent can select facts directly through current recovery. It does not first need to read an old baseline or replay every delta. Delta's path may address delivery.json; recovery and select_command address the complete current view. context_details then connects supporting material to the original capture.

+

Native navigation also stores complete capture/selection digests in immutable private reader references. The Agent copies the returned reference; the CLI still verifies the complete digests, selection and cursor on every page. SHA256 itself is not shortened. A first_read_command starts a selection; it does not establish that all required sources were read.

+
# Copy the original recovery.reference_file from current returned navigation.
+loopx --format json quota context-read \
+  --reference-file "$RECOVERY_READER_REFERENCE" \
+  --select "$POINTER_A" --select "$POINTER_B"
+
+

A continuation reference pins its selection: follow its next_command to EOF and return to the original recovery reference to change Pointers. Very small budgets may retain the explicit file/digest interface. The teaching measurements above use that compatible interface and retain their original conditions.

+

Saved-file continuity and what the model currently retains are separate facts. Verifiable files do not establish that the model remembers every original passage.

+

Recover missing context while preserving the original work

+

After host compaction, a subsequent work Turn builds a new complete baseline. Original goals, requirements and sources remain available for necessary reads.

+

If compaction, missing pages or truncated output interrupt an unfinished Turn, recover missing facts from its original capture while retaining task, effect and settlement identity. If a voice result was already sent but its receipt was lost, recovering context must not become sending the result again.

+

Reading has explicit failure boundaries:

+
    +
  • Changed bytes with an unchanged digest: reject the read and verify the version.
  • +
  • A missing Pointer: reject the whole batch; index a known parent to recover. A present JSON null returns normally.
  • +
  • Paged content: follow next_command with capture digest, selection digest and byte cursor; combine contiguous content in order. Selection EOF covers only that selection.
  • +
  • Unknown or inapplicable structures: retain complete content and original read obligations rather than guessing which prose can be hidden.
  • +
+

Continuity and recovery

One valid cycle: complete baseline → changed facts and delta → exact reconstruction.

New cycle or known continuity loss: complete current source → read necessary facts again.

An unfinished Turn retains its original capture, work and settlement identity. Reading recovery does not repeat external effects.
+

What the measurements establish

+

The example separates three mechanisms: avoid repeatedly moving history not currently needed, combine reads that belong together, and avoid retransmitting unchanged verified structures. Complete sources, requirements and recovery connect them.

+

Reader figures include actual CLI page metadata; local path length affects a small amount of framing. Projection figures compare capture bodies; the cycle table compares codec output. The reproduction script checks these distinct measurements and exact reconstruction.

+

Real long-running tasks must also count necessary later reads, recovery, cache hits, model input/output, tool calls, waiting and human attention. Effectiveness depends on constraints understood, decisions made and accepted outcomes. This synthetic example measures the mechanical path; real model benefit still needs comparable-task evidence.

+

Implemented scope includes complete sources, file entrypoints, batch selection, index depth, applicable acceptance layering, exact sharing, cycle deltas and recovery. Broader decision-stage candidate, preference and Explore delivery and C1's universal input convergence remain unfinished. Supported Codex sessions default on without a saved preference. Disable in Settings → This machine → Capabilities → Differential context → Codex; saved off survives upgrade. A command or new benchmark trial can use --context-delivery off. Trials do not inherit the machine switch, and existing frozen trials are not rewritten. Saving settings, exact hook/configuration setup and actual adoption remain separate checks; unavailable hooks retain full delivery. Ordinary CLI, unsupported hosts and non-heartbeat benchmarks retain their existing full paths. Final 2.2 release qualification follows the exact release version.

+

Read the same material yourself

+

example.py generates this complete synthetic voice task and invokes the existing reader, progressive projection and delta owners. It checks selected values, directory addresses, all ten requirements, shared references and complete recovery. It registers no Goal, admits or settles no Turn, and calls no model or speech service.

+

Prepare the original measurement checkout, a4a0fad889d91cba0d945ce658788bdb76ba351e, and its compatible dependencies. Run from that checkout’s root, substituting the downloaded program path. The output directory must be empty.

+
uv run --extra test python /path/to/example.py \
+  --loopx-root "$PWD" --output .local/context-delivery-example
+
+

Generated capture.json retains all 80 history entries. projection.json and required-context.json hold the complete/necessary views; cycle-base.json and cycle-delta.json hold cycle encodings; manifest.json pins files and digests. Production reads use currently returned paths, never copied teaching fields or another capture’s array indexes.

+

The original measurement record pins this article’s figures. Running on other source can check its mechanisms but cannot rewrite the original observation. Local path length also affects page framing bytes. Understanding this example requires no new research run.

+

Sources: complete-delivery contract, progressive projection, selection/index, delta/recovery. The example ran on a4a0fad; those three core owners are byte-identical in 0e78a19. Native final delivery also accounts for references and later reads, beyond codec output.

+
+ diff --git a/apps/presentation/site/public/blog/context-delivery/measurements.json b/apps/presentation/site/public/blog/context-delivery/measurements.json new file mode 100644 index 0000000000..f60fefc92c --- /dev/null +++ b/apps/presentation/site/public/blog/context-delivery/measurements.json @@ -0,0 +1 @@ +{"fixture":"synthetic voice-assistant task, 80 history entries; no model/provider call","source_revision":"a4a0fad889d91cba0d945ce658788bdb76ba351e","reader_page_bytes":16000,"reader_output_limit":20000,"reader_rows":[{"case":"complete_capture","calls":4,"body_bytes":51547,"output_bytes":55607},{"case":"three_separate_selects","calls":3,"body_bytes":804,"output_bytes":2694},{"case":"one_batched_select","calls":1,"body_bytes":674,"output_bytes":1362},{"case":"three_single_level_indexes","calls":3,"body_bytes":776,"output_bytes":2784},{"case":"one_depth_two_index","calls":1,"body_bytes":574,"output_bytes":1283}],"output_bytes_include_cli_page_metadata":true,"page_envelope_size_can_vary_with_local_path":true,"native_projection":{"original_bytes":57014,"required_bytes":5107,"requirements_retained":10,"original_unchanged":true,"shared_row_before_bytes":1052,"shared_row_reference_bytes":80},"cycle_codec":{"current_full_bytes":5543,"delta_bytes":2164,"same_epoch_mode":"delta","new_epoch_mode":"full","damaged_delta_recovery":"full","tiny_mode":"full","reconstructed_exactly":true},"not_measured":["model tokens","prompt cache effects","paid cost","long-horizon effectiveness","native host integration"],"live_goal_or_authority_state_changed":false} diff --git a/apps/presentation/site/public/blog/edgebench-feedback-and-memory/index.html b/apps/presentation/site/public/blog/edgebench-feedback-and-memory/index.html index 779c14e98e..da79912e08 100644 --- a/apps/presentation/site/public/blog/edgebench-feedback-and-memory/index.html +++ b/apps/presentation/site/public/blog/edgebench-feedback-and-memory/index.html @@ -16,7 +16,7 @@
-

Ruiteng Huang · October 29, 2026

What does an agent achieve with ten more hours?

How EdgeBench reshaped the LoopX control plane

A research run can start ahead, then barely improve for ten hours. It can keep changing code and lose its best result. These failures made us revisit goals, feedback, experiment size and recovery.

The work began with trace diagnosis in early October: repair evaluation and continuation, follow evidence into the next experiment, then charge the control plane for its own cost. This account follows that progression, including results that challenged the approach.

+

Ruiteng Huang · October 29, 2026

What does an agent achieve with ten more hours?

How EdgeBench reshaped the LoopX control plane

A research run can start ahead, then barely improve for ten hours. It can keep changing code and lose its best result. These failures made us revisit goals, feedback, experiment size and recovery.

The work began with trace diagnosis in early October: repair evaluation and continuation, follow evidence into the next experiment, then charge the control plane for its own cost. This account follows that progression, including results that challenged the approach.

This article asks how mechanisms changed real research and where they did not help. For what actually reaches the next decision, begin with progressive and differential context delivery, then return to the outcomes and complete costs below.

Here, kernel means LoopX’s shared goal, admission, transaction and recovery rules. LoopX keeps the original goal, acceptance conditions, work ownership and evidence durable across sessions and hosts. Its control plane constrains state transitions and supplies feedback for the model’s next choice. It does not certify that the choice is insightful. A recorded finding, a read receipt and a replan entry are intermediate evidence; the relevant chain ends in actual work and a validated outcome.

The TypeScript refactor article explains ownership and model-assisted semantic repair. Below, we follow how these rules affect actual research work.

  1. GoalAcceptance and scope
  2. EvidenceResults and limitations
  3. DecisionContinue or change course
  4. WorkExecute and validate
  5. RetentionKeep the best valid result
@@ -75,7 +75,7 @@

Measure structural input separately

Earlier byte comparisons and a withdrawn measurement

Historical offline replay illustrates why totals matter: structured Host and native presentation bytes fell 57.72% and 60.23%, while native entry plus full recovery rose 6.37%. These are historical byte observations, not current-head model-token results. An earlier offline probe also reported a 2.25% increase in CLI bytes, but its qualification as an actual CLI delivery measurement was withdrawn: it omitted final CLI compaction and reformatted entry output. That figure remains only as an invalid historical measurement and supports no complete-delivery or cost conclusion. A 60% smaller view cannot be reported as 60% lower total cost.

-

Our current efficiency work connects ordinary and staged delivery to the shared transport, reduces repeated reads and rebinding, and removes avoidable settlement round trips. The default with differencing off matters as much as the opt-in path. Enabled delivery also has to recover correctly and remain easy to activate across the product and benchmark. The reference of 15% for all mechanisms combined remains unqualified; it is neither a separate allowance per mechanism nor a reason to omit failures or reconstruction.

+

This efficiency work connects ordinary and staged delivery to the shared transport, reduces repeated reads and rebinding, and removes avoidable settlement round trips. The complete mechanism and voice-task example explains progressive selection, necessary facts, exact sharing and cycle deltas. Actual enabled reads, the explicit-off path and recovery need separate checks; newer implementation cannot retroactively qualify historical experiments. The reference of 15% for all mechanisms combined remains unqualified; it is neither a separate allowance per mechanism nor a reason to omit failures or reconstruction.

Same-checkpoint continuation: outcomes and complete usage

Ask whether evidence changed the next work

A mature checkpoint helps inspect a specific decision boundary. Both receivers inherit the same scientific state and incumbent; we then follow the evidence they read, the experiment they choose, the work they actually perform and the native feedback. A negative local result can be useful if it rules out a branch under stated conditions. Replanning need not force a direction change when continuing is justified.

Recent work on #7269 makes the reader first consume the goal, facts and feedback, then the writeback format. It also releases obsolete task-selection preference and preserves the original Turn settlement after a successor is created. This addresses two observed sources of wasted interaction: reading writer instructions before deciding, and needing another round to resolve which work was settled.

@@ -110,6 +110,6 @@

Measure structural input separately

The context study recorded on October 28 starts Grid, Schema and Ad Placement from their original tasks with Sol/max and an 18-hour upper limit per case. Historical Official or older LoopX runs provide descriptive references where usable. Their model/effort, source, scorer, opportunity and clock differences remain visible; they are not strict matched controls. A new baseline is warranted where the old material cannot answer the relevant question. Attempts with different source versions, continuity bases or transports are analyzed separately, rather than pooled as one treatment.

First verify that actual delivery changes: the initial full read, a subsequent delta with its continuity basis stated, complete fallback after known baseline loss, and a full review-to-work interaction. Then compare useful progress, retained artifacts and the complete usage vector. Requested flags, receipts and smaller local packets cannot substitute for that evidence. If the feature fails its intended behavior, stop the affected attempt, preserve its costs and history, repair it and use a new attempt identity.

The first Grid and Ad interactions on the new native Hook path have completed full paging, one delta and subsequent task work. Within each same capture, the delta payload was 19.53% and 19.48% smaller than its corresponding full packet. These are single-read payload comparisons: they exclude page envelopes, subsequent model input, hooks, recovery and review costs. They do not establish lower total cost. A complete review-to-native-outcome cycle, sustained benefit and failure recovery remain to be verified.

Our effectiveness target is useful progress after many hours and reliable retention of it. Our efficiency target is comparable accepted value with less complete cost and human attention. The next result must address both. Current runs retain the original deadline, and failed or replaced attempts retain their costs and history.

-

Numerical evidence retains each stated historical model, version, window and validity boundary. Public implementation: LoopX. Earlier detailed research records remain in the previous article revision. Raw trajectories, hidden evaluator material, runtime credentials and private operating context are not published here.

+

This remains the October 28 research checkpoint. Later reader, default-policy or codec merges do not automatically pass its unresolved checks. The mechanism article’s synthetic byte measurements and this section’s model trajectories are different evidence layers, not a combined savings result.

Numerical evidence retains each stated historical model, version, window and validity boundary. Public implementation: LoopX. Earlier detailed research records remain in the previous article revision. Raw trajectories, hidden evaluator material, runtime credentials and private operating context are not published here.

diff --git a/apps/presentation/site/public/blog/index.html b/apps/presentation/site/public/blog/index.html index 8518f51e2a..94151f8d27 100644 --- a/apps/presentation/site/public/blog/index.html +++ b/apps/presentation/site/public/blog/index.html @@ -29,11 +29,15 @@ Blog Docs -
中文GitHub
+
中文GitHub

LoopX · Blog

Engineering the long run.

Design, engineering, and field notes on long-horizon agents.

- + +
+

Context delivery · Mechanisms and examples

+

An Agent needs a way to look things up, too

One voice task explains JSON Pointers, batched selection, index depth, complete requirements, exact sharing and compaction-cycle deltas. Synthetic byte measurements remain distinct from real model benefit.

Read article
+

Research notes · EdgeBench and LHTB

EdgeBench / LHTB: notes from historical runs

Exploratory notes by songoow on historical, partly interrupted EdgeBench/LHTB runs. The feedback-first option is withdrawn; these are not official LoopX results or current capability claims.

Read the article
@@ -47,8 +51,8 @@

Agentic Software: Infrastructure for Long-Horizon Development

Using LoopX to explore infrastructure for agentic software: preserve goals, evidence, and human feedback across sessions, and carry exploration into verifiable delivery.

Read article
-

Research notes · EdgeBench

-

Giving long-horizon agents a reason for their next step

Portfolio and Lean traces illuminate LoopX’s semantic control plane: trustworthy feedback, continuation, scoped evidence, progressive context and research choices. Validated repairs are distinct from unproven capability gains.

Read article
+

Research notes · EdgeBench

· Revised October 29

+

What does an agent achieve with ten more hours?

Follow the research from early to late October: reliable feedback, goals, experiment size and recovery, tested against Schema’s plateau and complete usage.

Read article

Design perspective · Self-improvement

diff --git a/apps/presentation/site/public/blog/typescript-control-plane-refactor/index.html b/apps/presentation/site/public/blog/typescript-control-plane-refactor/index.html index ad93fa784d..af65cd6eed 100644 --- a/apps/presentation/site/public/blog/typescript-control-plane-refactor/index.html +++ b/apps/presentation/site/public/blog/typescript-control-plane-refactor/index.html @@ -13,12 +13,31 @@
← All articles

LoopX 2.0 · Engineering

LoopX 2.0: Two Months of TypeScript Control-Plane Engineering

An effect succeeds without a checkpoint. An expired executor returns with a valid receipt. An evidence correction restarts finished work. Two months of refactoring brought these problems under complete transactions and shared semantics.

-
-

LoopX 2.0 is out. This is an account of the history and technical details behind its TypeScript refactor.

+
+

Retrying an operation can execute its effect twice. Reading back a success receipt can revive execution rights that have already expired. These boundaries between execution, storage and recovery are central to LoopX’s TypeScript refactor.

+

1. The semantic questions we put stronger models to work on

+

We use stronger models in design, implementation and review, especially to trace assumptions across files and runtimes. The difficult cases often combine individually reasonable checks into an unsafe execution order. Core PRs in August and September already dealt with these problems; they were part of the migration itself.

+

The effect happened, but its checkpoint did not. Is retry safe?

+

A provider succeeds, then the process crashes before writing the checkpoint. The journal says unfinished; a blind retry may execute twice. Treating every uncertain result as success would instead lose work that never happened. A try/catch cannot settle that distinction.

+

On August 22, #3485 introduced a durable prepared attempt and stable effect identity before execution. Recovery asks the provider: confirmed committed means checkpoint the original result; confirmed absent permits execution with the same identity; unknown remains pending recovery. Effect order, receipt prefixes and identity checks remain part of the contract. This is not arbitrary external exactly-once execution: confirming the result depends on provider recovery support.

+

This complements the preflight in #3464. Before execution, determine whether the effect is allowed; after interruption, determine whether it already happened. Moving Python functions to TS one at a time does not protect both boundaries.

+

On September 13, #4286 converged receipt recovery for seven Todo operations on one owner while retaining a finer distinction. Suppose two agents update a task: A commits first; B receives a definite version-conflict rejection, then loses its connection while reading the receipt. The later read failure must not erase the earlier rejection. If the connection drops before the commit response arrives, the result remains uncertain and recovery must use the original operation identity.

+

Both paths can encounter a network error, but they require different next steps. The shared implementation attempts the write once, then reads the original receipt. Its regressions distinguish conclusive rejection, commit uncertainty and exact-receipt recovery. Shared error handling must retain the phase of failure and facts already established.

+

Claiming work and acquiring execution rights must commit together

+

Two agents see an unclaimed task. If the claim is written before the lease is acquired, who owns the intermediate state? If an earlier claimant returns with a receipt after its lease expires, may it keep writing?

+

From the coordination foundations in #3529 and #3669 to the September 6 transaction in #4032, claim, lease and operation receipt converge on one conditional commit. The #3798 store owns atomic persistence; the domain owner checks identity, scope and legal transitions. A receipt proves a past claim succeeded. The current lease and epoch determine permission now. Replay must recover the original result without reviving expired execution rights. Storage revision, domain revision and lease epoch remain different identities.

+

Idempotency therefore requires more than returning an old success. Recovery must remember history and respect present authority. Foundation, shadow and production qualification arrived in stages; the first interface merge did not establish deployment of every backend.

+

Why could correcting evidence restart finished work?

+

A planning update corrects evidence without changing monitor state. Rebuilding the object from defaults can accidentally rearm an already satisfied monitor. Conversely, an explicitly empty list or false cannot be interpreted as an omitted input.

+

On September 10, #4178 converged planning updates on one authority snapshot and a complete TS transaction: omission retains intent, explicit clearing follows field and authority rules, and evidence correction does not rearm a satisfied monitor. It also removed Python’s serialize-to-Markdown-and-parse-back route. This repaired behavior as well as consolidating ownership; describing it as a mechanically equivalent language translation would miss the point.

+

Song’s #4433 and #4494 extended this discipline to vocabulary definitions, actual producers and consumers. A compiling enum does not establish that all callers mean the same thing. The skip / quota_skip example in the Semantics section and separation of action from decision belong to this same thread.

+

Making a plausible model answer face a counterexample

+

Ask for the mistaken assumption, then an execution sequence that refutes it: disconnect after commit, replay an expired lease, correct only evidence, explicitly clear a value. Check the real owner, provider and caller.

+

Stronger models help connect scattered conditions; counterexamples, real storage and refusal paths constrain their answers. There is no per-PR model comparison here, so these examples cannot quantify a particular model’s independent contribution. They show the mechanisms and reasons for changing them. Later runtime routing in #7145 and original-Turn closeout in #7269 continue this work rather than defining its whole history.

+

2. Reconstruct the history: the migration plan changed too

The formal migration RFC merged on August 15. By the concentrated retirement of ordinary legacy writers in mid-October, the program had spanned roughly two months. Several tracks overlapped: transaction ownership, caller integration, shared authority, storage and history costs, Semantics, compatibility, and retirement.

The final relay by three developers and their agents in #6396 depended on that earlier work. Earlier choices determined what could be deleted and what still had to recover afterward.

Our new maintainer, Song (@songoow), has also been advancing the Semantics RFC, vocabulary convergence, production evidence, and checker fixes since mid-September. That track belongs alongside the transaction and storage story.

-

1. Reconstruct the history: the migration plan changed too

LoopX retains goals, tasks, evidence, and execution boundaries for long-running agents. Models propose routes. The control plane protects versions, execution authority, and state commits, then finds a valid recovery position after interruption.

Much of the original implementation was Python. TypeScript hosts, Pi integration, and the dashboard already existed. A Python call to make a decision, followed by a TS host consuming the result, was a natural starting point. As the system grew, defaults, state interpretation, ordering, and persistence could become distributed across both runtimes.

We wanted clear typed ownership of control-plane rules and contracts shared by the CLI, hosts, and App. The history developed through overlapping stages.

@@ -74,158 +93,6 @@

1. Reconstruct the history: the migration plan changed too
Migration history: overlapping transaction, authority/storage, and Semantics tracks
Migration history: overlapping transaction, authority/storage, and Semantics tracks Scroll on narrow screens; open the image for full size.

The original August proposal considered a read-first sequence and staged dual reads and writes. The accepted approach evolved toward Effect Programs first, then replacing complete transactions and deleting the old rules, with one production semantic owner. An early proposal's staging ideas should not be presented as the runtime architecture of 2.0.

Plans can change usefully. The important record is why the route changed, which slices cut over, and which remained references or candidates. The maintained TS RFC retains those checkpoints.

-

2. Core control-plane statistics across the full period

-

The reproducible scope here is loopx/control_plane/**. App, benchmark, documentation, and test-suite directories outside it do not enter the core code counts. Internal testing/support tools inside this directory remain included.

-

The baseline is d1fe059, immediately before the formal TS RFC. The endpoint is the October 16 snapshot 488e443. The formal RFC to that endpoint spans roughly 62 days, covering 63 calendar dates; 62 of those dates contain a core mainline commit. The source comparison fixes both versions.

-

Engineering activity over the whole period

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MetricCore-directory cohort
Mainline landing commits touching the directory, first-parent chain1,144
Verifiably associated merged PRs, deduplicated by PR number1,121
PR-author accounts in that cohort56
Review records in the API snapshot2,329
Conversation comments in the API snapshot, excluding inline review comments1,631
Associated PRs with review records1,031 / 1,121
Median PR creation-to-merge elapsed time5.0 hours
P90 / P95 creation-to-merge elapsed time25.4 / 45.0 hours
-

The scope includes migration, new capabilities, fixes, and maintenance during the period. The 56 accounts include automation and shared accounts; they do not establish 56 people or agents. Review totals can include self-review, repeated reviews, and post-merge discussion. Merge elapsed time includes waiting and is not active engineering time.

-

New maintainer Song is associated with 53 PRs in this narrow directory cohort. His work in loopx/semantics/ and other directories is not fully counted here. Concrete attribution still follows the contribution explanations and original PRs.

-

Source structure and cumulative churn

-

Physical line counts include comments and blank lines. File counts below include source files in the named language.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
Core-directory sourceBaselineEvidence snapshotCumulative additions / deletions
Python256 files; 80,473 lines471 files; 142,371 lines+120,899 / −59,001 lines
TypeScript0 files; 0 lines323 files; 87,268 lines+104,769 / −17,501 lines
Python + TypeScript80,473 lines229,639 lines+225,668 / −76,502 lines
-

TS represents 38.0% of the endpoint's Python-plus-TS physical lines. That describes the directory's language structure. It does not establish that 38% of migration is complete: some old entrypoints were outside this directory, and the period includes code moving in, new capabilities, and testing support.

-
Python and TypeScript source stocks in the core control-plane directory
Python and TypeScript source stocks in the core control-plane directory Scroll on narrow screens; open the image for full size.
-

Cumulative churn sums each mainline landing diff, so repeatedly editing a line counts repeatedly. Endpoint stocks describe only the two snapshots. The cumulative net, endpoint diff, and source-stock change were reconciled by language. The roughly 302,000 line edits record engineering activity; they do not measure unique output, quality, or model productivity.

-

How the work continued over time

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Beijing dates, weekly bucketsCore mainline commitsAssociated merged PRsPR-author accounts that week
08-15—08-21524810
08-22—08-28878614
08-29—09-04616116
09-05—09-11929214
09-12—09-1813313314
09-19—09-2515014710
09-26—10-0216116117
10-03—10-0921621412
10-10—10-1619217914
-
Weekly associated merged PRs touching the core directory throughout the refactor period
Weekly associated merged PRs touching the core directory throughout the refactor period Scroll on narrow screens; open the image for full size.
-

The first and last weeks cover only time inside the selected endpoints. PRs use merge time; mainline commits use commit time. These can differ, so the two columns need not correspond one-for-one within a week.

-

By title prefix, the cohort contains 658 fix, 208 feat, 137 refactor, and 28 perf PRs. The rest include validation, documentation, and titles without those prefixes. These are title categories, not a partition of pure migration effort.

-
PR title categories in the same core-directory cohort
PR title categories in the same core-directory cohort Scroll on narrow screens; open the image for full size.
-

These numbers support explaining the mechanisms by stage. Moving a rule was followed by caller integration, semantic fixes, recovery validation, and retirement. The final #6396 is one concentrated slice within that process.

-

Reproduce the inventory

-

Public-safe PR records, core mainline commits, and metric JSON accompany the draft. The PR cohort joins mainline commits touching the directory to GitHub merge metadata, counting each PR once. Two mainline commits have no verifiable merged-PR association; their commits and churn remain included.

-

The research enumerated public PRs, then checked against mainline Git history. Direct reads supplemented 14 PR metadata records missed by search indexing. Source snapshots and processing scripts remain in the research materials. This inventory does not estimate tokens, model cost, CI compute, engineer-hours, or benchmark gains.

3. Start with the Effect Program: agree on what happened

The first bounded cutover was #3416 on August 21. TypeScript took ownership of the Effect Program, settlement algebra, Turn-journal interpretation, and a durable checkpoint effect.

These boundaries fit together because recovery asks one connected question: which effects belong to this operation, which have committed, and what may happen next?

@@ -324,26 +191,7 @@

Counterexamples for the checker itself

False alarms and missed values have different consequences. A conservative candidate set may report an extra problem. Missing a real produced value can let an unregistered output through. Unsupported dynamic forms must preserve an unknown.

The checks also need scan-coverage floors, so scanning fewer files cannot make the result green. Retiring an expanding committed inventory in favor of on-demand full-tree computation did not remove that obligation. Gaps outside supported forms remain explicit, and the tracking issue remains part of the work.

Generation and checking reduce synchronization mistakes. Their assumptions, coverage, and error direction still require review.

-

8. The semantic questions we put stronger models to work on

-

We use stronger models in design, implementation and review, especially to trace assumptions across files and runtimes. The difficult cases often combine individually reasonable checks into an unsafe execution order. Core PRs in August and September already dealt with these problems; they were part of the migration itself.

-

The effect happened, but its checkpoint did not. Is retry safe?

-

A provider succeeds, then the process crashes before writing the checkpoint. The journal says unfinished; a blind retry may execute twice. Treating every uncertain result as success would instead lose work that never happened. A try/catch cannot settle that distinction.

-

On August 22, #3485 introduced a durable prepared attempt and stable effect identity before execution. Recovery asks the provider: confirmed committed means checkpoint the original result; confirmed absent permits execution with the same identity; unknown remains pending recovery. Effect order, receipt prefixes and identity checks remain part of the contract. This is not arbitrary external exactly-once execution: confirming the result depends on provider recovery support.

-

This complements the preflight in #3464. Before execution, determine whether the effect is allowed; after interruption, determine whether it already happened. Moving Python functions to TS one at a time does not protect both boundaries.

-

On September 13, #4286 converged receipt recovery for seven Todo operations on one owner while retaining a finer distinction. Suppose two agents update a task: A commits first; B receives a definite version-conflict rejection, then loses its connection while reading the receipt. The later read failure must not erase the earlier rejection. If the connection drops before the commit response arrives, the result remains uncertain and recovery must use the original operation identity.

-

Both paths can encounter a network error, but they require different next steps. The shared implementation attempts the write once, then reads the original receipt. Its regressions distinguish conclusive rejection, commit uncertainty and exact-receipt recovery. Shared error handling must retain the phase of failure and facts already established.

-

Claiming work and acquiring execution rights must commit together

-

Two agents see an unclaimed task. If the claim is written before the lease is acquired, who owns the intermediate state? If an earlier claimant returns with a receipt after its lease expires, may it keep writing?

-

From the coordination foundations in #3529 and #3669 to the September 6 transaction in #4032, claim, lease and operation receipt converge on one conditional commit. The #3798 store owns atomic persistence; the domain owner checks identity, scope and legal transitions. A receipt proves a past claim succeeded. The current lease and epoch determine permission now. Replay must recover the original result without reviving expired execution rights. Storage revision, domain revision and lease epoch remain different identities.

-

Idempotency therefore requires more than returning an old success. Recovery must remember history and respect present authority. Foundation, shadow and production qualification arrived in stages; the first interface merge did not establish deployment of every backend.

-

Why could correcting evidence restart finished work?

-

A planning update corrects evidence without changing monitor state. Rebuilding the object from defaults can accidentally rearm an already satisfied monitor. Conversely, an explicitly empty list or false cannot be interpreted as an omitted input.

-

On September 10, #4178 converged planning updates on one authority snapshot and a complete TS transaction: omission retains intent, explicit clearing follows field and authority rules, and evidence correction does not rearm a satisfied monitor. It also removed Python’s serialize-to-Markdown-and-parse-back route. This repaired behavior as well as consolidating ownership; describing it as a mechanically equivalent language translation would miss the point.

-

Song’s #4433 and #4494 extended this discipline to vocabulary definitions, actual producers and consumers. A compiling enum does not establish that all callers mean the same thing. The earlier skip / quota_skip example and separation of action from decision belong to this same thread.

-

Making a plausible model answer face a counterexample

-

Ask for the mistaken assumption, then an execution sequence that refutes it: disconnect after commit, replay an expired lease, correct only evidence, explicitly clear a value. Check the real owner, provider and caller.

-

Stronger models help connect scattered conditions; counterexamples, real storage and refusal paths constrain their answers. There is no per-PR model comparison here, so these examples cannot quantify a particular model’s independent contribution. They show the mechanisms and reasons for changing them. Later runtime routing in #7145 and original-Turn closeout in #7269 continue this work rather than defining its whole history.

-

9. Callers and defaults determine whether migration reaches users

+

8. Callers and defaults determine whether migration reaches users

Complete transactions also need callers to express intent accurately. In #4178, a blank note means no update; an explicit empty list or false is interpreted by its field’s contract. These values cannot all be discarded as absent, or all treated as clearing. Dry-run must model that intent accurately. An unavailable selected provider must not trigger fallback elsewhere. #4279 later converged read classification and projection-delivery semantics. Some Python read ownership was deliberately retained. Clear ownership matters more than creating a second interpretation to pursue language purity.

Defaults expose similar distinctions. Current priority regressions protect these cases:

@@ -381,7 +229,7 @@

9. Callers and defaults determine whether migration reaches u

The File and SQLite regressions protect these cases. Applying new defaults after original-receipt recovery prevents an upgrade from making new decisions for history.

The closing review found another caller gap. The TS core passed direct tests for metadata-only completion repair. The normal Python producer automatically attached defaults such as completion policy and auto-acquire. The core interpreted them as fresh work mixed into a historical repair. The actual File and SQLite entrypoints failed in both dry-run and execution. The public counterexample records this.

That recovery gap also existed in the baseline, so it cannot all be attributed to the final contributor. The repair had to reach the normal producer while continuing to reject real changes to text, continuation, ownership, or validation. A correctly constructed typed request proves only that the inner boundary can handle it.

-

10. Recover the original result while protecting current authority

+

9. Recover the original result while protecting current authority

Recovery can confuse two points in time: whether the original operation was valid, and whether today's executor may continue changing state.

Suppose a team-plan committed but its response was lost. After an upgrade, the caller retries the same operation ID under stricter admission rules. Rejecting it as fresh work first can hide the original success. A closing recovery review caught that problem.

Separating original-receipt recovery from current execution authority
Separating original-receipt recovery from current execution authority Scroll on narrow screens; open the image for full size.
@@ -389,7 +237,7 @@

10. Recover the original result while protecting current auth

Returning the original result does not renew a lease, overwrite later commits, or revive a retired writer. Lease transfers, epoch changes, and subsequent state have their own protections.

Types express the distinction too. Historical decoding still recognizes legacy; current fresh-execution handoff configuration accepts soft_claim and hard_lease. Reading an old record, recovering an original operation, and authorizing current execution each have independent conditions.

An internal receipt also has a limited scope. If a remote external effect lacks a verifiable idempotent identity and readback, settling once in the control plane cannot establish that the remote effect executed exactly once. Uncertainty belongs at the boundary where it actually occurs.

-

11. CLI output budgets: protect decision semantics before compression

+

10. CLI output budgets: protect decision semantics before compression

CLI language participates in an agent's decisions. This engineering constraint predates the final writer retirement and remained a validation boundary during migration.

The interface budget contract examines:

    @@ -402,7 +250,7 @@

    11. CLI output budgets: protect decision semantics before co

    Natural language requires clause-level review: obligations, ordering, evidence provenance, authority qualifiers, scope, continuation, and stop conditions. Removing a phrase such as “only when the original proof is valid” can change behavior even when every field remains.

    One bounded example removed JSON indentation and separator whitespace. On the same historical fixture of 36 Todos and 12 runs, output fell from 48,418 to 39,726 characters, about 18%, with the complete decoded payload unchanged. This establishes a presentation-size change. Tokens, cost, and agent outcomes need separate measurements.

    The budget protects an interface the consumer can use. Valuable guidance may justify increasing it with matched evidence. Dropping decision conditions to make a size test green damages the interface.

    -

    12. Final retirement: preserve credit and account for the deletions

    +

    11. Final retirement: preserve credit and account for the deletions

    Late-September work had already removed an unused authority prototype and the experimental Todo event overlay, dual-writer, and backfill. Old sources containing data received explicit preservation or refusal handling. This did not remove all event logging or the new authority's atomic events and receipts.

    October work further isolated ordinary Markdown writers and validated real subsequent writes without the old modules. Concentrated deletion became possible after consumer routes and replacement paths were connected.

    Duang777 led #6396. Song and maintainer-side agents continued recovery, producer, and integration work along the original branch, preserving contribution history. This three-developer-and-agent relay was the closing phase of the two-month program.

    @@ -442,6 +290,158 @@

    12. Final retirement: preserve credit and account for the de

Many removed lines were old tests. Deleted test lines do not establish product capability; the important question is whether current entrypoints and independent counterexamples still protect the intended invariants. These counts describe the closing scope. They do not validate the whole migration.

+

12. Core control-plane statistics across the full period

+

The reproducible scope here is loopx/control_plane/**. App, benchmark, documentation, and test-suite directories outside it do not enter the core code counts. Internal testing/support tools inside this directory remain included.

+

The baseline is d1fe059, immediately before the formal TS RFC. The endpoint is the October 16 snapshot 488e443. The formal RFC to that endpoint spans roughly 62 days, covering 63 calendar dates; 62 of those dates contain a core mainline commit. The source comparison fixes both versions.

+

Engineering activity over the whole period

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MetricCore-directory cohort
Mainline landing commits touching the directory, first-parent chain1,144
Verifiably associated merged PRs, deduplicated by PR number1,121
PR-author accounts in that cohort56
Review records in the API snapshot2,329
Conversation comments in the API snapshot, excluding inline review comments1,631
Associated PRs with review records1,031 / 1,121
Median PR creation-to-merge elapsed time5.0 hours
P90 / P95 creation-to-merge elapsed time25.4 / 45.0 hours
+

The scope includes migration, new capabilities, fixes, and maintenance during the period. The 56 accounts include automation and shared accounts; they do not establish 56 people or agents. Review totals can include self-review, repeated reviews, and post-merge discussion. Merge elapsed time includes waiting and is not active engineering time.

+

New maintainer Song is associated with 53 PRs in this narrow directory cohort. His work in loopx/semantics/ and other directories is not fully counted here. Concrete attribution still follows the contribution explanations and original PRs.

+

Source structure and cumulative churn

+

Physical line counts include comments and blank lines. File counts below include source files in the named language.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
Core-directory sourceBaselineEvidence snapshotCumulative additions / deletions
Python256 files; 80,473 lines471 files; 142,371 lines+120,899 / −59,001 lines
TypeScript0 files; 0 lines323 files; 87,268 lines+104,769 / −17,501 lines
Python + TypeScript80,473 lines229,639 lines+225,668 / −76,502 lines
+

TS represents 38.0% of the endpoint's Python-plus-TS physical lines. That describes the directory's language structure. It does not establish that 38% of migration is complete: some old entrypoints were outside this directory, and the period includes code moving in, new capabilities, and testing support.

+
Python and TypeScript source stocks in the core control-plane directory
Python and TypeScript source stocks in the core control-plane directory Scroll on narrow screens; open the image for full size.
+

Cumulative churn sums each mainline landing diff, so repeatedly editing a line counts repeatedly. Endpoint stocks describe only the two snapshots. The cumulative net, endpoint diff, and source-stock change were reconciled by language. The roughly 302,000 line edits record engineering activity; they do not measure unique output, quality, or model productivity.

+

How the work continued over time

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Beijing dates, weekly bucketsCore mainline commitsAssociated merged PRsPR-author accounts that week
08-15—08-21524810
08-22—08-28878614
08-29—09-04616116
09-05—09-11929214
09-12—09-1813313314
09-19—09-2515014710
09-26—10-0216116117
10-03—10-0921621412
10-10—10-1619217914
+
Weekly associated merged PRs touching the core directory throughout the refactor period
Weekly associated merged PRs touching the core directory throughout the refactor period Scroll on narrow screens; open the image for full size.
+

The first and last weeks cover only time inside the selected endpoints. PRs use merge time; mainline commits use commit time. These can differ, so the two columns need not correspond one-for-one within a week.

+

By title prefix, the cohort contains 658 fix, 208 feat, 137 refactor, and 28 perf PRs. The rest include validation, documentation, and titles without those prefixes. These are title categories, not a partition of pure migration effort.

+
PR title categories in the same core-directory cohort
PR title categories in the same core-directory cohort Scroll on narrow screens; open the image for full size.
+

These numbers support explaining the mechanisms by stage. Moving a rule was followed by caller integration, semantic fixes, recovery validation, and retirement. The final #6396 is one concentrated slice within that process.

+

Reproduce the inventory

+

Public-safe PR records, core mainline commits, and metric JSON accompany the draft. The PR cohort joins mainline commits touching the directory to GitHub merge metadata, counting each PR once. Two mainline commits have no verifiable merged-PR association; their commits and churn remain included.

+

The research enumerated public PRs, then checked against mainline Git history. Direct reads supplemented 14 PR metadata records missed by search indexing. Source snapshots and processing scripts remain in the research materials. This inventory does not estimate tokens, model cost, CI compute, engineer-hours, or benchmark gains.

13. Community contributions and the next step

Multiple contributors advanced this program. Representative work is listed by its concrete boundary so readers can follow the history.

@@ -489,6 +489,6 @@

13. Community contributions and the next step

2.0 does not close every RFC goal. Retained Python transports and specialized providers have specific purposes. Broader native CLI coverage and sustained-operation qualification continue along their own validation paths. We also want capability and efficiency comparisons on harder general long-horizon benchmarks such as EdgeBench and LHTB, especially in a single session.

I hope this refactor leaves a system that is easier to change, validate, and revert—and a working practice that keeps responding to counterexamples.

- +
LoopX

Keep work moving. Keep people in control.

↑
diff --git a/apps/presentation/site/public/blog/zh/context-delivery/index.html b/apps/presentation/site/public/blog/zh/context-delivery/index.html new file mode 100644 index 0000000000..df2abac8a4 --- /dev/null +++ b/apps/presentation/site/public/blog/zh/context-delivery/index.html @@ -0,0 +1,213 @@ + + + +Agent 读上下文,也需要一套“查书”的方法 · LoopX + + + + +
← 全部文章

Context delivery

Agent 读上下文,也需要一套“查书”的方法

从一个语音任务理解渐进式读取、JSON Pointer、精确共享、compaction 周期内的结构化差分,以及失效后的完整恢复。

+

Agent 做长任务,资料会越来越多:原目标、后来追加的约束、试过的方案、失败的实验、当前做到哪里。每次继续都把整份材料再塞一遍,重复会不断累积;只留一段摘要,又可能找不回决定所依赖的原话。

+

LoopX 的 context delivery 把这件事拆开做:完整资料保存下来,当前决定需要的事实先读,支持材料沿问题展开;同一个有效 compaction 周期内,再精确复用没有变化的结构。

+

本文核对源码 73cf83ed 的 Codex 原生路径;它是 2.2 候选源码,最终发布状态以 Releases 为准。该实现的默认策略是:受支持的 POSIX Codex App/SSH 会话与新的 benchmark heartbeat 开启 context delivery;已有关闭设置继续生效,也可以显式关闭。开启后完整内容先保存,Agent 收到当前读取入口。

+

可以把它想成查一本厚书:capture 是完整保存的那本书,目录告诉我们章节在哪,JSON Pointer 是书内地址。渐进式读取决定这一刻翻到多深;差分决定下一轮哪些内容可以沿用。

+

用“管家读语音”串起一次工作

+

假设要让管家理解语音消息,并在原对话返回结果。完整资料里保留了目标、服务约束、隐私要求、验收,以及很长的方案讨论。下面是教学示意,后文的示例程序会生成完整数据,可在隔离目录复现。

+
capture.json
+├── goal
+│   ├── objective:理解语音,并在原对话返回结果
+│   ├── constraints
+│   │   ├── provider:优先已有语音服务
+│   │   └── privacy:音频不能公开,外部处理仍需已有授权
+│   └── acceptance:转写正确、回到原对话、不可用时明确告知
+├── providers
+│   ├── configured
+│   │   ├── formats
+│   │   └── authorization
+│   └── alternative
+│       ├── formats
+│       └── authorization
+├── evidence:试验结果、输入格式、回传位置
+└── history:80 条完整历史讨论
+
+

Agent 此时先要弄清接入边界。它必须同时知道“优先已有服务”和“外部处理仍需授权”;服务偏好本身并不授权发送音频。历史讨论仍然保存着,可以在比较方案、核对依据时继续读。

+

完整来源从已有 typed owner 装配,带着 Goal、完整任务、累计验收和来源修订。已标记的机器生成区域由 canonical 任务接续,其余原叙事、注释和停止条件完整保留,不能按标题猜哪些文字可以删。这个例子将当前接入边界完整放在 goal;来源另有必读要求时,仍按它的读取约定执行。

+

为了把机制讲具体,下面的数据来自这份合成材料上的实际 reader/编码器测量。它没有调用模型或语音服务。文末提供生成完整案例的程序和原测量记录。

+

知道位置,直接一次读齐

+

/goal/constraints 是 JSON Pointer:从 JSON 根进入 goal,再进入 constraints。它类似文件路径,但定位的是 JSON 内部的值。

+

文件名、Pointer 和摘要各管一件事:capture.json 找到完整文件,Pointer 找到里面的位置,SHA-256 确认是哪一版。数组的 /requirements/0 表示第 1 项;数组重排后,同一位置可能变成另一项,所以地址必须和捕获版本一起使用。

+

运行文末的示例程序后,$CAPTURE 指向输出目录的 capture.json,$SHA 取自同目录的 manifest.json。一次选择三个已知位置:

+
loopx --format json quota context-read \
+  --capture-file "$CAPTURE" --capture-sha256 "$SHA" \
+  --select /goal/objective \
+  --select /goal/constraints \
+  --select /goal/acceptance
+
+

一次拿到目标、完整约束和验收,就能同时看到服务偏好与隐私边界。多次 --select 合并的是读取请求;三个值仍分别带着自己的 Pointer,便于核对出处。

+

这份完整 capture 为 51,547 字节。在相同文件、每页 16,000 字节、CLI 输出上限 20,000 字节的设置下:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
读取方式CLI 调用次数返回正文CLI 完整返回
分页读完整 capture451,547 B55,607 B
三个位置分别读取3804 B2,694 B
三个位置一次批量读取1674 B1,362 B
+

后两行取到的 Pointer/值完全相同,差别在重复请求和响应封装。第一行还读出了全部历史,信息范围更大。这里比较的是“当前先读三处事实”这一步;完整 capture 的生成、保存与首次引用是共同前置成本。

+

不知道结构,查相关目录,再往下读

+

如果 Agent 不知道服务记录里有哪些字段,可以只展开 /providers。--list 返回目录元数据:Pointer、类型、大小,以及对象或数组的成员数量。

+
loopx --format json quota context-read \
+  --capture-file "$CAPTURE" --capture-sha256 "$SHA" \
+  --select /providers --list --list-depth 2
+
+

--list-depth 2 一次看到服务项和它们下面的字段:

+
/providers/configured                 object
+/providers/configured/formats         array
+/providers/configured/authorization   string
+/providers/alternative                object
+/providers/alternative/formats        array
+/providers/alternative/authorization  string
+
+

随后可以批量读格式和授权状态。目录告诉 Agent 去哪里找;值要通过 --select 真正读到,才能支撑后续决定。

+

同一份目录,本例逐层列出 /providers 和它的两个服务子树,需要 3 次调用、2,784 字节 CLI 返回;两层一次展开,得到相同的一组字段地址,需要 1 次调用、1,283 字节返回。

+

知道地址就直接读,不知道才查相关目录。 小引用能放下时已经附有顶层目录,也不需要再从头查一遍。渐进式读取围绕当前问题展开,并不固定要求“先目录、再单字段、再下一层”的调用顺序。

+

要求先看见,证明它的材料再展开

+

“接入成功”不只意味着转写文本正确。这个任务还要求结果回到原对话。

+

示例里的两次记录是:

+
sample-1:转写正确,回到了原对话
+sample-2:转写正确,却回复到了另一对话
+
+

验收时,如果只看“转写成功”的摘要,就可能放过第二个问题。LoopX 已实现的原生验收分层会保留完整要求和当前评审状态,让 Agent 先看到关键字段:

+
{
+  "description": "转写结果回到原对话,保留消息来源、顺序及原始音频引用。",
+  "status": "unverified",
+  "agent_review": {
+    "conclusion": "unmet",
+    "basis_current": false,
+    "independently_verified": false
+  }
+}
+
+

要求没有通过、已有依据过期,这些事实先出现在决策层。为什么失败、哪些证据支持这个判断,再沿原文入口读深。Agent 自评与独立核验也保留为不同事实。

+

实际实现中的 supporting_material_pointer 给出原始 outcome 的位置。假设把这个返回前缀记为 $P,需要评审解释时,就沿它接上 /requirements/2/agent_review/note;需要证据引用时,接上 /requirements/2/agent_review/evidence_refs。前缀来自当前捕获,不能照抄另一份文件的数组序号。

+

本例将语音任务装配成现有 typed owner 支持的验收结构后,完整原始捕获是 57,014 字节,必要视图为 5,107 字节。10 条要求的原文全部保留,未通过、依据过期和独立核验标记仍在;原始 57,014 字节也完整保存。 支持历史与长解释有了可展开的地址。

+

关系导航还可以沿任务依赖、共享验收、来源和证据,建议先看哪些 outcome。关系不完整时扩大范围;其他路线的反证仍然可达。它帮助安排阅读顺序,最终哪些事实影响当前判断,仍需要 Agent 理解。

+

同一份交付里的相同记录,保留一个完整位置

+

同一个任务可能同时出现在“当前工作”和“队列摘要”里。完全相同的正文重复两遍,并没有增加事实。

+

原生必要视图可以保留一份完整任务,让另一处准确引用它:

+
{
+  "todo_id": "todo_voice",
+  "context_ref": "/agent_todo_summary/first_open_items/0"
+}
+
+

这条引用指向同一份当前视图中的完整记录。本例将任务记录与引用各自单独序列化(含结尾换行),分别为 1,052 字节和 80 字节;完整约束仍在原位置,每个队列的成员和顺序也保留。

+

这是精确共享。标题相同、版本不同,或者 owner、证据、约束不同的记录,要继续分别保留。陌生字段和不支持的结构也保留原内容。这样的共享不依赖旧会话基线,和下一节跨轮次的差分是两件事。

+

下一轮继续,交付这次改变了什么

+

现在语音任务继续推进:新增了第三个样本,工作从“核验原对话返回”进入“核验修复后的返回”,评审依据也更新了。原目标和大部分要求没有变化。

+

这时可以做 compaction 周期内的结构化上下文差分。

+

在同一有效周期内,保存的完整基线经过核验,不变的文字、数组和对象可以精确复用;新增、修改、删除与数组重排则明确表示。对象换了位置时,也可以引用原子树,再叠加这次修改。还原后必须与完整当前来源一致。

+
同一周期
+上一份:完整目标 + 全部要求 + 样本 1、2 + 旧工作状态
+这一份:新增样本 3;更新工作状态与评审依据
+还原后:仍是完整的当前上下文
+
+

同一合成任务、同一 scope 下,本例编码层得到:

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
情况编码结果大小或读回结果
当前视图完整编码full5,543 B
有效周期内复用已核验基线delta2,164 B;完整还原逐值一致
切换 context epochfull不沿用旧周期基线
差分内容损坏恢复当前 full与完整当前视图逐值一致
很小的两字段输入发生变化full差分开销不合适,保留完整交付
+

这张表测的是编码结果。原生适配层还会比较文件引用、分页封装和读取指令等实际交付字节;完整交付更合适时使用 full。大小比较服务于交付效率,不能替代事实完整性。

+

开启后,默认交付的是一个读取入口

+

把前面的动作接回产品,当前支持的 Codex 原生 quota 路径是:

+ +

Context delivery 开启后的路径

  1. 完整来源:projection.json 保存当前事实。
  2. 必要视图:required-context.json 保留完整要求,支持材料指回原文。
  3. 周期交付:核对基线与 scope,选择 full 或 delta。
  4. 当前读取入口:首读当前准入、停止条件、原任务与累计要求;目录和短概览在放得下时附上。需要解释时,沿 Pointer 展开。
文件是可核验的来源;进入模型的内容,还取决于实际完成了哪些读取。
+

这里有一个很有用的设计:即使返回 mode: "delta",Agent 也能从当前 recovery 直接选读事实。 它不必为了开始判断,先通读旧基线或重放全部差分。差分的 path 可以指向 delivery.json,而 recovery、select_command 指向当前完整视图;context_details 再把支持材料接回原始捕获。

+

原生导航还把完整 capture/selection 摘要保存在不可变的私有 reader 引用中。Agent 复制返回的引用读内容,CLI 仍在每页校验完整摘要、选择与游标;并没有把 SHA256 截短。first_read_command 是起始选读,不代表全部必读来源已经读完。

+
# 从当前返回的 recovery.reference_file 复制原 recovery 引用。
+loopx --format json quota context-read \
+  --reference-file "$RECOVERY_READER_REFERENCE" \
+  --select "$POINTER_A" --select "$POINTER_B"
+
+

续页引用固定当前选择,沿它返回的 next_command 读至 EOF;更换 Pointer 时,回到原 recovery 引用。极小预算可能保留原显式文件/摘要接口。上面的教学测量也使用这个兼容接口,数字仍对应原实验条件。

+

文件基线和模型此刻保留了什么,需要分别判断。保存文件可核验,不能据此假定模型记住了全部原文。

+

压缩或读取失败,恢复上下文,也保留原工作

+

宿主发生 compaction,后续新工作轮次建立新的完整基线。原目标、要求和来源仍然存在,必要事实可以重新读到。

+

如果压缩、缺页或输出截断发生在尚未结束的 Turn 内,就沿原捕获补回缺失事实,保留原任务、执行和结算身份。假设语音结果已经发送,只是回执没有读到,恢复上下文不能变成再发一次结果。

+

读取本身也有明确的失败边界:

+
    +
  • 来源变了,摘要没变: 拒绝这次读取,先核对版本。
  • +
  • 路径不存在: 整个批次拒绝;先从已知父节点查目录。存在但值为 null,则正常返回 null。
  • +
  • 长内容跨页: 按 next_command 接读,保留捕获摘要、选择摘要和字节游标,按连续偏移组合正文。某组选读的 EOF 只覆盖该选择。
  • +
  • 遇到未知结构或不适用的来源: 保留完整内容及原有读取义务,不猜哪些文字可以隐藏。
  • +
+

连续性与恢复

同一有效周期:完整基线 → 新事实与差分 → 完整还原。

新周期或已知连续性丢失:当前完整来源 → 必要事实重新读取。

未结束的 Turn 保留原捕获、原工作与结算身份。恢复读取不重新执行外部副作用。
+

这些数据说明了什么

+

这组例子把三个收益来源分开了:少重复搬当前用不上的历史,少发本可合并的读取请求,少重复交付已经核验的不变结构。 完整来源、要求与恢复路径贯穿其中。

+

上面的 reader 数字包含实际 CLI 响应中的分页元数据;本机路径长度会影响少量封装字节。原生投影数字比较捕获正文,周期表比较编码层,三种口径分别列出。示例脚本可复算这些值与完整还原结果。

+

放回真实长程任务,还要把必要补读、恢复、缓存命中、模型输入输出、工具调用、等待与人工介入一起算进去;效果则看是否漏掉约束、做错决定,最后交付了什么。这个合成例子测清了机械路径,真实模型收益仍需可比任务验证。

+

当前实现已覆盖完整来源、文件入口、批量选择、目录深度、适用验收分层、精确共享、周期差分与恢复。更广的候选、偏好、Explore 按决策阶段统一交付及 C1 全入口收敛仍有未完成部分。受支持的 Codex 会话未保存偏好时默认开启;在「设置 → 本机 → 能力 → 差分上下文 → Codex」关闭,已有 off 会保留。单次命令或新 benchmark trial 可用 --context-delivery off;trial 不继承本机开关,已有冻结 trial 也不被重写。设置、准确 hooks/配置、实际采用分别核验;hooks 不可用时完整交付。普通 CLI、不支持的宿主和非 heartbeat benchmark 保留原完整路径。具体 2.2 发布资格沿最终版本确认。

+

用同一份材料动手读一遍

+

example.py 完整生成这个合成语音任务,调用现有 reader、渐进投影与差分 owner,逐项核对选择值、目录地址、全部 10 条要求、共享引用与完整恢复。程序不注册 Goal,不做准入或结算,也不调用模型或语音服务。

+

先准备原测量的源码 a4a0fad889d91cba0d945ce658788bdb76ba351e 及其兼容依赖,在该 checkout 根目录运行。将下载的程序路径填入下方;输出目录必须为空。

+
uv run --extra test python /path/to/example.py \
+  --loopx-root "$PWD" --output .local/context-delivery-example
+
+

生成的 capture.json 保留全部 80 条历史;projection.json、required-context.json 对应完整/必要视图;cycle-base.json、cycle-delta.json 对应周期编码;manifest.json 固定文件与摘要。生产中使用当前返回的真实路径,不能照抄教学树或另一份捕获的数组位置。

+

原测量记录固定本文数据。程序在其他源码上可以检查机制,但新结果不能改写原观察;页面封装字节还受本机路径长度影响。无需启动一次新研究来理解这个例子。

+

来源:完整交付契约 · 渐进投影 · 选择与目录 · 差分与恢复。例子运行源为 a4a0fad;上述三项核心 owner 与 0e78a19 逐字一致。原生最终交付还会核算引用和后续读取,不能由编码层数字替代。

+
+
LoopX

让工作持续推进,让判断由人掌握。

↑
diff --git a/apps/presentation/site/public/blog/zh/edgebench-feedback-and-memory/index.html b/apps/presentation/site/public/blog/zh/edgebench-feedback-and-memory/index.html index b939f4df97..88961448c7 100644 --- a/apps/presentation/site/public/blog/zh/edgebench-feedback-and-memory/index.html +++ b/apps/presentation/site/public/blog/zh/edgebench-feedback-and-memory/index.html @@ -16,7 +16,7 @@
-

黄睿腾 · 2026 年 10 月 29 日

让 Agent 多做十小时,究竟多做出了什么?

EdgeBench 如何反过来改造 LoopX 的长程控制面

一项研究可以起步更好,却在接下来的十小时里几乎没有增长。也可以不断改代码,最后丢掉最好结果。我们用这两种失败,重新审视目标、反馈、实验步长与恢复。

这条研究从 10 月初的轨迹诊断开始,先修评测与续跑,再追踪证据怎样进入下一次实验,最后把控制面自己的成本算进来。下面按这个过程展开:哪些机制改了,哪些结果支持它,哪些结果迫使我们改方向。

+

黄睿腾 · 2026 年 10 月 29 日

让 Agent 多做十小时,究竟多做出了什么?

EdgeBench 如何反过来改造 LoopX 的长程控制面

一项研究可以起步更好,却在接下来的十小时里几乎没有增长。也可以不断改代码,最后丢掉最好结果。我们用这两种失败,重新审视目标、反馈、实验步长与恢复。

这条研究从 10 月初的轨迹诊断开始,先修评测与续跑,再追踪证据怎样进入下一次实验,最后把控制面自己的成本算进来。下面按这个过程展开:哪些机制改了,哪些结果支持它,哪些结果迫使我们改方向。

本文回答机制怎样改变真实研究,以及还没有改善什么。若想先看“下一次决定到底读到了什么”,可从上下文的渐进与差分交付开始,再回到下文的成果与完整成本。

这里的 kernel 指 LoopX 共享的目标、准入、事务和恢复规则。LoopX 让原始目标、验收条件、工作归属和证据跨会话、跨宿主持久化。控制面约束状态转换,为模型的下一步提供反馈,但不能认证这个选择是否高明。一条发现、一次读取回执、一条 replan 记录都只是中间证据;真正需要追踪的链条,要落到实际工作和经过验证的成果。

这些规则的归属和强模型参与的语义修复,见 TypeScript 重构一文。下面从研究过程检查这些规则怎样影响实际工作。

  1. 目标验收与范围
  2. 证据结果与限制
  3. 决策继续或换方向
  4. 工作执行与验证
  5. 保留保住最佳有效成果
@@ -75,7 +75,7 @@

把结构输入单独计量

较早的字节对照与撤回的测量

历史离线回放说明了为什么必须算总量:结构化 Host 和原生呈现字节下降 57.72%、60.23%,原生入口加完整恢复上升 6.37%。这些是历史字节观察,不是当前提交的模型 token 结果。早期离线探针还曾报告 CLI 字节增加 2.25%,但因漏掉最终 CLI 压缩并重新格式化入口,已撤回其实际 CLI 交付测量资格。该数字仅作为无效历史记录保留,不用于完整交付或成本结论。不能把视图缩小 60% 写成总成本下降 60%。

-

当前效率工作把普通入口、分段交付接到共享传输,减少重复读取和重新绑定,消掉可避免的结算往返。差分关闭的默认路径同样重要;开启后也必须正确恢复,并让产品和 benchmark 都易于启用。所有机制合计 15% 的参考目标尚未完成资格验证;它不是每个机制各有一份额度,也不能用来漏记失败和重建成本。

+

这条效率主线把普通入口、分段交付接到共享传输,减少重复读取和重新绑定,消掉可避免的结算往返。当前 context delivery 的渐进选择、必要事实分层、精确共享与周期差分,另见完整机制与语音任务示例。启用后的实际读取、关闭后的原路径和失效恢复都需要分别核验;新实现不能回填历史实验的资格。所有机制合计 15% 的参考目标尚未完成资格验证;它不是每个机制各有一份额度,也不能用来漏记失败和重建成本。

同点接续:完整结果与用量

证据有没有改变下一步工作?

成熟 checkpoint 可以帮助观察一个具体决策边界。接收者继承相同科学状态和 incumbent,再追踪它读了什么证据、选了什么实验、实际做了什么、原生反馈如何。负向本地结果若能在明确条件下排除一条分支,也有价值。继续原方向有依据时,replan 不必强行改道。

近期 #7269 让 Agent 先读目标、事实和反馈,再读写回格式;释放过时的任务选择偏好,并在创建 successor 后保留原 Turn 的结算身份。它对应两个真实往返来源:决策前先读大段写入指令,以及后续任务创建后还要补一轮确认结算归属。

@@ -110,6 +110,6 @@

把结构输入单独计量

截至 10 月 28 日的上下文研究让 Grid、Schema、Ad Placement 从原始任务开始,使用 Sol/max,每题最多 18h。可用的历史 Official 或旧 LoopX 作为描述性参考,保留模型/effort、源码、评分器、机会和时钟差异,不冒称严格配对;旧材料无法回答相应问题时再补 base。各次尝试按实际源码、连续性依据和传输路径分别分析,不合并成同一处理。

先核实实际交付确实改变:首次完整读取、声明连续性依据的后续差分、已知基线失效时的完整回退,以及一次从复盘到工作的完整交互。再比较有效进展、成果保留和完整用量。开关、回执、局部小包都不能替代这些证据。Feature 偏离预期时,停止相关尝试,保留其成本和历史,修复后用新的尝试身份重启。

新原生 Hook 路径的首批 Grid、Ad 交互已完成完整分页、一次差分及后续任务工作。同一次捕获内,差分载荷分别比对应完整包小 19.53%、19.48%;这只是一轮读取的载荷比较,不含分页封装、后续模型输入、Hook、恢复或复盘费用,不能外推为总成本下降。完整复盘到后续原生成果、持续收益和故障恢复仍待验证。

效果目标是很多小时之后仍能取得有效进展并保住成果;效率目标是用更低完整成本和人工介入取得同等验收价值。下一份结果需要同时回答它们;这些尝试沿用各自原定截止时间,替换尝试的失败和消耗也保留。

-

数值分别保留各历史模型、版本、窗口与有效性边界。公开实现:LoopX。早期详细记录保留在上一版文章。这里不发布原始轨迹、隐藏评测材料、运行时凭证或私有操作上下文。

+

这里保留的是 10 月 28 日的研究检查点。后续 reader、默认策略或编码器合入,不会使这些未验证项自动通过。机制文章的合成字节测量与本节的模型轨迹属于不同证据层,不能拼成一项节费结论。

数值分别保留各历史模型、版本、窗口与有效性边界。公开实现:LoopX。早期详细记录保留在上一版文章。这里不发布原始轨迹、隐藏评测材料、运行时凭证或私有操作上下文。

diff --git a/apps/presentation/site/public/blog/zh/index.html b/apps/presentation/site/public/blog/zh/index.html index ac8efafc64..c12680f671 100644 --- a/apps/presentation/site/public/blog/zh/index.html +++ b/apps/presentation/site/public/blog/zh/index.html @@ -29,11 +29,15 @@ Blog 文档 - +

LoopX · 博客

长程工作的工程实践。

关于长程 Agent 的设计、工程与实践。

- + +

研究札记 · EdgeBench 与 LHTB

EdgeBench / LHTB:一轮历史试跑的工程复盘

songoow 对历史 EdgeBench/LHTB 实验配置的探索性工程记录,包含提前中断、局部修复与待验证假设。feedback-first 开关已撤回;不代表 LoopX 官方或正式评测结论及当前版本能力。

阅读全文
@@ -47,8 +51,8 @@

Agentic Software:从代码生成到长程自主研发

以 LoopX 为例,讨论 Agentic Software 的通用基础设施:让目标、证据与人的反馈跨越会话,把探索推进为可验证的交付。

阅读全文
-

研究札记 · EdgeBench

-

让长程 Agent 的下一步有依据:LoopX 语义控制面的阶段性实验

从 Portfolio 与 Lean 的真实轨迹,分析可信反馈、目标续行、条件化证据、渐进式上下文与研究选路;区分已验证的修复和未证明的能力增益。

阅读全文
+

研究札记 · EdgeBench

· 10 月 29 日修订

+

让 Agent 多做十小时,究竟多做出了什么?

从 10 月初到中下旬的研究过程,看可信反馈、目标、实验步长与恢复怎样被修正;用 Schema 的平台期和完整用量检验后程收益。

阅读全文

设计观点 · 系统级自迭代

diff --git a/apps/presentation/site/public/blog/zh/typescript-control-plane-refactor/index.html b/apps/presentation/site/public/blog/zh/typescript-control-plane-refactor/index.html index b4bb4de776..ee9c54f32d 100644 --- a/apps/presentation/site/public/blog/zh/typescript-control-plane-refactor/index.html +++ b/apps/presentation/site/public/blog/zh/typescript-control-plane-refactor/index.html @@ -13,12 +13,31 @@
← 全部文章

LoopX 2.0 · Engineering

LoopX 2.0:两个月的 TypeScript 控制面重构

副作用做完却没记账,旧执行者拿着成功回执回来,修正证据意外重启任务——两个月的重构,逐步把这些问题收敛到完整事务和统一语义。

-
-

LoopX 2.0 发布了。借这个节点,我想把 TypeScript 重构的历史和技术细节整理出来。

+
+

重试一次操作,可能把副作用做两遍;读回一张成功回执,也可能恢复了早已过期的执行权。LoopX 的 TypeScript 重构,要修的正是这些跨越执行、存储与恢复的语义问题。

+

1. 强模型参与的,是这些跨边界的语义问题

+

我们把强能力模型用在设计、实现和评审里,尤其是跨文件、跨 runtime 的假设检查。真正难的部分往往是:几个局部判断都对,组合起来却允许错误的执行顺序。8、9 月的核心 PR 已经反复遇到这类问题;它们不是迁移收尾后的补丁。

+

副作用已经发生,记录还没写下:重试会不会做两遍?

+

假设 provider 已执行成功,进程却在写 checkpoint 前崩溃。只检查 journal,会看到“未完成”;直接重试可能重复执行。相反,把所有不确定都当作成功,又会吞掉尚未发生的工作。这不是一个 try/catch 能解决的问题。

+

8 月 22 日的 #3485 在执行前持久化 prepared attempt 和稳定的 effect identity。恢复先询问 provider:确认已提交,就补记原结果;确认不存在,才按同一身份执行;结果未知,就停在待恢复状态。 对 effect 顺序、receipt 前缀和身份的检查同时保留。这里没有承诺任意外部系统都能 exactly-once:能否确认原结果,仍取决于 provider 的恢复能力。

+

它接续了 #3464 的 preflight:执行前判断“能不能做”,中断后判断“是否已经做过”。两者共同保护一次完整操作。只把 Python 函数逐个翻译成 TS,保不住这两个时间边界。

+

9 月 13 日的 #4286 把七类 Todo 操作的回执恢复收敛到一个 owner,并保留了更细的区别。假设两个 Agent 同时修改任务:A 先提交,B 因版本冲突被明确拒绝;随后 B 查回执时断网。后一次读取失败,不能抹掉前一次明确拒绝。 若断连发生在提交响应返回前,结果才需要保持未知,并沿原 operation identity 恢复。

+

这两条路径最后都可能遇到网络错误,下一步却不同。共享实现只尝试一次写入,随后读取原回执;对应回归分别检查明确拒绝、提交结果未知和准确回执恢复。统一错误处理不能丢掉错误发生的阶段,也不能把已知事实降成未知。

+

领取任务和取得执行权,必须是同一件事

+

两个 Agent 同时看到一个未领取任务。如果 claim 已写入、lease 尚未取得,中间状态究竟归谁?如果旧 Agent 曾成功领取,租约过期后又拿着旧 receipt 回来,它还能继续写吗?

+

从 #3529、#3669 的协调基础,到 9 月 6 日的 #4032,领取、租约和操作回执被纳入同一次条件提交。#3798 的 store 负责原子持久化,领域 owner 判断身份、作用域和合法转换。回执证明过去那次领取成功;当前租约与 epoch 才决定现在能否执行。 操作重放要能找回原结果,却不能复活已失效的执行权。不同存储中的 revision 也不能与领域版本或 lease epoch 混用。

+

这解释了为什么“幂等”不是把旧成功结果返回就结束。正确恢复既要记住历史,也要服从现在的权威状态。早期 foundation、shadow 和生产路径的资格是分阶段建立的,不能把第一个接口合入日写成所有后端都已投入使用。

+

修正一条证据,为什么会重新触发已经结束的工作?

+

规划更新尤其容易出现看似无害的默认值错误。用户只修正一条证据,没有改监控状态;如果更新逻辑用缺省值重建整个对象,已经满足的 monitor 可能被重新启用。与此同时,调用方显式传入空列表或 false,也不能被当作“没有提供”。

+

9 月 10 日的 #4178 将规划更新收敛到同一份权威快照和完整 TS transaction:省略保留原意,显式清空按字段与权限解释,证据修正不重新武装已满足的 monitor。它还删掉了 Python 合成 Markdown 再解析回状态的路径。这既是边界收敛,也是行为修复,不能笼统宣称逐字迁移、行为完全不变。

+

Song 后续的 #4433、#4494 把这种检查延伸到词表的定义、实际生产与消费:一个枚举能编译,不代表所有调用方都在表达同一个含义。前文的 skip / quota_skip 和 action / decision 分离,属于同一条语义主线。

+

怎样约束模型给出的“看起来正确”

+

让模型先指出错误假设,再构造会推翻它的执行序列:提交后断连、旧 lease 重放、只更新证据、显式清空。随后检查真实 owner、provider 和调用入口。

+

强模型帮助把散在各处的条件连起来;反例、真实存储与拒绝路径约束它的答案。目前没有逐 PR 的模型型号对照,不能据此量化某个模型的独立收益。我们能展示的是这些机制怎样改变,以及为什么需要改变。后来的 #7145 运行时路由、#7269 原 Turn 收尾是这条主线的延续,不代替前中期的核心工作。

+

2. 先还原历史:迁移方案本身也在变化

正式迁移 RFC 在 8 月 15 日合入。到 10 月中旬集中清理普通旧 writer,这项工程已经跨了差不多两个月。它有多条并行线:事务规则迁移、调用方收敛、共享权威、存储与历史成本、Semantics,以及后续兼容与退役。

最后 3 位开发者与各自 Agent 接力的 #6396,是这些工作累积后的一次集中收尾。前面的选择和转折,决定了最后能删什么,以及删掉以后还能恢复什么。

其中,新 maintainer Song(@songoow) 从 9 月中旬持续推进 Semantics RFC、词表收敛、生产证据和检查器修复。这部分也值得与事务、存储放在一起讲。

-

1. 先还原历史:迁移方案本身也在变化

LoopX 保存长程 Agent 的目标、任务、证据与执行边界。模型可以提出新路线,控制面要保护版本、执行权和状态提交,并在中断后找到正确的恢复位置。

最初的大量实现是 Python,TS 的宿主、Pi 集成与 dashboard 已经存在。通过一次 Python 调用来做决策,再把结果接回 TS,是自然的起点。随着规则增多,默认值、状态解释、调用顺序和持久化也可能分散在两边。

我们希望这些控制面规则有清楚的 typed owner,同时让 CLI、宿主和 App 共享合同。实际过程可以分成以下几个互相重叠的阶段。

@@ -74,158 +93,6 @@

1. 先还原历史:迁移方案本身也在变化

迁移历史:事务、权威与存储、Semantics 三条线交错推进
迁移历史:事务、权威与存储、Semantics 三条线交错推进 窄屏可横向滚动;点击查看原图。

8 月原始提案考虑过 read-first 和分阶段 dual-read/dual-write。后来接受的方案改为 Effect Program 先行,再按完整事务替换、删除旧规则,生产路径只有一个语义 owner。最初提案中的阶段设想,不能直接当成 2.0 的运行时设计。

这种变化很正常。重要的是把为什么改路线、已经切到哪里、哪些仍是 reference 或候选写清楚。当前维护中的 TS RFC 记录了这些检查点。

-

2. 只统计核心 control plane:研发规模与代码变化

-

为了把整段工程的规模说清楚,这里固定一个可复算的窄范围:loopx/control_plane/**。其他目录的 App、benchmark、文档、测试套件不计入核心代码量。这个目录自身的测试支持工具仍在目录口径内。

-

基线是正式 TS RFC 合入前的 d1fe059,终点是 10 月 16 日的 488e443。从正式 RFC 到终点约 62 天,跨 63 个日历日期;其中 62 个日期有核心目录的主干提交。起止源码对照可以复查版本。

-

整个周期的研发活动

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
指标核心目录口径
触及核心目录的主干落地提交,按第一父链去重1,144
可核验关联的已合并 PR,按 PR 编号去重1,121
这些 PR 的作者账号56
本次 API 快照中的 review 记录2,329
本次 API 快照中的会话评论,不含行内 review comments1,631
有 review 记录的关联 PR1,031 / 1,121
PR 创建至合并的中位历时5.0 小时
PR 创建至合并的 P90 / P95 历时25.4 / 45.0 小时
-

这组范围包含同期的迁移、新能力、修复与维护。56 是 GitHub 账号数,其中有自动化与共享账号;它不等于 56 个人或 56 个 Agent。review 数也包含自审、重复审查等记录,部分讨论发生在合并后。合并历时包含等待,不能换算成有效研发工时。

-

新 maintainer Song 在这个窄目录口径下关联 53 个 PR。他在 loopx/semantics/ 等目录的贡献没有全部进入这个数,具体技术归属仍以本文的贡献说明和原 PR 为准。

-

代码结构与累计变化量

-

下表按物理行统计,包含注释和空行;列出的文件量只计相应语言源码。

-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
核心目录源码基线取证终点期间累计新增 / 删除
Python256 个文件;80,473 行471 个文件;142,371 行+120,899 / −59,001 行
TypeScript0 个文件;0 行323 个文件;87,268 行+104,769 / −17,501 行
Python + TypeScript80,473 行229,639 行+225,668 / −76,502 行
-

TS 占终点这两种语言源码物理行数的 38.0%。这是目录里的语言结构,不能当作“38% 的控制面已完成迁移”:一部分旧入口本来就在目录外,迁移中也有模块归位、新能力与测试支持代码进入。

-
核心 control plane 的 Python 与 TypeScript 源码存量变化
核心 control plane 的 Python 与 TypeScript 源码存量变化 窄屏可横向滚动;点击查看原图。
-

累计新增和删除按主干每次落地差分相加,同一行反复修改会重复计数;两端存量只看各自快照。本次将累计净变化与端点差分、源码存量变化逐项对齐。这里能看到约 30.2 万行次的 Python/TS 改动,不能据此计算独立产出、质量或模型生产率。

-

节奏:这段工程怎样持续推进

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
北京日期,按周分桶核心主干提交关联合并 PR当周 PR 作者账号
08-15—08-21524810
08-22—08-28878614
08-29—09-04616116
09-05—09-11929214
09-12—09-1813313314
09-19—09-2515014710
09-26—10-0216116117
10-03—10-0921621412
10-10—10-1619217914
-
整个重构期间,触及核心目录的关联合并 PR 按周分布
整个重构期间,触及核心目录的关联合并 PR 按周分布 窄屏可横向滚动;点击查看原图。
-

首末周只覆盖统计起止时间以内的部分。周内按合并时间计 PR、按提交时间计主干提交,两种时间可能不同,因此不要把两个数逐行当成一一对应。

-

再按标题前缀观察,fix 为 658,feat 为 208,refactor 为 137,perf 为 28,其他为验证、文档或未按这些前缀命名的工作。它们是标题分类,不能把其中某一类当作全部迁移工作。

-
同一核心目录 PR 集合的标题类别分布
同一核心目录 PR 集合的标题类别分布 窄屏可横向滚动;点击查看原图。
-

这些数据让我更愿意把后面的机制按阶段讲:规则搬迁之后,还有调用方接入、语义修复、恢复验证和旧路径退役。最后的 #6396 是整个过程中的一个集中切片。

-

统计如何复查

-

公开安全的PR 清单、核心主干提交清单和指标 JSON随稿提供。PR 集合来自触及该目录的主干提交与 GitHub 合并元数据的对应关系;同一 PR 只计一次。2 次主干提交没有可核验的合并 PR 对应,仍计入提交和代码变化量。

-

取证中先枚举公开 PR,再用 Git 主干反查;直接读取补齐了搜索索引漏掉的 14 个 PR 元数据。源数据与处理脚本保留在本次调研材料中。没有从这份盘点推算 token、模型费用、CI 算力、研发工时或 benchmark 收益。

3. Effect Program 先行:先统一“做过什么”

第一次有界切换发生在 8 月 21 日的 #3416。TS 接下 Effect Program、settlement algebra、Turn journal 的解释,以及持久 checkpoint effect。

这组边界之所以连在一起,是因为恢复要回答同一个问题:这笔工作有哪些 effect,哪些已经发生,下一个合法动作是什么?

@@ -324,26 +191,7 @@

检查器也需要能推翻自己的反例

这里误报与漏报的代价不同。保守扩大候选值可能多报一个问题;漏掉真实生产值,会让未登记输出通过检查。没有把握的动态形式应留下 unknown。

检查还要有扫描覆盖下限,不能靠少扫文件过线。后来删除持续膨胀的已提交 inventory,改成按需计算全树清单,也没有取消这个义务。当前支持形式之外仍有缺口,跟踪 issue 继续保留。

这项工作让我很认同一个实践:自动生成和自动检查,可以减少同步错误;它们自己的前提、覆盖和错误方向,也需要被审查。

-

8. 强模型参与的,是这些跨边界的语义问题

-

我们把强能力模型用在设计、实现和评审里,尤其是跨文件、跨 runtime 的假设检查。真正难的部分往往是:几个局部判断都对,组合起来却允许错误的执行顺序。8、9 月的核心 PR 已经反复遇到这类问题;它们不是迁移收尾后的补丁。

-

副作用已经发生,记录还没写下:重试会不会做两遍?

-

假设 provider 已执行成功,进程却在写 checkpoint 前崩溃。只检查 journal,会看到“未完成”;直接重试可能重复执行。相反,把所有不确定都当作成功,又会吞掉尚未发生的工作。这不是一个 try/catch 能解决的问题。

-

8 月 22 日的 #3485 在执行前持久化 prepared attempt 和稳定的 effect identity。恢复先询问 provider:确认已提交,就补记原结果;确认不存在,才按同一身份执行;结果未知,就停在待恢复状态。 对 effect 顺序、receipt 前缀和身份的检查同时保留。这里没有承诺任意外部系统都能 exactly-once:能否确认原结果,仍取决于 provider 的恢复能力。

-

它接续了 #3464 的 preflight:执行前判断“能不能做”,中断后判断“是否已经做过”。两者共同保护一次完整操作。只把 Python 函数逐个翻译成 TS,保不住这两个时间边界。

-

9 月 13 日的 #4286 把七类 Todo 操作的回执恢复收敛到一个 owner,并保留了更细的区别。假设两个 Agent 同时修改任务:A 先提交,B 因版本冲突被明确拒绝;随后 B 查回执时断网。后一次读取失败,不能抹掉前一次明确拒绝。 若断连发生在提交响应返回前,结果才需要保持未知,并沿原 operation identity 恢复。

-

这两条路径最后都可能遇到网络错误,下一步却不同。共享实现只尝试一次写入,随后读取原回执;对应回归分别检查明确拒绝、提交结果未知和准确回执恢复。统一错误处理不能丢掉错误发生的阶段,也不能把已知事实降成未知。

-

领取任务和取得执行权,必须是同一件事

-

两个 Agent 同时看到一个未领取任务。如果 claim 已写入、lease 尚未取得,中间状态究竟归谁?如果旧 Agent 曾成功领取,租约过期后又拿着旧 receipt 回来,它还能继续写吗?

-

从 #3529、#3669 的协调基础,到 9 月 6 日的 #4032,领取、租约和操作回执被纳入同一次条件提交。#3798 的 store 负责原子持久化,领域 owner 判断身份、作用域和合法转换。回执证明过去那次领取成功;当前租约与 epoch 才决定现在能否执行。 操作重放要能找回原结果,却不能复活已失效的执行权。不同存储中的 revision 也不能与领域版本或 lease epoch 混用。

-

这解释了为什么“幂等”不是把旧成功结果返回就结束。正确恢复既要记住历史,也要服从现在的权威状态。早期 foundation、shadow 和生产路径的资格是分阶段建立的,不能把第一个接口合入日写成所有后端都已投入使用。

-

修正一条证据,为什么会重新触发已经结束的工作?

-

规划更新尤其容易出现看似无害的默认值错误。用户只修正一条证据,没有改监控状态;如果更新逻辑用缺省值重建整个对象,已经满足的 monitor 可能被重新启用。与此同时,调用方显式传入空列表或 false,也不能被当作“没有提供”。

-

9 月 10 日的 #4178 将规划更新收敛到同一份权威快照和完整 TS transaction:省略保留原意,显式清空按字段与权限解释,证据修正不重新武装已满足的 monitor。它还删掉了 Python 合成 Markdown 再解析回状态的路径。这既是边界收敛,也是行为修复,不能笼统宣称逐字迁移、行为完全不变。

-

Song 后续的 #4433、#4494 把这种检查延伸到词表的定义、实际生产与消费:一个枚举能编译,不代表所有调用方都在表达同一个含义。前文的 skip / quota_skip 和 action / decision 分离,属于同一条语义主线。

-

怎样约束模型给出的“看起来正确”

-

让模型先指出错误假设,再构造会推翻它的执行序列:提交后断连、旧 lease 重放、只更新证据、显式清空。随后检查真实 owner、provider 和调用入口。

-

强模型帮助把散在各处的条件连起来;反例、真实存储与拒绝路径约束它的答案。目前没有逐 PR 的模型型号对照,不能据此量化某个模型的独立收益。我们能展示的是这些机制怎样改变,以及为什么需要改变。后来的 #7145 运行时路由、#7269 原 Turn 收尾是这条主线的延续,不代替前中期的核心工作。

-

9. 调用方和默认值,决定迁移能否到用户手上

+

8. 调用方和默认值,决定迁移能否到用户手上

完整事务还要求调用方准确表达意图。前述 #4178 中,空白 note 表示不修改;显式空列表和 false 则是按对应字段解释的输入。不能把它们统一过滤为“没传”,也不能一律解释成“清空”。dry-run 要准确模拟,不能因为选定 provider 不可用就回退别处。随后 #4279 也收敛了读取分类与投影交付语义;部分 Python read owner 被有意保留。一个 owner 是否清楚,比为了语言纯度再造一份解释更重要。

新建默认值是另一个例子。当前 priority 回归保护以下区别:

@@ -381,7 +229,7 @@

9. 调用方和默认值,决定迁移能否到用户手上<

这些区别由 File/SQLite 回归 保护。把“新建默认值”放在原回执恢复之后,才能避免升级替历史做决定。

最后一轮评审还发现:TS 核心的 metadata-only completion repair 可以通过直接测试,普通 Python producer 却会自动带上 completion policy 和 auto-acquire 等默认参数,被核心视为混入了新工作,导致 File/SQLite、dry-run/执行的实际入口都失败。公开反例 记录了这一点。

这个恢复缺口在基线也存在,不能全部归因给最后的贡献者。修复要走到普通调用方,同时继续拒绝真正的新正文、continuation、所有权或验证修改。直接构造正确 typed request,仅证明内层会处理它。

-

10. 恢复原结果,同时保护当前执行权

+

9. 恢复原结果,同时保护当前执行权

恢复最容易混淆两个时间点:原操作当时合法,现在的执行者是否还能继续改状态。

设想一次 team-plan 已经提交,响应丢了。升级后,调用者拿原 operation ID 重试,新准入规则却变严了。若先按新操作拒绝,就会把原成功结果挡住。最后的 恢复评审 抓到了这个问题。

原回执恢复与当前执行权的分离
原回执恢复与当前执行权的分离 窄屏可横向滚动;点击查看原图。
@@ -389,7 +237,7 @@

10. 恢复原结果,同时保护当前执行权

返回原结果不会续租,不会覆盖后来提交,也不会复活旧 writer。租约转交、epoch 改变和后续状态,都有自己的保护。

类型也表达这种区别:历史解码仍认识 legacy,当前新执行的 handoff 配置只接受 soft_claim 与 hard_lease。旧记录可读、原操作可恢复、当前执行获准,各自有独立条件。

内部回执保护的范围也有限。一次外部远端 effect 若没有可核验的幂等身份与回读,不能只凭控制面只结算一次,就宣称远端恰好执行一次。unknown 应在它实际发生的边界上保留。

-

11. CLI 输出约束:压缩前先保护决策语义

+

10. CLI 输出约束:压缩前先保护决策语义

对 Agent 来说,CLI 的文字会参与决策。这项工程约束早于最后的 writer 退役,在迁移中继续作为验证边界。

接口预算合同 关注:

    @@ -402,7 +250,7 @@

    11. CLI 输出约束:压缩前先保护决策语义

    自然语言还需要逐条看:义务、顺序、证据来源、权限限定、适用范围、继续和停止条件。删除一句“仅在原证明成立时”可能比改一个字段更影响行为。

    一个有界实例是去掉 JSON 缩进与分隔空白。在同一历史 fixture 的 36 个 Todo、12 条 run 上,输出从 48,418 降到 39,726 字符,完整 payload 解码保持一致,字符数减少约 18%。它证明展示体积变化;token、费用和 Agent 效果需要另测。

    预算保护的是消费者能用的接口。新增指导确实有用,可以带同条件证据提高预算;为了变绿而删掉决定所需的条件,反而损坏接口。

    -

    12. 最后退役:保留贡献,核对删除的究竟是什么

    +

    11. 最后退役:保留贡献,核对删除的究竟是什么

    9 月下旬已经删除了未使用的 authority prototype,以及实验性 Todo event overlay、dual-writer 和 backfill;其中有数据的旧来源有显式保留或拒绝处理。这里没有删除所有 event logging,也没有取消新 authority 的原子事件与回执。

    10 月继续隔离普通 Markdown writer,验证模块不在时真实后续写入仍走正确 owner。等 consumer 路由与替代路径接上,才具备集中删除的条件。

    #6396 由 Duang777 主导,Song 和维护侧 Agent 接力补恢复、producer 与集成,沿原分支保留贡献历史。这一轮 3 位开发者与 Agent 的接力,是整个两个月工程的收尾阶段。

    @@ -442,6 +290,158 @@

    12. 最后退役:保留贡献,核对删除的究竟是

大部分删除也包括旧测试。不能把被删测试行当成业务能力;应继续核对原来保护的 invariant 是否由现有入口和独立反例接住。这里的数字用于说明收尾范围,不能替代整个迁移的结果验证。

+

12. 只统计核心 control plane:研发规模与代码变化

+

为了把整段工程的规模说清楚,这里固定一个可复算的窄范围:loopx/control_plane/**。其他目录的 App、benchmark、文档、测试套件不计入核心代码量。这个目录自身的测试支持工具仍在目录口径内。

+

基线是正式 TS RFC 合入前的 d1fe059,终点是 10 月 16 日的 488e443。从正式 RFC 到终点约 62 天,跨 63 个日历日期;其中 62 个日期有核心目录的主干提交。起止源码对照可以复查版本。

+

整个周期的研发活动

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指标核心目录口径
触及核心目录的主干落地提交,按第一父链去重1,144
可核验关联的已合并 PR,按 PR 编号去重1,121
这些 PR 的作者账号56
本次 API 快照中的 review 记录2,329
本次 API 快照中的会话评论,不含行内 review comments1,631
有 review 记录的关联 PR1,031 / 1,121
PR 创建至合并的中位历时5.0 小时
PR 创建至合并的 P90 / P95 历时25.4 / 45.0 小时
+

这组范围包含同期的迁移、新能力、修复与维护。56 是 GitHub 账号数,其中有自动化与共享账号;它不等于 56 个人或 56 个 Agent。review 数也包含自审、重复审查等记录,部分讨论发生在合并后。合并历时包含等待,不能换算成有效研发工时。

+

新 maintainer Song 在这个窄目录口径下关联 53 个 PR。他在 loopx/semantics/ 等目录的贡献没有全部进入这个数,具体技术归属仍以本文的贡献说明和原 PR 为准。

+

代码结构与累计变化量

+

下表按物理行统计,包含注释和空行;列出的文件量只计相应语言源码。

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
核心目录源码基线取证终点期间累计新增 / 删除
Python256 个文件;80,473 行471 个文件;142,371 行+120,899 / −59,001 行
TypeScript0 个文件;0 行323 个文件;87,268 行+104,769 / −17,501 行
Python + TypeScript80,473 行229,639 行+225,668 / −76,502 行
+

TS 占终点这两种语言源码物理行数的 38.0%。这是目录里的语言结构,不能当作“38% 的控制面已完成迁移”:一部分旧入口本来就在目录外,迁移中也有模块归位、新能力与测试支持代码进入。

+
核心 control plane 的 Python 与 TypeScript 源码存量变化
核心 control plane 的 Python 与 TypeScript 源码存量变化 窄屏可横向滚动;点击查看原图。
+

累计新增和删除按主干每次落地差分相加,同一行反复修改会重复计数;两端存量只看各自快照。本次将累计净变化与端点差分、源码存量变化逐项对齐。这里能看到约 30.2 万行次的 Python/TS 改动,不能据此计算独立产出、质量或模型生产率。

+

节奏:这段工程怎样持续推进

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
北京日期,按周分桶核心主干提交关联合并 PR当周 PR 作者账号
08-15—08-21524810
08-22—08-28878614
08-29—09-04616116
09-05—09-11929214
09-12—09-1813313314
09-19—09-2515014710
09-26—10-0216116117
10-03—10-0921621412
10-10—10-1619217914
+
整个重构期间,触及核心目录的关联合并 PR 按周分布
整个重构期间,触及核心目录的关联合并 PR 按周分布 窄屏可横向滚动;点击查看原图。
+

首末周只覆盖统计起止时间以内的部分。周内按合并时间计 PR、按提交时间计主干提交,两种时间可能不同,因此不要把两个数逐行当成一一对应。

+

再按标题前缀观察,fix 为 658,feat 为 208,refactor 为 137,perf 为 28,其他为验证、文档或未按这些前缀命名的工作。它们是标题分类,不能把其中某一类当作全部迁移工作。

+
同一核心目录 PR 集合的标题类别分布
同一核心目录 PR 集合的标题类别分布 窄屏可横向滚动;点击查看原图。
+

这些数据让我更愿意把后面的机制按阶段讲:规则搬迁之后,还有调用方接入、语义修复、恢复验证和旧路径退役。最后的 #6396 是整个过程中的一个集中切片。

+

统计如何复查

+

公开安全的PR 清单、核心主干提交清单和指标 JSON随稿提供。PR 集合来自触及该目录的主干提交与 GitHub 合并元数据的对应关系;同一 PR 只计一次。2 次主干提交没有可核验的合并 PR 对应,仍计入提交和代码变化量。

+

取证中先枚举公开 PR,再用 Git 主干反查;直接读取补齐了搜索索引漏掉的 14 个 PR 元数据。源数据与处理脚本保留在本次调研材料中。没有从这份盘点推算 token、模型费用、CI 算力、研发工时或 benchmark 收益。

13. 社区贡献与下一步

这项工程有多位贡献者逐步推进。下面按具体边界列出代表工作,便于继续读历史。

@@ -489,6 +489,6 @@

13. 社区贡献与下一步

2.0 也没有把所有 RFC 目标画上句号。保留的 Python transport 与专业 provider 有明确用途,更广的 native CLI、持续运行资格继续按各自路径验证。工程闭环更清楚以后,我们还要在 EdgeBench、LHTB 这类通用长程 benchmark 上做能力与效率对照,尤其是 single session。

我希望这次重构留下的,是下一轮修改更容易定位、验证和回滚的系统,以及遇到反例时愿意继续修正的工作方式。

- +
LoopX

让工作持续推进,让判断由人掌握。

↑