diff --git a/docs/reference/required-work-context.md b/docs/reference/required-work-context.md index a2ce483d3d..4a991d51e0 100644 --- a/docs/reference/required-work-context.md +++ b/docs/reference/required-work-context.md @@ -287,8 +287,10 @@ serialized response. Read the top-level `content` and follow its `next_command` until that selection's `eof`. If the whole initial selection would need paging and its decision and read obligations fit in one page, the opening contains those controls and -`navigation.remaining_read_command` points to the rest. Read it and follow -its cursor before work. Both selections pin the same immutable capture. +`navigation.remaining_read_command` points to the rest. The page's +`read_instruction` directs the reader to that command even when the opening +reports EOF. Follow it and its cursor before work. Both selections pin the same +immutable capture. `navigation.first_read_command` replays the opening. Use `navigation.recovery.command` for other fields. If the response is lost, use the original digest-bound capture in the wake prompt. Recovery reuses the saved @@ -303,8 +305,9 @@ decision and its original receipt. 阅读顶层 `content`,按 `next_command` 续读到当前选区的 `eof`。首读内容需要分页且决策 和读取义务能完整放在一页时,首屏先交付这些控制信息,并给出 -`navigation.remaining_read_command`。工作前沿这条命令及其游标读完余下的首读内容。 -两个选区绑定同一份不可变捕获。`navigation.first_read_command` 可重读首屏,其他字段沿 +`navigation.remaining_read_command`。即使首屏已到 EOF,页级 `read_instruction` 仍指向 +这条命令。工作前沿这条命令及其游标读完余下的首读内容。两个选区绑定同一份不可变捕获。 +`navigation.first_read_command` 可重读首屏,其他字段沿 `navigation.recovery.command` 读取。结果丢失时,用唤醒正文中的原文件及摘要恢复,复用原决策和回执。 When the existing acceptance owner supplies complete `outcome_context` diff --git a/loopx/cli_commands/quota_capture.py b/loopx/cli_commands/quota_capture.py index 4bf1e7449a..141838f675 100644 --- a/loopx/cli_commands/quota_capture.py +++ b/loopx/cli_commands/quota_capture.py @@ -749,6 +749,10 @@ def command(reference: Path) -> str: instruction=False, select=[], reference_file=opening, reader_argv=reader_argv) # An opening is useful only as a complete, independently readable # page. Keep the ordinary cursor when even the opening cannot fit. + page["read_instruction"] = ( + "EOF ends the opening. Before work, read its content and follow navigation.remaining_read_command " + "and its next_command cursor through the remaining initial context. Both views pin the same capture. " + "EOF does not establish retention, authority or freshness.") page["navigation"] = navigation return page if len(_native_output_bytes(page)) <= output_bytes else None except (OSError, ValueError): @@ -805,8 +809,7 @@ def project_saved_context_capture(args: argparse.Namespace, *, hook_session: str activation = native_context_activation(args) saved_page = bool(getattr(args, "initial_read", False) or getattr(args, "select", None)) if saved_page and (args.format != "json" or not _context_page_output_enabled(args, activation) or args.offset != 0 - or args.reference_file or args.selection_sha256 or args.page_bytes is not None - or (args.initial_read and args.select)): + or args.reference_file or args.selection_sha256 or (args.initial_read and args.select)): raise ValueError("Use JSON context-project at offset zero with native delivery or progressive --initial-read. " "Choose either --initial-read or --select. Use context-read for replay or continuation.") caller_output_limit = getattr(args, "max_page_output_bytes", None) diff --git a/tests/control_plane/test_saved_context_project.py b/tests/control_plane/test_saved_context_project.py index 6ccdcf8b83..ef87e4449e 100644 --- a/tests/control_plane/test_saved_context_project.py +++ b/tests/control_plane/test_saved_context_project.py @@ -1155,6 +1155,9 @@ def follow(command): assert "without reading an older baseline" in navigation["instruction"] assert "Start with first_read_command" not in navigation["instruction"] assert ("remaining_read_command" in navigation) == staged + assert ("navigation.remaining_read_command" in first["read_instruction"]) == staged + if staged: + assert "Before work" in first["read_instruction"] assert ("next_command" in first) is paged if page_bytes is not None: for command in (navigation["first_read_command"], navigation.get("remaining_read_command"),