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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,18 @@ identity use the existing projection-edit transport. This changes neither
required-read obligations nor admission, settlement or the off path; it does
not close C1/C2 adoption or establish model-outcome/full-cost benefit.

The existing initial reader also consumes complete acceptance navigation bound
to the captured Goal/Agent/Todo and source revisions. Suggested outcome bodies
reach the starting read, including peer dependencies; other outcomes remain
addressable. Missing or mismatched navigation keeps the prior detail route.
This reuses the relationship owner rather than adding an ownership/prose scope
rule. It changes neither activation defaults nor saved-view bytes or Delta;
matched initial-plus-required-detail traffic is a separate component comparison,
not the original quota outcome/full-cost qualification or an unread ledger.
The TurnEnvelope owner retains the top-level decision-field vocabulary and
supplies it to Progressive selection. Moving the selector does not duplicate
that vocabulary across owners or relax its semantic module budget.

C1's inventory is part of its usable replacement, not a standalone architecture
framework. C3/C4/C5 can proceed independently once C1's contract is stable;
C7 can prepare measurements before C6 but cannot claim two-session outcomes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -921,6 +921,14 @@ backoff 继续归当前 scheduler owner。本文不引入模型空轮询或新
本改动不改变必读义务、准入、结算或关闭路径,也不代表 C1/C2 采用资格或
模型结果与完整成本收益已经验收。

现有首读还消费与捕获的 Goal/Agent/Todo 及来源版本绑定的完整 acceptance 导航,
将建议成果正文直接放入起始读取,包括 peer 依赖;其他成果仍可按地址展开。导航缺失
或错配时保留原详情路线。复用既有关系 owner,不新增按归属/正文猜 scope 的规则;
不改变启用默认值、落盘视图字节或 Delta。相同首读加必需详情的流量只作独立组件对照,
不代表原 quota 成果/完整成本验收,也不交付未读台账。
顶层 decision 字段清单保留在 TurnEnvelope owner,由其传给 Progressive 选读;迁移
selector 不跨 owner 重复声明该词汇,也不放宽语义模块预算。

C1 盘点是可用替换的一部分,不单独建设架构框架。C1 契约稳定后,C3/C4/C5 可以独立
推进;C7 可以提前准备测量,但不能提前宣称双会话成果。实现 PR 列明替换的调用方、剩余
缺口、实际测试与回退。完整语言迁移或无关 manager 重写不是前置条件;新抽象能编译
Expand Down
18 changes: 18 additions & 0 deletions docs/reference/required-work-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,17 @@ evidence and the complete operation/settlement contract before depending on them
The original SHA-bound full recovery remains available; a selected page's EOF
does not prove complete source delivery, model retention or fresh authority.

When the existing acceptance owner supplies complete `outcome_context`
navigation matching this capture's Goal, Agent, selected Todo, outcome revision
and provider revision, the initial read expands its suggested outcomes in full
as present in the required view, including cross-Agent dependencies and unknown
outcome fields. Other outcomes retain their existing addresses; this is reading
guidance, not proof of independence or permission to skip applicable criteria.
Incomplete, mismatched, ambiguous or unavailable navigation keeps the existing
index/detail route. Folded supporting material still has its original read
obligations. The generic reader needs no Session Hook for this selection;
activation defaults, saved files, Delta and full-read receipts are unchanged.

中文:已启用原生传输的完整引用可给出 `first_read_command`,合并当前准入、停止条件、
任务和完整 Goal/Todo 正文,以及来源状态、版本与读取入口;历史和可选格式说明仍在
同一捕获中按需展开。它是起始选读,不代表已读全部必要来源;依赖具体验收、证据或
Expand All @@ -216,6 +227,13 @@ does not prove complete source delivery, model retention or fresh authority.
回传入队不等于完成。待对端结果、计数、遗漏和不可用观测保留原来源语义。
完整请求按需读取,评估、执行或回传前仍须读其全文;首读不消费结果,也不授予权限。

既有 acceptance owner 给出的完整 `outcome_context` 导航,与当前 capture 的 Goal、
Agent、所选 Todo、成果版本及 provider revision 一致时,首读完整展开其建议成果在
必读视图中的正文,包括跨 Agent 依赖和未知成果字段;其他成果仍保留原地址。这是读取
建议,不证明相互独立,也不允许省略适用要求。导航不完整、错配、歧义或不可用时保留
原索引/详情路线;折叠的支持材料仍遵守原读取义务。此选读使用无需 Session Hook 的
通用 reader,不改变启用默认值、落盘文件、Delta 或完整读取回执。

Checkpoint Host preflight uses the hidden `--defer-context-presentation` option
with an explicitly enabled native JSON `should-run` capture. It collects the
same complete Goal source for admitted work-context reads and writes the ordinary
Expand Down
114 changes: 113 additions & 1 deletion loopx/control_plane/quota/progressive_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* addressed in the immutable source. This plan changes no canonical state. */
import type {JsonObject} from "../effect_program.ts";
import {jsonObject, requireJsonObject} from "../runtime_decode.ts";
import {GOAL_OUTCOMES_SCHEMA} from "../goals/outcome_requirements.ts";
import {GOAL_OUTCOMES_SCHEMA, OUTCOME_CONTEXT_NAVIGATION_SCHEMA} from "../goals/outcome_requirements.ts";
import {FULL_OUTCOME_READ_GUIDANCE, PROGRESSIVE_OUTCOME_READ_GUIDANCE} from "../work_items/interaction_contract.ts";
import {quotaSummaryReferences, contextSourceIdentity, contextProjectionChanges,
type ProjectionSourceValues} from "./diagnostic_projection.ts";
Expand Down Expand Up @@ -193,3 +193,115 @@ export function prepareProgressiveContextDelivery(request: JsonObject, legacyFie
const {operation: _operation, source_edits: _edits, source_number_tokens: _numbers, ...source} = request;
return contextProjectionChanges(source, {context: required.context, delivery, projected: required.projected}, sourceValues);
}

export function initialContextReadPointers(context: JsonObject, decisionFields: readonly string[]): string[] {
const object = (value: unknown): JsonObject | undefined =>
value !== null && typeof value === "object" && !Array.isArray(value) ? value as JsonObject : undefined;
const interaction = object(context.interaction_contract);
// Unknown envelopes retain generic discovery instead of guessing their policy.
if (interaction?.schema_version !== "loopx_interaction_contract_v0") return [];
const pointers: string[] = [];
const include = (...path: (string | number)[]): void => {
let value: unknown = context;
for (const key of path) {
if (value === null || typeof value !== "object" || !Object.hasOwn(value, key)) return;
value = (value as Record<string | number, unknown>)[key];
}
pointers.push("/" + path.map(key => String(key).replaceAll("~", "~0").replaceAll("/", "~1")).join("/"));
};
for (const field of decisionFields) include(field);
include("agent_lane_next_action", "next_step");
include("agent_lane_next_action", "next_action_basis");
include("interaction_contract", "user_channel");
include("interaction_contract", "agent_channel", "required_reads");
const work = ["interaction_contract", "agent_channel", "work_context"];
include(...work, "instruction");
include(...work, "user_todos");
const channel = object(interaction.agent_channel);
const sources = object(channel?.work_context)?.sources;
if (Array.isArray(sources)) sources.forEach((_source, index) => {
const source = [...work, "sources", index];
for (const field of ["source", "kind", "reason", "ordering", "command"])
include(...source, field);
// Current Goal/Todo text and source obligations stay whole. Expansive
// evidence pages, example recipes and historical bodies remain on demand.
include(...source, "content", "text");
include(...source, "content", "instruction");
for (const field of ["ok", "status", "reason", "error", "recovery", "revision", "provider_revision", "source_authority",
"decision_read_from_provider", "legacy_fallback_used", "graph_enabled", "harness_enabled", "boundary", "authority_read"])
include(...source, "content", field);
// The capability already bounds this agenda. Keep pending returns and
// incomplete observations visible without expanding full request bodies.
include(...source, "content", "read_complete");
include(...source, "content", "unfinished_delegations");
include(...source, "content", "current", "revision");
include(...source, "content", "current", "instruction");
include(...source, "content", "outcome_context");
const sourceRow = object(_source), content = object(sourceRow?.content);
const requirements = object(object(content?.goal_acceptance_contract)?.outcome_requirements);
const outcomes = requirements?.outcomes, navigation = object(content?.outcome_context);
const identityAgent = object(context.agent_identity)?.agent_id;
const agentId = context.agent_id ?? identityAgent;
const suggested = navigation?.suggested_outcome_ids;
// Reuse the acceptance owner's relationship navigation; do not infer scope
// from ownership or prose. This only expands the starting read: other
// outcomes and the original required-read obligations remain available.
const expand = sourceRow?.source === "goal_acceptance" && content?.ok !== false
&& content?.status === "loaded" && content.decision_read_from_provider === true
&& content.legacy_fallback_used === false && content.read_complete !== false
&& requirements?.schema_version === GOAL_OUTCOMES_SCHEMA && requirements.current_lifetime === true
&& navigation?.schema_version === OUTCOME_CONTEXT_NAVIGATION_SCHEMA && navigation.coverage_complete === true
&& typeof context.goal_id === "string" && navigation.goal_id === context.goal_id
&& typeof agentId === "string" && agentId.length > 0 && navigation.agent_id === agentId
&& (context.agent_id === undefined || identityAgent === undefined || context.agent_id === identityAgent)
&& typeof object(context.selected_todo)?.todo_id === "string"
&& navigation.todo_id === object(context.selected_todo)?.todo_id
&& navigation.outcome_revision === requirements.revision
&& typeof content.provider_revision === "string" && navigation.provider_revision === content.provider_revision
&& Array.isArray(outcomes) && Array.isArray(suggested)
&& suggested.every(id => typeof id === "string"
&& outcomes.filter(value => object(value)?.id === id).length === 1);
const expanded = new Set(expand ? suggested as string[] : []);
if (Array.isArray(outcomes)) outcomes.forEach((_outcome, outcomeIndex) => {
const outcome = [...source, "content", "goal_acceptance_contract", "outcome_requirements", "outcomes", outcomeIndex];
const outcomeId = object(_outcome)?.id;
if (typeof outcomeId === "string" && expanded.has(outcomeId)) { include(...outcome); return; }
include(...outcome, "id");
include(...outcome, "supporting_material_pointer");
});
include(...source, "content", "todo", "text");
include(...source, "content", "todo", "note");
include(...source, "content", "graph", "guidance");
include(...source, "content", "graph", "recent_findings");
include(...source, "content", "graph", "result_page");
include(...source, "content", "harness", "guidance");
include(...source, "content", "harness", "orchestration_gate");
});
for (const field of ["next_cli_actions", "spend_allowed_now", "spend_after_validation", "spend_policy",
"quota_spend_source", "delivery_workspace_causality", "vision_continuation_audit"])
include("interaction_contract", "cli_channel", field);
const planPath = ["interaction_contract", "cli_channel", "settlement_plan"];
const plan = object(object(interaction.cli_channel)?.settlement_plan);
if (plan?.schema_version === "quota_settlement_plan_v1" && Array.isArray(plan.ordered_steps)) {
for (const field of Object.keys(plan)) if (field !== "ordered_steps") include(...planPath, field);
plan.ordered_steps.forEach((value, stepIndex) => {
const step = object(value), stepPath = [...planPath, "ordered_steps", stepIndex];
if (!step) { include(...stepPath); return; }
for (const field of Object.keys(step)) {
if (field !== "optional_attachments" || !Array.isArray(step[field])) { include(...stepPath, field); continue; }
step[field].forEach((attachment, attachmentIndex) => {
const path = [...stepPath, field, attachmentIndex];
if (object(attachment)?.required !== false) { include(...path); return; }
// Explicitly optional guidance is read before using that attachment.
// Keep its identity and actual read/authoring routes discoverable.
for (const key of Object.keys(object(attachment)!)) {
if (["guidance", "attachment_template", "linked_question_attachment_template", "path_delta_attachment_template",
"optional_measurement_example", "optional_question_evolution_example"].includes(key)) continue;
include(...path, key); // Unknown attachment controls are never hidden.
}
});
}
});
} else include(...planPath); // Unknown plan versions keep their complete obligations.
return pointers;
}
Loading
Loading