loci-preflight
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chineseloci-preflight
loci-preflight
This skill is a thinking tool, not a write-gate. Run it during planning —
while you are still deciding what to write — so the execution fit is visible
before any code changes. The output shapes how you write, not just whether.
Preflight requires compiled artifacts. It does not fall back to source-level
reasoning. If the project cannot be compiled or the architecture is not
supported, the skill stops and tells the user why.
本Skill是思考工具,而非代码提交门禁。请在规划阶段运行它——也就是你还在决定编写什么内容的时候——这样你就能在修改任何代码之前直观看到执行适配性。它的输出会指导你如何写代码,而不仅仅是判断能不能写。
预检需要编译产物,它不会回退到源码级推理。如果项目无法编译,或者架构不被支持,该Skill会停止运行并告知用户原因。
When to run
何时运行
Run preflight as part of forming your plan, immediately after you understand
what function(s) you need to write and before you issue any Edit/Write call:
- User describes the task
- You read the relevant files to understand the call site and surrounding code
- ← run preflight here, while thinking
- Adjust the plan based on findings
- Write the code
Plan mode: Always emit the full preflight report (Execution, CFG Analysis,
Execution fit, footer) in the response text — never inside the plan body.
The plan body should contain only the adjusted implementation steps that
incorporate preflight findings. The user must see the complete structured
report in the response, not a summary buried in the plan context.
在你明确需要编写哪些函数之后、发起任何编辑/写入调用之前,把预检作为制定计划的一环运行:
- 用户描述任务
- 你阅读相关文件,理解调用点和周边代码
- ← 在此处思考阶段运行预检
- 根据分析结果调整计划
- 编写代码
计划模式: 请始终在响应文本中输出完整的预检报告(执行、CFG分析、执行适配性、页脚)——永远不要放在计划正文里。计划正文只应包含结合预检结果调整后的实现步骤。用户必须在响应中看到完整的结构化报告,而不是埋藏在计划上下文里的摘要。
Step 0: Check session context
步骤0:检查会话上下文
Check that loci MCP is connected and authenticated, you see the tools before
running the preflight steps that require it. If the MCP is unavailable, tell
the user:
LOCI MCP server is not connected. Please runin Claude Code to manage MCP servers, then approve the loci server. If it does not appear, restart Claude Code — the plugin registers it automatically on startup./mcp
For plugin to work mcp should be authenticated and connected.
Read the persisted detection results from in the
plugin directory. This file is written once by setup.sh at session start and is
the single source of truth for compiler, architecture, and build system.
Do NOT re-run detection scripts.
state/project-context.jsonjson
{
"compiler": "...",
"build_system": "...",
"architecture": "...",
"loci_target": "...",
...
}If the file does not exist, stop and tell the user:
LOCI session context not found. Please restart Claude Code so the plugin setup runs and detects the project environment.
Also check the block emitted at session start for:
system-reminderTarget: <target>, Compiler: <compiler>, Build: <build>
LOCI target: <loci_target>Map the LOCI target to loci MCP supported architectures and binary targets:
| LOCI target | Time from CPU |
|---|---|
| aarch64 | A53 |
| armv7e-m | CortexM4 |
| armv6-m | CortexM0P |
| tc3xx | TC399 |
The CPU column identifies which real silicon hardware the LOCI timing and
energy predictions are traced from.
If the architecture is not in this table, emit and stop:
undefined运行需要loci MCP的预检步骤前,请先确认loci MCP已连接且完成认证,你能看到对应的工具。如果MCP不可用,告知用户:
LOCI MCP server is not connected. Please runin Claude Code to manage MCP servers, then approve the loci server. If it does not appear, restart Claude Code — the plugin registers it automatically on startup./mcp
插件正常工作需要MCP完成认证并连接。
读取插件目录下中持久化的检测结果。该文件由setup.sh在会话启动时写入一次,是编译器、架构和构建系统的唯一可信来源。请勿重新运行检测脚本。
state/project-context.jsonjson
{
"compiler": "...",
"build_system": "...",
"architecture": "...",
"loci_target": "...",
...
}如果该文件不存在,停止运行并告知用户:
LOCI session context not found. Please restart Claude Code so the plugin setup runs and detects the project environment.
同时检查会话启动时输出的块,确认包含以下内容:
system-reminderTarget: <target>, Compiler: <compiler>, Build: <build>
LOCI target: <loci_target>将LOCI目标映射到loci MCP支持的架构和二进制目标:
| LOCI target | Time from CPU |
|---|---|
| aarch64 | A53 |
| armv7e-m | CortexM4 |
| armv6-m | CortexM0P |
| tc3xx | TC399 |
CPU列指明了LOCI时序和能耗预测所基于的真实硅硬件。
如果架构不在该表中,输出以下内容并停止:
undefinedPreflight: STOPPED
Preflight: STOPPED
Architecture not supported.
Supported: aarch64 , armv7e-m , armv6-m , tc3xx
Preflight requires compiled artifacts — it does not fall back to source-level reasoning.
If no compiler was detected, emit and stop:
Architecture not supported.
Supported: aarch64 , armv7e-m , armv6-m , tc3xx
Preflight requires compiled artifacts — it does not fall back to source-level reasoning.
如果未检测到编译器,输出以下内容并停止:
Preflight: STOPPED
Preflight: STOPPED
No compiler detected in session context.
Preflight requires compiled artifacts — it does not fall back to source-level reasoning.
Action: resolve the build environment, then re-run preflight.
undefinedNo compiler detected in session context.
Preflight requires compiled artifacts — it does not fall back to source-level reasoning.
Action: resolve the build environment, then re-run preflight.
undefinedStep 1: Compile or locate artifact
步骤1:编译或定位产物
The goal is to obtain a compiled artifact containing the callees the new code
will invoke. Partial compilation with files is the primary path — you do
NOT need a fully linked binary.
.oThis works for all supported platforms and compilers — the flag is
universal across gcc, clang, tiarmclang, arm-none-eabi-gcc, tricore-elf-gcc,
etc. Use the compiler and target detected in Step 0.
-cPrimary path: partial compilation
.o- If a previous exists for the source file, save it as
.o(this enables delta reporting in Step 3)..o.prev - Compile only the relevant source file with . Always include
-cto emit DWARF debug info (required by asm-analyze):-g<compiler> -g <flags> -c <source> -o <basename>.o - Validate the .o — a standalone compile can exit 0 yet produce an empty object file when the source is wrapped in
-c/#ifguards whose defines (#ifdef) were not on the command line. After compiling, run:-DIf the result shows 0 symbols or returns an error mentioning "no code" or "preprocessor", the target function was compiled out. Fall back to the secondary path below.<asm-analyze-cmd> extract-symbols --elf-path <basename>.o --arch <loci_target>
Secondary path: existing binary
Use a full binary (.elf, .out) only if the user explicitly provides one or if
the callees span multiple compilation units and linking is needed.
Even when using the secondary path, you MUST still compile the source file
to with (primary path steps 1–2). The binary is used for
analysis; the is required for the snapshot pipeline — the PreToolUse
hook snapshots it as before each Edit, enabling delta comparison in
post-edit. Skipping the compilation breaks the entire pre/post chain.
.o-c -g.o.o.prev.oHard stop: no compilation possible
If there is no binary, no , and compilation is not possible (missing
dependencies, build errors, etc.), the skill MUST stop:
.oundefined目标是获取包含新代码将要调用的被调用方的编译产物。文件的部分编译是主要路径——你不需要完全链接的二进制文件。
.o这适用于所有支持的平台和编译器——参数在gcc、clang、tiarmclang、arm-none-eabi-gcc、tricore-elf-gcc等编译器中都是通用的。使用步骤0中检测到的编译器和目标。
-c主要路径:部分编译
.o- 如果源文件已有之前生成的文件,将其保存为
.o(这支持步骤3中的增量报告)。.o.prev - 仅使用参数编译相关源文件,始终包含
-c参数输出DWARF调试信息(asm-analyze需要该信息):-g<compiler> -g <flags> -c <source> -o <basename>.o - 验证文件——当源文件被
.o/#ifguard包裹,且命令行中没有对应的定义(#ifdef)时,单独的-D编译可能返回退出码0但生成空目标文件。编译完成后运行:-c如果结果显示0个符号,或者返回提到“no code”或“preprocessor”的错误,说明目标函数被编译掉了,请回退到下面的次要路径。<asm-analyze-cmd> extract-symbols --elf-path <basename>.o --arch <loci_target>
次要路径:现有二进制文件
仅当用户明确提供完整二进制文件(.elf、.out),或者被调用方跨多个编译单元需要链接时,才使用该路径。
即便使用次要路径,你仍然必须按照主要路径的步骤1-2将源文件编译为带参数的文件。 二进制文件用于分析;文件是快照流水线的必需项——PreToolUse钩子会在每次编辑前将其快照为,支持编辑后的增量对比。跳过编译会破坏整个前后校验链。
-c -g.o.o.o.prev.o强制停止:无法编译
如果没有二进制文件、没有文件,且无法完成编译(依赖缺失、构建错误等),该Skill必须停止:
.oundefinedPreflight: STOPPED
Preflight: STOPPED
No compiled artifact available and compilation is not possible.
Reason: <compilation failed: error | missing headers | missing dependencies>
Preflight requires compiled artifacts — it does not fall back to source-level reasoning.
Action: resolve the build environment, then re-run preflight.
Do NOT proceed with any analysis. Do NOT emit Call graph, Latency, Energy, or
Execution fit lines.No compiled artifact available and compilation is not possible.
Reason: <compilation failed: error | missing headers | missing dependencies>
Preflight requires compiled artifacts — it does not fall back to source-level reasoning.
Action: resolve the build environment, then re-run preflight.
请勿继续任何分析,不要输出调用图、延迟、能耗或执行适配性相关内容。Step 2: Call graph and timing/energy analysis
步骤2:调用图与时序/能耗分析
Read , , and from the LOCI session context (system-reminder at session start). Use these as , , and in the commands below.
asm-analyze command:venv python:plugin dir:<asm-analyze-cmd><venv-python><plugin-dir>The goal is to analyze existing compiled callees — functions the new code will
call — before writing anything.
从LOCI会话上下文(会话启动时的system-reminder)中读取、和,在下面的命令中分别用作、和。
asm-analyze command:venv python:plugin dir:<asm-analyze-cmd><venv-python><plugin-dir>目标是在编写任何代码之前,分析现有已编译的被调用方——也就是新代码将要调用的函数。
Extract assembly
提取汇编
Extract CFGs for the callees the new function will invoke:
<asm-analyze-cmd> extract-assembly --elf-path <.o or binary> --functions <callee_1,callee_2...> --arch <loci_target>The JSON contains the field with annotated CFGs in
text-format optimized for LLM analysis.
control_flow_graphThe JSON output contains , , and fields needed
for the MCP call.
timing_csv_chunkstiming_csvtiming_architecturethe calls for extracting fields from the json output:
data = json.load(...)
cfg_text = data["control_flow_graph"] # all functions, annotated CFG blocks
timing_csv_chunks = data["timing_csv_chunks"] # list of per-block CSV chunks for MCP
timing_architecture = data["timing_architecture"] # timing architecture
提取新函数将要调用的被调用方的CFG:
<asm-analyze-cmd> extract-assembly --elf-path <.o or binary> --functions <callee_1,callee_2...> --arch <loci_target>返回的JSON包含字段,存储了优化后适合LLM分析的文本格式带标注CFG。
control_flow_graphJSON输出还包含MCP调用所需的、和字段。
timing_csv_chunkstiming_csvtiming_architecture从JSON输出提取字段的调用:
python
data = json.load(...)
cfg_text = data["control_flow_graph"] # 所有函数的带标注CFG块
timing_csv_chunks = data["timing_csv_chunks"] # 供MCP使用的逐块CSV分片列表
timing_architecture = data["timing_architecture"] # 时序架构Timing and energy via LOCI MCP
通过LOCI MCP获取时序和能耗数据
Immediately after extraction, get hardware-accurate timing and energy for the
callees:
Call for all chunks in
parallel (one call per chunk, all in the same response):
mcp__loci__get_assembly_block_exec_behavior- : the chunk
csv_text - : the
architecturefield from the output abovetiming_architecture
IMPORTANT: Issue all chunk calls simultaneously in a single message — do NOT
call them sequentially. Concatenate the result CSVs (skip duplicate headers)
before computing per-callee metrics.
Compute per-callee:
- Happy path = -
execution_time_nsstd_dev - Worst path = +
execution_time_nsstd_dev - Energy = (report in uWs; convert from Ws by multiplying by 1e6)
energy_ws
Sum worst-case timings and energy across the hot-path call chain. If the
cumulative chain exceeds a known deadline or energy budget, flag it now —
before any code is written.
If modifying an existing function and a exists, also extract timing
and energy for the baseline (pre-edit) callees. Compute delta:
.o.prevdiff_pct = ((post_value - pre_value) / pre_value) * 100If the MCP is unavailable, skip timing/energy and note
"(timing/energy unavailable — MCP not connected)".
提取完成后,立即获取被调用方的硬件级准确时序和能耗数据:
并行调用所有分片对应的(每个分片一个调用,全部放在同一响应中):
mcp__loci__get_assembly_block_exec_behavior- : 分片内容
csv_text - : 上面输出中的
architecture字段timing_architecture
重要提示:请在单条消息中同时发起所有分片调用——不要顺序调用。计算单被调用方指标前,请拼接所有结果CSV(跳过重复表头)。
计算每个被调用方的指标:
- 最优路径 = -
execution_time_nsstd_dev - 最差路径 = +
execution_time_nsstd_dev - 能耗 = (单位为uWs,从Ws转换需乘以1e6)
energy_ws
累加热路径调用链的最差情况时序和能耗。如果累计链超过已知的截止时间或能耗预算,请在编写代码前就标记出来。
如果是修改现有函数且存在,还需要提取基线(编辑前)被调用方的时序和能耗,计算增量:
.o.prevdiff_pct = ((post_value - pre_value) / pre_value) * 100如果MCP不可用,跳过时序/能耗计算并标注“(timing/energy unavailable — MCP not connected)”。
Analyze the CFG output
分析CFG输出
Check the CFG text from the extract-assembly output for structural hazards:
- Missing declarations: are callees present in the binary with the expected signatures? If a callee is absent, flag a missing forward declaration or linkage issue.
- Indirect calls: any to a register in a callee's CFG — flag as a potential CFI hazard.
bl - Recursion/cycles: back edges in the CFG with no visible exit condition — flag unbounded recursion.
- Latency: use the MCP timing results above; flag any callee whose worst path violates a timing budget, or where the cumulative hot-path chain exceeds a known deadline.
- Energy: use the MCP energy results above; flag any callee or hot-path chain whose energy cost is notably high relative to the use case (e.g., battery-powered device, ISR context, tight power budget).
检查extract-assembly输出的CFG文本,排查结构风险:
- 声明缺失:被调用方是否以预期签名存在于二进制中?如果被调用方不存在,标记前向声明缺失或链接问题。
- 间接调用:被调用方CFG中存在跳转到寄存器的指令——标记为潜在CFI风险。
bl - 递归/循环:CFG中存在无可见退出条件的回边——标记为无界递归。
- 延迟:使用上面的MCP时序结果;标记任何最差路径超过时序预算的被调用方,或者累计热路径链超过已知截止时间的情况。
- 能耗:使用上面的MCP能耗结果;标记任何被调用方或热路径链的能耗相对于使用场景明显过高的情况(例如电池供电设备、ISR上下文、严格功耗预算)。
Reason over results
结果推理
After analyzing the CFG and receiving LOCI results, reason through the
following before proceeding to output. This is a mandatory thinking step —
do not skip it when results look clean. Increment R (reasoning cycle
counter) by 1 now.
Interpretation questions:
- What is this function's role in the system — is it on a hot path, ISR, periodic task, or called once? This determines whether any timing delta is critical, advisory, or irrelevant.
- If exists: is
.o.prev? If yes — change is within measurement noise, treat as stable. If|delta| < std_dev— change is real; flag it. If no|delta| > std_dev: this is the first measurement — record these numbers as the baseline and note no prior exists for comparison..o.prev - Does std_dev indicate a stable path or high hardware variance — and why (cache sensitivity, branch misprediction, pipeline stalls visible in CFG)?
- Is a timing budget known from the session context? If yes, compare hot-path worst against it and flag if exceeded. If no budget is known, report the number and skip the fit assessment.
- What does the CFG structure explain about the timing — which blocks dominate, are there expensive paths the new code will always hit?
- Is the hot-path energy distribution balanced across callees, or does one callee dominate? If dominated, that callee is the leverage point — plan to cache its result, call it less frequently, or substitute a lighter alternative.
- Do any CFG findings (indirect calls, recursion, missing declarations) change the design — does the plan need a guard, a different callee, or a linkage fix?
Escalation triggers (run skill inline, then reason over its results):
Escalate to when — increment R by 1 at trigger:
stack-depth- Execution context is ISR, HWI, or interrupt callback, AND call chain depth > 3 levels visible in CFG, OR
- Recursion already flagged in CFG analysis above, OR
- Plan adds a new RTOS task (xTaskCreate, Task_construct, osThreadNew) that needs stack sizing, OR
- Plan introduces large local variables on stack (buffers, arrays, C++ objects with non-trivial constructors), OR
- Plan adds a known-deep callee (printf, snprintf, crypto, TLS functions).
After stack-depth returns, reason over its results — increment R by 1:
- Does worst-case stack depth fit the task's or ISR's configured stack budget?
- Are there large frames that could move to static or heap allocation?
- Does any frame in the chain add cost the plan can eliminate?
- Could the call chain be flattened to reduce depth? → adjust plan based on conclusion before proceeding.
Escalate to when — increment R by 1 at trigger:
memory-report- The plan introduces significant new static allocations (large buffers, global arrays, static structs) visible from reading the source, OR
- exists and the plan grows or restructures existing data sections.
.o.prev
After memory-report returns, reason over its results — increment R by 1:
- Does the new allocation fit within available ROM/RAM headroom? (answerable only if map file was provided — memory_regions shows usage %; without map file, report section size delta only)
- Which region is under most pressure after the change?
- Does the plan need to reduce static footprint before proceeding? → adjust plan based on conclusion before proceeding.
分析完CFG并收到LOCI结果后,在输出前先梳理以下问题。这是强制思考步骤——即便结果看起来没问题也不要跳过。现在将R(推理循环计数器)加1。
解读问题:
- 该函数在系统中的角色是什么——它在热路径、ISR、周期任务上,还是仅被调用一次?这决定了时序增量是关键、建议还是无关项。
- 如果存在:
.o.prev是否成立?如果是——改动在测量噪声范围内,视为稳定。如果|delta| < std_dev——改动是真实的,需要标记。如果没有|delta| > std_dev:这是第一次测量——将这些数值记录为基线,并注明没有历史数据可对比。.o.prev - 标准差说明路径稳定还是硬件方差高——原因是什么(缓存敏感性、分支预测失败、CFG中可见的流水线停顿)?
- 会话上下文中是否有时序预算?如果有,将热路径最差情况与之对比,超量则标记。如果没有已知预算,上报数值即可,跳过适配性评估。
- CFG结构能解释哪些时序特征——哪些块占比最高,有没有新代码一定会命中的高开销路径?
- 热路径能耗在各被调用方之间分布是否均衡,还是单个被调用方占比过高?如果占比过高,该被调用方就是优化着力点——计划缓存其结果、降低调用频率,或者替换为更轻量的实现。
- 有没有CFG发现(间接调用、递归、声明缺失)需要调整设计——计划是否需要增加 guard、更换被调用方,或者修复链接问题?
升级触发条件(内联运行对应Skill,然后分析其结果):
升级到 当满足以下条件时——触发时R加1:
stack-depth- 执行上下文是ISR、HWI或中断回调,且CFG中可见调用链深度>3层,或者
- 上面的CFG分析已经标记了递归,或者
- 计划新增需要栈大小配置的RTOS任务(xTaskCreate、Task_construct、osThreadNew),或者
- 计划在栈上引入大型局部变量(缓冲区、数组、带非平凡构造函数的C++对象),或者
- 计划添加已知深度很深的被调用方(printf、snprintf、加密、TLS函数)。
After stack-depth returns, reason over its results — increment R by 1:
- 最差情况栈深度是否符合任务或ISR配置的栈预算?
- 有没有可以移动到静态或堆分配的大帧?
- 调用链中有没有可以通过计划消除的开销帧?
- 能不能扁平化调用链降低深度? → 继续下一步前根据结论调整计划。
升级到 当满足以下条件时——触发时R加1:
memory-report- 计划引入可观的新静态分配(从源码中可见的大缓冲区、全局数组、静态结构体),或者
- 存在且计划扩大或重构现有数据段。
.o.prev
memory-report返回结果后,分析其结果——R加1:
- 新分配是否适配可用的ROM/RAM余量?(仅当提供了map文件时可回答——memory_regions会显示使用率百分比;没有map文件时仅上报段大小增量)
- 改动后哪个区域的压力最大?
- 继续下一步前计划是否需要减小静态占用? → 继续下一步前根据结论调整计划。
Re-query loop
重新查询循环
After reasoning, check whether a better candidate exists before committing to
the plan. If any of the following is true, go back to Extract assembly with
the alternative callees and repeat through Reason over results:
- Reasoning identified a lighter or safer alternative callee worth evaluating
- A flagged callee (timing violation, CFI hazard, recursion) has a named alternative visible in the source files already read
- Hot-path energy is dominated by one callee that may have a lighter variant
- The plan for the new function changed (different call sequence, new callees introduced) and those callees have not yet been measured by LOCI — re-query with the new callee set before finalizing the plan
Increment R by 1 and M by the number of new MCP calls for each re-query cycle.
Cycle limit: 3 re-query iterations maximum. If the limit is reached without
a stable plan, emit the best candidate found and note the cycle limit was hit.
Convergence condition — exit the loop when:
- The plan is stable (no new callees to evaluate and no unresolved flags), OR
- All remaining flags are ✗ BLOCK (require user decision, not further querying), OR
- The cycle limit is reached.
推理完成后,在确定计划前检查是否存在更优的候选方案。如果满足以下任一条件,回到提取汇编步骤使用替代被调用方,重复到结果推理的流程:
- 推理发现值得评估的更轻量或更安全的替代被调用方
- 被标记的被调用方(时序违规、CFI风险、递归)在已读取的源文件中有可见的命名替代实现
- 热路径能耗被单个可能有更轻量变体的被调用方主导
- 新函数的计划发生变化(不同的调用序列、引入新的被调用方)且这些被调用方尚未经过LOCI测量——在最终确定计划前使用新的被调用方集合重新查询
每次重新查询循环,R加1,M增加新的MCP调用数量。
循环上限:最多3次重新查询迭代。 如果达到上限仍未得到稳定计划,输出找到的最优候选方案并注明达到循环上限。
收敛条件——满足以下条件时退出循环:
- 计划稳定(没有新的被调用方需要评估,且没有未解决的标记),或者
- 所有剩余标记都是✗ BLOCK(需要用户决策,无需进一步查询),或者
- 达到循环上限。
Output format
输出格式
Emit the preflight report in the response text, before describing what
you will write. Keep it short when things are clean; be specific when they
are not. In mode, the report goes in the response — NOT inside the
plan body. Always use the full structured format below with per-callee
timings and itemized CFG checks; never condense into a single-line summary.
/planundefined在描述你要编写的内容之前,在响应文本中输出预检报告。情况正常时尽量简短,有问题时请明确说明。在模式下,报告放在响应中——不要放在计划正文里。始终使用下面的完整结构化格式,包含单被调用方时序和逐项CFG检查;不要压缩为单行摘要。
/planundefinedPreflight: <FunctionName>
Preflight: <FunctionName>
Execution (<loci_target>)
Execution (<loci_target>)
Per-callee:
<callee_1>: worst=XXX.XX ns energy=X.XX uWs
<callee_2>: worst=XXX.XX ns energy=X.XX uWs
Hot path total: worst=XXX.XX ns energy=X.XX uWs
Per-callee:
<callee_1>: worst=XXX.XX ns energy=X.XX uWs
<callee_2>: worst=XXX.XX ns energy=X.XX uWs
Hot path total: worst=XXX.XX ns energy=X.XX uWs
CFG Analysis
CFG Analysis
Missing declarations: [OK | ⚠ <callee> absent — forward declaration or linkage issue]
Indirect calls: [OK | ⚠ <callee>: bl to register — potential CFI hazard]
Recursion/cycles: [OK | ⚠ <callee>: back edge with no visible exit condition]
Call graph: [OK | ⚠ <issue>]
Latency: [OK | ⚠ <callee>: worst=XXX ns exceeds budget | (timing/energy unavailable — MCP not connected)]
Energy: [OK | ⚠ hot-path sum X.XX uWs | (timing/energy unavailable — MCP not connected)]
Execution fit: GOOD | ADJUST PLAN | STOP
→ <one sentence: what changes, if any, before writing>
When modifying an existing function (`.o.prev` available), add delta:Missing declarations: [OK | ⚠ <callee> absent — forward declaration or linkage issue]
Indirect calls: [OK | ⚠ <callee>: bl to register — potential CFI hazard]
Recursion/cycles: [OK | ⚠ <callee>: back edge with no visible exit condition]
Call graph: [OK | ⚠ <issue>]
Latency: [OK | ⚠ <callee>: worst=XXX ns exceeds budget | (timing/energy unavailable — MCP not connected)]
Energy: [OK | ⚠ hot-path sum X.XX uWs | (timing/energy unavailable — MCP not connected)]
Execution fit: GOOD | ADJUST PLAN | STOP
→ <one sentence: what changes, if any, before writing>
修改现有函数时(有`.o.prev`可用),增加增量部分:Delta (vs baseline)
Delta (vs baseline)
Baseline Projected Diff
Worst path: XXX.XX ns XXX.XX ns +X.X%
Energy: XXX.XX uWs XXX.XX uWs +X.X%
Severity:
- **OK** — nothing to flag for this check
- **⚠ RISK** — likely bug or concern; adjust the plan to fix it before or during writing
- **✗ BLOCK** — almost certainly wrong; resolve with the user before writing
All-clear shorthand (use when all checks pass):Preflight <FunctionName>: execution fit is good — proceeding with plan.
undefinedBaseline Projected Diff
Worst path: XXX.XX ns XXX.XX ns +X.X%
Energy: XXX.XX uWs XXX.XX uWs +X.X%
严重等级:
- **OK**——该检查项无需要标记的问题
- **⚠ RISK**——可能存在bug或隐患;在编写前或编写过程中调整计划修复
- **✗ BLOCK**——几乎肯定有问题;编写前先和用户确认解决
所有检查通过时可使用简写:Preflight <FunctionName>: execution fit is good — proceeding with plan.
undefinedAdjusting the plan based on findings
根据结果调整计划
The value of running preflight during thinking is that findings change the
plan, not just add comments:
- A missing forward declaration → add it as a step before the function edit
- An unbounded loop in a callee → plan to add a termination guard or budget
- A callee timing violation → plan to cache the result, call asynchronously, or choose a lighter alternative before committing to the design
- An energy concern → plan to batch calls, use a lighter alternative, or move work off the hot path
Write the adjusted plan, then write the code. Do not write the code and then
note risks afterward — that defeats the purpose.
在思考阶段运行预检的价值在于发现的问题会改变计划,而不仅仅是增加注释:
- 前向声明缺失→在函数编辑前增加添加声明的步骤
- 被调用方存在无界循环→计划添加终止guard或预算
- 被调用方时序违规→计划缓存结果、异步调用,或者在确定设计前选择更轻量的替代方案
- 能耗问题→计划批量调用、使用更轻量的替代方案,或者将任务移出热路径
编写调整后的计划,然后再写代码。不要先写代码再备注风险——这违背了预检的目的。
LOCI voice remark
LOCI 话术备注
Before the footer, add one short LOCI voice remark (max 15 words) that
acknowledges the user's work grounded in a specific number from the
analysis. Attribute improvements to the user ("clean work", "smart move",
"tight code"). For concerns, be honest and constructive with specifics.
Skip if the analysis produced no results or the user needs raw data only.
在页脚前,添加一句简短的LOCI话术备注(最多15个单词),基于分析中的具体数值认可用户的工作。将改进归功于用户(“clean work”、“smart move”、“tight code”)。如果是问题,要诚实且有建设性地给出具体说明。如果分析没有生成结果或者用户只需要原始数据可以跳过。
LOCI footer
LOCI 页脚
After emitting the preflight report (or all-clear shorthand), append this footer
as the last thing printed — only if N > 0 (at least one function was sent to LOCI).
If no functions were processed (MCP unavailable or no callees to measure), do NOT emit the footer.
Record cumulative stats (run via Bash before rendering the footer):
<venv-python> <plugin-dir>/lib/loci_stats.py record --skill preflight --functions <N> --mcp-calls <M> --co-reasoning <R>Read cumulative summary (run via Bash; capture output):
<venv-python> <plugin-dir>/lib/loci_stats.py summaryRender the footer — include the summary line only if the command produced output:
─── LOCI · preflight ───────────────────
<N> functions · <M> MCP calls · <R> co-reasoning
escalated: <skills> ← omit if no escalation
<cumulative-summary-output> ← omit if empty
────────────────────────────────────────- N = unique callee functions whose assembly was sent to LOCI
- M = MCP calls to (exec-behaviors)
mcp__loci__get_assembly_block_exec_behavior - R = co-reasoning: 1 for the initial LOCI result pass, +1 for each re-query loop iteration, +2 for each escalated skill (stack-depth, memory-report) — 1 at trigger, 1 when reasoning over results
- escalated = space-separated list of skills called (e.g. ); omit the line entirely if no escalation occurred
stack-depth · memory-report
输出预检报告(或全通过简写)后,仅当N>0(至少有一个函数被发送到LOCI)时,在最后追加该页脚。如果没有处理任何函数(MCP不可用或没有被调用方需要测量),不要输出页脚。
记录累计统计数据(渲染页脚前通过Bash运行):
<venv-python> <plugin-dir>/lib/loci_stats.py record --skill preflight --functions <N> --mcp-calls <M> --co-reasoning <R>读取累计摘要(通过Bash运行,捕获输出):
<venv-python> <plugin-dir>/lib/loci_stats.py summary渲染页脚——仅当命令有输出时包含摘要行:
─── LOCI · preflight ───────────────────
<N> functions · <M> MCP calls · <R> co-reasoning
escalated: <skills> ← 没有升级则省略
<cumulative-summary-output> ← 为空则省略
────────────────────────────────────────- N = 汇编被发送到LOCI的唯一被调用方函数数量
- M = 到的MCP调用次数(exec-behaviors)
mcp__loci__get_assembly_block_exec_behavior - R = 协同推理:初始LOCI结果处理计1,每次重新查询循环迭代加1,每个升级的Skill(stack-depth、memory-report)加2——触发时计1,结果推理时计1
- escalated = 调用的Skill空格分隔列表(例如);如果没有升级则完全省略该行
stack-depth · memory-report