docs/adr/0008-kitaru-durable-runtime.mdXem bản gốc Bản dịch đầy đủ theo đúng cấu trúc tài liệu; code, liên kết và định danh kỹ thuật được giữ nguyên.
0008. runtime bền vững của Kitaru — một luồng headless như một đường dẫn vào thứ hai, không phải là một trình bao bọc xung quanh REPL trực tiếp
Trạng thái: Đã chấp nhận Ngày: 2026-06-27
Bối cảnh
decode hôm nay là một TUI phát trực tuyến tương tác: Runner ổ đĩa agent.iter() và suối
token đến terminal (agent/loop.py:366), con người lái giữa lượt/hủy bỏ bằng Esc/xếp hàng
các bước tiếp theo (các Boundary máy, ADR-0002) và độ bền đã tồn tại dưới dạng chỉ gắn thêm
Nhật ký phiên JSONL cộng thêm --resume (context/session_log.py, tui/app.py:835). Câu hỏi bước 7 là một
runtime Kitaru đưa ra bốn yếu tố: độ bền, con người trong vòng lặp (HITL), proxy thông tin xác thực và
lập kế hoạch.
Cách đọc ngây thơ - "bọc vòng lặp agent trong Kitaru @flow" — sai, và phạm vi của Kitaru
hướng dẫn nói như vậy: Giao diện người dùng trò chuyện trực tuyến và việc phân phát yêu cầu/phản hồi có độ trễ thấp được liệt kê dưới dạng tín hiệu
việc thực hiện lâu dài đó là không cần thiết. Việc gói vòng lặp trực tiếp sẽ (a) sao chép vòng lặp hiện có
Độ bền của JSONL, (b) đặt bộ điều phối thứ hai lên trên hàng đợi khai thác + cổng ưu tiên và
(c) mua giá trị chơi lại gần như bằng 0 đối với người ngồi trên bàn phím, người có thể gõ lại.
Nơi Kitaru thành công là một chạy headless, không có người giám sát — một nhiệm vụ trong vòng lặp công cụ agent để hoàn thành, xuất ra - đó chính xác là những gì các cột mốc sau này cần: bước 12 (triển khai tới Modal) và bước 13 (đánh giá PR GitHub trên đám mây; triển khai tính năng ×N). Những người đó không có con người ở một terminal, do đó, phê duyệt phải tạm dừng toàn bộ quá trình thực thi và được giải quyết ngoài phạm vi vài giờ sau đó, và việc chạy nhiều công cụ đắt tiền phải tồn tại sau khi khởi động lại quá trình. Đó chính xác là mô hình của Kitaru.
Các sự kiện được xác nhận trong khi xác định phạm vi (giải quyết TODO "xác nhận nguồn gói" AGENTS.md):
kitaruđang sử dụng PyPI, hiện tại0.18.0(plugin Claude-Code skills đã cài đặt là một plugin riêng biệt0.7.0hiện vật). Cài đặt:uv add kitaruvới tính năng bổ sunglocal(cốt lõi),pydantic-ai(bộ chuyển đổi decode nhu cầu),llm,mcp.- Bộ chuyển đổi PydanticAI
KitaruAgentbao bọc một hiện cópydantic_ai.Agent; chế độ chi tiết cung cấp cho mỗi model/tool/MCP gọi điểm kiểm tra của chính nó. Nó hỗ trợ phát trực tuyến (run_stream()/iter()), với cảnh báo được ghi lại rằng các lượt được phát trực tuyến có thể chuyển từ điểm kiểm tra chi tiết sang điểm kiểm tra mỗi lượt độ chi tiết. Vì vậy, tính năng phát trực tuyến và điểm kiểm tra cùng tồn tại - tính năng phát trực tuyến chưa bao giờ là yếu tố chặn. - Kitaru không có cron/lập lịch riêng. Theo tài liệu ZenML, việc lập lịch định kỳ là bên ngoài:
triển khai luồng (
kitaru deploy) và kích hoạt nó từ bộ lập lịch bên ngoài (crontab hệ thống, ModalCron, CronJob của K8 hoặc được tạokitaru flow deployments curl). Await(..., timeout=…)là một bộ hẹn giờ lâu dài một lần gốc nhưng không phải là lịch trình định kỳ. - HITL là phạm vi luồng
wait(), được giải quyết thông quaclient.executions.input(...)/hành quyết kitaru đầu vào/ MCP —đầu vàoresolves,sơ yếu lý lịchlà dự phòng thủ công. - Bí mật là hạng nhất (
create_secret/get_secret/delete_secret);llm()tự động giải quyết bí mật liên kết với bí danh. Đây là đường nối proxy thông tin xác thực.
Các ràng buộc của dự án được tôn trọng: cơ sở hạ tầng được nhập/gọi trực tiếp cho đến lần triển khai thứ hai
tồn tại (AGENTS.md); runtime/ là mô-đun cấp cao nhất dành riêng cho việc này; bí mật không bao giờ chạm tới được
mô hình hoặc tải trọng hộp cát (bất biến hiện có); I/O không đồng bộ cho vòng lặp.
ADR này ghi lại cấu trúc luồng và quyết định cho tính năng runtime Kitaru
(kitaru-runtime, bước 7). Được chăm sóc bởi /plan vào các tác vụ 057-062 (cài đặt/dep/bảng thuật ngữ →
dòng chảy bền vững + decode run → HITL → bền bỉ sleep → proxy thông tin xác thực → capstone ngoại tuyến) và
Được chấp nhận. Ba kết quả khám phá được trình bày bên dưới: ranh giới không đồng bộ/luồng được giải quyết
(đồng bộ @flow + KitaruAgent.run_sync()), việc thực thi cục bộ/ngoại tuyến được xác nhận và
bề mặt proxy thông tin đăng nhập được ghi lại là ít lấy mẫu nhất (xác minh trước).
Quyết định
-
Dòng bền bỉ headless là đường dẫn vào THỨ HAI - REPL trực tiếp không bị ảnh hưởng. Thêm
src/decode/runtime/nhà ở của Kitaru@flowchạy giốngbuild_agent()(agent/factory.py:68) một cách độc lập. Một cái mớidecode run "<task>"lệnh phụ (và sau đó, một lệnh được triển khai điểm cuối) khởi chạy nó. TUI tương tác tiếp tục phát triểnagent.iter()thông qua harness chính xác như ngày hôm nay. Đây là cuốn sách giáo khoa người gọi cụ thể thứ hai kiếm đượcruntime/mô-đun, và nó là bước đệm cho TUI phát trực tuyến dựa trên dòng chảy trong tương lai (cấu trúc liên kết "thống nhất") mà không cần viết lại bất cứ điều gì bây giờ. -
Độ bền thông qua bộ chuyển đổi PydanticAI, không phải điểm kiểm tra được cuộn bằng tay. Dòng chảy bao bọc agent trong
KitaruAgent(build_agent_inner_agent, checkpoint_strategy=settings.runtime_checkpoint_strategy)— được xác nhận dựa trên bộ chuyển đổi đã cài đặt;"turn"(một điểm kiểm tra cho mỗirun_sync()lượt) là MVP mặc định,"calls"là cho mỗi lệnh gọi mô hình/công cụ. Mỗi điểm kiểm tra hoàn thành sẽ được phát lại từ bộ đệm; một vụ tai nạn tiếp tục lại gần lỗi thay vì chạy lại các công cụ. Không@checkpointđược bao quanh agent bằng tay.Sửa đổi (28-06-2026, nhiệm vụ 058) — bỏ qua chạy các công cụ decode nội tuyến, nó không bỏ qua toàn bộ vòng lặp. Khung "vòng lặp decode thay thế headless" của §1 chưa hoàn chỉnh. Mỗi decode công cụ — thậm chí chỉ đọc
read/glob/grep- mở cơ thể của nó bằngraise ApprovalRequiredcho đến khi đã được phê duyệt; việc trì hoãn đó được giải quyết bằng vòng lặp của bộ decode (agent/loop.py), cái nàorun_synclàm không chạy. Và bộ chuyển đổi Kitaru chuyển đổi bất kỳApprovalRequiredbên trong một trạm kiểm soát vào một phạm vi luồngkitaru.wait()(tạm dừng HITL) - vì vậy dướirun_synclệnh gọi công cụ đầu tiên của một hoạt động bỏ qua không giám sát sẽ tăng lênKitaruUsageError("chờ đợi phải ở phạm vi luồng"), không quay lại một chuỗi sạch. Tiền đề "bỏ qua → khôngApprovalRequired" chỉ đúng nếu một công cụ tham khảo ý kiến chế độ. Fix (nhỏ, trung tâm): một vị ngữ,decode.tools.approval.needs_approval(ctx)=not ctx.tool_call_approved and ctx.deps.gate.mode is not BYPASS, thay thế nội tuyếnnot ctx.tool_call_approvedkiểm tra tại tất cả 9 địa điểm có cổng (files.py×5,web,tasks,bash,lsp). Trong BỎ QUA một công cụ được kiểm soát sẽ chạy nội tuyến (không trì hoãn, không chờ đợi); theo mặc định/kế hoạch/chỉnh sửa, nó trì hoãn chính xác như trước và vòng lặp giải quyết nó thông qua cổng — hành vi tương tác không thay đổi byte. Thế là người headless dòng chảy giữKitaruAgentbộ chuyển đổi để đảm bảo độ bền và chỉ đơn giản là tạo ra các công cụ dùng chung nhận biết bỏ qua; nó không chạy lại vòng lặp tương tác và không điều khiển bằng tayDeferredToolResults. -
HITL = hoán đổi kênh quyết định duy nhất lấy một
wait()bridge. decode các tuyến đường đã cóask_uservà mọi phê duyệt quyền (chế độ thoát kế hoạch, cổng ghi/bash) thông qua một người giải quyết,resolve_user_question(agent/deps.py:81). Trong chế độ headless, trình phân giải đó là điều duy nhất thay đổi: nó trở thành cầu nối đến phạm vi luồngkitaru.wait(name=…, question=…, lược đồ=…), resolved out-of-band byđầu vào thực thi kitaru. Chế độ tương tác giữ bảng điều khiển người giải quyết. Thiết kế một kênh (một đường nối) là điều làm cho việc hoán đổi này trở nên rõ ràng hơn là một viết lại. Thời gian chờ đợi của công cụ sử dụng bộ điều hợphitl_tool/wait_for_inputhoặc chọn công cụ chờ ngoài các điểm kiểm tra chi tiết (tool_checkpoint_config_by_name={...: False}), theo quy tắc bộ chuyển đổi đang chờ trực tiếp ở phạm vi luồng.Sửa đổi (28-06-2026, nhiệm vụ 058). Với sửa đổi §2 đã được thực hiện, HITL headless của 059 là bổ sung tự nhiên: thay vì buộc BỎ QUA, các bộ phận headless sử dụng chế độ không bỏ qua để có cổng công cụ
ApprovalRequiredkhông kích hoạt và bộ chuyển đổiApprovalRequired → kitaru.wait()cầu (với các công cụ được kiểm soát đã chọn không tham gia các điểm kiểm tra chi tiết,tool_checkpoint_config_by_name={tool: Sai}, andallow_sync_tool_body_waits=True) biến mỗi phê duyệt thành một sự chờ đợi lâu dài được giải quyết ngoài băng tần bởikitaru executions input. 058 vận chuyển lát BYPASS (không có con người); 059 lớp phê duyệt bền vững ở trên cùng — không cần thay đổi công cụ, chỉ có chế độ phụ kiện + cấu hình bộ chuyển đổi.Sửa đổi (28-06-2026, nhiệm vụ 059 — những gì đã được vận chuyển, đã được xác minh dựa trên bộ điều hợp đã cài đặt 0.18). 059 đã thêm luồng giây,
runtime/flow.py::run_agent_task_hitl(đường tránhrun_agent_taskkhông bị ảnh hưởng), được đưa ra bởidecode run --hitl. Năm thực tế đóng khung trước khi thực hiện không lường trước được, từng xác nhận bằng cách tăng vọt local stack thật nhé:- Lực HITL
checkpoint_strategy="calls"— khôngsettings.runtime_checkpoint_strategy. Việc chọn không tham gia điểm kiểm tra trên mỗi công cụ nâng cao phạm vi chờ chuyển luồng chỉ được chấp nhận theo"calls"; dưới"turn"điểm kiểm tra lần lượt duy nhất sẽ kết thúc công cụ và thời gian chờ tăng lên "phải ở phạm vi luồng". Vì vậy, "theo lượt không cần chọn không tham gia" của AC không có giá trị đối với thực sự đang chờ HITL chạy —"turn"không thể lưu trữ phạm vi luồng chờ đợi chút nào.runtime_checkpoint_strategydo đó chỉ chi phối việc chạy vòng. - Công cụ chỉ đọc phải chạy nội tuyến hoặc lần chạy HITL bị tạm dừng/gặp sự cố trong lần chạy đầu tiên
read. Dướirun_synckhông có vòng decode nào áp dụng tầng cho phép chỉ đọc của cổng, do đó, cờ deps mớiAgentDeps.headless_durable_waitslàm choneeds_approvaltự áp dụng nó: chỉ đọc → nội tuyến, đột biến →ApprovalRequired→ chờ đợi bền bỉ. Các đại diện tương tác để lại cờFalse(byte không thay đổi). Bản đồ chọn không tham gia chỉ là công cụ chờ —write/edit/bash+ask_user/exit_plan_mode. ask_user/exit_plan_modecầu quaresolve_user_question→wait_for_input; phê duyệt là bản gốc của bộ chuyển đổiApprovalRequired → wait.resolve_permissionlà không cầu phê duyệt dướirun_sync(không có vòng lặp nào gọi nó) - nó vẫn là mạng lưới an toàn từ chối. các trình phân giải không đồng bộ gọi đồng bộ hóawait_for_inputtrực tiếp (khônganyio.to_thread): dướirun_sync+allow_sync_tool_body_waits=Truevòng lặp sự kiện của agent chạy trên vòng lặp sự kiện của Kitaru luồng quy trình làm việc, đây là nơi phải tạo chờ trong phạm vi luồng. Giới hạn đã biết —runtime_wait_timeout_schỉ phạm vi các ổ đĩa decode chờ. Bởi vìwait_for_inputlà cuộc gọi của chính bộ decode, nó sẽ vượt quatimeout=runtime_wait_timeout_s, vì vậyask_user/exit_plan_modecâu hỏi chờ đợi vinh dự thiết lập. cácwrite/edit/bashphê duyệt thời gian chờ được tạo bên trong bộ chuyển đổi từApprovalRequirednhưkitaru.wait(timeout=None), quay lại bản sửa lỗi của ZenML600smặc định - họ bỏ quaruntime_wait_timeout_s(một buổi chạy trực tiếp vớiRUNTIME_WAIT_TIMEOUT_S=6vẫn ghi nhật kýtimeout=600s). Việc thực hiện cài đặt chờ phê duyệt sẽ yêu cầu hủy bỏ bộ chuyển đổi_invoke_wait; decode cơ sở hạ tầng nhập khẩu thay vì phân nhánh nó, vì vậy sự khác biệt là được ghi lại và trì hoãn, không được vá lỗi.- ** Phê duyệt bị từ chối DỪNG quá trình chạy; nó không phản hồi lại mô hình.** Bộ điều hợp giải quyết
từ chối bằng cách nâng cao
_ToolApprovalDeniedra khỏirun_sync- không có pydantic-ai từ chối kết quả chuyến đi khứ hồi, vì bộ chuyển đổi chặn mọiApprovalRequiredvà không bao giờ cho phép nó nổi lên như mộtDeferredToolRequestsdòng chảy có thể được điều khiển bằng tay. Dòng chảy bắt lấy nó và kết thúc bằng thông báo từ chối (công cụ bị từ chối không bao giờ chạy). Đây là nơi duy nhất không có đầu HITL khác với cổng tương tác (trả về lý do từ chối và cho phép mô hình thích nghi); đường dẫn phản hồi khi bị từ chối sẽ cần các công cụ thay đổi của bộ decode để kết nối các phê duyệt bản thân họ thay vì nâng caoApprovalRequired- được hoãn lại như một biện pháp tiếp theo có thể. "calls"+ từ chối phá vỡ Kitaru.wait()trích xuất giá trị trả về (một số terminal điểm kiểm tra yêu cầu mô hình →_MultipleTerminalStepsOutputError). Luồng lưu trữ kết quả cuối cùng của nó văn bản kết thúc@checkpointnhư một hiện vật được đặt tên (decode_runtime_output) và người đọc tải lại theo tên; một lần chạy bị tạm dừng (chờ chưa được giải quyết) không trả về tạo tác nào và trình đọc báo cáo bị tạm dừngexec_id. Kiểm tra ngoại tuyến giải quyết từng lần chờ đợi nội tuyến bằng cách vá lỗi của Kitaru đường nối đầu vào tương tác cục bộ (nềnKitaruClient.inputluồng khởi tạo lại ZenML lưu trữ theo luồng và chạy SQLite; sau thời gian chờresumecần một luồng được triển khai trong quá trình thiếu ngăn xếp cục bộ).
- Lực HITL
-
sleep→ bộ hẹn giờ bền bỉ, có thể tiếp tục sử dụng. Ở chế độ dòng chảy,sleepcông cụ (tools/sleep.py:37, hôm nay trần trụiasyncio.sleep) trở thànhkitaru.wait(name="sleep", timeout=…)— việc thực thi có thể tạm dừng và quá trình thoát ra, sau đó tiếp tục. Chế độ tương tác giữasyncio.sleep. Bề mặt dụng cụ đơn giống nhau, thực hiện phụ thuộc vào chế độ. -
Proxy thông tin xác thực = Bí mật Kitaru tại đường nối mô hình-xây dựng. Ở chế độ luồng, hãy thay thế trực tiếp
settings.<provider>_api_key.get_secret_value()khi xây dựng mô hình (agent/factory.py:115) với Kitaruget_secret(...)/llm()độ phân giải bí danh, do đó tải trọng luồng được triển khai mang theo tay cầm, không phải khóa thô - đáp ứng bất biến tải trọng bí mật không bao giờ có trong trường hợp này điều đó thực sự quan trọng (một luồng được thực hiện từ xa). Các hoạt động tương tác trong quá trình tiếp tục đọcSecretStrtừ cài đặt. Đây là bề mặt Kitaru ít được lấy mẫu nhất — không có Agent Harness Ví dụ về nền tảng nối khóa mẫu thông qua các bí mật (ví dụ về proxy thông tin xác thực đưa vào tiêu đề HTTP hộp cát) và vì bộ điều hợp PydanticAI cần một mô hình cụ thể khi xây dựng, đường dẫn được tài liệu hỗ trợ là env tiêm (ImageSettings(secret_environment_from=[...])). Vậy nhiệm vụ 061 xác minh API bí mật dựa trên SDK đã cài đặt trước tiên và gửi tính năng tiêm env dưới dạng dự phòng được ghi lại; đường dẫn được chọn tham gia (runtime_secret_store_model_key, mặc định tắt).Sửa đổi (29-06-2026, nhiệm vụ 064 — kiến trúc thông tin xác thực được sửa theo Kitaru chính thức tài liệu proxy thông tin xác thực (
agent-harness-platform/04-credential-proxy) + cáiagent_harness_platformví dụ, Giai đoạn 4). Điều §5 này kết hợp hai tính năng khác biệt của Kitaru và xác định sai phạm vi cơ chế. Đã sửa, tác vụ tiêm env được soạn thảo từ §5 ban đầu đã bị loại bỏ:- "Proxy thông tin xác thực" là một cách viết sai. Proxy thông tin xác thực thực tế của Kitaru là tiêu đề HTTP
tiêm qua vùng chứa proxy riêng —
SandboxProxyRule(mẫu tiêu đề trên mỗi máy chủ) +build_credential_map(trình phân giải mẫu phía máy chủ) +DockerProxy(một tiện ích bổ sung mitmproxy). các lưu lượng truy cập đi của công nhân được định tuyến thông qua proxy, gắn vớiAuthorizationtiêu đề sau khi yêu cầu đã rời khỏi nhân viên, vì vậy "nhân viên không bao giờ giữ bí mật." Nhiệm vụ 061 đã giao là không cái đó - đó là tra cứu kho bí mật (get_secret(...)) cho khóa API mô hình khi xây dựng mô hình. Cả hai đều hợp pháp nhưng khác nhau; chìa khóa mô hình là trường hợp phù hợp cho tra cứu cửa hàng (harness sử dụng nó để gọi LLM — nó không phải là thông tin xác thực do model chọnbashsử dụng lệnh). Nhãn "Proxy thông tin xác thực" của 061 được đổi tên độ phân giải bí mật của khóa mô hình để giải phóng thuật ngữ cho proxy thực. (Đây là khái niệm / docs đổi tên — mã định danhruntime_credentials_proxy_enabled/runtime_secret_namegiữ tên của họ cho đến khi đổi tên riêng, sự phân kỳ giữa khái niệm và nhận dạng được ghi lại.) Việc đổi tên chuyên dụng đã được thực hiện — xem bản sửa đổi 2026-07-13 bên dưới. - Việc tiêm Env bị từ chối do cơ chế bí mật. §5 có tên là tiêm env
(
ImageSettings(secret_environment_from=[...])) làm dự phòng. Tài liệu chính thức lập luận trực tiếp chống lại nó: "nếu một token tồn tại trong môi trường của agent, agent có thể rò rỉ nó." Đưa bí mật vào môi trường công nhân/quy trình là vectơ rò rỉ chính xác mà proxy thông tin xác thực tồn tại để xóa, do đó việc decode không sử dụngsecret_environment_fromvì những bí mật. (secret_environment_fromtrong mọi trường hợp đều là tùy chọn transport/deployment — không hoạt động trên ngăn xếp nội bộ trong quá trình — vì vậy nó cũng không mua gì ở địa phương.) - Thay vào đó, nhiệm vụ 064 được giao là gì — một repository bí mật nguồn cấu hình. Tổng quát hóa khóa đơn của 061
tra cứu nguồn tùy chỉnh cài đặt pydantic (
KitaruSecretSettingsSource) cái đó, headless chỉ (decode run, được kiểm soát bởiruntime_secret_store_config, mặc định tắt), dưỡng ẩm toàn bộ.env.examplebề mặt từ một bí mật Kitaru vàoSettingsđối tượng - không bao giờos.environ, không bao giờ là một công nhân env — vì thế một model được chọnbashkhông bao giờ kế thừa nó. Ưu tiên: môi trường thực sự > Bí mật của Kitaru >.env> mặc định. Singleton được xây dựng lại tại chỗ cho dòng chảy span và được khôi phục khi thoát (_durable_sleeperthiết lập lại kỷ luật); REPL không bao giờ nhập khẩu kitaru (nguồn không hoạt động và bỏ qua quá trình nhập khi không hoạt động). Quy tắc quản lý, một dòng: Bí mật của Kitaru →Settings, vâng; → quy trình/công nhân env, không. (get_secret/create_secretlà Của Kitaru; decode chỉ thêm phần đọc vàoSettingshội nhập. Bảng chú giải thuật ngữ "Thông tin xác thực Thuật ngữ Proxy" được chia theo cùng một cách: repository bí mật + nguồn cấu hình repository bí mật bây giờ; Thông tin xác thực Proxy dành riêng cho tính năng chèn tiêu đề.) - Proxy thông tin xác thực thực sự được trì hoãn theo cột mốc hộp cát — nó cần một
công nhân ngồi trước mặt (hôm nay
bashchạy trong quá trình thông quaLocalExecutor). Sự tích hợp của nó thiết kế hiện đã được sửa trong "Công việc trong tương lai — Proxy thông tin xác thực ở bước hộp cát" bên dưới; nó sẽ có ADR triển khai riêng khi được xây dựng.
Sửa đổi (13-07-2026 — đổi tên mã định danh chuyên dụng). Sửa đổi ngày 29-06-2026 đã được đổi tên khái niệm nhưng cố tình để các mã định danh khác nhau, như một IOU. Với thực tế Proxy thông tin xác thực hiện đã được xuất xưởng (ADR-0011 §6, ADR-0012 §10), sự khác biệt đó đã tạo nên hai tính năng thực sự không thể phân biệt được theo tên trong mã,
.env.examplevà README - người đọc liên tục nhầm lẫn việc tra cứu cửa hàng bí mật với việc chèn tiêu đề. IOU được thanh toán; các số nhận dạng bây giờ khớp khái niệm:Đã Là RUNTIME_CREDENTIALS_PROXY_ENABLED/runtime_credentials_proxy_enabledRUNTIME_SECRET_STORE_MODEL_KEY/runtime_secret_store_model_keyresolve_provider_key_via_proxy()resolve_provider_key_from_secret_store()PROXY_SECRET_KEYSECRET_STORE_KEY_uses_credentials_proxy()/_proxy_credential_error()(cli)_uses_secret_store_model_key()/_model_key_secret_error()Hai núm bây giờ được đọc như một gia đình đối với một bí mật được đặt tên bởi
runtime_secret_name:RUNTIME_SECRET_STORE_MODEL_KEYchỉ lấy khóa mẫu từ nó,RUNTIME_SECRET_STORE_CONFIGchiếm toàn bộ bề mặt cấu hình. Cả hai đều chọn tham gia và chỉ không có đầu, và cả hai vẫn khả dụng — với cả hai phím tắt đều đến từ.env, đó là điểm của việc giữ núm vặn hẹp hơn thay vì gập vào nguồn cấu hình. Thay đổi đột phá: hiện cóRUNTIME_CREDENTIALS_PROXY_ENABLED=truetrong một.envhiện bị bỏ qua một cách âm thầm (pydantic-settings không không có lỗi trên các bình không xác định); đổi tên nó. Không có bí danh tương thích nào được cung cấp - cơ sở mã giảng dạy sẽ tốt hơn được phục vụ bởi một tên thay vì hai tên mà cả hai đều hoạt động.docs/glossary.mdvàcredentials.md(thực hiện bài kiểm tra e2e cho cả hai tính năng, bật và tắt) mang phiên bản hướng tới người dùng.Sửa đổi (13-07-2026 — được thay thế bởi ADR-0015, Nhóm Môi trường). Mọi thứ §5 và nó hai sửa đổi ở trên nêu rõ về nguồn gốc của thông tin xác thực bị xóa:
RUNTIME_SECRET_NAME,RUNTIME_SECRET_STORE_CONFIG,RUNTIME_SECRET_STORE_MODEL_KEY, cái chuyển đổi quá trình hydrat hóa toàn cầu của mô-đun không có giao diện người dùng và bối cảnh chụp nhanh/khôi phục theo từng luồng đã không còn nữa, không có miếng chêm (cũ.envmục nhập được âm thầm bỏ qua). Chúng được thay thế bởiDECODE_ENV-có cổng Nhóm môi trường — bí mật bắt nguồn từ Kitarudecode-<env>, hoạt động trong TUI và headless giống nhau, với.envrơi khỏi chuỗi tại một env từ xa - xem ADR-0015 §§1–5. Các bất biến §5 được thiết lập chuyển tiếp không thay đổi: giá trị nằm trongSettingschỉ (không bao giờos.environ/ một env công nhân), env quy trình thực vẫn thắng và quy tắc an toàn REPL được trình bày lại là tạiDECODE_ENV=local(mặc định), decode không bao giờ nhập kitaru. Phần còn lại của ADR này (dòng bền, điểm kiểm tra, thời gian chờ HITL, độ bềnsleep) không bị ảnh hưởng. - "Proxy thông tin xác thực" là một cách viết sai. Proxy thông tin xác thực thực tế của Kitaru là tiêu đề HTTP
tiêm qua vùng chứa proxy riêng —
-
Lập lịch/cron là bên ngoài - decode gửi điểm vào có thể triển khai chứ không phải bộ lập lịch. Bởi vì Kitaru không có cron gốc, các lần chạy định kỳ là:
kitaru deploydòng chảy + một kích hoạt bên ngoài. Bước 7 cung cấp điểm vào luồng có thể triển khai và ghi lại trình kích hoạt; ** lịch trình định kỳ thực sự đến bước 12** thông qua hạng nhất của Modalschedule=modal.Cron(...). Chúng tôi không cuộn bằng tay lập lịch để decode. -
Bề mặt toán tử (bắt đầu cục bộ, từ xa sau). Khởi chạy thông qua đối tượng luồng /
decode run/ MCPkitaru_executions_run; kiểm tra + giải quyết chờ + phát lại qua CLI và KitaruClient; duyệt qua tạo tác thông qua KitaruClient/MCP. Bắt đầu trên ngăn xếp cục bộ (uv sync --extra local;kitaru initđánh dấu gốc dự án bằng.kitaru/) — đã xác nhận để chạy hoàn toàn ngoại tuyến mà không cần máy chủ Kitaru (máy chủ chỉ lưu trữ siêu dữ liệu; các luồng chạy ở nơi được thực thi). CI và capstone (nhiệm vụ 062) ở lại ngoại tuyến bằng cách vá đường nối runtime và ranh giới mô hình, chính xác như tính năng LSP vá nó đường may dịch vụ. Ngăn xếp từ xa (cho bước 12) được CLI/MCP tạo sau. -
Cùng tồn tại với nhật ký phiên JSONL — không di chuyển nó. Độ bền tương tác vẫn được duy trì JSONL +
--resume; độ bền headless là điểm kiểm tra/phát lại Kitaru. Hai chế độ, hai cơ chế, mộtbuild_agent(). Việc hợp nhất chúng vào Kitaru rõ ràng không phải là mục tiêu ở đây (xem Hậu quả).
Sơ đồ
flowchart TB
subgraph shared["shared core (unchanged)"]
ba["build_agent() — agent/factory.py:68<br/>pydantic-ai Agent + tools + instructions"]
end
subgraph interactive["INTERACTIVE path (untouched)"]
tui["decode (TUI) → Runner → agent.iter()<br/>streaming · steer/abort/follow-up (Boundary)"]
jsonl[("JSONL session log + --resume<br/>context/session_log.py")]
consoleR["resolve_user_question → console prompt"]
tui --> ba
tui --> jsonl
tui --- consoleR
end
subgraph headless["HEADLESS path (NEW: src/decode/runtime/)"]
run["decode run \"task\" / deployed endpoint / MCP run"]
flow["@flow run_agent_task(task)"]
kagent["KitaruAgent(build_agent's Agent)<br/>checkpoints per model/tool call (per-turn if streaming)"]
waitb["resolve_user_question → kitaru.wait()<br/>(ask_user + permission approvals + sleep-timeout)"]
secrets["model creds via kitaru get_secret / llm() alias<br/>handles, not raw keys"]
run --> flow --> kagent --> ba
flow --- waitb
kagent --- secrets
end
subgraph ops["operator surface"]
cli["CLI: kitaru executions input / replay / logs"]
client["KitaruClient: inspect · pending_waits · artifacts"]
deploy["kitaru deploy + EXTERNAL trigger (cron/Modal Cron) → step 12"]
end
waitb -. paused .-> cli
flow -.-> client
flow -.-> deploy
classDef core fill:#37474f,stroke:#102027,color:#ffffff;
classDef inter fill:#1565c0,stroke:#0d47a1,color:#ffffff;
classDef head fill:#2e7d32,stroke:#1b5e20,color:#ffffff;
classDef opsc fill:#e65100,stroke:#bf360c,color:#ffffff;
class ba core;
class tui,jsonl,consoleR inter;
class run,flow,kagent,waitb,secrets head;
class cli,client,deploy opsc;
hậu quả
runtime/kiếm được chứ không phải sớm. Dòng chảy headless là người gọi thứ hai thực sựbuild_agent(), do đó mô-đun mới đáp ứng yêu cầu "không trừu tượng hóa mà không có giây phút" của AGENTS.md thực hiện." Kitaru được nhập và gọi trực tiếp (không có trình bao bọc cổng) cho đến bề mặt thứ ba buộc một.- Bỏ chặn các bước 12 và 13. Bản chất, người đánh giá PR triển khai sang phương thức và đám mây không được giám sát; họ cần chính xác luồng headless, có thể phát lại, tạm dừng chờ này. Xây dựng nó bây giờ là nền tảng cho cả hai.
- Kênh quyết định duy nhất mang lại kết quả. Bởi vì
ask_uservà phê duyệt quyền đã chia sẻ mộtresolve_user_questionđường may, HITL trở thành hoán đổi bộ giải quyết cho mỗi chế độ thay vì chênh lệch thay đổi trên mọi công cụ có kiểm soát. - Truyền phát được bảo toàn; TUI "hợp nhất" là sự trì hoãn Giai đoạn 2 có chủ ý. Kitaru có thể phát trực tuyến
(cái
checkpoint_streamingtính năng), do đó, bước sau có thể tạo ra dòng chảy của động cơ duy nhất và quay TUI thành một ứng dụng khách phát trực tiếp giải quyết vấn đề chờ tại chỗ — trạng thái phía máy chủ / cấu trúc liên kết truyền phát tới khách hàng từ wiki nghiên cứu dự án (comparisons/application-state-3way). các con đường headless không đóng được cánh cửa đó; nó mở nó ra. - Không có bộ lập lịch nào được xây dựng — nền tảng được mượn. Kitaru không có cron gốc, vì vậy chúng tôi gửi một
điểm vào có thể triển khai và để Modal/cron kích hoạt nó. Tạm dừng bền một lần (
sleep, thời gian chờ) là bản xứwait()s. - Rủi ro trung thực. (a) Đã giải quyết khi sắp xếp: ranh giới không đồng bộ/luồng được xử lý bởi bộ điều hợp —
Kitaru
@flowlà đồng bộ vàKitaruAgent.run_sync()kết nối agent pydantic-ai async nội bộ, do đó nội dung luồng không cần vòng lặp sự kiện/không đồng bộ thủ công. Đường may còn lại là ** không đồng bộ trình giải quyết quyết định → đồng bộ hóakitaru.wait/wait_for_input** cầu nối cho HITL (nhiệm vụ 059) và bền bỉsleep(nhiệm vụ 060), được xác nhận sớm dựa trên SDK đã cài đặt (allow_sync_tool_body_waits=Truekhi cần thiết); nhiệm vụ 059/060 mang AC giảm rủi ro rõ ràng. (b) Kitaru0.18là pre-1.0 — ghim quauv.lock, chấp nhận sự gián đoạn, giữ cho runtime bị cô lập mô-đun. (c) Truyền trực tuyến bộ điều hợp ** làm rõ hơn ** mức độ chi tiết của điểm kiểm tra từ mỗi cuộc gọi đến mỗi lượt — chấp nhận được cho một hoạt động không cần giám sát. - CI vẫn ngoại tuyến. Luồng Kitaru chạy trên ngăn xếp cục bộ; kiểm tra đơn vị vá runtime đường nối (không có máy chủ, không có mạng), phản ánh cách kiểm tra dịch vụ LSP (ADR-0007). Capstone e2e chỉ hoán đổi ranh giới mô hình.
- Bảng thuật ngữ + cài đặt tăng lên. Các thuật ngữ bằng ngôn ngữ phổ biến được đưa vào
docs/glossary.md(runtime headless, Luồng bền vững, Điểm kiểm tra, Phát lại, Chờ (HITL); cộng — theo bản sửa đổi 29-06-2026 §5 — Cấu hình lưu trữ bí mật và Proxy thông tin xác thực dành riêng, thay thế đơn gốc Thuật ngữ "Proxy thông tin xác thực") và cài đặt runtime (runtime_enabled,runtime_checkpoint_strategy,runtime_wait_timeout_s,runtime_secret_store_model_key,runtime_secret_namevàruntime_secret_store_configđược thêm vào nhiệm vụ 064) trongconfig/settings.py.env.example— bảng thuật ngữ được áp dụng ở cổng kế hoạch, các cài đặt đã được đưa vào nhiệm vụ 057 trước độc giả của chúng ( LSP/mẫu cài đặt nén đầu tiên). Ngăn xếp Kitaru được chọn bởikitaru init/ Của riêng Kitaru config, không phải cài đặt decode.
- Không có mục tiêu (cố ý). Bao bọc REPL trực tiếp theo một luồng; di chuyển nhật ký phiên JSONL vào Kitaru; cron gốc bên trong decode; API trạng thái khóa-giá trị bền vững gốc (sử dụng các tạo phẩm / bên ngoài nhà nước); phối hợp đa luồng; và ngăn xếp từ xa (chuyển sang bước 12). Dòng chảy đơn headless lát là điểm mở rộng nếu có được xem lại.
Công việc trong tương lai - Proxy thông tin xác thực ở bước hộp cát (cách nó sẽ tích hợp)
Bản sửa đổi §5 đã đổi tên việc tra cứu khóa mẫu của 061 và ghi lại rằng Proxy thông tin xác thực thực của Kitaru
được hoãn lại. Nó được hoãn lại vì lý do cấu trúc: proxy là một quá trình nằm giữa một
nhân viên bị cô lập và mạng, và bộ decode chưa có nhân viên bị cô lập nào — bash chạy trong quá trình thông qua
LocalExecutor. Trong kinh điển agent_harness_platform ví dụ proxy là Giai đoạn 4, đúng vậy
sau Giai đoạn 2 (hộp cát Docker). Vì vậy, proxy đạt được cột mốc hộp cát của decode, đã xây dựng
cách kinh điển. Việc tích hợp đã được khắc phục ở đây (nó có ADR triển khai riêng khi được xây dựng) vì vậy
cửa hàng bí mật hoạt động trên các khe cắm vào đó mà không cần làm lại.
Nguyên tắc ranh giới thông tin xác thực (toàn bộ điểm). Phía chạy các lệnh do mô hình chọn không giữ bí mật; bên giữ bí mật không chạy lệnh do mô hình chọn. Một agent được đưa vào dấu nhắc có thể đọc bất cứ thứ gì trong môi trường của nó — vì vậy không có token nào đi vào env của công nhân. Người công nhân gửi yêu cầu; một quy trình riêng biệt sẽ đính kèm thông tin xác thực sau khi yêu cầu đã rời khỏi nhân viên.
Ba phần và cách mỗi phần tích hợp với các thành phần hiện có:
SandboxProxyRule— bề mặt cấu hình mới (tích hợp với cấu hình Hồ sơ/agent). Khai báo, trên mỗi máy chủ, tiêu đề nào sẽ được đưa vào mẫu bí mật, ví dụ:SandboxProxyRule(name="github-auth", hosts=["api.github.com"], headers={"Authorization": "Bearer {{ github-token.value }}"}). Đây là danh sách các quy tắc trên agent/hồ sơ - khác biệt và bổ sung cho cửa hàng bí mật nguồn cấu hình (064). Nguồn cấu hình = cài đặt riêng của harness; quy tắc proxy = công cụ' thông tin xác thực cuộc gọi đi.build_credential_map(...)— tích hợp với repository bí mật. Khi bắt đầu luồng, trên máy chủ, nó giải quyết từng{{ name.key }}mẫu bằng cách gọikitaru.get_secret(name).values- tức là proxy được xây dựng dựa trên cùng repository bí mật Kitaru mà §5/064 đã sử dụng. Một cửa hàng, nhiều cửa hàng người tiêu dùng; không có phụ trợ bí mật mới. Việc giải quyết{host: {header: value}}bản đồ chỉ được trao cho môi trường của bộ chứa proxy — không bao giờ là của nhân viên.DockerProxy— tiêm (tích hợp với hộp cátrunđường may). Một tiện ích bổ sung mitmproxy đang chạy bên cạnhDockerSandbox; của công nhânhttp_proxy/https_proxychỉ vào nó và nó tin tưởng CA của proxy. Tiện ích bổ sung khớp máy chủ của từng yêu cầu với bản đồ thông tin xác thực và đưa tiêu đề vào quá cảnh, vì vậycurl https://api.github.com/...từ người công nhân thành công mặc dù người công nhân chưa bao giờ nắm giữ một token.DockerProxy+SandboxProxyRulelà hai điểm trao đổi nếu mitmproxy được thay thế.
Cách nó kết hợp với phần còn lại của decode:
- Cửa hàng bí mật (§5 / 061 / 064): một cửa hàng, ba người tiêu dùng phía máy chủ — (a) 061 model-key
độ phân giải, (b) 064 nguồn cấu hình kho bí mật (→
Settings), (c)build_credential_map(→ ủy quyền thùng đựng). Không ai trong số ba người đặt bí mật công cụ cho công nhân. - Hộp cát
runđường may (AGENTS.md "sự trừu tượng thực sự"): proxy yêu cầu hộp cát cách ly vùng chứa + mạng, đó chính xác là lý do tại sao nó không thể đi trước bước hộp cát. các hộp cát nhận biết proxy được kết nối tạirunđường may (Docker/Firecracker cục bộ, Modal từ xa), không ở trên nó. bashhôm nay và lúc đó. Hôm nayLocalExecutorbashkế thừaos.environ, đó là tại sao 064 nguồn cấu hình cố tình ghi vàoSettingsvà không bao giờos.environ. Một lầnbashchạy trong nhân viên hộp cát, nhân viên giữ không thông tin xác thực và các cuộc gọi được xác thực sẽ đi qua proxy — thu hẹp khoảng cách "khôngos.environwrite" sẽ bảo vệ tạm thời.- Đã nhập các dịch vụ dưới dạng đường dẫn thông tin xác thực thứ hai (ví dụ Giai đoạn 5). Đối với các cuộc gọi có cấu trúc, phía máy chủ
exec_servicecông văn có thể chứa thông tin xác thực mà nhân viên không bao giờ chạm vào - bỏ qua cả shell và proxy. Một ứng cử viên cho việc decodeservices/lớp khi có nhu cầu. modal: proxy kép của nó token (MODAL_PROXY_TOKEN_ID/_SECRET) là bề mặt tiêu đề yêu cầu - hình dạng tương tự mà proxy này đưa vào - đó là lý do tại sao §5/061 cố tình rời đimodalra khỏi đường dẫn lưu trữ bí mật/khóa mô hình. thông tin xác thực của phương thức thuộc về bước proxy này, không phải tra cứu khóa mô hình.
Phần này là mục đích thiết kế, không phải là một tính năng được xây dựng. Phần này đi kèm với cột mốc hộp cát và sẽ được được ghi lại trong ADR triển khai của chính mình (cơ chế, phá bỏ container, kiểm tra) tại thời điểm đó.