loci-preflight

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

loci-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:
  1. User describes the task
  2. You read the relevant files to understand the call site and surrounding code
  3. ← run preflight here, while thinking
  4. Adjust the plan based on findings
  5. 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.
在你明确需要编写哪些函数之后、发起任何编辑/写入调用之前,把预检作为制定计划的一环运行:
  1. 用户描述任务
  2. 你阅读相关文件,理解调用点和周边代码
  3. ← 在此处思考阶段运行预检
  4. 根据分析结果调整计划
  5. 编写代码
计划模式: 请始终在响应文本中输出完整的预检报告(执行、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 run
/mcp
in 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.
For plugin to work mcp should be authenticated and connected.
Read the persisted detection results from
state/project-context.json
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.
json
{
  "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
system-reminder
block emitted at session start for:
Target: <target>, Compiler: <compiler>, Build: <build>
LOCI target: <loci_target>
Map the LOCI target to loci MCP supported architectures and binary targets:
LOCI targetTime from CPU
aarch64A53
armv7e-mCortexM4
armv6-mCortexM0P
tc3xxTC399
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 run
/mcp
in 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完成认证并连接。
读取插件目录下
state/project-context.json
中持久化的检测结果。该文件由setup.sh在会话启动时写入一次,是编译器、架构和构建系统的唯一可信来源。请勿重新运行检测脚本。
json
{
  "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-reminder
块,确认包含以下内容:
Target: <target>, Compiler: <compiler>, Build: <build>
LOCI target: <loci_target>
将LOCI目标映射到loci MCP支持的架构和二进制目标:
LOCI targetTime from CPU
aarch64A53
armv7e-mCortexM4
armv6-mCortexM0P
tc3xxTC399
CPU列指明了LOCI时序和能耗预测所基于的真实硅硬件。
如果架构不在该表中,输出以下内容并停止:
undefined

Preflight: 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.
undefined
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.
undefined

Step 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
.o
files is the primary path — you do NOT need a fully linked binary.
This works for all supported platforms and compilers — the
-c
flag is universal across gcc, clang, tiarmclang, arm-none-eabi-gcc, tricore-elf-gcc, etc. Use the compiler and target detected in Step 0.
Primary path:
.o
partial compilation
  1. If a previous
    .o
    exists for the source file, save it as
    .o.prev
    (this enables delta reporting in Step 3).
  2. Compile only the relevant source file with
    -c
    . Always include
    -g
    to emit DWARF debug info (required by asm-analyze):
    <compiler> -g <flags> -c <source> -o <basename>.o
  3. Validate the .o — a standalone
    -c
    compile can exit 0 yet produce an empty object file when the source is wrapped in
    #if
    /
    #ifdef
    guards whose defines (
    -D
    ) were not on the command line. After compiling, run:
    <asm-analyze-cmd> extract-symbols --elf-path <basename>.o --arch <loci_target>
    If 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.
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
.o
with
-c -g
(primary path steps 1–2).
The binary is used for analysis; the
.o
is required for the snapshot pipeline — the PreToolUse hook snapshots it as
.o.prev
before each Edit, enabling delta comparison in post-edit. Skipping the
.o
compilation breaks the entire pre/post chain.
Hard stop: no compilation possible
If there is no binary, no
.o
, and compilation is not possible (missing dependencies, build errors, etc.), the skill MUST stop:
undefined
目标是获取包含新代码将要调用的被调用方的编译产物。
.o
文件的部分编译是主要路径——你不需要完全链接的二进制文件。
这适用于所有支持的平台和编译器——
-c
参数在gcc、clang、tiarmclang、arm-none-eabi-gcc、tricore-elf-gcc等编译器中都是通用的。使用步骤0中检测到的编译器和目标。
主要路径:
.o
部分编译
  1. 如果源文件已有之前生成的
    .o
    文件,将其保存为
    .o.prev
    (这支持步骤3中的增量报告)。
  2. 仅使用
    -c
    参数编译相关源文件,始终包含
    -g
    参数输出DWARF调试信息(asm-analyze需要该信息):
    <compiler> -g <flags> -c <source> -o <basename>.o
  3. 验证
    .o
    文件
    ——当源文件被
    #if
    /
    #ifdef
    guard包裹,且命令行中没有对应的定义(
    -D
    )时,单独的
    -c
    编译可能返回退出码0但生成空目标文件。编译完成后运行:
    <asm-analyze-cmd> extract-symbols --elf-path <basename>.o --arch <loci_target>
    如果结果显示0个符号,或者返回提到“no code”或“preprocessor”的错误,说明目标函数被编译掉了,请回退到下面的次要路径
次要路径:现有二进制文件
仅当用户明确提供完整二进制文件(.elf、.out),或者被调用方跨多个编译单元需要链接时,才使用该路径。
即便使用次要路径,你仍然必须按照主要路径的步骤1-2将源文件编译为带
-c -g
参数的
.o
文件。
二进制文件用于分析
.o
文件是快照流水线的必需项——PreToolUse钩子会在每次编辑前将其快照为
.o.prev
,支持编辑后的增量对比。跳过
.o
编译会破坏整个前后校验链。
强制停止:无法编译
如果没有二进制文件、没有
.o
文件,且无法完成编译(依赖缺失、构建错误等),该Skill必须停止:
undefined

Preflight: 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
asm-analyze command:
,
venv python:
, and
plugin dir:
from the LOCI session context (system-reminder at session start). Use these as
<asm-analyze-cmd>
,
<venv-python>
, and
<plugin-dir>
in the commands below.
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
control_flow_graph
field with annotated CFGs in text-format optimized for LLM analysis.
The JSON output contains
timing_csv_chunks
,
timing_csv
, and
timing_architecture
fields needed for the MCP call.
the 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包含
control_flow_graph
字段,存储了优化后适合LLM分析的文本格式带标注CFG。
JSON输出还包含MCP调用所需的
timing_csv_chunks
timing_csv
timing_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
mcp__loci__get_assembly_block_exec_behavior
for all chunks in parallel (one call per chunk, all in the same response):
  • csv_text
    : the chunk
  • architecture
    : the
    timing_architecture
    field from the output above
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_ns
    -
    std_dev
  • Worst path =
    execution_time_ns
    +
    std_dev
  • Energy =
    energy_ws
    (report in uWs; convert from Ws by multiplying by 1e6)
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
.o.prev
exists, also extract timing and energy for the baseline (pre-edit) callees. Compute delta:
diff_pct = ((post_value - pre_value) / pre_value) * 100
If 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_ns
    -
    std_dev
  • 最差路径 =
    execution_time_ns
    +
    std_dev
  • 能耗 =
    energy_ws
    (单位为uWs,从Ws转换需乘以1e6)
累加热路径调用链的最差情况时序和能耗。如果累计链超过已知的截止时间或能耗预算,请在编写代码前就标记出来。
如果是修改现有函数且存在
.o.prev
,还需要提取基线(编辑前)被调用方的时序和能耗,计算增量:
diff_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
    bl
    to a register in a callee's CFG — flag as a potential CFI hazard.
  • 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中存在跳转到寄存器的
    bl
    指令——标记为潜在CFI风险。
  • 递归/循环: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
    .o.prev
    exists: is
    |delta| < std_dev
    ? If yes — change is within measurement noise, treat as stable. If
    |delta| > std_dev
    — change is real; flag it. If no
    .o.prev
    : this is the first measurement — record these numbers as the baseline and note no prior exists for comparison.
  • 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
stack-depth
when — increment R by 1 at trigger:
  • 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
memory-report
when — increment R by 1 at trigger:
  • The plan introduces significant new static allocations (large buffers, global arrays, static structs) visible from reading the source, OR
  • .o.prev
    exists and the plan grows or restructures existing data sections.
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,然后分析其结果):
升级到
stack-depth
当满足以下条件时——触发时R加1:
  • 执行上下文是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配置的栈预算?
  • 有没有可以移动到静态或堆分配的大帧?
  • 调用链中有没有可以通过计划消除的开销帧?
  • 能不能扁平化调用链降低深度? → 继续下一步前根据结论调整计划。
升级到
memory-report
当满足以下条件时——触发时R加1:
  • 计划引入可观的新静态分配(从源码中可见的大缓冲区、全局数组、静态结构体),或者
  • 存在
    .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
/plan
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.
undefined
在描述你要编写的内容之前,在响应文本中输出预检报告。情况正常时尽量简短,有问题时请明确说明。在
/plan
模式下,报告放在响应中——不要放在计划正文里。始终使用下面的完整结构化格式,包含单被调用方时序和逐项CFG检查;不要压缩为单行摘要。
undefined

Preflight: <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.
undefined
Baseline 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.
undefined

Adjusting 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 summary
Render 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
    mcp__loci__get_assembly_block_exec_behavior
    (exec-behaviors)
  • 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.
    stack-depth · memory-report
    ); omit the line entirely if no escalation occurred
输出预检报告(或全通过简写)后,仅当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__loci__get_assembly_block_exec_behavior
    的MCP调用次数(exec-behaviors)
  • R = 协同推理:初始LOCI结果处理计1,每次重新查询循环迭代加1,每个升级的Skill(stack-depth、memory-report)加2——触发时计1,结果推理时计1
  • escalated = 调用的Skill空格分隔列表(例如
    stack-depth · memory-report
    );如果没有升级则完全省略该行